extends Node signal mode_changed(mode: Mode) enum Mode { KB_MOUSE, CONTROLLER } enum ControllerType { XBOX, SONY, NINTENDO, STEAM, KNOCKOFF } const LEFT_TRIGGER_SPRITE_INDEX: int = 20 const RIGHT_TRIGGER_SPRITE_INDEX: int = 21 const LEFT_STICK_SPRITE_INDEX: int = 23 const RIGHT_STICK_SPRITE_INDEX: int = 24 @export var mode: Mode = Mode.KB_MOUSE @export var _controller: ControllerType = ControllerType.XBOX: set(value): _set_current_prompts(value) _controller = value @export var _prompt_grid_size: int = 5 @export var _prompt_icon_size: int = 60 var _prompts_xbox := preload("res://assets/textures/ui/prompts_xbox.png") var _prompts_sony := preload("res://assets/textures/ui/prompts_sony.png") var _prompts_nintendo := preload("res://assets/textures/ui/prompts_nintendo.png") var _prompts_steam := preload("res://assets/textures/ui/prompts_steam.png") var _prompts_knockoff := preload("res://assets/textures/ui/prompts_knockoff.png") var _current_prompts: CompressedTexture2D = _prompts_xbox func _ready() -> void: Debugger.add_event("mode_changed") mode_changed.connect( func(new_mode: Mode) -> void: Debugger.event_emitted("mode_changed", [Mode.keys()[new_mode]]) ) _get_controller_type() func _input(event: InputEvent) -> void: if event is InputEventMouseMotion: return var event_mode := _get_event_mode(event) if mode == Mode.KB_MOUSE and event_mode == Mode.CONTROLLER: mode = Mode.CONTROLLER mode_changed.emit(mode) if mode == Mode.CONTROLLER and event_mode == Mode.KB_MOUSE: mode = Mode.KB_MOUSE mode_changed.emit(mode) if Debugger.show_debug() and event.is_pressed(): Debugger.text("input", _get_event_prompt_current_mode(event)) func get_action_prompt(action: StringName) -> String: var events := InputMap.action_get_events(action) var bbcode: PackedStringArray = [] for event in events: var event_bbcode := _get_event_prompt_current_mode(event) if event_bbcode: bbcode.append(event_bbcode) if bbcode.size() != 0: return " / ".join(bbcode) return _get_event_prompt(events[0]) if events.size() != 0 else "???" func _get_event_prompt_current_mode(event: InputEvent) -> String: var event_mode := _get_event_mode(event) if mode == Mode.CONTROLLER and event_mode == Mode.CONTROLLER: return _get_controller_prompt(event) if mode == Mode.KB_MOUSE and event_mode == Mode.KB_MOUSE: return _get_kb_mouse_prompt(event) return "" func _get_event_prompt(event: InputEvent) -> String: var event_mode := _get_event_mode(event) if event_mode == Mode.CONTROLLER: return _get_controller_prompt(event) if event_mode == Mode.KB_MOUSE: return _get_kb_mouse_prompt(event) return event.as_text() func _get_kb_mouse_prompt(event: InputEvent) -> String: if event is InputEventKey: var button_event := event as InputEventKey return button_event.as_text_physical_keycode() if event is InputEventMouseButton: return event.as_text() return event.as_text() func _get_controller_prompt(event: InputEvent) -> String: if event is InputEventJoypadButton: var button_event := event as InputEventJoypadButton return _get_prompt_sprite(button_event.button_index) if event is InputEventJoypadMotion: var motion_event := event as InputEventJoypadMotion if motion_event.axis == JOY_AXIS_LEFT_X or motion_event.axis == JOY_AXIS_LEFT_Y: return _get_prompt_sprite(LEFT_STICK_SPRITE_INDEX) if ( motion_event.axis == JOY_AXIS_RIGHT_X or motion_event.axis == JOY_AXIS_RIGHT_Y ): return _get_prompt_sprite(RIGHT_STICK_SPRITE_INDEX) if motion_event.axis == JOY_AXIS_TRIGGER_LEFT: return _get_prompt_sprite(LEFT_TRIGGER_SPRITE_INDEX) if motion_event.axis == JOY_AXIS_TRIGGER_RIGHT: return _get_prompt_sprite(RIGHT_TRIGGER_SPRITE_INDEX) return event.as_text() func _get_prompt_sprite(index: int) -> String: var region := _get_prompt_sprite_region(index) return ( "[img region=%d,%d,%d,%d height=%d width=%d]%s[/img]" % [ region.position.x, region.position.y, region.size.x, region.size.y, _prompt_icon_size, _prompt_icon_size, _current_prompts.resource_path ] ) func _get_prompt_sprite_region(index: int) -> Rect2i: var corner_x: int = index % _prompt_grid_size var corner_y: int = index / _prompt_grid_size var sprite_size: int = _current_prompts.get_width() / _prompt_grid_size return Rect2i( corner_x * sprite_size, corner_y * sprite_size, sprite_size, sprite_size, ) func _get_controller_type() -> void: var controller_name := Input.get_joy_name(0).to_lower() if ( controller_name.begins_with("ps") or controller_name.contains("sony") or controller_name.contains("playstation") ): _controller = ControllerType.SONY elif controller_name.contains("steam"): _controller = ControllerType.STEAM elif controller_name.contains("nintendo"): _controller = ControllerType.NINTENDO else: _controller = ControllerType.XBOX func _set_current_prompts(type: ControllerType) -> void: match type: ControllerType.XBOX: _current_prompts = _prompts_xbox ControllerType.SONY: _current_prompts = _prompts_sony ControllerType.NINTENDO: _current_prompts = _prompts_nintendo ControllerType.STEAM: _current_prompts = _prompts_steam ControllerType.KNOCKOFF: _current_prompts = _prompts_knockoff func _get_event_mode(event: InputEvent) -> Mode: if event is InputEventJoypadButton or event is InputEventJoypadMotion: return Mode.CONTROLLER return Mode.KB_MOUSE