diff --git a/.gdlintrc b/.gdlintrc index eb8df5b..e8c2cf6 100644 --- a/.gdlintrc +++ b/.gdlintrc @@ -35,7 +35,7 @@ load-constant-name: (([A-Z][a-z0-9]*)+|_?[A-Z][A-Z0-9]*(_[A-Z0-9]+)*) loop-variable-name: _?[a-z][a-z0-9]*(_[a-z0-9]+)* max-file-lines: 1000 max-line-length: 100 -max-public-methods: 20 +max-public-methods: 40 max-returns: 6 mixed-tabs-and-spaces: null no-elif-return: null diff --git a/assets/text/text.csv b/assets/text/text.csv index 37ceec2..5b359d3 100644 --- a/assets/text/text.csv +++ b/assets/text/text.csv @@ -133,6 +133,7 @@ ACTION_SET_POWER,"Set Power Level" ACTION_SET_CURVE,"Set Shot Curve" ACTION_CHANGE_BALL,"Switch Ball" ACTION_CHANGE_CLUB,"Switch Club" +ACTION_FREE_CAM_MOVE,"Move Camera" , CLUB_DRIVER,Driver CLUB_IRON,Iron diff --git a/src/game/game.tscn b/src/game/game.tscn index 8bb2df8..6e09999 100644 --- a/src/game/game.tscn +++ b/src/game/game.tscn @@ -119,7 +119,6 @@ _data = { [node name="Game" type="Node" groups=["GameGroup"]] process_mode = 3 script = ExtResource("1_4qa87") -start_scene = "res://src/world/world.tscn" [node name="RootControl" type="Control" parent="."] unique_name_in_owner = true diff --git a/src/player/shot_setup/shot_setup.gd b/src/player/shot_setup/shot_setup.gd index 9759f24..af11ea0 100644 --- a/src/player/shot_setup/shot_setup.gd +++ b/src/player/shot_setup/shot_setup.gd @@ -339,6 +339,7 @@ func insert_free_cam() -> void: arrow_animation.play("hide") _show_shot_projection() hud.hide_hud() + hud.show_free_cam_prompts() _free_camera = FreeCamera.create(camera) add_sibling(_free_camera) # Un-gimbal-lock ourselves: quickly tween Z rotation to 0 @@ -356,6 +357,7 @@ func return_free_cam() -> void: shot_projection.hide() hud.show_hud() + hud.hide_free_cam_prompts() _free_camera.queue_free() _free_camera = null control_disabled = false @@ -715,6 +717,10 @@ static func create(_player: WorldPlayer) -> ShotSetup: func _on_idle_prompt_timer_timeout() -> void: + if _free_camera: + # Don't show idle prompts while in free-cam mode + return + match phase: Phase.AIM: hud.show_aim_prompt() diff --git a/src/ui/camera/free_camera/free_camera.tscn b/src/ui/camera/free_camera/free_camera.tscn index 6db7a28..78c8a99 100644 --- a/src/ui/camera/free_camera/free_camera.tscn +++ b/src/ui/camera/free_camera/free_camera.tscn @@ -1,9 +1,46 @@ -[gd_scene load_steps=3 format=3 uid="uid://dd17ce110sw6p"] +[gd_scene load_steps=7 format=3 uid="uid://dd17ce110sw6p"] [ext_resource type="Script" path="res://src/ui/camera/free_camera/free_camera.gd" id="1_3gm3q"] +[ext_resource type="PackedScene" uid="uid://b47goj32i6sdh" path="res://src/ui/elements/input_prompt/input_prompt.tscn" id="2_6hucw"] [sub_resource type="SphereShape3D" id="SphereShape3D_wmusx"] +[sub_resource type="Animation" id="Animation_vc2i5"] +resource_name = "RESET" +length = 0.001 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:offset_bottom") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.2, 0, 0.2, 0), +"times": PackedFloat32Array(0) +} + +[sub_resource type="Animation" id="Animation_8gctc"] +resource_name = "show" +length = 0.4 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:offset_bottom") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(0, -0.2, 0, 0.2, 0, 55, -0.2, 0, 0.2, 0), +"times": PackedFloat32Array(0, 0.4) +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_fk25i"] +_data = { +"RESET": SubResource("Animation_vc2i5"), +"show": SubResource("Animation_8gctc") +} + [node name="FreeCamera" type="CharacterBody3D"] process_mode = 3 collision_layer = 0 @@ -16,3 +53,42 @@ shape = SubResource("SphereShape3D_wmusx") [node name="Camera3D" type="Camera3D" parent="."] current = true far = 8192.0 + +[node name="FreeCamHUD" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="UtilityPrompts" type="MarginContainer" parent="FreeCamHUD"] +layout_mode = 1 +anchors_preset = -1 +anchor_left = 0.5 +anchor_right = 0.5 +grow_horizontal = 2 +grow_vertical = 0 +theme_override_constants/margin_top = 16 +theme_override_constants/margin_right = 16 + +[node name="HBoxContainer" type="HBoxContainer" parent="FreeCamHUD/UtilityPrompts"] +layout_mode = 2 +theme_override_constants/separation = 64 + +[node name="InputPrompt" parent="FreeCamHUD/UtilityPrompts/HBoxContainer" instance=ExtResource("2_6hucw")] +layout_mode = 2 +text = "❓ - ACTION_camera_sprint" +action = &"camera_sprint" + +[node name="InputPrompt2" parent="FreeCamHUD/UtilityPrompts/HBoxContainer" instance=ExtResource("2_6hucw")] +layout_mode = 2 +text = "❓ - ACTION_camera_cancel" +action = &"camera_cancel" + +[node name="AimEquipPromptAnimation" type="AnimationPlayer" parent="FreeCamHUD/UtilityPrompts"] +unique_name_in_owner = true +libraries = { +"": SubResource("AnimationLibrary_fk25i") +} +autoplay = "show" diff --git a/src/ui/menus/title_screen/title_screen.tscn b/src/ui/menus/title_screen/title_screen.tscn index d92d47c..87b6c28 100644 --- a/src/ui/menus/title_screen/title_screen.tscn +++ b/src/ui/menus/title_screen/title_screen.tscn @@ -1482,7 +1482,7 @@ grow_horizontal = 2 grow_vertical = 2 [node name="PressStart" type="Label" parent="Menu"] -modulate = Color(1, 1, 1, 0.974307) +modulate = Color(1, 1, 1, 0.98649) layout_mode = 1 anchors_preset = 8 anchor_left = 0.5 diff --git a/src/ui/shot_hud/shot_hud.gd b/src/ui/shot_hud/shot_hud.gd index 19317c5..498593c 100644 --- a/src/ui/shot_hud/shot_hud.gd +++ b/src/ui/shot_hud/shot_hud.gd @@ -17,6 +17,7 @@ var player: WorldPlayer var _aim_prompt_shown := false var _power_prompt_shown := false var _curve_prompt_shown := false +var _free_cam_prompts_shown := false @onready var power_bar: TextureProgressBar = %PowerBar @onready var curve_bar: CurveBar = %CurveBar @@ -44,6 +45,8 @@ var _curve_prompt_shown := false @onready var _aim_prompt_animation: AnimationPlayer = %AimPromptAnimation @onready var _power_prompt_animation: AnimationPlayer = %PowerPromptAnimation @onready var _curve_prompt_animation: AnimationPlayer = %CurvePromptAnimation +@onready var _free_cam_util_prompt_animation: AnimationPlayer = %FreeCamUtilPromptAnimation +@onready var _free_cam_motion_prompt_animation: AnimationPlayer = %FreeCamMotionPromptAnimation @onready var _life_bar_rumbler: Rumbler = %LifeBarRumbler @@ -126,10 +129,6 @@ func hide_reset_prompt() -> void: _reset_prompt_animation.play_backwards("show") -func _is_animation_at_neutral(player: AnimationPlayer) -> bool: - return player.current_animation and false - - func show_aim_prompt() -> void: if not _aim_prompt_shown: _aim_prompt_shown = true @@ -168,6 +167,20 @@ func hide_curve_prompt() -> void: _curve_prompt_animation.play_backwards("show") +func show_free_cam_prompts() -> void: + if not _free_cam_prompts_shown: + _free_cam_prompts_shown = true + _free_cam_motion_prompt_animation.play("show") + _free_cam_util_prompt_animation.play("show") + + +func hide_free_cam_prompts() -> void: + if _free_cam_prompts_shown: + _free_cam_prompts_shown = false + _free_cam_motion_prompt_animation.play_backwards("show") + _free_cam_util_prompt_animation.play_backwards("show") + + func hide_idle_prompts() -> void: hide_aim_prompt() hide_power_prompt() diff --git a/src/ui/shot_hud/shot_hud.tscn b/src/ui/shot_hud/shot_hud.tscn index 29f45db..b227964 100644 --- a/src/ui/shot_hud/shot_hud.tscn +++ b/src/ui/shot_hud/shot_hud.tscn @@ -479,6 +479,7 @@ _data = { } [sub_resource type="Animation" id="Animation_i0y3d"] +resource_name = "RESET" length = 0.001 tracks/0/type = "bezier" tracks/0/imported = false @@ -1241,6 +1242,149 @@ libraries = { "": SubResource("AnimationLibrary_o70c6") } +[node name="FreeCamUtilPrompts" type="MarginContainer" parent="Prompts"] +layout_mode = 1 +anchors_preset = -1 +anchor_left = 0.5 +anchor_right = 0.5 +grow_horizontal = 2 +grow_vertical = 0 +theme_override_constants/margin_top = 16 +theme_override_constants/margin_right = 16 + +[node name="HBoxContainer" type="HBoxContainer" parent="Prompts/FreeCamUtilPrompts"] +layout_mode = 2 +theme_override_constants/separation = 64 + +[node name="InputPrompt" parent="Prompts/FreeCamUtilPrompts/HBoxContainer" instance=ExtResource("14_ik4gg")] +layout_mode = 2 +text = "❓ - ACTION_camera_sprint" +action = &"camera_sprint" + +[node name="InputPrompt2" parent="Prompts/FreeCamUtilPrompts/HBoxContainer" instance=ExtResource("14_ik4gg")] +layout_mode = 2 +text = "❓ - ACTION_camera_cancel" +action = &"camera_cancel" + +[node name="FreeCamUtilPromptAnimation" type="AnimationPlayer" parent="Prompts/FreeCamUtilPrompts"] +unique_name_in_owner = true +libraries = { +"": SubResource("AnimationLibrary_e82k6") +} + +[node name="FreeCamMotionPrompts" type="MarginContainer" parent="Prompts"] +layout_mode = 1 +anchors_preset = -1 +anchor_left = 0.5 +anchor_top = 1.0 +anchor_right = 0.5 +anchor_bottom = 1.0 +offset_left = -230.5 +offset_right = 230.5 +offset_bottom = 55.0 +grow_horizontal = 2 +grow_vertical = 0 +theme_override_constants/margin_right = 16 +theme_override_constants/margin_bottom = 16 + +[node name="HBoxContainer" type="HBoxContainer" parent="Prompts/FreeCamMotionPrompts"] +layout_mode = 2 +theme_override_constants/separation = 64 + +[node name="WASDPrompt" type="HBoxContainer" parent="Prompts/FreeCamMotionPrompts/HBoxContainer"] +layout_mode = 2 +theme_type_variation = &"InputPromptContainer" + +[node name="WASDFader" type="Control" parent="Prompts/FreeCamMotionPrompts/HBoxContainer/WASDPrompt"] +custom_minimum_size = Vector2(32, 0) +layout_mode = 2 +size_flags_horizontal = 4 +script = ExtResource("19_vn2m0") +show_time = 1.0 +fade_time = 0.2 + +[node name="InputPrompt" parent="Prompts/FreeCamMotionPrompts/HBoxContainer/WASDPrompt/WASDFader" instance=ExtResource("14_ik4gg")] +layout_mode = 1 +anchors_preset = 6 +anchor_left = 1.0 +anchor_top = 0.5 +anchor_bottom = 0.5 +offset_left = -32.0 +offset_top = -19.5 +offset_bottom = 19.5 +grow_horizontal = 0 +text = "❓" +action = &"camera_forward" +show_name = false + +[node name="InputPrompt2" parent="Prompts/FreeCamMotionPrompts/HBoxContainer/WASDPrompt/WASDFader" instance=ExtResource("14_ik4gg")] +layout_mode = 1 +anchors_preset = 6 +anchor_left = 1.0 +anchor_top = 0.5 +anchor_bottom = 0.5 +offset_left = -32.0 +offset_top = -19.5 +offset_bottom = 19.5 +grow_horizontal = 0 +text = "❓" +action = &"camera_left" +show_name = false + +[node name="InputPrompt3" parent="Prompts/FreeCamMotionPrompts/HBoxContainer/WASDPrompt/WASDFader" instance=ExtResource("14_ik4gg")] +layout_mode = 1 +anchors_preset = 6 +anchor_left = 1.0 +anchor_top = 0.5 +anchor_bottom = 0.5 +offset_left = -32.0 +offset_top = -19.5 +offset_bottom = 19.5 +grow_horizontal = 0 +text = "❓" +action = &"camera_back" +show_name = false + +[node name="InputPrompt4" parent="Prompts/FreeCamMotionPrompts/HBoxContainer/WASDPrompt/WASDFader" instance=ExtResource("14_ik4gg")] +layout_mode = 1 +anchors_preset = 6 +anchor_left = 1.0 +anchor_top = 0.5 +anchor_bottom = 0.5 +offset_left = -32.0 +offset_top = -19.5 +offset_bottom = 19.5 +grow_horizontal = 0 +text = "❓" +action = &"camera_right" +show_name = false + +[node name="Label" type="Label" parent="Prompts/FreeCamMotionPrompts/HBoxContainer/WASDPrompt"] +layout_mode = 2 +theme_type_variation = &"InputPrompt" +text = "-" + +[node name="Label2" type="Label" parent="Prompts/FreeCamMotionPrompts/HBoxContainer/WASDPrompt"] +layout_mode = 2 +theme_type_variation = &"InputPrompt" +text = "ACTION_FREE_CAM_MOVE" + +[node name="InputPrompt" parent="Prompts/FreeCamMotionPrompts/HBoxContainer" instance=ExtResource("14_ik4gg")] +layout_mode = 2 +text = "❓ - ACTION_camera_up" +action = &"camera_up" + +[node name="InputPrompt2" parent="Prompts/FreeCamMotionPrompts/HBoxContainer" instance=ExtResource("14_ik4gg")] +layout_mode = 2 +text = "❓ - ACTION_camera_down" +action = &"camera_down" + +[node name="FreeCamMotionPromptAnimation" type="AnimationPlayer" parent="Prompts/FreeCamMotionPrompts"] +unique_name_in_owner = true +libraries = { +"": SubResource("AnimationLibrary_o70c6") +} + [node name="AlertContainer" type="Control" parent="."] unique_name_in_owner = true layout_mode = 1