diff --git a/game/src/core/autoloads/input_manager.gd b/game/src/core/autoloads/input_manager.gd index e937eed..1c5dc95 100644 --- a/game/src/core/autoloads/input_manager.gd +++ b/game/src/core/autoloads/input_manager.gd @@ -6,7 +6,7 @@ var using_controller: bool = false func _input(event: InputEvent) -> void: - if not window_focused(): + if not is_window_focused(): get_viewport().set_input_as_handled() return @@ -21,7 +21,7 @@ func _input(event: InputEvent) -> void: toggle_mouse() -func window_focused() -> bool: +func is_window_focused() -> bool: return DisplayServer.window_is_focused() diff --git a/game/src/core/interaction/interaction_area.gd b/game/src/core/interaction/interaction_area.gd index f4c3c80..537be61 100644 --- a/game/src/core/interaction/interaction_area.gd +++ b/game/src/core/interaction/interaction_area.gd @@ -6,6 +6,7 @@ signal unfocused signal hint_prompts_changed @export var interaction_types: Array[InteractionType] = []: set = set_interaction_types +@export var focus_highlight_node: Node3D var is_focused: bool = false @@ -13,38 +14,45 @@ var is_focused: bool = false func _ready() -> void: set_interaction_types(interaction_types) + if is_instance_valid(focus_highlight_node): + focus_highlight_node.hide() + func set_interaction_types(types: Array[InteractionType]) -> void: for type: InteractionType in interaction_types: if type.hint_prompt_changed.is_connected(hint_prompts_changed.emit): type.hint_prompt_changed.disconnect(hint_prompts_changed.emit) + if type.enabled_changed.is_connected(_on_interaction_type_enabled_changed): + type.enabled_changed.disconnect(_on_interaction_type_enabled_changed) interaction_types = types for type: InteractionType in interaction_types: if not type.hint_prompt_changed.is_connected(hint_prompts_changed.emit): type.hint_prompt_changed.connect(hint_prompts_changed.emit) + if not type.enabled_changed.is_connected(_on_interaction_type_enabled_changed): + type.enabled_changed.connect(_on_interaction_type_enabled_changed) func set_area_focused(value: bool) -> void: is_focused = value (focused if is_focused else unfocused).emit() + if is_instance_valid(focus_highlight_node): + focus_highlight_node.visible = value + for type: InteractionType in interaction_types: type.set_focused(is_focused) -func get_interaction_strings() -> Array[Array]: - var strings: Array[Array] = [] +func get_interaction_strings() -> PackedStringArray: + var strings: PackedStringArray = [] for interaction_type: InteractionType in interaction_types: if interaction_type.enabled: - var pre: String = interaction_type.get_hint(0) - var prompt: Texture2D = interaction_type.button_prompt - var post: String = interaction_type.get_hint(1) - strings.append([pre, prompt, post]) + var hint: String = interaction_type.get_correct_hover_hint() + strings.append(hint) - print("Interaction Strings: ", strings) return strings @@ -54,3 +62,7 @@ func _interaction_started(_interaction_ray: InteractionRay) -> void: func _interaction_ended(_interaction_ray: InteractionRay) -> void: pass + + +func _on_interaction_type_enabled_changed() -> void: + set_area_focused(is_focused) diff --git a/game/src/core/interaction/interaction_ray.gd b/game/src/core/interaction/interaction_ray.gd index 15e9594..8796ecc 100644 --- a/game/src/core/interaction/interaction_ray.gd +++ b/game/src/core/interaction/interaction_ray.gd @@ -4,7 +4,6 @@ extends RayCast3D signal focused_gained(interaction_area: InteractionArea) signal focus_lost(interaction_area: InteractionArea) -var is_interacting: bool = false var focused_area: InteractionArea var had_focus: bool = false @@ -19,7 +18,6 @@ func _physics_process(_delta: float) -> void: #focused_area = null #focused_gained.emit(null) - if collider == focused_area: if not is_instance_valid(focused_area) and had_focus: had_focus = false @@ -28,21 +26,21 @@ func _physics_process(_delta: float) -> void: return if is_instance_valid(focused_area): - focused_area.set_area_focused(false) - had_focus = false - focus_lost.emit(focused_area) + lose_area_focus(focused_area) focused_area = collider if collider is InteractionArea else null focused_gained.emit(focused_area) if is_instance_valid(focused_area): - had_focus = true - focused_area.set_area_focused(true) + gain_area_focus(focused_area) -func get_interaction() -> InteractionArea: - var collider: Object = get_collider() - if collider is InteractionArea: - return collider +func gain_area_focus(area: InteractionArea) -> void: + had_focus = true + area.set_area_focused(true) - return null + +func lose_area_focus(area: InteractionArea) -> void: + area.set_area_focused(false) + had_focus = false + focus_lost.emit(area) diff --git a/game/src/core/interaction/interaction_type.gd b/game/src/core/interaction/interaction_type.gd index 9d9be84..a25d472 100644 --- a/game/src/core/interaction/interaction_type.gd +++ b/game/src/core/interaction/interaction_type.gd @@ -3,12 +3,15 @@ class_name InteractionType extends Node signal hint_prompt_changed +signal enabled_changed -@export var enabled: bool = true -@export var hover_hint: String = "Press {prompt} to interact": set = set_hover_hint -@export var button_prompt: Texture2D -#@export var additional_prompts: Dictionary[String, Texture2D] = {} +@export var enabled: bool = true: set = set_enabled +@export var hover_hint: String = "Press {interact} to interact": set = set_hover_hint @export_custom(PROPERTY_HINT_INPUT_NAME, "") var action: StringName = &"interact" +@export var texture_size: float = 42.0 +@export var interaction_textures: Dictionary[String, String] = { + "interact": "uid://c5nyul3r2u4wu", +} var is_focused: bool = false var is_interacting: bool = false @@ -26,25 +29,13 @@ func stop_interaction() -> void: _interaction_ended() -func get_hint(slice_idx: int) -> String: - return hover_hint.get_slice("{prompt}", slice_idx) - #return hover_hint.format({"prompt": str("[img]", button_prompt, "[/img]]")}) +func get_correct_hover_hint() -> String: + var hint: String = hover_hint + for key: String in interaction_textures.keys(): + hint = hint.replace("{%s}" % key, "[img=%s]%s[/img]" % [texture_size, interaction_textures[key]]) -# TODO: Convert from string to array. -# "Press {prompt} to {interact} interact{exclamation}" -# ["Press ", Texture, " to ", Texture, " interact", Texture] -func get_full_hint() -> Array: - var prompts: Dictionary[String, Texture2D] = {}#additional_prompts.duplicate() - prompts.set("{prompt}", button_prompt) - - var entries: Array = [] - var strings: Array[String] = [] - - for key: String in prompts.keys(): - strings.append(hover_hint.split(key)) - - return entries + return hint func set_focused(value: bool) -> void: @@ -61,6 +52,13 @@ func set_hover_hint(text: String) -> void: hint_prompt_changed.emit() +func set_enabled(value: bool) -> void: + var was_different: bool = enabled != value + enabled = value + + if was_different: + enabled_changed.emit() + @abstract func _interaction_started() -> void diff --git a/game/src/gameplay/characters/player/head.gd b/game/src/gameplay/characters/player/head.gd index fd71276..8a372d7 100644 --- a/game/src/gameplay/characters/player/head.gd +++ b/game/src/gameplay/characters/player/head.gd @@ -82,7 +82,7 @@ func get_sensitivity() -> float: func _process_input(delta: float) -> void: - if Input.mouse_mode != Input.MOUSE_MODE_CAPTURED or not InputManager.window_focused(): + if Input.mouse_mode != Input.MOUSE_MODE_CAPTURED or not InputManager.is_window_focused(): return if input_event is InputEventMouseMotion: diff --git a/game/src/gameplay/characters/player/hud.gd b/game/src/gameplay/characters/player/hud.gd index 1dd8c6d..0c51011 100644 --- a/game/src/gameplay/characters/player/hud.gd +++ b/game/src/gameplay/characters/player/hud.gd @@ -34,6 +34,9 @@ func _on_interaction_ray_focused(area: InteractionArea) -> void: func _on_interaction_ray_focus_lost(area: InteractionArea) -> void: + interaction_prompt.clear() + _play_crosshair_anim(&"to_dot") + if is_instance_valid(area): area.hint_prompts_changed.disconnect(_populate_focused_hints) @@ -46,20 +49,5 @@ func _play_crosshair_anim(anim_name: StringName) -> void: func _populate_focused_hints(area: InteractionArea) -> void: interaction_prompt.clear() interaction_prompt.push_paragraph(HORIZONTAL_ALIGNMENT_CENTER) - - #for hint: Array in area.get_interaction_strings(): - #for entry: Variant in hint: - #if typeof(entry) == TYPE_STRING: - #interaction_prompt.append_text(entry) - #elif entry is Texture2D: - #interaction_prompt.add_image(entry, 42, 42) -# - #interaction_prompt.add_text("\n") - - for string: Array in area.get_interaction_strings(): - if not string[0].is_empty() or not string[2].is_empty(): - interaction_prompt.append_text(string[0]) - interaction_prompt.add_image(string[1], 42, 42) - interaction_prompt.append_text(string[2] + "\n") - + interaction_prompt.append_text("\n".join(area.get_interaction_strings())) interaction_prompt.pop_all() diff --git a/game/src/gameplay/characters/player/player_character.gd b/game/src/gameplay/characters/player/player_character.gd index 60a1f9a..4e9e504 100644 --- a/game/src/gameplay/characters/player/player_character.gd +++ b/game/src/gameplay/characters/player/player_character.gd @@ -32,14 +32,13 @@ var can_run: bool = true var is_crouching: bool = false var crouch_speed_affection: float = 0.0 -@onready var head: PlayerHead = $Head -@onready var collision_shape: CollisionShape3D = $CylinderCollider -@onready var standup_checker: Area3D = $StandupChecker +@onready var head: PlayerHead = %Head +@onready var collision_shape: CollisionShape3D = %CylinderCollider +@onready var standup_checker: Area3D = %StandupChecker @onready var interaction_ray: InteractionRay = %InteractionRay @onready var flashlight: Flashlight = %Flashlight -#@onready var stair_stepper: StairStepper = $StairStepper func _init() -> void: player = self @@ -50,15 +49,7 @@ func _ready() -> void: flashlight.manager = flashlight_manager -#func _ready() -> void: -#if not get_tree().current_scene.is_node_ready(): -#await get_tree().current_scene.ready -# -#var spawn_point := PlayerSpawnPoint.get_spawnpoint_by_identifier(Game.instance.spawn_id) -# -#if is_instance_valid(spawn_point): -#global_position = spawn_point.global_position -#head.global_rotation = spawn_point.global_rotation + func _physics_process(delta: float) -> void: #var lagspike: bool = randf() < 0.005 #if lagspike: @@ -137,7 +128,7 @@ func apply_gravity(delta: float) -> void: func get_input_direction() -> Vector3: - if not InputManager.window_focused(): + if not InputManager.is_window_focused(): return Vector3.ZERO var input_dir := Input.get_vector( diff --git a/game/src/gameplay/characters/player/player_character.tscn b/game/src/gameplay/characters/player/player_character.tscn index a04c628..4e009b6 100644 --- a/game/src/gameplay/characters/player/player_character.tscn +++ b/game/src/gameplay/characters/player/player_character.tscn @@ -13,7 +13,7 @@ [ext_resource type="Script" uid="uid://dd0i7xqjwgc6r" path="res://src/core/camera/effects/view_roll_effect.gd" id="7_3mv4n"] [ext_resource type="Script" uid="uid://dyoa3tnirv7wh" path="res://src/core/camera/camera_effect_target.gd" id="7_ghuot"] [ext_resource type="Script" uid="uid://gvuvxikepb2r" path="res://src/gameplay/characters/player/hud.gd" id="11_y2ktv"] -[ext_resource type="Texture2D" uid="uid://cwvfdx2v41k0h" path="res://src/ui/hud/crosshair.png" id="13_qx1cj"] +[ext_resource type="Texture2D" uid="uid://biljky5uh45hg" path="res://src/ui/hud/crosshair_outline.png" id="13_qx1cj"] [ext_resource type="PackedScene" uid="uid://ct2u3f03lwsnr" path="res://src/ui/hud/hud_subtitle.tscn" id="15_hqe5n"] [sub_resource type="Resource" id="Resource_vq0uu"] @@ -166,19 +166,17 @@ shape = SubResource("CapsuleShape3D_bdj5f") disabled = true [node name="CylinderCollider" type="CollisionShape3D" parent="." unique_id=397310478] +unique_name_in_owner = true transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9, 0) shape = SubResource("CylinderShape3D_bdj5f") [node name="Head" type="Node3D" parent="." unique_id=647306642 node_paths=PackedStringArray("camera", "character")] +unique_name_in_owner = true transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0) script = ExtResource("2_fjt7c") camera = NodePath("EffectsRoot/ShakingCamera") character = NodePath("..") -[node name="InteractionRay" parent="Head" unique_id=941602125 instance=ExtResource("4_de0uv")] -unique_name_in_owner = true -target_position = Vector3(0, 0, -1.75) - [node name="Flashlight" type="Node3D" parent="Head" unique_id=884032976 node_paths=PackedStringArray("light")] unique_name_in_owner = true script = ExtResource("5_vxew7") @@ -186,7 +184,7 @@ light = NodePath("FlashlightSpot") metadata/_custom_type_script = "uid://1i0linakw8mg" [node name="FlashlightSpot" type="SpotLight3D" parent="Head/Flashlight" unique_id=1000286492] -light_energy = 3.0 +light_energy = 1.5 light_specular = 0.15 light_bake_mode = 0 shadow_enabled = true @@ -194,6 +192,10 @@ spot_range = 30.0 spot_attenuation = 2.0 spot_angle_attenuation = 0.5 +[node name="InteractionRay" parent="Head" unique_id=941602125 instance=ExtResource("4_de0uv")] +unique_name_in_owner = true +target_position = Vector3(0, 0, -1.75) + [node name="EffectsRoot" type="Node3D" parent="Head" unique_id=274091696 node_paths=PackedStringArray("camera")] script = ExtResource("7_ghuot") camera = NodePath("ShakingCamera") @@ -243,6 +245,7 @@ target = NodePath("..") metadata/_custom_type_script = "uid://ds461t4g8nlnh" [node name="StandupChecker" type="Area3D" parent="." unique_id=1209822543] +unique_name_in_owner = true collision_layer = 0 input_ray_pickable = false @@ -289,6 +292,5 @@ unique_name_in_owner = true scale = Vector2(0.25, 0.25) sprite_frames = SubResource("SpriteFrames_p81y6") animation = &"to_hollow" -frame = 5 [node name="HudSubtitle" parent="Hud" unique_id=123148710 instance=ExtResource("15_hqe5n")] diff --git a/game/src/gameplay/systems/flashlight/flashlight_battery.tscn b/game/src/gameplay/systems/flashlight/flashlight_battery.tscn index 2dd1c8c..cde6a74 100644 --- a/game/src/gameplay/systems/flashlight/flashlight_battery.tscn +++ b/game/src/gameplay/systems/flashlight/flashlight_battery.tscn @@ -3,7 +3,6 @@ [ext_resource type="Script" uid="uid://nsxr1qkvivsf" path="res://src/gameplay/systems/flashlight/flashlight_battery.gd" id="1_p5331"] [ext_resource type="Script" uid="uid://ckdo7huqoleoi" path="res://src/core/interaction/interaction_types/pickup.gd" id="2_0r1sb"] [ext_resource type="Script" uid="uid://qifiwdgyx6e" path="res://src/core/world/level/world_proxy.gd" id="2_3nps0"] -[ext_resource type="Script" uid="uid://ch00l1e1rteyw" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="3_3nps0"] [ext_resource type="PackedScene" uid="uid://2dre1e56emw6" path="res://src/core/interaction/interaction_area.tscn" id="3_ouj7b"] [sub_resource type="CylinderMesh" id="CylinderMesh_0r1sb"] @@ -11,12 +10,9 @@ top_radius = 0.05 bottom_radius = 0.05 height = 0.15 -[sub_resource type="Texture2D" id="Texture2D_er8ho"] -resource_local_to_scene = false -resource_name = "" -script = ExtResource("3_3nps0") -path = "interact" -metadata/_custom_type_script = "uid://c2w177bb5r70x" +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ouj7b"] +cull_mode = 1 +shading_mode = 0 [sub_resource type="CylinderShape3D" id="CylinderShape3D_3nps0"] height = 0.2 @@ -27,20 +23,28 @@ script = ExtResource("1_p5331") metadata/_custom_type_script = "uid://nsxr1qkvivsf" [node name="WorldProxy" type="Node" parent="." unique_id=930661856] +unique_name_in_owner = true script = ExtResource("2_3nps0") metadata/_custom_type_script = "uid://qifiwdgyx6e" [node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=1939916981] mesh = SubResource("CylinderMesh_0r1sb") +[node name="FocusHightlight" type="MeshInstance3D" parent="MeshInstance3D" unique_id=2040210883] +transform = Transform3D(1.035, 0, 0, 0, 1.035, 0, 0, 0, 1.035, 0, 0, 0) +material_override = SubResource("StandardMaterial3D_ouj7b") +mesh = SubResource("CylinderMesh_0r1sb") + [node name="PickupInteraction" type="Node" parent="." unique_id=1627706216] +unique_name_in_owner = true script = ExtResource("2_0r1sb") -hover_hint = "Press {prompt} to pickup" -button_prompt = SubResource("Texture2D_er8ho") +hover_hint = "Press {interact} to pickup" metadata/_custom_type_script = "uid://ckdo7huqoleoi" -[node name="InteractionArea" parent="." unique_id=1987460629 node_paths=PackedStringArray("interaction_types") instance=ExtResource("3_ouj7b")] +[node name="InteractionArea" parent="." unique_id=1987460629 node_paths=PackedStringArray("interaction_types", "focus_highlight_node") instance=ExtResource("3_ouj7b")] +unique_name_in_owner = true interaction_types = [NodePath("../PickupInteraction")] +focus_highlight_node = NodePath("../MeshInstance3D/FocusHightlight") [node name="CollisionShape3D" type="CollisionShape3D" parent="InteractionArea" unique_id=1272180976] shape = SubResource("CylinderShape3D_3nps0") diff --git a/game/src/gameplay/systems/power_box/fuse_pickup.tscn b/game/src/gameplay/systems/power_box/fuse_pickup.tscn index e08c9ed..1f300f1 100644 --- a/game/src/gameplay/systems/power_box/fuse_pickup.tscn +++ b/game/src/gameplay/systems/power_box/fuse_pickup.tscn @@ -3,16 +3,8 @@ [ext_resource type="Script" uid="uid://dkao86mwhq1tm" path="res://src/gameplay/systems/power_box/fuse_pickup.gd" id="1_b733i"] [ext_resource type="Script" uid="uid://ckdo7huqoleoi" path="res://src/core/interaction/interaction_types/pickup.gd" id="2_of2nm"] [ext_resource type="Script" uid="uid://qifiwdgyx6e" path="res://src/core/world/level/world_proxy.gd" id="2_p036h"] -[ext_resource type="Script" uid="uid://ch00l1e1rteyw" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="3_hqmg0"] [ext_resource type="PackedScene" uid="uid://2dre1e56emw6" path="res://src/core/interaction/interaction_area.tscn" id="4_3b6jw"] -[sub_resource type="Texture2D" id="Texture2D_3b6jw"] -resource_local_to_scene = false -resource_name = "" -script = ExtResource("3_hqmg0") -path = "interact" -metadata/_custom_type_script = "uid://c2w177bb5r70x" - [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_3b6jw"] albedo_color = Color(0.4862745, 0.6, 1, 1) @@ -35,8 +27,7 @@ metadata/_custom_type_script = "uid://qifiwdgyx6e" [node name="PickupInteraction" type="Node" parent="." unique_id=285803844] script = ExtResource("2_of2nm") -hover_hint = "Press {prompt} to pickup" -button_prompt = SubResource("Texture2D_3b6jw") +hover_hint = "Press {interact} to pickup" metadata/_custom_type_script = "uid://ckdo7huqoleoi" [node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=476632181] diff --git a/game/src/gameplay/systems/power_box/power_box_fuse.tscn b/game/src/gameplay/systems/power_box/power_box_fuse.tscn index d64ce29..8bc947f 100644 --- a/game/src/gameplay/systems/power_box/power_box_fuse.tscn +++ b/game/src/gameplay/systems/power_box/power_box_fuse.tscn @@ -3,16 +3,8 @@ [ext_resource type="Script" uid="uid://bpvawt7ate0ug" path="res://src/gameplay/systems/power_box/power_box.gd" id="1_m14vv"] [ext_resource type="Script" uid="uid://ckdo7huqoleoi" path="res://src/core/interaction/interaction_types/pickup.gd" id="2_35cpc"] [ext_resource type="Script" uid="uid://qifiwdgyx6e" path="res://src/core/world/level/world_proxy.gd" id="2_v6qxf"] -[ext_resource type="Script" uid="uid://ch00l1e1rteyw" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="3_35cpc"] [ext_resource type="PackedScene" uid="uid://2dre1e56emw6" path="res://src/core/interaction/interaction_area.tscn" id="4_v6qxf"] -[sub_resource type="Texture2D" id="Texture2D_35cpc"] -resource_local_to_scene = false -resource_name = "" -script = ExtResource("3_35cpc") -path = "interact" -metadata/_custom_type_script = "uid://ch00l1e1rteyw" - [sub_resource type="BoxShape3D" id="BoxShape3D_v6qxf"] size = Vector3(0.5, 0.8, 0.5) @@ -30,7 +22,6 @@ metadata/_custom_type_script = "uid://qifiwdgyx6e" [node name="PickupInteraction" type="Node" parent="." unique_id=1698155134] script = ExtResource("2_35cpc") -button_prompt = SubResource("Texture2D_35cpc") metadata/_custom_type_script = "uid://ckdo7huqoleoi" [node name="InteractionArea" parent="." unique_id=1987460629 node_paths=PackedStringArray("interaction_types") instance=ExtResource("4_v6qxf")] diff --git a/game/src/ui/hud/crosshair_outline.png b/game/src/ui/hud/crosshair_outline.png new file mode 100644 index 0000000..f5475bf Binary files /dev/null and b/game/src/ui/hud/crosshair_outline.png differ diff --git a/game/src/ui/hud/crosshair_outline.png.import b/game/src/ui/hud/crosshair_outline.png.import new file mode 100644 index 0000000..a4a23f6 --- /dev/null +++ b/game/src/ui/hud/crosshair_outline.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://biljky5uh45hg" +path="res://.godot/imported/crosshair_outline.png-dabc3110529c569dd574195e16b52c92.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://src/ui/hud/crosshair_outline.png" +dest_files=["res://.godot/imported/crosshair_outline.png-dabc3110529c569dd574195e16b52c92.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +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/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +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