cadastery/scripts/globals/inputer.gd

189 lines
5.4 KiB
GDScript

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", [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 can_control_player() -> bool:
return Referencer.main.menu == null
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