diff --git a/assets/textures/ui/prompts_knockoff.png b/assets/textures/ui/prompts_knockoff.png new file mode 100644 index 0000000..7b0f321 --- /dev/null +++ b/assets/textures/ui/prompts_knockoff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:954ba2e131894885feeb38e1f0839796e76a137098577ff536627c2a49d8e11e +size 44221 diff --git a/assets/textures/ui/prompts_knockoff.png.import b/assets/textures/ui/prompts_knockoff.png.import new file mode 100644 index 0000000..37f3cbb --- /dev/null +++ b/assets/textures/ui/prompts_knockoff.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cl70fhjkyjmra" +path="res://.godot/imported/prompts_knockoff.png-5b647c81df243ea3ead18368bce1d392.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/textures/ui/prompts_knockoff.png" +dest_files=["res://.godot/imported/prompts_knockoff.png-5b647c81df243ea3ead18368bce1d392.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/textures/ui/prompts_nintendo.png b/assets/textures/ui/prompts_nintendo.png new file mode 100644 index 0000000..78d8442 --- /dev/null +++ b/assets/textures/ui/prompts_nintendo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5c5335bf5094ac8174ca6436afcbabfaa2cfa22e1182e9b22eb1c1b50c3384ec +size 40686 diff --git a/assets/textures/ui/prompts_nintendo.png.import b/assets/textures/ui/prompts_nintendo.png.import new file mode 100644 index 0000000..313983e --- /dev/null +++ b/assets/textures/ui/prompts_nintendo.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c2c31w2y6uxkx" +path="res://.godot/imported/prompts_nintendo.png-28ede9e8741f5cfaa72bad5138602590.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/textures/ui/prompts_nintendo.png" +dest_files=["res://.godot/imported/prompts_nintendo.png-28ede9e8741f5cfaa72bad5138602590.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/textures/ui/prompts_sony.png b/assets/textures/ui/prompts_sony.png new file mode 100644 index 0000000..8ad3319 --- /dev/null +++ b/assets/textures/ui/prompts_sony.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:843488aba6ed662ceb85ccd992209ba6037477dd4ed8a44b7697d187c874e7f7 +size 47555 diff --git a/assets/textures/ui/prompts_sony.png.import b/assets/textures/ui/prompts_sony.png.import new file mode 100644 index 0000000..c68aa28 --- /dev/null +++ b/assets/textures/ui/prompts_sony.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://4jxiawup7wc" +path="res://.godot/imported/prompts_sony.png-89cf210c76dd715bbc0618094b9884c9.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/textures/ui/prompts_sony.png" +dest_files=["res://.godot/imported/prompts_sony.png-89cf210c76dd715bbc0618094b9884c9.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/textures/ui/prompts_steam.png b/assets/textures/ui/prompts_steam.png new file mode 100644 index 0000000..56bddcd --- /dev/null +++ b/assets/textures/ui/prompts_steam.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ecf7cce88847d4122602bfdf60796a30beb20a8e435ab62a296639c70877251 +size 52011 diff --git a/assets/textures/ui/prompts_steam.png.import b/assets/textures/ui/prompts_steam.png.import new file mode 100644 index 0000000..1e1f09b --- /dev/null +++ b/assets/textures/ui/prompts_steam.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://brsup7v2ndbea" +path="res://.godot/imported/prompts_steam.png-db018fc85ed40282a93a1832de39afe4.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/textures/ui/prompts_steam.png" +dest_files=["res://.godot/imported/prompts_steam.png-db018fc85ed40282a93a1832de39afe4.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/textures/ui/prompts_xbox.png b/assets/textures/ui/prompts_xbox.png new file mode 100644 index 0000000..094295b --- /dev/null +++ b/assets/textures/ui/prompts_xbox.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:914c5da592b7452f28cc1d7d390cf797d9e123b1ff426cccf9859d9617e186f0 +size 49303 diff --git a/assets/textures/ui/prompts_xbox.png.import b/assets/textures/ui/prompts_xbox.png.import new file mode 100644 index 0000000..aee300d --- /dev/null +++ b/assets/textures/ui/prompts_xbox.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cdob73gkfcd7s" +path="res://.godot/imported/prompts_xbox.png-8e5a43d77f829c81cde286f296d4ac19.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/textures/ui/prompts_xbox.png" +dest_files=["res://.godot/imported/prompts_xbox.png-8e5a43d77f829c81cde286f296d4ac19.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/project.godot b/project.godot index 3cc2cb9..757cb25 100644 --- a/project.godot +++ b/project.godot @@ -22,15 +22,17 @@ config/icon="res://icon.svg" [autoload] +Debugger="*res://scenes/debugger.tscn" Settings="*res://scripts/globals/settings.gd" Networker="*res://scripts/globals/networker.gd" Cursorer="*res://scripts/globals/cursorer.gd" +Referencer="*res://scripts/globals/referencer.gd" +Inputer="*res://scripts/globals/inputer.gd" [debug] gdscript/warnings/untyped_declaration=2 gdscript/warnings/unsafe_property_access=2 -gdscript/warnings/unsafe_method_access=2 gdscript/warnings/unsafe_call_argument=2 gdscript/warnings/integer_division=0 @@ -123,6 +125,11 @@ camera_right={ "events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":1.0,"script":null) ] } +toggle_debug={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":96,"key_label":0,"unicode":96,"location":0,"echo":false,"script":null) +] +} [layer_names] diff --git a/scenes/debugger.tscn b/scenes/debugger.tscn new file mode 100644 index 0000000..4cdefd0 --- /dev/null +++ b/scenes/debugger.tscn @@ -0,0 +1,108 @@ +[gd_scene load_steps=3 format=3 uid="uid://da38h87ik1v4v"] + +[ext_resource type="Script" path="res://scripts/debug/debugger.gd" id="1_xl6mi"] + +[sub_resource type="SystemFont" id="SystemFont_184hu"] +font_names = PackedStringArray("Monospace") +font_weight = 700 + +[node name="Debugger" type="CanvasLayer"] +process_mode = 3 +process_priority = 1000 +process_physics_priority = 1000 +script = ExtResource("1_xl6mi") + +[node name="Control" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 + +[node name="LabelContainer1" type="VBoxContainer" parent="Control"] +layout_mode = 1 +anchors_preset = 9 +anchor_bottom = 1.0 +offset_right = 1300.0 +grow_vertical = 2 +mouse_filter = 2 + +[node name="Label1" type="RichTextLabel" parent="Control/LabelContainer1"] +clip_contents = false +layout_mode = 2 +mouse_filter = 2 +theme_override_constants/outline_size = 10 +theme_override_fonts/normal_font = SubResource("SystemFont_184hu") +theme_override_font_sizes/normal_font_size = 24 +bbcode_enabled = true +text = "Lorem Ipsum" +fit_content = true + +[node name="LabelContainer2" type="VBoxContainer" parent="Control"] +layout_mode = 1 +anchors_preset = 9 +anchor_bottom = 1.0 +offset_right = 1300.0 +grow_vertical = 2 +mouse_filter = 2 +alignment = 2 + +[node name="Label2" type="RichTextLabel" parent="Control/LabelContainer2"] +clip_contents = false +layout_mode = 2 +mouse_filter = 2 +theme_override_constants/outline_size = 10 +theme_override_fonts/normal_font = SubResource("SystemFont_184hu") +theme_override_font_sizes/normal_font_size = 24 +bbcode_enabled = true +text = "Lorem Ipsum" +fit_content = true + +[node name="LabelContainer3" type="VBoxContainer" parent="Control"] +layout_mode = 1 +anchors_preset = 11 +anchor_left = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -600.0 +grow_horizontal = 0 +grow_vertical = 2 +mouse_filter = 2 + +[node name="Label3" type="RichTextLabel" parent="Control/LabelContainer3"] +clip_contents = false +layout_mode = 2 +mouse_filter = 2 +theme_override_constants/outline_size = 10 +theme_override_fonts/normal_font = SubResource("SystemFont_184hu") +theme_override_font_sizes/normal_font_size = 24 +bbcode_enabled = true +text = "Lorem Ipsum" +fit_content = true + +[node name="LabelContainer4" type="VBoxContainer" parent="Control"] +layout_mode = 1 +anchors_preset = 11 +anchor_left = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -600.0 +grow_horizontal = 0 +grow_vertical = 2 +mouse_filter = 2 +alignment = 2 + +[node name="Label4" type="RichTextLabel" parent="Control/LabelContainer4"] +clip_contents = false +layout_mode = 2 +mouse_filter = 2 +theme_override_constants/outline_size = 10 +theme_override_fonts/normal_font = SubResource("SystemFont_184hu") +theme_override_font_sizes/normal_font_size = 24 +bbcode_enabled = true +text = "DEBUG CONTROLS +toggle debug: [ ` ] +toggle freelook: [ 1 ]" +fit_content = true diff --git a/scripts/debug/debugger.gd b/scripts/debug/debugger.gd new file mode 100644 index 0000000..861daeb --- /dev/null +++ b/scripts/debug/debugger.gd @@ -0,0 +1,312 @@ +extends CanvasLayer +## Handles displaying debug info. + +signal mode_changed(mode: Mode) + +enum Mode { DISABLED, PERFORMANCE, FULL } + +const LINE_WIDTH: float = 2 +const MARKER_RADIUS: float = 0.2 +const CIRCLE_RADIUS: float = 3 +const DEFAULT_COLOR: Color = Color.RED + +var mode: Mode = Mode.PERFORMANCE + +var _vectors_to_draw: Dictionary = {} +var _markers_to_draw: Dictionary = {} +var _circles_to_draw: Dictionary = {} +var _text_to_draw: Dictionary = {} +var _events_to_draw: Dictionary = {} + +var _label1_text: String = "" +var _label2_text: String = "" +var _label3_text: String = "" + +@onready var _control: Control = $Control +@onready var _label1: RichTextLabel = $Control/LabelContainer1/Label1 +@onready var _label2: RichTextLabel = $Control/LabelContainer2/Label2 +@onready var _label3: RichTextLabel = $Control/LabelContainer3/Label3 +@onready var _label4: RichTextLabel = $Control/LabelContainer4/Label4 + + +func _ready() -> void: + assert(_control, str(self) + ": _control missing!") + assert(_label1, str(self) + ": _label1 missing!") + assert(_label2, str(self) + ": _label2 missing!") + assert(_label3, str(self) + ": _label2 missing!") + assert(_label4, str(self) + ": _label2 missing!") + _control.draw.connect(_on_control_draw) + Inputer.mode_changed.connect(_on_inputer_mode_changed) + # enabled = OS.has_feature("editor") + _update_visibility() + _update_controls_label() + mode_changed.emit(mode) + + +func _process(_delta: float) -> void: + if mode == Mode.DISABLED: + return + + _control.queue_redraw() + + +func _input(event: InputEvent) -> void: + if event.is_action_pressed("toggle_debug"): + mode = wrapi(mode + 1, 0, Mode.size()) as Mode + _update_visibility() + mode_changed.emit(mode) + + +func show_debug() -> bool: + return mode == Mode.FULL + + +func text(key: String, value: Variant, label_index: int = 1) -> void: + if not show_debug(): + return + + _text_to_draw[key] = {"value": value, "label_index": label_index} + + +func add_event(key: String) -> void: + _events_to_draw[key] = {"frame": -9999, "args": []} + + +func event_emitted(key: String, args: Array[Variant] = []) -> void: + if not show_debug(): + return + + _events_to_draw[key] = {"frame": Engine.get_physics_frames(), "args": args} + + +func vector( + key: String, from: Vector3, to: Vector3, color: Color = DEFAULT_COLOR +) -> void: + if not show_debug(): + return + + _vectors_to_draw[key] = {"from": from, "to": to, "color": color, "on": true} + + +func marker( + key: String, + pos: Vector3, + radius: float = MARKER_RADIUS, + color: Color = DEFAULT_COLOR +) -> void: + if not show_debug(): + return + + _markers_to_draw[key] = ({"pos": pos, "radius": radius, "color": color, "on": true}) + + +func circle(key: String, pos: Vector3, color: Color = DEFAULT_COLOR) -> void: + if not show_debug(): + return + + _circles_to_draw[key] = {"pos": pos, "color": color, "on": true} + + +func _update_visibility() -> void: + visible = mode != Mode.DISABLED + + +func _unproject(pos: Vector3) -> Vector2: + return Referencer.main_camera.unproject_position(pos) + + +func _update_controls_label() -> void: + var label_text: String = ( + "DEBUG CONTROLS\ntoggle debug: %s" + % [ + Inputer.get_action_prompt("toggle_debug"), + ] + ) + + _label4.text = label_text + + +func _append_text(key: String, value: Variant, label_index: int) -> void: + var line := str(value) + + if value is int: + line = (" " if value >= 0 else "") + line + if (value as int) > 0: + line = "[color=sky_blue]%s[/color]" % line + elif (value as int) < 0: + line = "[color=salmon]%s[/color]" % line + + elif value is float: + line = (" " if value >= 0 else "") + "%.6f" % value + if value > 0: + line = "[color=sky_blue]%s[/color]" % line + elif value < 0: + line = "[color=salmon]%s[/color]" % line + + elif value is bool: + if value: + line = "[color=sky_blue]%s[/color]" % line + else: + line = "[color=salmon]%s[/color]" % line + + elif value is Vector3: + line = ( + "(%s, %s, %s)" + % [ + (" " if value.x >= 0 else "") + ("%.6f" % value.x), + (" " if value.y >= 0 else "") + ("%.6f" % value.y), + (" " if value.z >= 0 else "") + ("%.6f" % value.z), + ] + ) + + elif value is Vector2: + line = ( + "(%s, %s)" + % [ + (" " if value.x >= 0 else "") + ("%.6f" % value.x), + (" " if value.y >= 0 else "") + ("%.6f" % value.y), + ] + ) + + line = "%s: %s\n" % [key, line] + + if label_index == 2: + _label2_text += line + else: + _label1_text += line + + +func _append_event(key: String, frame: int, args: Array[Variant]) -> void: + var line := key + + if args.size() > 0: + line += "(%s)" % ", ".join(args.map(str)) + + var physics_frame := Engine.get_physics_frames() + var color := Color.SALMON.lerp( + Color.WHITE, clampf(float(physics_frame - frame) / 30.0, 0, 1) + ) + if physics_frame - frame < 5: + color = Color.SKY_BLUE + + line = "[color=#%s]%s[/color]\n" % [color.to_html(), line] + + _label3_text += line + + +func _draw_vector(from: Vector3, to: Vector3, color: Color) -> void: + if ( + not Referencer.main_camera.is_position_in_frustum(from) + and not Referencer.main_camera.is_position_in_frustum(to) + ): + return + + var start := _unproject(from) + var end := _unproject(to) + if (start - end).length() > 0: + _control.draw_line(start, end, color, LINE_WIDTH) + if get_viewport().get_visible_rect().has_point(end): + _draw_triangle(end, start.direction_to(end), 5, color) + + +func _draw_triangle( + pos: Vector2, + dir: Vector2, + size: float, + color: Color, +) -> void: + var a := pos + dir * size + var b := pos + dir.rotated(2 * PI / 3) * size + var c := pos + dir.rotated(4 * PI / 3) * size + var points := PackedVector2Array([a, b, c]) + _control.draw_polygon(points, PackedColorArray([color])) + + +func _draw_marker(pos: Vector3, radius: float, color: Color) -> void: + if not Referencer.main_camera.is_position_in_frustum(pos): + return + + var x_start := _unproject(pos + (Vector3.LEFT * radius)) + var x_end := _unproject(pos + (Vector3.RIGHT * radius)) + _control.draw_line(x_start, x_end, color, LINE_WIDTH) + + var y_start := _unproject(pos + (Vector3.UP * radius)) + var y_end := _unproject(pos + (Vector3.DOWN * radius)) + _control.draw_line(y_start, y_end, color, LINE_WIDTH) + + var z_start := _unproject(pos + (Vector3.FORWARD * radius)) + var z_end := _unproject(pos + (Vector3.BACK * radius)) + _control.draw_line(z_start, z_end, color, LINE_WIDTH) + + +func _draw_circle(pos: Vector3, color: Color) -> void: + if not Referencer.main_camera.is_position_in_frustum(pos): + return + + var point := _unproject(pos) + _control.draw_circle(point, CIRCLE_RADIUS, color) + + +func _set_label_texts() -> void: + _label1.text = _label1_text + _label2.text = _label2_text + _label3.text = _label3_text + + +func _on_control_draw() -> void: + if mode != Mode.DISABLED: + _label1_text = "" + _label2_text = "" + _label3_text = "" + + _append_text("fps", Engine.get_frames_per_second() as int, 0) + _append_text( + "draw calls", + ( + Performance.get_monitor(Performance.RENDER_TOTAL_DRAW_CALLS_IN_FRAME) + as int + ), + 0 + ) + + if mode != Mode.FULL: + if mode != Mode.DISABLED: + _set_label_texts() + return + + for v: Dictionary in _vectors_to_draw.values(): + if v["on"]: + _draw_vector( + v["from"] as Vector3, + v["to"] as Vector3, + v["color"] as Color, + ) + # v["on"] = false + + for v: Dictionary in _markers_to_draw.values(): + if v["on"]: + _draw_marker( + v["pos"] as Vector3, + v["radius"] as float, + v["color"] as Color, + ) + # v["on"] = false + + for v: Dictionary in _circles_to_draw.values(): + if v["on"]: + _draw_circle(v["pos"] as Vector3, v["color"] as Color) + # v["on"] = false + + for k: String in _text_to_draw.keys(): + var v: Dictionary = _text_to_draw[k] + _append_text(k, v["value"] as Variant, v["label_index"] as int) + + for k: String in _events_to_draw.keys(): + var v: Dictionary = _events_to_draw[k] + _append_event(k, v["frame"] as int, v["args"] as Array[Variant]) + + _set_label_texts() + + +func _on_inputer_mode_changed(_input_mode: Inputer.Mode) -> void: + _update_controls_label() diff --git a/scripts/globals/inputer.gd b/scripts/globals/inputer.gd new file mode 100644 index 0000000..88dfff4 --- /dev/null +++ b/scripts/globals/inputer.gd @@ -0,0 +1,184 @@ +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 prompt_grid_size: int = 5 +@export var prompt_icon_size: int = 60 + +@export var mode: Mode = Mode.KB_MOUSE +@export var controller: ControllerType = ControllerType.XBOX: + set(value): + _set_current_prompts(value) + controller = value + +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 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 diff --git a/scripts/globals/referencer.gd b/scripts/globals/referencer.gd new file mode 100644 index 0000000..753225f --- /dev/null +++ b/scripts/globals/referencer.gd @@ -0,0 +1,12 @@ +extends Node + +var main_camera: Camera3D +var player: Player + + +func set_player(node: Player) -> void: + player = node + + +func set_main_camera(node: Camera3D) -> void: + main_camera = node