SelectableInputOptionNode.gd 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. class_name SelectableInputOption
  2. extends HBoxContainer
  3. @export var settings_category := "video"
  4. @export var selected := false
  5. @export var action_name := ""
  6. @export var title := ""
  7. @export_enum("Keyboard", "Controller") var type := 0
  8. @export var player_idx := 0
  9. signal input_changed(action_name: String, input_event: InputEvent)
  10. var awaiting_input := false
  11. static var rebinding_input := false
  12. var event_name := ""
  13. var can_remap := true
  14. var current_device_brand := 0
  15. var input_event: InputEvent = null
  16. const button_id_translation := [
  17. ["A", "B", "~"],
  18. ["B", "A", "&"],
  19. ["X", "Y", "%"],
  20. ["Y", "X", "{"],
  21. ["Select", "-", "Share"],
  22. "Home",
  23. ["Start", "+", "Options"],
  24. ["LS Push", "LS Push", "L3"],
  25. ["RS Push", "RS Push", "R3"],
  26. ["LB", "L", "L1"],
  27. ["RB", "R", "R1"],
  28. "DPad U",
  29. "DPad D",
  30. "DPad L",
  31. "DPad R"
  32. ]
  33. func _process(_delta: float) -> void:
  34. if selected:
  35. handle_inputs()
  36. $Cursor.modulate.a = int(selected)
  37. $Title.text = tr(title) + ":"
  38. $Value.text = get_event_string(input_event) if not awaiting_input else "Press Any..."
  39. func handle_inputs() -> void:
  40. if selected and can_remap:
  41. if Input.is_action_just_pressed("ui_accept"):
  42. begin_remap()
  43. func begin_remap() -> void:
  44. $Timer.stop()
  45. $Timer.start()
  46. rebinding_input = true
  47. can_remap = false
  48. get_parent().can_input = false
  49. await get_tree().create_timer(0.1).timeout
  50. awaiting_input = true
  51. func _input(event: InputEvent) -> void:
  52. if awaiting_input == false: return
  53. if event.is_pressed() == false:
  54. return
  55. if event is InputEventKey:
  56. if event.as_text_physical_keycode() == "Escape":
  57. cancel_remap()
  58. return
  59. if type == 0 and event is InputEventKey:
  60. map_event_to_action(event)
  61. elif type == 1 and (event is InputEventJoypadButton or event is InputEventJoypadMotion):
  62. if event is InputEventJoypadMotion:
  63. event.axis_value = sign(event.axis_value)
  64. map_event_to_action(event)
  65. func map_event_to_action(event) -> void:
  66. var action = action_name + "_" + str(player_idx)
  67. var events = InputMap.action_get_events(action).duplicate()
  68. events[type] = event
  69. InputMap.action_erase_events(action)
  70. for i in events:
  71. InputMap.action_add_event(action, i)
  72. input_changed.emit(action, event)
  73. input_event = event
  74. awaiting_input = false
  75. await get_tree().create_timer(0.1).timeout
  76. rebinding_input = false
  77. get_parent().can_input = true
  78. can_remap = true
  79. func get_event_string(event: InputEvent) -> String:
  80. var event_string := ""
  81. if event is InputEventKey:
  82. event_string = OS.get_keycode_string(event.keycode)
  83. elif event is InputEventJoypadButton:
  84. var translation = button_id_translation[event.button_index]
  85. if translation is Array:
  86. translation = translation[current_device_brand]
  87. event_string = translation
  88. elif event is InputEventJoypadMotion:
  89. var stick = "LS"
  90. var direction = "Left"
  91. if event.axis == JOY_AXIS_TRIGGER_LEFT:
  92. return ["LT", "ZL", "L2"][current_device_brand]
  93. elif event.axis == JOY_AXIS_TRIGGER_RIGHT:
  94. return ["RT", "ZR", "R2"][current_device_brand]
  95. if event.axis == JOY_AXIS_RIGHT_X or event.axis == JOY_AXIS_RIGHT_Y:
  96. stick = "RS"
  97. if (event.axis == JOY_AXIS_LEFT_X or event.axis == JOY_AXIS_RIGHT_X):
  98. if event.axis_value < 0:
  99. direction = "Left"
  100. else:
  101. direction = "Right"
  102. elif (event.axis == JOY_AXIS_LEFT_Y or event.axis == JOY_AXIS_RIGHT_Y):
  103. if event.axis_value < 0:
  104. direction = "Up"
  105. else:
  106. direction = "Down"
  107. event_string = stick + " " + direction
  108. return event_string
  109. func _unhandled_input(event: InputEvent) -> void:
  110. if event is not InputEventJoypadButton and event is not InputEventJoypadMotion:
  111. return
  112. var device_name = Input.get_joy_name(event.device)
  113. if device_name.to_upper().contains("NINTENDO") or device_name.to_upper().contains("SWITCH") or device_name.to_upper().contains("WII"):
  114. current_device_brand = 1
  115. elif device_name.to_upper().contains("PS") or device_name.to_upper().contains("PLAYSTATION"):
  116. current_device_brand = 2
  117. else:
  118. current_device_brand = 0
  119. func cancel_remap() -> void:
  120. awaiting_input = false
  121. await get_tree().create_timer(0.1).timeout
  122. rebinding_input = false
  123. get_parent().can_input = true
  124. can_remap = true