Files
Super-Mario-Bros.-Remastere…/Scripts/UI/SelectableInputOptionNode.gd
2025-09-27 21:17:50 +01:00

161 lines
4.3 KiB
GDScript

class_name SelectableInputOption
extends HBoxContainer
@export var settings_category := "video"
@export var selected := false
@export var action_names := [""]
@export var title := ""
@export_enum("Keyboard", "Controller") var type := 0
@export var player_idx := 0
signal input_changed(action_name: String, input_event: InputEvent)
var awaiting_input := false
static var rebinding_input := false
var event_name := ""
var can_remap := true
var current_device_brand := 0
var input_event: InputEvent = null
const button_id_translation := [
["A", "B", ""],
["B", "A", ""],
["X", "Y", ""],
["Y", "X", ""],
["Select", "-", "Share"],
"Home",
["Start", "+", "Options"],
["LS Push", "LS Push", "L3"],
["RS Push", "RS Push", "R3"],
["LB", "L", "L1"],
["RB", "R", "R1"],
"DPad U",
"DPad D",
"DPad L",
"DPad R"
]
func _ready() -> void:
update_value()
func _process(_delta: float) -> void:
if selected:
handle_inputs()
$Cursor.modulate.a = int(selected)
func update_value() -> void:
$Title.text = tr(title) + ":"
$Value.text = get_event_string(input_event) if not awaiting_input else "Press Any..."
func handle_inputs() -> void:
if selected and can_remap:
if Input.is_action_just_pressed("ui_accept"):
begin_remap()
func begin_remap() -> void:
$Timer.stop()
$Timer.start()
rebinding_input = true
can_remap = false
get_parent().can_input = false
await get_tree().create_timer(0.1).timeout
awaiting_input = true
update_value()
func _input(event: InputEvent) -> void:
if awaiting_input == false: return
if event.is_pressed() == false:
return
#if event is InputEventKey:
#if event.as_text_physical_keycode() == "Escape":
#cancel_remap()
#return
if type == 0 and event is InputEventKey:
map_event_to_action(event)
elif type == 1 and (event is InputEventJoypadButton or event is InputEventJoypadMotion):
if event is InputEventJoypadMotion:
event.axis_value = sign(event.axis_value)
map_event_to_action(event)
func map_event_to_action(event) -> void:
for action_name in action_names:
var action = action_name
if action.contains("ui_") == false and action != "pause":
action = action_name + "_" + str(player_idx)
var events = InputMap.action_get_events(action).duplicate()
events[type] = event
InputMap.action_erase_events(action)
for i in events:
InputMap.action_add_event(action, i)
input_changed.emit(action, event)
input_event = event
awaiting_input = false
await get_tree().create_timer(0.1).timeout
rebinding_input = false
get_parent().can_input = true
can_remap = true
update_value()
func get_event_string(event: InputEvent) -> String:
var event_string := ""
if event is InputEventKey:
print(event.keycode)
event_string = OS.get_keycode_string(event.keycode)
elif event is InputEventJoypadButton:
var translation = button_id_translation[event.button_index]
if translation is Array:
translation = translation[current_device_brand]
event_string = translation
elif event is InputEventJoypadMotion:
var stick = "LS"
var direction = "Left"
if event.axis == JOY_AXIS_TRIGGER_LEFT:
return ["LT", "ZL", "L2"][current_device_brand]
elif event.axis == JOY_AXIS_TRIGGER_RIGHT:
return ["RT", "ZR", "R2"][current_device_brand]
if event.axis == JOY_AXIS_RIGHT_X or event.axis == JOY_AXIS_RIGHT_Y:
stick = "RS"
if (event.axis == JOY_AXIS_LEFT_X or event.axis == JOY_AXIS_RIGHT_X):
if event.axis_value < 0:
direction = "Left"
else:
direction = "Right"
elif (event.axis == JOY_AXIS_LEFT_Y or event.axis == JOY_AXIS_RIGHT_Y):
if event.axis_value < 0:
direction = "Up"
else:
direction = "Down"
event_string = stick + " " + direction
else:
pass
return event_string
func _unhandled_input(event: InputEvent) -> void:
if event is not InputEventJoypadButton and event is not InputEventJoypadMotion:
return
var device_name = Input.get_joy_name(event.device)
if device_name.to_upper().contains("NINTENDO") or device_name.to_upper().contains("SWITCH") or device_name.to_upper().contains("WII"):
current_device_brand = 1
elif device_name.to_upper().contains("PS") or device_name.to_upper().contains("PLAYSTATION"):
current_device_brand = 2
else:
current_device_brand = 0
func cancel_remap() -> void:
awaiting_input = false
await get_tree().create_timer(0.1).timeout
rebinding_input = false
get_parent().can_input = true
can_remap = true