From ed369cf71841fbd8f3ed2870eb59987da998416b Mon Sep 17 00:00:00 2001 From: Rendo Date: Mon, 28 Jul 2025 05:07:37 +0500 Subject: [PATCH] Gamepad support --- project.godot | 72 +++++++++++++++++-- scenes/entities/Zombies/zombie.tscn | 28 ++++---- scenes/entities/plants/snipach.tscn | 4 +- scenes/entities/plants/spikeweed.tscn | 1 + scenes/gui/almanach.tscn | 10 ++- scenes/gui/cursor_canvas_layer.tscn | 13 ++++ scenes/main_menu.tscn | 5 +- scenes/particles/potato_explosion.tscn | 6 +- scenes/templates/level_template.tscn | 7 +- scripts/Cursor.cs | 64 +++++++++-------- .../plants/behaviours/SnipachBehaviour.cs | 2 +- scripts/gamepad/ExplosionVibration.cs | 10 +++ scripts/gamepad/ExplosionVibration.cs.uid | 1 + scripts/gamepad/GamepadHandler.cs | 52 ++++++++++++++ scripts/gamepad/GamepadHandler.cs.uid | 1 + scripts/gui/ShovelButton.cs | 5 +- scripts/gui/choose_your_seeds/GridLoader.cs | 2 + .../gui/choose_your_seeds/LevelRunButton.cs | 2 + scripts/gui/menu_buttons.gd | 2 + scripts/gui/seedpackets/Seedpacket.cs | 9 --- scripts/level/PlantField.cs | 6 +- scripts/particles/StandardParticles.cs | 11 +-- translations/rewards.csv | 1 + translations/rewards.csv.import | 4 +- 24 files changed, 240 insertions(+), 78 deletions(-) create mode 100644 scenes/gui/cursor_canvas_layer.tscn create mode 100644 scripts/gamepad/ExplosionVibration.cs create mode 100644 scripts/gamepad/ExplosionVibration.cs.uid create mode 100644 scripts/gamepad/GamepadHandler.cs create mode 100644 scripts/gamepad/GamepadHandler.cs.uid diff --git a/project.godot b/project.godot index 751a535..ff3a6fe 100644 --- a/project.godot +++ b/project.godot @@ -31,6 +31,7 @@ Cheats="*res://scripts/debug/Cheats.cs" AudioSequencer="*res://scenes/audio_sequencer.tscn" SaveSerializer="*res://scripts/SaveSerializer.cs" PlayerProgress="*res://scripts/systems/static-data/PlayerProgress.cs" +GamepadHandler="*res://scripts/gamepad/GamepadHandler.cs" [display] @@ -72,6 +73,14 @@ theme/custom_font="res://assets/fonts/pico12.ttf" [input] +ui_accept={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194309,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194310,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":true,"script":null) +] +} ui_focus_next={ "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":93,"key_label":0,"unicode":1098,"location":0,"echo":false,"script":null) @@ -82,6 +91,36 @@ ui_focus_prev={ "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":91,"key_label":0,"unicode":1093,"location":0,"echo":false,"script":null) ] } +ui_left={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194319,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":9,"pressure":0.0,"pressed":true,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":-1.0,"script":null) +] +} +ui_right={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194321,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":10,"pressure":0.0,"pressed":true,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":1.0,"script":null) +] +} +ui_up={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194320,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":-1.0,"script":null) +] +} +ui_down={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194322,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":1.0,"script":null) +] +} cheat_add_sun={ "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":4194333,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) @@ -91,11 +130,13 @@ cancel_plant={ "deadzone": 0.5, "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":2,"position":Vector2(82, 2),"global_position":Vector2(91, 41),"factor":1.0,"button_index":2,"canceled":false,"pressed":true,"double_click":false,"script":null) , 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":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":true,"script":null) ] } primary_action={ "deadzone": 0.5, "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(49, 18),"global_position":Vector2(58, 57),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":true,"script":null) ] } cheat_zombie_spawn={ @@ -106,11 +147,7 @@ cheat_zombie_spawn={ short_pause={ "deadzone": 0.2, "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":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) -] -} -short_ff={ -"deadzone": 0.2, -"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":4194306,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":6,"pressure":0.0,"pressed":true,"script":null) ] } short_shovel={ @@ -123,6 +160,31 @@ cheat_unlock_all={ "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":4194334,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } +short_ff={ +"deadzone": 0.2, +"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":4194306,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} +cursor_up={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null) +] +} +cursor_down={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null) +] +} +cursor_left={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":-1.0,"script":null) +] +} +cursor_right={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null) +] +} [internationalization] diff --git a/scenes/entities/Zombies/zombie.tscn b/scenes/entities/Zombies/zombie.tscn index 4117e84..88699b8 100644 --- a/scenes/entities/Zombies/zombie.tscn +++ b/scenes/entities/Zombies/zombie.tscn @@ -856,7 +856,7 @@ metadata/_edit_lock_ = true [node name="LeftUpperLeg" type="Bone2D" parent="CanvasGroup/basic_zombie_walk/Zombie/Butt"] use_parent_material = true position = Vector2(6, 4) -scale = Vector2(0.999835, 0.999835) +scale = Vector2(0.999836, 0.999836) rest = Transform2D(1, 0, 0, 1, 6, 4) editor_settings/show_bone_gizmo = false @@ -896,7 +896,7 @@ metadata/_edit_lock_ = true [node name="Body" type="Bone2D" parent="CanvasGroup/basic_zombie_walk/Zombie/Butt"] use_parent_material = true position = Vector2(1, -2) -scale = Vector2(0.999829, 0.999829) +scale = Vector2(0.999828, 0.999828) rest = Transform2D(1, 0, 0, 1, 1, -2) editor_settings/show_bone_gizmo = false @@ -904,7 +904,7 @@ editor_settings/show_bone_gizmo = false z_index = -1 use_parent_material = true position = Vector2(-14, -23) -scale = Vector2(0.999827, 0.999827) +scale = Vector2(0.999828, 0.999828) rest = Transform2D(1, 0, 0, 1, -14, -23) editor_settings/show_bone_gizmo = false @@ -916,7 +916,7 @@ metadata/_edit_lock_ = true [node name="RightLowerArm" type="Bone2D" parent="CanvasGroup/basic_zombie_walk/Zombie/Butt/Body/RightUpperArm"] position = Vector2(-2, 15) -scale = Vector2(0.999828, 0.999828) +scale = Vector2(0.999829, 0.999829) rest = Transform2D(1, 0, 0, 1, -2, 15) editor_settings/show_bone_gizmo = false @@ -950,8 +950,8 @@ metadata/_edit_lock_ = true [node name="Tie" type="Bone2D" parent="CanvasGroup/basic_zombie_walk/Zombie/Butt/Body"] position = Vector2(-9, -21) -rotation = -0.151557 -skew = -0.000476003 +rotation = 0.0871529 +skew = -0.000476122 rest = Transform2D(1, 0, 0, 1, -9, -21) auto_calculate_length_and_angle = false length = 24.0 @@ -989,6 +989,7 @@ metadata/_edit_lock_ = true [node name="Right_Eye" type="Sprite2D" parent="CanvasGroup/basic_zombie_walk/Zombie/Butt/Body/Head/HeadParticle/Head"] position = Vector2(-16, -8) +scale = Vector2(1, 1) texture = SubResource("AtlasTexture_vcc72") centered = false offset = Vector2(-2, -2) @@ -996,15 +997,16 @@ metadata/_edit_lock_ = true [node name="Left_Eye" type="Sprite2D" parent="CanvasGroup/basic_zombie_walk/Zombie/Butt/Body/Head/HeadParticle/Head"] position = Vector2(-4, -9) +scale = Vector2(1, 1) texture = SubResource("AtlasTexture_kto0i") centered = false offset = Vector2(-2, -2) metadata/_edit_lock_ = true [node name="Jaw" type="Sprite2D" parent="CanvasGroup/basic_zombie_walk/Zombie/Butt/Body/Head/HeadParticle/Head"] -position = Vector2(-2.81092, 2.54366) -rotation = -0.107471 -scale = Vector2(0.99983, 0.99983) +position = Vector2(-3.00107, 2.99818) +rotation = 0.00845789 +scale = Vector2(0.999829, 0.999829) texture = SubResource("AtlasTexture_x5uj2") centered = false offset = Vector2(-12, -2) @@ -1077,7 +1079,7 @@ minTorque = -45.0 maxTorque = 45.0 [node name="Left_Lower_Arm" type="Sprite2D" parent="CanvasGroup/basic_zombie_walk/Zombie/Butt/Body/LeftUpperArm/HandProjectile"] -rotation = -0.160747 +rotation = 0.0819429 scale = Vector2(0.999998, 0.999998) texture = SubResource("AtlasTexture_auqeq") centered = false @@ -1086,8 +1088,8 @@ metadata/_edit_lock_ = true [node name="Left_Hand" type="Sprite2D" parent="CanvasGroup/basic_zombie_walk/Zombie/Butt/Body/LeftUpperArm/HandProjectile/Left_Lower_Arm"] show_behind_parent = true -position = Vector2(-0.999828, 12.9978) -rotation = -0.133017 +position = Vector2(-0.99983, 12.9978) +rotation = -0.0361645 scale = Vector2(0.999656, 0.999656) texture = SubResource("AtlasTexture_vlvtp") centered = false @@ -1165,7 +1167,7 @@ entity = NodePath("..") [node name="Mover" type="Node" parent="."] script = ExtResource("4_u5syx") _speed = SubResource("Resource_ckb7n") -_speedControlMult = 1.02866 +_speedControlMult = 0.271112 [node name="HitPlayer" type="Node" parent="."] script = ExtResource("12_he8da") diff --git a/scenes/entities/plants/snipach.tscn b/scenes/entities/plants/snipach.tscn index 23319ae..cc6a782 100644 --- a/scenes/entities/plants/snipach.tscn +++ b/scenes/entities/plants/snipach.tscn @@ -21,7 +21,7 @@ atlas = ExtResource("3_ktw4a") region = Rect2(525, 241, 79, 72) [sub_resource type="RectangleShape2D" id="RectangleShape2D_ktw4a"] -size = Vector2(37, 66) +size = Vector2(39.5, 66) [sub_resource type="AtlasTexture" id="AtlasTexture_3hyni"] atlas = ExtResource("3_ktw4a") @@ -40,7 +40,7 @@ position = Vector2(8, -16) texture = SubResource("AtlasTexture_f4wwx") [node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox" index="0"] -position = Vector2(-2, -13) +position = Vector2(-0.75, -13) shape = SubResource("RectangleShape2D_ktw4a") [node name="DragAction" type="Node" parent="Hitbox" index="1"] diff --git a/scenes/entities/plants/spikeweed.tscn b/scenes/entities/plants/spikeweed.tscn index 6375ed5..b76c66a 100644 --- a/scenes/entities/plants/spikeweed.tscn +++ b/scenes/entities/plants/spikeweed.tscn @@ -54,6 +54,7 @@ material = SubResource("ShaderMaterial_yfuxj") texture = ExtResource("2_ffrjr") hframes = 10 vframes = 2 +frame = 6 [node name="AnimationPlayer" parent="." index="1"] libraries = { diff --git a/scenes/gui/almanach.tscn b/scenes/gui/almanach.tscn index 9e90602..0603133 100644 --- a/scenes/gui/almanach.tscn +++ b/scenes/gui/almanach.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=11 format=3 uid="uid://bvpt0q4j6nx18"] +[gd_scene load_steps=13 format=3 uid="uid://bvpt0q4j6nx18"] [ext_resource type="Texture2D" uid="uid://dr8a0rx42o3qy" path="res://assets/sprites/gui/ChooseYourSeeds/PlantFrame.tres" id="1_1hnxi"] [ext_resource type="Script" uid="uid://bs1qywtqijyd2" path="res://scenes/gui/almanach.gd" id="1_oy57w"] @@ -12,6 +12,13 @@ [sub_resource type="ViewportTexture" id="ViewportTexture_ru62c"] viewport_path = NodePath("plants/Infobox/FrameAndTitle/VboxContainer/Frame/Previewport") +[sub_resource type="InputEventAction" id="InputEventAction_vvhxq"] +action = &"ui_cancel" +pressed = true + +[sub_resource type="Shortcut" id="Shortcut_lmmwe"] +events = [SubResource("InputEventAction_vvhxq")] + [sub_resource type="ViewportTexture" id="ViewportTexture_7yl8g"] viewport_path = NodePath("zombies/Infobox/FrameAndTitle/VBoxContainer/Frame/Previewport") @@ -81,6 +88,7 @@ texture = SubResource("ViewportTexture_ru62c") [node name="QuitButton" type="Button" parent="plants/Infobox/FrameAndTitle/VboxContainer"] layout_mode = 2 size_flags_vertical = 4 +shortcut = SubResource("Shortcut_lmmwe") text = "exit" [node name="Label" type="Label" parent="plants/Infobox/FrameAndTitle"] diff --git a/scenes/gui/cursor_canvas_layer.tscn b/scenes/gui/cursor_canvas_layer.tscn new file mode 100644 index 0000000..8cbf299 --- /dev/null +++ b/scenes/gui/cursor_canvas_layer.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=3 format=3 uid="uid://djfsa0pxqeoq1"] + +[ext_resource type="Texture2D" uid="uid://c20dwjohaljdk" path="res://assets/sprites/atlases/cursor/default_arrow.png" id="1_0pqw0"] +[ext_resource type="Script" uid="uid://c6ucy48qwaxuc" path="res://scripts/Cursor.cs" id="2_yv0fr"] + +[node name="CursorCanvasLayer" type="CanvasLayer"] +process_mode = 3 +layer = 11 +follow_viewport_enabled = true + +[node name="Cursor" type="Sprite2D" parent="."] +texture = ExtResource("1_0pqw0") +script = ExtResource("2_yv0fr") diff --git a/scenes/main_menu.tscn b/scenes/main_menu.tscn index 31f7a16..5c434df 100644 --- a/scenes/main_menu.tscn +++ b/scenes/main_menu.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=18 format=3 uid="uid://bfstrli64u23y"] +[gd_scene load_steps=19 format=3 uid="uid://bfstrli64u23y"] [ext_resource type="Texture2D" uid="uid://dvldjlg0nr355" path="res://assets/sprites/atlases/atlas1.png" id="1_jk1qb"] [ext_resource type="Script" uid="uid://drru785m4eep" path="res://scripts/gui/main_menu_rich_text.gd" id="2_5dd4i"] @@ -13,6 +13,7 @@ [ext_resource type="AudioStream" uid="uid://bdx83fokp6kha" path="res://assets/audio/sfx/buttonclick.mp3" id="8_5pajh"] [ext_resource type="AudioStream" uid="uid://djgyc7bbwcepp" path="res://assets/audio/music/Александр Зацепин - Увертюра.mp3" id="9_j7ex8"] [ext_resource type="PackedScene" uid="uid://bvpt0q4j6nx18" path="res://scenes/gui/almanach.tscn" id="12_rcqid"] +[ext_resource type="PackedScene" uid="uid://djfsa0pxqeoq1" path="res://scenes/gui/cursor_canvas_layer.tscn" id="14_1ajci"] [sub_resource type="GDScript" id="GDScript_5dd4i"] resource_name = "main_menu" @@ -218,6 +219,8 @@ horizontal_alignment = 2 vertical_alignment = 1 script = SubResource("GDScript_flqon") +[node name="CursorCanvasLayer" parent="." instance=ExtResource("14_1ajci")] + [connection signal="meta_clicked" from="PrototypeWindow/ScrollContainer/PrototypeNotification" to="PrototypeWindow/ScrollContainer/PrototypeNotification" method="_on_meta_clicked"] [connection signal="pressed" from="Buttons/GameButtons/PlayButton" to="Buttons" method="_on_play_button_pressed"] [connection signal="pressed" from="Buttons/GameButtons/ExitButton" to="Buttons" method="_on_exit_button_pressed"] diff --git a/scenes/particles/potato_explosion.tscn b/scenes/particles/potato_explosion.tscn index 1ce4899..c2b63b8 100644 --- a/scenes/particles/potato_explosion.tscn +++ b/scenes/particles/potato_explosion.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=7 format=3 uid="uid://ckanq33rao1ur"] +[gd_scene load_steps=8 format=3 uid="uid://ckanq33rao1ur"] [ext_resource type="PackedScene" uid="uid://b4lx8adw6rbqs" path="res://scenes/particles/dirt_explosion.tscn" id="1_c4q5e"] [ext_resource type="Texture2D" uid="uid://cad45iyh16x5g" path="res://assets/sprites/particles/nachinka1.tres" id="2_lgu5b"] @@ -6,6 +6,7 @@ [ext_resource type="Texture2D" uid="uid://b3yfl2had6t3o" path="res://assets/sprites/particles/nachinka2.tres" id="4_xwh7c"] [ext_resource type="Texture2D" uid="uid://e5v4vpux4h8k" path="res://assets/sprites/particles/nachinka3.tres" id="5_ryjsf"] [ext_resource type="Texture2D" uid="uid://dny6mfpspd3o8" path="res://assets/sprites/particles/nachinka4.tres" id="6_ursbv"] +[ext_resource type="Script" uid="uid://b8v8xrsyswmg4" path="res://scripts/gamepad/ExplosionVibration.cs" id="7_xwh7c"] [node name="PotatoExplosion" instance=ExtResource("1_c4q5e")] @@ -52,3 +53,6 @@ explosiveness = 1.0 randomness = 0.11 local_coords = true process_material = ExtResource("3_lgu5b") + +[node name="VibrationController" type="Node" parent="." index="10"] +script = ExtResource("7_xwh7c") diff --git a/scenes/templates/level_template.tscn b/scenes/templates/level_template.tscn index f6e4449..ffce36c 100644 --- a/scenes/templates/level_template.tscn +++ b/scenes/templates/level_template.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=56 format=3 uid="uid://dd3yegl1xo44m"] +[gd_scene load_steps=57 format=3 uid="uid://dd3yegl1xo44m"] [ext_resource type="AudioStream" uid="uid://b6xb6mjdecg6a" path="res://assets/audio/sfx/level/readysetplant.mp3" id="1_4gg2g"] [ext_resource type="Script" uid="uid://bndu1h5kgcde8" path="res://scripts/level/RuntimeLevelData.cs" id="1_31ltw"] @@ -37,6 +37,7 @@ [ext_resource type="AudioStream" uid="uid://cfybn7wn04frs" path="res://assets/audio/music/Grasswalk_Standard.mp3" id="34_tqd4v"] [ext_resource type="AudioStream" uid="uid://get7nh1goi1c" path="res://assets/audio/music/Grasswalk_cool.mp3" id="35_4gg2g"] [ext_resource type="Script" uid="uid://bnj5tlcpmep2o" path="res://scripts/audio/MusicTransitioner.cs" id="36_wwgye"] +[ext_resource type="PackedScene" uid="uid://djfsa0pxqeoq1" path="res://scenes/gui/cursor_canvas_layer.tscn" id="38_wwgye"] [sub_resource type="Animation" id="Animation_vbgdr"] resource_name = "CYS_Sequence" @@ -681,6 +682,7 @@ metadata/_edit_lock_ = true layer = -1 [node name="RuntimeGUI" parent="HUD" instance=ExtResource("4_okro4")] +focus_neighbor_bottom = NodePath("../../GUI/ChooseYourSeeds") metadata/_edit_lock_ = true [node name="Overlay" type="CanvasLayer" parent="."] @@ -702,6 +704,7 @@ anchor_top = 1.0 anchor_bottom = 2.0 size_flags_horizontal = 3 size_flags_vertical = 3 +focus_neighbor_top = NodePath("../../HUD/RuntimeGUI") metadata/_edit_lock_ = true [node name="PauseMenu" parent="GUI" instance=ExtResource("6_4bmqp")] @@ -895,6 +898,8 @@ ignore_time_scale = true [node name="ReadySetPlantPlayer" type="AudioStreamPlayer" parent="."] +[node name="CursorCanvasLayer" parent="." instance=ExtResource("38_wwgye")] + [connection signal="OnLevelStateChanged" from="Data" to="SunSpawner/Timer" method="OnLevelStateChanged"] [connection signal="OnLevelStateChanged" from="Data" to="ZombieLevelPrevewer" method="OnLevelStateChanged"] [connection signal="OnLevelStateChanged" from="Data" to="InitialSpawner" method="OnLevelStateChanged"] diff --git a/scripts/Cursor.cs b/scripts/Cursor.cs index 8d83fcf..17d9acf 100644 --- a/scripts/Cursor.cs +++ b/scripts/Cursor.cs @@ -1,50 +1,52 @@ using Godot; +using Newlon.Components.Level; namespace Newlon; -public partial class Cursor : Node +public partial class Cursor : Node2D { - public static Cursor Instance { get; private set; } + #region Textures + private readonly Texture2D defaultArrow = ResourceLoader.Load("uid://c20dwjohaljdk"); + private readonly Texture2D defaultPoint = ResourceLoader.Load("uid://cw0rqtl8ulndd"); + private readonly Texture2D shovelArrow = ResourceLoader.Load("uid://dq375kjjo17g2"); + private readonly Texture2D plantArrow = ResourceLoader.Load("uid://dx123mhv4oee"); + #endregion + public static Cursor Instance { get; private set; } public bool shovel = false; public bool plant = false; + public static CursorMode Mode = CursorMode.Mouse; + private float sensitivity = 200.0f; - public override void _Ready() + public enum CursorMode + { + Mouse, + Gamepad + } + public override void _EnterTree() { Instance = this; - SetDefaultCursor(); } - public void UpdateCursor() + public override void _Process(double delta) { - if (shovel) + switch (Mode) { - SetShovelCursor(); - return; + case CursorMode.Mouse: + break; + case CursorMode.Gamepad: + var vector = Input.GetVector("cursor_left", "cursor_right", "cursor_up", "cursor_down"); + + var set_position = GetGlobalMousePosition() + vector * (float)delta * sensitivity; + + GetViewport().WarpMouse(GetGlobalTransformWithCanvas() * set_position); + break; + } - - if (plant) - { - SetPlantCursor(); - return; - } - - SetDefaultCursor() ; - } - - public void SetDefaultCursor() + +} + public static Vector2 GetCursorPosition() { - Input.SetCustomMouseCursor(ResourceLoader.Load("res://assets/sprites/atlases/cursor/default_arrow.png"),shape:Input.CursorShape.Arrow); - Input.SetCustomMouseCursor(ResourceLoader.Load("res://assets/sprites/atlases/cursor/default_point.png"),shape:Input.CursorShape.PointingHand); - } - - public void SetPlantCursor() - { - Input.SetCustomMouseCursor(ResourceLoader.Load("res://assets/sprites/atlases/cursor/plant_arrow.png")); - } - - public void SetShovelCursor() - { - Input.SetCustomMouseCursor(ResourceLoader.Load("res://assets/sprites/atlases/cursor/shovel_arrow.png")); + return Instance.GetGlobalMousePosition(); } } diff --git a/scripts/entities/plants/behaviours/SnipachBehaviour.cs b/scripts/entities/plants/behaviours/SnipachBehaviour.cs index 1f0f329..fffd2c1 100644 --- a/scripts/entities/plants/behaviours/SnipachBehaviour.cs +++ b/scripts/entities/plants/behaviours/SnipachBehaviour.cs @@ -29,7 +29,7 @@ public partial class SnipachBehaviour : BaseBehaviour { if (dragging) { - attackBox.GlobalPosition = (attackBox.GetGlobalMousePosition() / FieldParams.Tile).Ceil() * FieldParams.Tile - new Vector2(20, 14); + attackBox.GlobalPosition = (Cursor.GetCursorPosition() / FieldParams.Tile).Ceil() * FieldParams.Tile - new Vector2(20, 14); } } diff --git a/scripts/gamepad/ExplosionVibration.cs b/scripts/gamepad/ExplosionVibration.cs new file mode 100644 index 0000000..39b2507 --- /dev/null +++ b/scripts/gamepad/ExplosionVibration.cs @@ -0,0 +1,10 @@ +using Godot; +using System; + +public partial class ExplosionVibration : Node +{ + public override void _EnterTree() + { + Input.StartJoyVibration(GamepadHandler.Instance.CurrentDevice, 0, 1,0.25f); + } +} diff --git a/scripts/gamepad/ExplosionVibration.cs.uid b/scripts/gamepad/ExplosionVibration.cs.uid new file mode 100644 index 0000000..4baefc4 --- /dev/null +++ b/scripts/gamepad/ExplosionVibration.cs.uid @@ -0,0 +1 @@ +uid://b8v8xrsyswmg4 diff --git a/scripts/gamepad/GamepadHandler.cs b/scripts/gamepad/GamepadHandler.cs new file mode 100644 index 0000000..033cc36 --- /dev/null +++ b/scripts/gamepad/GamepadHandler.cs @@ -0,0 +1,52 @@ +using Godot; +using Newlon; +using System; + +public partial class GamepadHandler : Node +{ + public static GamepadHandler Instance { get; private set; } + public int CurrentDevice { get; private set; } = 0; + public bool IsGamepadControlled => focused && controlled; + private bool focused; + private bool controlled; + public override void _EnterTree() + { + Instance = this; + } + + public override void _Notification(int what) + { + if (what == NotificationApplicationFocusIn) + { + focused = true; + } + if (what == NotificationApplicationFocusOut) + { + focused = false; + } + } + public override void _Input(InputEvent @event) + { + if (@event is InputEventJoypadButton || @event is InputEventJoypadMotion) + { + SetControlled(true); + } + if ((@event is InputEventMouse && Input.GetVector("cursor_left", "cursor_right", "cursor_up", "cursor_down") == Vector2.Zero) || @event is InputEventKey) + { + SetControlled(false); + } + } + private void SetControlled(bool to) + { + controlled = to; + if (controlled) + { + Cursor.Mode = Cursor.CursorMode.Gamepad; + } + else + { + Cursor.Mode = Cursor.CursorMode.Mouse; + } + } + +} diff --git a/scripts/gamepad/GamepadHandler.cs.uid b/scripts/gamepad/GamepadHandler.cs.uid new file mode 100644 index 0000000..6de2a37 --- /dev/null +++ b/scripts/gamepad/GamepadHandler.cs.uid @@ -0,0 +1 @@ +uid://cyw4fh4x0fdjg diff --git a/scripts/gui/ShovelButton.cs b/scripts/gui/ShovelButton.cs index be9dc6a..7b9de71 100644 --- a/scripts/gui/ShovelButton.cs +++ b/scripts/gui/ShovelButton.cs @@ -29,7 +29,6 @@ public partial class ShovelButton : TextureButton public override void _Toggled(bool toggledOn) { Cursor.Instance.shovel = toggledOn; - Cursor.Instance.UpdateCursor(); } public override void _Input(InputEvent @event) @@ -68,7 +67,7 @@ public partial class ShovelButton : TextureButton if (ButtonPressed) { - var gridEntity = GetTile(PoolContainer.Instance.Plants.GetGlobalMousePosition()); + var gridEntity = GetTile(Cursor.GetCursorPosition()); if (TrySetGridEntity(gridEntity)) return; if (TrySetDynEntity()) return; @@ -129,7 +128,7 @@ public partial class ShovelButton : TextureButton } private bool TrySetDynEntity() { - raycast.GlobalPosition = PoolContainer.Instance.GetGlobalMousePosition(); + raycast.GlobalPosition = Cursor.GetCursorPosition(); if (raycast.IsColliding()) { diff --git a/scripts/gui/choose_your_seeds/GridLoader.cs b/scripts/gui/choose_your_seeds/GridLoader.cs index 35f4e55..3f2c24f 100644 --- a/scripts/gui/choose_your_seeds/GridLoader.cs +++ b/scripts/gui/choose_your_seeds/GridLoader.cs @@ -22,9 +22,11 @@ public partial class GridLoader : GridContainer Seedpacket slot = _plantCard.Instantiate(); AddChild(slot); + slot.SetResource(resource); slot.SetForbidden(RuntimeLevelData.LevelResource.forbiddenPlants.Contains(resource.internal_id)); slot.SetLocked(PlayerProgress.Instance.PlayerPlants.Contains(resource) == false); + if (GetChildCount() == 1) slot.GrabFocus(); var handler = new ChoosableHandler(slot); slot.SetHandler(handler); } diff --git a/scripts/gui/choose_your_seeds/LevelRunButton.cs b/scripts/gui/choose_your_seeds/LevelRunButton.cs index 12a5c15..98664ec 100644 --- a/scripts/gui/choose_your_seeds/LevelRunButton.cs +++ b/scripts/gui/choose_your_seeds/LevelRunButton.cs @@ -1,4 +1,5 @@ using Godot; +using Newlon.Components.GUI.Seedpackets; using Newlon.Components.Level; namespace Newlon.Components.GUI; @@ -8,5 +9,6 @@ public partial class LevelRunButton : Button public override void _Pressed() { RuntimeLevelData.Instance.SetLevelState(RuntimeLevelData.LevelStates.Pregame); + LevelGUIElements.Instance.SeedpacketsHotbar.GetChild(0).GrabFocus(); } } diff --git a/scripts/gui/menu_buttons.gd b/scripts/gui/menu_buttons.gd index 9df0a36..41900ed 100644 --- a/scripts/gui/menu_buttons.gd +++ b/scripts/gui/menu_buttons.gd @@ -1,5 +1,7 @@ extends Node +func _ready() -> void: + $InfoButtons/AboutButton.grab_focus() func _on_play_button_pressed() -> void: LevelController.call("StartLevel",preload("uid://dd3yegl1xo44m"),preload("uid://dwd5oqr0tuvhv")) diff --git a/scripts/gui/seedpackets/Seedpacket.cs b/scripts/gui/seedpackets/Seedpacket.cs index e408f8c..23fe08d 100644 --- a/scripts/gui/seedpackets/Seedpacket.cs +++ b/scripts/gui/seedpackets/Seedpacket.cs @@ -37,14 +37,6 @@ public partial class Seedpacket : TextureButton public override void _Process(double delta) { Disabled = disablePacket || _timer.TimeLeft > 0; - if (Disabled) - { - FocusMode = FocusModeEnum.None; - } - else - { - FocusMode = FocusModeEnum.All; - } if (_handler is ISeedpacketProcess processHandler) processHandler.Process(); } public void SetResource(GridEntityResource resource) @@ -88,7 +80,6 @@ public partial class Seedpacket : TextureButton public void Recharge() { _timer.Start(); - ReleaseFocus(); } public void OnUnfocused() diff --git a/scripts/level/PlantField.cs b/scripts/level/PlantField.cs index bd47041..c93254f 100644 --- a/scripts/level/PlantField.cs +++ b/scripts/level/PlantField.cs @@ -47,7 +47,7 @@ public partial class PlantField : Node2D public override void _Process(double delta) { // Getting and storing global mouse position, setting plant-poiner to it - var mouse_pos = GetGlobalMousePosition(); + var mouse_pos = Cursor.GetCursorPosition(); _plantSetter.GlobalPosition = mouse_pos; // Getting position in grid coordinates @@ -74,7 +74,6 @@ public partial class PlantField : Node2D Material.Set("shader_parameter/amount", 1); } Cursor.Instance.plant = canPlace; - Cursor.Instance.UpdateCursor(); } _previousCanPlace = canPlace; @@ -86,7 +85,7 @@ public partial class PlantField : Node2D { if (@event.IsActionPressed("cancel_plant") && _slot != null) { - _slot.ReleaseFocus(); + ResetPlant(); } if (@event.IsActionPressed("primary_action") && _previousCanPlace) @@ -106,6 +105,7 @@ public partial class PlantField : Node2D // Unfocusing and recharging slot _slot.Recharge(); + ResetPlant(); } } } diff --git a/scripts/particles/StandardParticles.cs b/scripts/particles/StandardParticles.cs index cb39b2d..2857121 100644 --- a/scripts/particles/StandardParticles.cs +++ b/scripts/particles/StandardParticles.cs @@ -8,11 +8,14 @@ public partial class StandardParticles : Node2D private int counterMax = 0; public override void _Ready() { - foreach (GpuParticles2D emitter in GetChildren()) + foreach (Node child in GetChildren()) { - emitter.Emitting = true; - counterMax += 1; - emitter.Finished += MarkForDestruction; + if (child is GpuParticles2D emitter) + { + emitter.Emitting = true; + counterMax += 1; + emitter.Finished += MarkForDestruction; + } } } public void MarkForDestruction() diff --git a/translations/rewards.csv b/translations/rewards.csv index 4e77c62..1e9c09a 100644 --- a/translations/rewards.csv +++ b/translations/rewards.csv @@ -12,3 +12,4 @@ rwd_spikeweed,Attacks zombies that step on it,Атакует зомби кото moneybag,Money bag,Мешок с монетами rwd_moneybag,Now you have some money to buy new plants.,Теперь у вас есть деньги чтобы затариться в магазине. rwd_peashooter,Simply shoots peas at zomibes.,Просто стреляет горошинами по зомби. +rwd_snipach,Snipes a tile of your choice.,Отстреливает клетку по вашему усмотрению. diff --git a/translations/rewards.csv.import b/translations/rewards.csv.import index 5e333f6..0030832 100644 --- a/translations/rewards.csv.import +++ b/translations/rewards.csv.import @@ -3,13 +3,11 @@ importer="csv_translation" type="Translation" uid="uid://xvsya47m66cl" +valid=false [deps] -files=["res://translations/rewards.en.translation", "res://translations/rewards.ru.translation"] - source_file="res://translations/rewards.csv" -dest_files=["res://translations/rewards.en.translation", "res://translations/rewards.ru.translation"] [params]