From 0a6a2317bf2c4ce7ea29b4d38c23ea3157d0bed8 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Sat, 24 Jan 2026 05:59:34 +0100 Subject: [PATCH] init --- max-effort/.editorconfig | 4 + max-effort/.gitattributes | 2 + max-effort/.gitignore | 3 + max-effort/MaxEffort.gdextension | 14 ++ max-effort/MaxEffort.gdextension.uid | 1 + max-effort/Objects/bench_press.tscn | 30 +++ max-effort/Objects/bench_press_stickman.tscn | 46 ++++ max-effort/Objects/deadlift.tscn | 16 ++ max-effort/Objects/hazard_animated.tscn | 15 ++ max-effort/Resources/Day_Day1.tres | 9 + max-effort/Resources/Day_Day2.tres | 11 + max-effort/Resources/GameState.tres | 3 + max-effort/Resources/Hazard_GymBro.tres | 72 ++++++ max-effort/Resources/SoundBank.tres | 3 + max-effort/Scenes/.idea/.gitignore | 15 ++ .../copilot.data.migration.ask2agent.xml | 6 + max-effort/Scenes/.idea/encodings.xml | 4 + max-effort/Scenes/.idea/indexLayout.xml | 8 + .../inspectionProfiles/Project_Default.xml | 6 + max-effort/Scenes/main.tscn | 147 ++++++++++++ max-effort/Scenes/main_menu.tscn | 62 +++++ max-effort/Shaders/TunnelVision.gdshader | 20 ++ max-effort/Shaders/TunnelVision.gdshader.uid | 1 + max-effort/Sprites/barbell.png | Bin 0 -> 935 bytes max-effort/Sprites/barbell.png.import | 40 ++++ max-effort/Sprites/bench.png | Bin 0 -> 2267 bytes max-effort/Sprites/bench.png.import | 40 ++++ max-effort/Sprites/bench_press0.png | Bin 0 -> 2327 bytes max-effort/Sprites/bench_press0.png.import | 40 ++++ max-effort/Sprites/bench_press1.png | Bin 0 -> 2306 bytes max-effort/Sprites/bench_press1.png.import | 40 ++++ max-effort/Sprites/bench_press2.png | Bin 0 -> 2287 bytes max-effort/Sprites/bench_press2.png.import | 40 ++++ max-effort/Sprites/bench_press3.png | Bin 0 -> 2241 bytes max-effort/Sprites/bench_press3.png.import | 40 ++++ max-effort/Sprites/bench_press4.png | Bin 0 -> 2370 bytes max-effort/Sprites/bench_press4.png.import | 40 ++++ max-effort/Sprites/bench_press5.png | Bin 0 -> 2409 bytes max-effort/Sprites/bench_press5.png.import | 40 ++++ max-effort/Sprites/bench_press6.png | Bin 0 -> 2407 bytes max-effort/Sprites/bench_press6.png.import | 40 ++++ max-effort/Sprites/bench_press7.png | Bin 0 -> 2371 bytes max-effort/Sprites/bench_press7.png.import | 40 ++++ max-effort/Sprites/chad_walk0.png | Bin 0 -> 2322 bytes max-effort/Sprites/chad_walk0.png.import | 40 ++++ max-effort/Sprites/chad_walk1.png | Bin 0 -> 2242 bytes max-effort/Sprites/chad_walk1.png.import | 40 ++++ max-effort/Sprites/chad_walk2.png | Bin 0 -> 2024 bytes max-effort/Sprites/chad_walk2.png.import | 40 ++++ max-effort/Sprites/chad_walk3.png | Bin 0 -> 2211 bytes max-effort/Sprites/chad_walk3.png.import | 40 ++++ max-effort/Sprites/chad_walk4.png | Bin 0 -> 2420 bytes max-effort/Sprites/chad_walk4.png.import | 40 ++++ max-effort/Sprites/chad_wave0.png | Bin 0 -> 2176 bytes max-effort/Sprites/chad_wave0.png.import | 40 ++++ max-effort/Sprites/chad_wave1.png | Bin 0 -> 2245 bytes max-effort/Sprites/chad_wave1.png.import | 40 ++++ max-effort/Sprites/chad_wave2.png | Bin 0 -> 2156 bytes max-effort/Sprites/chad_wave2.png.import | 40 ++++ max-effort/Sprites/chad_wave3.png | Bin 0 -> 2223 bytes max-effort/Sprites/chad_wave3.png.import | 40 ++++ max-effort/Sprites/chad_wave4.png | Bin 0 -> 2237 bytes max-effort/Sprites/chad_wave4.png.import | 40 ++++ max-effort/Sprites/chad_wave5.png | Bin 0 -> 2259 bytes max-effort/Sprites/chad_wave5.png.import | 40 ++++ max-effort/Sprites/chad_wave6.png | Bin 0 -> 2177 bytes max-effort/Sprites/chad_wave6.png.import | 40 ++++ max-effort/Sprites/stick-bench-bend.png | Bin 0 -> 4021 bytes .../Sprites/stick-bench-bend.png.import | 40 ++++ max-effort/Sprites/stick-bench-straight.png | Bin 0 -> 3750 bytes .../Sprites/stick-bench-straight.png.import | 40 ++++ max-effort/icon.svg | 1 + max-effort/icon.svg.import | 43 ++++ max-effort/project.godot | 30 +++ rust/.gitignore | 1 + rust/Cargo.lock | 203 +++++++++++++++++ rust/Cargo.toml | 10 + rust/src/core/game_state.rs | 161 +++++++++++++ rust/src/core/mod.rs | 1 + rust/src/data/day_config.rs | 37 +++ rust/src/data/hazard_def.rs | 55 +++++ rust/src/data/mod.rs | 4 + rust/src/data/sound_bank.rs | 48 ++++ rust/src/data/tunnel_config.rs | 29 +++ rust/src/lib.rs | 12 + rust/src/systems/bench_press_system.rs | 70 ++++++ rust/src/systems/camera_shake_system.rs | 86 +++++++ rust/src/systems/deadlift_system.rs | 105 +++++++++ rust/src/systems/game_manager.rs | 207 +++++++++++++++++ rust/src/systems/hazard_controller.rs | 209 +++++++++++++++++ rust/src/systems/hazard_system.rs | 144 ++++++++++++ rust/src/systems/mod.rs | 9 + rust/src/systems/player_input_system.rs | 40 ++++ rust/src/systems/sound_manager.rs | 213 ++++++++++++++++++ rust/src/systems/tunnel_system.rs | 82 +++++++ rust/src/ui/lift_progress_bar.rs | 37 +++ rust/src/ui/main_menu.rs | 59 +++++ rust/src/ui/mod.rs | 2 + rust/src/visuals/lift_sync_controller.rs | 107 +++++++++ rust/src/visuals/mod.rs | 1 + 100 files changed, 3464 insertions(+) create mode 100644 max-effort/.editorconfig create mode 100644 max-effort/.gitattributes create mode 100644 max-effort/.gitignore create mode 100644 max-effort/MaxEffort.gdextension create mode 100644 max-effort/MaxEffort.gdextension.uid create mode 100644 max-effort/Objects/bench_press.tscn create mode 100644 max-effort/Objects/bench_press_stickman.tscn create mode 100644 max-effort/Objects/deadlift.tscn create mode 100644 max-effort/Objects/hazard_animated.tscn create mode 100644 max-effort/Resources/Day_Day1.tres create mode 100644 max-effort/Resources/Day_Day2.tres create mode 100644 max-effort/Resources/GameState.tres create mode 100644 max-effort/Resources/Hazard_GymBro.tres create mode 100644 max-effort/Resources/SoundBank.tres create mode 100644 max-effort/Scenes/.idea/.gitignore create mode 100644 max-effort/Scenes/.idea/copilot.data.migration.ask2agent.xml create mode 100644 max-effort/Scenes/.idea/encodings.xml create mode 100644 max-effort/Scenes/.idea/indexLayout.xml create mode 100644 max-effort/Scenes/.idea/inspectionProfiles/Project_Default.xml create mode 100644 max-effort/Scenes/main.tscn create mode 100644 max-effort/Scenes/main_menu.tscn create mode 100644 max-effort/Shaders/TunnelVision.gdshader create mode 100644 max-effort/Shaders/TunnelVision.gdshader.uid create mode 100644 max-effort/Sprites/barbell.png create mode 100644 max-effort/Sprites/barbell.png.import create mode 100644 max-effort/Sprites/bench.png create mode 100644 max-effort/Sprites/bench.png.import create mode 100644 max-effort/Sprites/bench_press0.png create mode 100644 max-effort/Sprites/bench_press0.png.import create mode 100644 max-effort/Sprites/bench_press1.png create mode 100644 max-effort/Sprites/bench_press1.png.import create mode 100644 max-effort/Sprites/bench_press2.png create mode 100644 max-effort/Sprites/bench_press2.png.import create mode 100644 max-effort/Sprites/bench_press3.png create mode 100644 max-effort/Sprites/bench_press3.png.import create mode 100644 max-effort/Sprites/bench_press4.png create mode 100644 max-effort/Sprites/bench_press4.png.import create mode 100644 max-effort/Sprites/bench_press5.png create mode 100644 max-effort/Sprites/bench_press5.png.import create mode 100644 max-effort/Sprites/bench_press6.png create mode 100644 max-effort/Sprites/bench_press6.png.import create mode 100644 max-effort/Sprites/bench_press7.png create mode 100644 max-effort/Sprites/bench_press7.png.import create mode 100644 max-effort/Sprites/chad_walk0.png create mode 100644 max-effort/Sprites/chad_walk0.png.import create mode 100644 max-effort/Sprites/chad_walk1.png create mode 100644 max-effort/Sprites/chad_walk1.png.import create mode 100644 max-effort/Sprites/chad_walk2.png create mode 100644 max-effort/Sprites/chad_walk2.png.import create mode 100644 max-effort/Sprites/chad_walk3.png create mode 100644 max-effort/Sprites/chad_walk3.png.import create mode 100644 max-effort/Sprites/chad_walk4.png create mode 100644 max-effort/Sprites/chad_walk4.png.import create mode 100644 max-effort/Sprites/chad_wave0.png create mode 100644 max-effort/Sprites/chad_wave0.png.import create mode 100644 max-effort/Sprites/chad_wave1.png create mode 100644 max-effort/Sprites/chad_wave1.png.import create mode 100644 max-effort/Sprites/chad_wave2.png create mode 100644 max-effort/Sprites/chad_wave2.png.import create mode 100644 max-effort/Sprites/chad_wave3.png create mode 100644 max-effort/Sprites/chad_wave3.png.import create mode 100644 max-effort/Sprites/chad_wave4.png create mode 100644 max-effort/Sprites/chad_wave4.png.import create mode 100644 max-effort/Sprites/chad_wave5.png create mode 100644 max-effort/Sprites/chad_wave5.png.import create mode 100644 max-effort/Sprites/chad_wave6.png create mode 100644 max-effort/Sprites/chad_wave6.png.import create mode 100644 max-effort/Sprites/stick-bench-bend.png create mode 100644 max-effort/Sprites/stick-bench-bend.png.import create mode 100644 max-effort/Sprites/stick-bench-straight.png create mode 100644 max-effort/Sprites/stick-bench-straight.png.import create mode 100644 max-effort/icon.svg create mode 100644 max-effort/icon.svg.import create mode 100644 max-effort/project.godot create mode 100644 rust/.gitignore create mode 100644 rust/Cargo.lock create mode 100644 rust/Cargo.toml create mode 100644 rust/src/core/game_state.rs create mode 100644 rust/src/core/mod.rs create mode 100644 rust/src/data/day_config.rs create mode 100644 rust/src/data/hazard_def.rs create mode 100644 rust/src/data/mod.rs create mode 100644 rust/src/data/sound_bank.rs create mode 100644 rust/src/data/tunnel_config.rs create mode 100644 rust/src/lib.rs create mode 100644 rust/src/systems/bench_press_system.rs create mode 100644 rust/src/systems/camera_shake_system.rs create mode 100644 rust/src/systems/deadlift_system.rs create mode 100644 rust/src/systems/game_manager.rs create mode 100644 rust/src/systems/hazard_controller.rs create mode 100644 rust/src/systems/hazard_system.rs create mode 100644 rust/src/systems/mod.rs create mode 100644 rust/src/systems/player_input_system.rs create mode 100644 rust/src/systems/sound_manager.rs create mode 100644 rust/src/systems/tunnel_system.rs create mode 100644 rust/src/ui/lift_progress_bar.rs create mode 100644 rust/src/ui/main_menu.rs create mode 100644 rust/src/ui/mod.rs create mode 100644 rust/src/visuals/lift_sync_controller.rs create mode 100644 rust/src/visuals/mod.rs diff --git a/max-effort/.editorconfig b/max-effort/.editorconfig new file mode 100644 index 0000000..f28239b --- /dev/null +++ b/max-effort/.editorconfig @@ -0,0 +1,4 @@ +root = true + +[*] +charset = utf-8 diff --git a/max-effort/.gitattributes b/max-effort/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/max-effort/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/max-effort/.gitignore b/max-effort/.gitignore new file mode 100644 index 0000000..0af181c --- /dev/null +++ b/max-effort/.gitignore @@ -0,0 +1,3 @@ +# Godot 4+ specific ignores +.godot/ +/android/ diff --git a/max-effort/MaxEffort.gdextension b/max-effort/MaxEffort.gdextension new file mode 100644 index 0000000..27a274b --- /dev/null +++ b/max-effort/MaxEffort.gdextension @@ -0,0 +1,14 @@ +[configuration] +entry_symbol = "gdext_rust_init" +compatibility_minimum = 4.5 +reloadable = true + +[libraries] +linux.debug.x86_64 = "res://../rust/target/debug/libmax_effort_lib.so" +linux.release.x86_64 = "res://../rust/target/release/libmax_effort_lib.so" +windows.debug.x86_64 = "res://../rust/target/debug/max-effort-lib.dll" +windows.release.x86_64 = "res://../rust/target/release/max-effort-lib.dll" +macos.debug = "res://../rust/target/debug/libmax_effort_lib.dylib" +macos.release = "res://../rust/target/release/libmax_effort_lib.dylib" +macos.debug.arm64 = "res://../rust/target/debug/libmax_effort_lib.dylib" +macos.release.arm64 = "res://../rust/target/release/libmax_effort_lib.dylib" diff --git a/max-effort/MaxEffort.gdextension.uid b/max-effort/MaxEffort.gdextension.uid new file mode 100644 index 0000000..023e9d0 --- /dev/null +++ b/max-effort/MaxEffort.gdextension.uid @@ -0,0 +1 @@ +uid://ddxl1hldnuqrv diff --git a/max-effort/Objects/bench_press.tscn b/max-effort/Objects/bench_press.tscn new file mode 100644 index 0000000..4b32fc7 --- /dev/null +++ b/max-effort/Objects/bench_press.tscn @@ -0,0 +1,30 @@ +[gd_scene load_steps=5 format=3 uid="uid://dxq2510ywj1hy"] + +[ext_resource type="GameState" uid="uid://2gma8vvisnqo" path="res://Resources/GameState.tres" id="1_tik8c"] +[ext_resource type="PackedScene" uid="uid://dn8y3bgovnh4a" path="res://Objects/bench_press_stickman.tscn" id="2_0c1tm"] +[ext_resource type="Texture2D" uid="uid://dsovna2tmb4o3" path="res://Sprites/bench.png" id="2_ky8t4"] +[ext_resource type="Texture2D" uid="uid://cbgn8aspf7oi0" path="res://Sprites/barbell.png" id="3_ky8t4"] + +[node name="BenchPress" type="Node"] + +[node name="System" type="BenchPressSystem" parent="."] +game_state = ExtResource("1_tik8c") + +[node name="Bench" type="Sprite2D" parent="."] +position = Vector2(11, 1) +scale = Vector2(2.086, 2.086) +texture = ExtResource("2_ky8t4") + +[node name="BenchPressStickman" parent="." instance=ExtResource("2_0c1tm")] + +[node name="Barbell" type="Sprite2D" parent="."] +position = Vector2(22, -5) +scale = Vector2(2.432, 2.432) +texture = ExtResource("3_ky8t4") + +[node name="LiftSyncController" type="LiftSyncController" parent="." node_paths=PackedStringArray("player_anim", "barbell")] +player_anim = NodePath("../BenchPressStickman") +barbell = NodePath("../Barbell") +game_state = ExtResource("1_tik8c") +animation_name = "default" +bar_positions = Array[Vector2]([Vector2(19, -5), Vector2(19, -19), Vector2(21, -36), Vector2(21, -15), Vector2(23, 3), Vector2(22, 11), Vector2(22, -1), Vector2(22, -1)]) diff --git a/max-effort/Objects/bench_press_stickman.tscn b/max-effort/Objects/bench_press_stickman.tscn new file mode 100644 index 0000000..2475c72 --- /dev/null +++ b/max-effort/Objects/bench_press_stickman.tscn @@ -0,0 +1,46 @@ +[gd_scene load_steps=10 format=3 uid="uid://dn8y3bgovnh4a"] + +[ext_resource type="Texture2D" uid="uid://dci4cuavfc4la" path="res://Sprites/bench_press0.png" id="1_8snp0"] +[ext_resource type="Texture2D" uid="uid://dya801bkqxdpa" path="res://Sprites/bench_press1.png" id="2_ckjrk"] +[ext_resource type="Texture2D" uid="uid://bbxviq4c0pyju" path="res://Sprites/bench_press2.png" id="3_s2d21"] +[ext_resource type="Texture2D" uid="uid://biu7q8mfw62be" path="res://Sprites/bench_press3.png" id="4_e1c5r"] +[ext_resource type="Texture2D" uid="uid://bg06qtcl207do" path="res://Sprites/bench_press4.png" id="5_pwixy"] +[ext_resource type="Texture2D" uid="uid://bkypgv8rfcd8k" path="res://Sprites/bench_press5.png" id="6_6piga"] +[ext_resource type="Texture2D" uid="uid://warnmdoebwht" path="res://Sprites/bench_press6.png" id="7_ex7t0"] +[ext_resource type="Texture2D" uid="uid://yrorih7pbt0q" path="res://Sprites/bench_press7.png" id="8_as8xi"] + +[sub_resource type="SpriteFrames" id="SpriteFrames_edqll"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": ExtResource("1_8snp0") +}, { +"duration": 1.0, +"texture": ExtResource("2_ckjrk") +}, { +"duration": 1.0, +"texture": ExtResource("3_s2d21") +}, { +"duration": 1.0, +"texture": ExtResource("4_e1c5r") +}, { +"duration": 1.0, +"texture": ExtResource("5_pwixy") +}, { +"duration": 1.0, +"texture": ExtResource("6_6piga") +}, { +"duration": 1.0, +"texture": ExtResource("7_ex7t0") +}, { +"duration": 1.0, +"texture": ExtResource("8_as8xi") +}], +"loop": true, +"name": &"default", +"speed": 12.0 +}] + +[node name="BenchPressStickman" type="AnimatedSprite2D"] +sprite_frames = SubResource("SpriteFrames_edqll") +speed_scale = 0.0 diff --git a/max-effort/Objects/deadlift.tscn b/max-effort/Objects/deadlift.tscn new file mode 100644 index 0000000..984418f --- /dev/null +++ b/max-effort/Objects/deadlift.tscn @@ -0,0 +1,16 @@ +[gd_scene load_steps=3 format=3 uid="uid://dx1k40qfioaas"] + +[ext_resource type="GameState" uid="uid://2gma8vvisnqo" path="res://Resources/GameState.tres" id="1_n6ace"] +[ext_resource type="Texture2D" uid="uid://cbgn8aspf7oi0" path="res://Sprites/barbell.png" id="2_ltxro"] + +[node name="Deadlift" type="Node"] + +[node name="System" type="DeadliftSystem" parent="." node_paths=PackedStringArray("bar_visual")] +bar_height = 7.0 +bar_visual = NodePath("../Barbell") +end_pos = Vector2(0, -30) +game_state = ExtResource("1_n6ace") + +[node name="Barbell" type="Sprite2D" parent="."] +scale = Vector2(2, 2) +texture = ExtResource("2_ltxro") diff --git a/max-effort/Objects/hazard_animated.tscn b/max-effort/Objects/hazard_animated.tscn new file mode 100644 index 0000000..56a9fb1 --- /dev/null +++ b/max-effort/Objects/hazard_animated.tscn @@ -0,0 +1,15 @@ +[gd_scene load_steps=2 format=3 uid="uid://bqxc62tofqger"] + +[ext_resource type="GameState" uid="uid://2gma8vvisnqo" path="res://Resources/GameState.tres" id="1_strkh"] + +[node name="HazardAnimated" type="HazardController" node_paths=PackedStringArray("anim_sprite", "click_area", "click_shape")] +anim_sprite = NodePath("AnimatedSprite2D") +click_area = NodePath("Area2D") +click_shape = NodePath("Area2D/CollisionShape2D") +game_state = ExtResource("1_strkh") + +[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."] + +[node name="Area2D" type="Area2D" parent="."] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] diff --git a/max-effort/Resources/Day_Day1.tres b/max-effort/Resources/Day_Day1.tres new file mode 100644 index 0000000..5e3aeb8 --- /dev/null +++ b/max-effort/Resources/Day_Day1.tres @@ -0,0 +1,9 @@ +[gd_resource type="DayConfig" load_steps=3 format=3 uid="uid://d30pwvrr7m72j"] + +[ext_resource type="HazardDef" uid="uid://pgmnp6ev1ark" path="res://Resources/Hazard_GymBro.tres" id="1_qov1i"] +[ext_resource type="PackedScene" uid="uid://dxq2510ywj1hy" path="res://Objects/bench_press.tscn" id="2_ilyy2"] + +[resource] +target_weight = 25.0 +mini_game_scene = ExtResource("2_ilyy2") +available_hazards = Array[HazardDef]([ExtResource("1_qov1i")]) diff --git a/max-effort/Resources/Day_Day2.tres b/max-effort/Resources/Day_Day2.tres new file mode 100644 index 0000000..75b8262 --- /dev/null +++ b/max-effort/Resources/Day_Day2.tres @@ -0,0 +1,11 @@ +[gd_resource type="DayConfig" load_steps=3 format=3 uid="uid://b0j1f8h6tioaf"] + +[ext_resource type="HazardDef" uid="uid://pgmnp6ev1ark" path="res://Resources/Hazard_GymBro.tres" id="1_x1txs"] +[ext_resource type="PackedScene" uid="uid://dx1k40qfioaas" path="res://Objects/deadlift.tscn" id="2_x1txs"] + +[resource] +day_number = 1 +day_title = "Day 2" +target_weight = 7.0 +mini_game_scene = ExtResource("2_x1txs") +available_hazards = Array[HazardDef]([ExtResource("1_x1txs")]) diff --git a/max-effort/Resources/GameState.tres b/max-effort/Resources/GameState.tres new file mode 100644 index 0000000..fb88a00 --- /dev/null +++ b/max-effort/Resources/GameState.tres @@ -0,0 +1,3 @@ +[gd_resource type="GameState" format=3 uid="uid://2gma8vvisnqo"] + +[resource] diff --git a/max-effort/Resources/Hazard_GymBro.tres b/max-effort/Resources/Hazard_GymBro.tres new file mode 100644 index 0000000..35abba4 --- /dev/null +++ b/max-effort/Resources/Hazard_GymBro.tres @@ -0,0 +1,72 @@ +[gd_resource type="HazardDef" load_steps=14 format=3 uid="uid://pgmnp6ev1ark"] + +[ext_resource type="Texture2D" uid="uid://c43wo6u2c0d43" path="res://Sprites/chad_walk0.png" id="1_v1id6"] +[ext_resource type="Texture2D" uid="uid://dt5i4j2gvqso" path="res://Sprites/chad_walk1.png" id="2_xcd3t"] +[ext_resource type="Texture2D" uid="uid://by265t6kx8us4" path="res://Sprites/chad_walk2.png" id="3_57x2g"] +[ext_resource type="Texture2D" uid="uid://dway2w8pbk5lp" path="res://Sprites/chad_walk3.png" id="4_s8hf6"] +[ext_resource type="Texture2D" uid="uid://bunfddn1pa8pj" path="res://Sprites/chad_walk4.png" id="5_tdncn"] +[ext_resource type="Texture2D" uid="uid://664m2cxtmmur" path="res://Sprites/chad_wave0.png" id="6_twq7w"] +[ext_resource type="Texture2D" uid="uid://tu8ph6cjdwhv" path="res://Sprites/chad_wave1.png" id="7_jshom"] +[ext_resource type="Texture2D" uid="uid://b28aaketyf0t1" path="res://Sprites/chad_wave2.png" id="8_hejui"] +[ext_resource type="Texture2D" uid="uid://jyr4f2p7jbk8" path="res://Sprites/chad_wave3.png" id="9_envil"] +[ext_resource type="Texture2D" uid="uid://f013utfdsqqe" path="res://Sprites/chad_wave4.png" id="10_tcjtc"] +[ext_resource type="Texture2D" uid="uid://duryxgc54alp5" path="res://Sprites/chad_wave5.png" id="11_i0i8i"] +[ext_resource type="Texture2D" uid="uid://yy2yrm4gq6w4" path="res://Sprites/chad_wave6.png" id="12_seh7d"] + +[sub_resource type="SpriteFrames" id="SpriteFrames_44y3n"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": ExtResource("1_v1id6") +}, { +"duration": 1.0, +"texture": ExtResource("2_xcd3t") +}, { +"duration": 1.0, +"texture": ExtResource("3_57x2g") +}, { +"duration": 1.0, +"texture": ExtResource("4_s8hf6") +}, { +"duration": 1.0, +"texture": ExtResource("5_tdncn") +}], +"loop": true, +"name": &"walking", +"speed": 12.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": ExtResource("6_twq7w") +}, { +"duration": 1.0, +"texture": ExtResource("7_jshom") +}, { +"duration": 1.0, +"texture": ExtResource("8_hejui") +}, { +"duration": 1.0, +"texture": ExtResource("9_envil") +}, { +"duration": 1.0, +"texture": ExtResource("10_tcjtc") +}, { +"duration": 1.0, +"texture": ExtResource("11_i0i8i") +}, { +"duration": 1.0, +"texture": ExtResource("12_seh7d") +}], +"loop": true, +"name": &"waving", +"speed": 12.0 +}] + +[resource] +hazard_type = "GymBro" +display_name = "Chad" +animations = SubResource("SpriteFrames_44y3n") +idle_anim_name = "waving" +walk_anim_name = "walking" +time_to_fail = 3.0 +min_focus_to_spawn = 0.3 diff --git a/max-effort/Resources/SoundBank.tres b/max-effort/Resources/SoundBank.tres new file mode 100644 index 0000000..85d0084 --- /dev/null +++ b/max-effort/Resources/SoundBank.tres @@ -0,0 +1,3 @@ +[gd_resource type="SoundBank" format=3 uid="uid://b8ouri8tqw8vp"] + +[resource] diff --git a/max-effort/Scenes/.idea/.gitignore b/max-effort/Scenes/.idea/.gitignore new file mode 100644 index 0000000..bc420b8 --- /dev/null +++ b/max-effort/Scenes/.idea/.gitignore @@ -0,0 +1,15 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/projectSettingsUpdater.xml +/.idea.Scenes.iml +/modules.xml +/contentModel.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/max-effort/Scenes/.idea/copilot.data.migration.ask2agent.xml b/max-effort/Scenes/.idea/copilot.data.migration.ask2agent.xml new file mode 100644 index 0000000..1f2ea11 --- /dev/null +++ b/max-effort/Scenes/.idea/copilot.data.migration.ask2agent.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/max-effort/Scenes/.idea/encodings.xml b/max-effort/Scenes/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/max-effort/Scenes/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/max-effort/Scenes/.idea/indexLayout.xml b/max-effort/Scenes/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/max-effort/Scenes/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/max-effort/Scenes/.idea/inspectionProfiles/Project_Default.xml b/max-effort/Scenes/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..03d9549 --- /dev/null +++ b/max-effort/Scenes/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/max-effort/Scenes/main.tscn b/max-effort/Scenes/main.tscn new file mode 100644 index 0000000..938e13c --- /dev/null +++ b/max-effort/Scenes/main.tscn @@ -0,0 +1,147 @@ +[gd_scene load_steps=11 format=3 uid="uid://xtm08af0e82g"] + +[ext_resource type="GameState" uid="uid://2gma8vvisnqo" path="res://Resources/GameState.tres" id="1_bo1nx"] +[ext_resource type="Shader" uid="uid://dndm4jfifooyk" path="res://Shaders/TunnelVision.gdshader" id="1_jjgbg"] +[ext_resource type="DayConfig" uid="uid://d30pwvrr7m72j" path="res://Resources/Day_Day1.tres" id="2_8gbba"] +[ext_resource type="SoundBank" uid="uid://b8ouri8tqw8vp" path="res://Resources/SoundBank.tres" id="2_21xkr"] +[ext_resource type="HazardDef" uid="uid://pgmnp6ev1ark" path="res://Resources/Hazard_GymBro.tres" id="3_kry3j"] +[ext_resource type="PackedScene" uid="uid://bg4uaukekjbx" path="res://Scenes/main_menu.tscn" id="4_6bp64"] +[ext_resource type="PackedScene" uid="uid://bqxc62tofqger" path="res://Objects/hazard_animated.tscn" id="4_21xkr"] + +[sub_resource type="Curve" id="Curve_bo1nx"] +_data = [Vector2(0, 0), 0.0, 1.4, 0, 0, Vector2(1, 1), 0.0, 0.0, 0, 0] +point_count = 2 + +[sub_resource type="TunnelConfig" id="TunnelConfig_8gbba"] +max_tunnel_intensity = 0.7 +vision_curve = SubResource("Curve_bo1nx") + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_bo1nx"] +shader = ExtResource("1_jjgbg") +shader_parameter/vignette_intensity = 0.0 +shader_parameter/vignette_color = Color(0, 0, 0, 1) + +[node name="Main" type="Node"] + +[node name="Systems" type="Node" parent="."] + +[node name="PlayerInputSystem" type="PlayerInputSystem" parent="Systems"] +game_state = ExtResource("1_bo1nx") + +[node name="TunnelSystem" type="TunnelSystem" parent="Systems" node_paths=PackedStringArray("vignette_overlay")] +game_state = ExtResource("1_bo1nx") +config = SubResource("TunnelConfig_8gbba") +vignette_overlay = NodePath("../../Ui/Vignette") + +[node name="SoundManager" type="SoundManager" parent="Systems"] +bank = ExtResource("2_21xkr") +game_state = ExtResource("1_bo1nx") + +[node name="GameManager" type="GameManager" parent="Systems" node_paths=PackedStringArray("hazard_system", "minigame_container", "win_screen", "lose_screen")] +days = Array[DayConfig]([ExtResource("2_8gbba")]) +game_state = ExtResource("1_bo1nx") +hazard_system = NodePath("../HazardSystem") +minigame_container = NodePath("../../GameContainer") +win_screen = NodePath("../../Ui/Win") +lose_screen = NodePath("../../Ui/Lose") +main_menu_scene = ExtResource("4_6bp64") + +[node name="CameraShakeSystem" type="CameraShakeSystem" parent="Systems" node_paths=PackedStringArray("camera")] +camera = NodePath("../../Camera2D") +game_state = ExtResource("1_bo1nx") +min_focus_for_shake = 0.7 + +[node name="HazardSystem" type="HazardSystem" parent="Systems" node_paths=PackedStringArray("spawn_locations")] +possible_hazards = Array[HazardDef]([ExtResource("3_kry3j")]) +spawn_locations = [NodePath("../../HazardSpots/Right"), NodePath("../../HazardSpots/Left")] +hazard_prefab = ExtResource("4_21xkr") +game_state = ExtResource("1_bo1nx") + +[node name="GameContainer" type="Node" parent="."] + +[node name="HazardSpots" type="Node2D" parent="."] + +[node name="Right" type="Marker2D" parent="HazardSpots"] +position = Vector2(502, 0) + +[node name="Left" type="Marker2D" parent="HazardSpots"] +position = Vector2(-500, 0) + +[node name="Ui" type="CanvasLayer" parent="."] + +[node name="Vignette" type="ColorRect" parent="Ui"] +material = SubResource("ShaderMaterial_bo1nx") +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 + +[node name="LiftProgressBar" type="LiftProgressBar" parent="Ui"] +game_state = ExtResource("1_bo1nx") +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -27.0 +grow_horizontal = 2 +grow_vertical = 0 + +[node name="Win" type="ColorRect" parent="Ui"] +visible = false +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0, 1, 0, 1) + +[node name="Label" type="Label" parent="Ui/Win"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -20.0 +offset_top = -11.5 +offset_right = 20.0 +offset_bottom = 11.5 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_font_sizes/font_size = 72 +text = "Light Weight" +horizontal_alignment = 1 +vertical_alignment = 1 +uppercase = true + +[node name="Lose" type="ColorRect" parent="Ui"] +visible = false +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(1, 0, 0, 1) + +[node name="Label" type="Label" parent="Ui/Lose"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -20.0 +offset_top = -11.5 +offset_right = 20.0 +offset_bottom = 11.5 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_font_sizes/font_size = 72 +text = "Failure" +horizontal_alignment = 1 +vertical_alignment = 1 +uppercase = true + +[node name="Camera2D" type="Camera2D" parent="."] diff --git a/max-effort/Scenes/main_menu.tscn b/max-effort/Scenes/main_menu.tscn new file mode 100644 index 0000000..44b5dfc --- /dev/null +++ b/max-effort/Scenes/main_menu.tscn @@ -0,0 +1,62 @@ +[gd_scene load_steps=2 format=3 uid="uid://bg4uaukekjbx"] + +[ext_resource type="PackedScene" uid="uid://xtm08af0e82g" path="res://Scenes/main.tscn" id="1_28flt"] + +[node name="MainMenu" type="MainMenu" node_paths=PackedStringArray("mute_button")] +game_scene = ExtResource("1_28flt") +mute_button = NodePath("VBoxContainer/MuteButton") +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="ColorRect" type="ColorRect" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0.14117648, 0.14117648, 0.14117648, 1) + +[node name="Title" type="Label" parent="."] +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +offset_bottom = 67.0 +grow_horizontal = 2 +theme_override_font_sizes/font_size = 48 +text = "max effort" +horizontal_alignment = 1 +vertical_alignment = 1 +uppercase = true + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -20.0 +offset_top = -20.0 +offset_right = 20.0 +offset_bottom = 20.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="PlayButton" type="Button" parent="VBoxContainer"] +layout_mode = 2 +text = "Play" + +[node name="QuitButton" type="Button" parent="VBoxContainer"] +layout_mode = 2 +text = "Quit" + +[node name="MuteButton" type="CheckButton" parent="VBoxContainer"] +layout_mode = 2 +text = "Mute" + +[connection signal="pressed" from="VBoxContainer/PlayButton" to="." method="on_play_pressed"] +[connection signal="pressed" from="VBoxContainer/QuitButton" to="." method="on_quit_pressed"] diff --git a/max-effort/Shaders/TunnelVision.gdshader b/max-effort/Shaders/TunnelVision.gdshader new file mode 100644 index 0000000..b1e9f09 --- /dev/null +++ b/max-effort/Shaders/TunnelVision.gdshader @@ -0,0 +1,20 @@ +shader_type canvas_item; + +uniform float vignette_intensity : hint_range(0.0, 1.0) = 0.0; +uniform vec4 vignette_color : source_color = vec4(0.0, 0.0, 0.0, 1.0); + +void fragment() { + vec2 center = vec2(0.5, 0.5); + + float dist = distance(UV, center); + + float radius = 0.8 - (vignette_intensity * 0.7); + + float softness = 0.2; + + float vignette = smoothstep(radius, radius - softness, dist); + + float alpha = 1.0 - vignette; + + COLOR = vec4(vignette_color.rgb, alpha * vignette_intensity * 1.5); +} \ No newline at end of file diff --git a/max-effort/Shaders/TunnelVision.gdshader.uid b/max-effort/Shaders/TunnelVision.gdshader.uid new file mode 100644 index 0000000..ad05119 --- /dev/null +++ b/max-effort/Shaders/TunnelVision.gdshader.uid @@ -0,0 +1 @@ +uid://dndm4jfifooyk diff --git a/max-effort/Sprites/barbell.png b/max-effort/Sprites/barbell.png new file mode 100644 index 0000000000000000000000000000000000000000..8642f3d7173a76496512b96c8b2a20eaf53732df GIT binary patch literal 935 zcmeAS@N?(olHy`uVBq!ia0vp^`9N&V!3HEtZ(V5wQk(@Ik;M!QddeWoSh3W;jDdkU z($mE;q$2L^Oy3M)N0H;RU3irk`xk|M5Vnc@s#FoMp;dwF-XqUF6`vF;0tH0&R(^UG zdL)j?RYO#Bsbz(LNXsgA*1#n{L`}U+w#;%6`p;kXIPG&~S9f3AM{ z=FOW60{TJ_R@VTok@D0(CB zhTjeC8zxOLs;{1KHhfoIpZR;ri}i+O3~%md%-lVz-Qlpn-R9h|Bm8^R;{58knk5DI z_$NIxPfCk-`s`-vt7b9dY+C-~&vMQidL`^R&eklxSYb0`$K<)D5nhk49d)_Obl2IS zUh>+~zl?vlQuf-W1m2V6=2bOhIq=&+MS0qSzKmUdpFb?s3Yg=z=g725O=E!#Pj%mE zKc2OmOUUEQyO%6EVLLs_w0|ki_F8(3tMyRakG%2^{~2;GFZds#BNm@=U$OtsiWKFq z+t@sYuAOXHa&POa^Wk%g_7k47TGUt6EC&SP8Vro zI#b0O@oc$|VgXn3`J@wfn4T9-UiR9Nw|%~UA&1uc$z`rAQ(KNNEWP)BQ|o?C4*MIW zAL4ogZ)$Lr|DVL%ot<&#rbgPU(-CVs_z>-C!nh zf9pwspK5ol8^q4mvOKAu#T%IA(ZE6)N@(Et!=!Wg!iw90<=cTdkHOQ`&t;ucLK6V_ Cla`?X literal 0 HcmV?d00001 diff --git a/max-effort/Sprites/barbell.png.import b/max-effort/Sprites/barbell.png.import new file mode 100644 index 0000000..78f0c38 --- /dev/null +++ b/max-effort/Sprites/barbell.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cbgn8aspf7oi0" +path="res://.godot/imported/barbell.png-18c805fdd277089a294c3e4ab4576f9d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/barbell.png" +dest_files=["res://.godot/imported/barbell.png-18c805fdd277089a294c3e4ab4576f9d.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 diff --git a/max-effort/Sprites/bench.png b/max-effort/Sprites/bench.png new file mode 100644 index 0000000000000000000000000000000000000000..6e3968bbf9c77507f6464939a198bcf87df2f608 GIT binary patch literal 2267 zcmb`J={wYo8pnUXF_@VwV{9FhnnfZSG)+jBrWryhTiIe}tO?nZb!;&rBjqtDp31&N zN}|SCk}TOur1Q*#xhVUSt+E`?`2)_Y^Wt-VuIqb!?^pMmn{~m;OcJ4l002PJ{0zlr z*UW!_iS5pIBYMxS;DKixLjZt){|7Ll*f<;jU>W9=Q+5%q^Or5JIaB4h;RSljcx=GX zNte856?URuEQG}bc7(lO6QH7?S%eO+YI1LVqK3MfbU2=UxHW-&f;F?C296ITRN`@aZ@N8%b{ zjE5^d4enVK6AqzRe|{H1qtUY(8X6&2uU@VE868Vkq#6tA%`^(*YTZnG`Sr2_Dl<+r zSn1Bp!omUzPsL?9L`6kCuCDG&oP2%3XOW?Biz@B0G_@!c3dOm-!r%w6JDbZgQ%Aha z7Cj9Nz-@BtFZVi!?OqOX(BtTs*N}O3cJ`;me>bm-g}NrXkjlrkn%ZJ@9$OiZj~qFo ztL4%N@bkmCqr-fDVfkoSz18pN9fyu}g#~|s?8Kw9s`Xx#5@jdE4mVvJ>wYvC$-(nH zU#;4_Eqo@*D7Q-^ucM|eIo~+uq(uU6D;qR0WKC93$N!A`%WHqeNZ(neoKoDud;kY| zMvi-_f&9>MmN^OAxj3$!Og^>Zo%lUk{SSNK2;{m#Q+9QAHR_?iDhn9;DB;J*0D>e| zQf;elyI0lJAX=*~5;MFMG{6%ECr(tkraOIYJfvSqR;LRbk-`-{l?>vTUF3T zhjNINO=nYFqS_;98QQQ}`ZfkK8URFET3U|$sNFNX{n-(3azZJ?DbApNY_4+~8N8El z2Y~gloNQl}xFiGt89)io&TyN;JPM(KW->7=VR7VcPx*r&l%YA2D@^!YI5LEy1q1|q zEMx~eQY`^O?$*_66t9IF#NeQK@ZRk{3S8jE*Q+}V7eKvsyvUXSx`($ls~VM4hr)aq z8&lT^Cn?K-7a=PCS};Rg&9Th-8hAR5ocb}`Eh|yJ1Bqj9k?7pud&=&6;RClWx0uht zpCz8jzT)X8B0>LsJ^ST5*PwsF1#}YIkdk+nhzIvuLvr2K@!(NHPEvm2C_is^Pg#nX zH-8?djT48U-L&F&rbM|ozL`1`JKhqs(xhG;PItDJW`uPk7yN&vT|{kE1ygN!mr zK_4_AASba;H#W3DJ%1E7un=q>A*`Lb^52RqND$$v;dndOo5!f3A#^%6Qe)qm(Zq3w9Hkxrp!~ z*xh_eR+X#8M~6@R{`)K-_`CoG8<>XZebLfHBcCGz!8Py)FAGq9e=~kijIBP+m-a!= z_vhkFo>o@&j5W|!fR6IuTM9oy1k3 z{Oqbw9|1`|TYn6!%1ud8I+Mq-I)j;xZAjHyPJx*hpwr?>bupSM3H{PxY-rog=IE${ zVpBrqY5yYKB)hFP3bUWS5^`@za}X0Rikoz3dLC0bs?E*rzgU|hz;3E0(><23PDYn0 z$8(r_pT7Ih-qdmq))|{NJ3!PYkyeS@JE#X?#Ce~k`Lav$vS33_(B_wyA*IWmi-8|z zW@d~xzGkwgU!26$N0nmEmkxi^O-V@+N@|s|SS-fz{A#OPJ+yX3w&HiuyYu=b$4%tN zHBO&C?R`BYR&vQRrGK66jbc%LKCbiqK0BLjw8Lj>u+i*UKdX~zuQm6O8*-MPx3>Ph zKkKqAId)Im&jMe0!fwW}cLv6yB#8w))enuJ(P%9-m7&6J zv+ji)s{*~c$r}`T{SX0)vzVUSLt(Bz?hw~gwNeP#=LZ0f$agnx;+;vpVvd$44oKV_*mV|jUbT_?hp++&!|ZPqm~a5j0pBg?HM zOhni~sMH26d|m;E13x{1$K%oEc8AlwKk0nj)QR1ZnhNW3u+?EU);{5_UB?!ZJvMZk zsoSHET&_eDUPHej(z;qa=lRqwwW-58`@=X~x5NrUu~FQN(pfQhV literal 0 HcmV?d00001 diff --git a/max-effort/Sprites/bench.png.import b/max-effort/Sprites/bench.png.import new file mode 100644 index 0000000..5da80a8 --- /dev/null +++ b/max-effort/Sprites/bench.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dsovna2tmb4o3" +path="res://.godot/imported/bench.png-7eaea02148a24455b27861ad276687ec.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/bench.png" +dest_files=["res://.godot/imported/bench.png-7eaea02148a24455b27861ad276687ec.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 diff --git a/max-effort/Sprites/bench_press0.png b/max-effort/Sprites/bench_press0.png new file mode 100644 index 0000000000000000000000000000000000000000..ac6aa7116c1b79c101f416040f967d2897d115a3 GIT binary patch literal 2327 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 CXf{Cr literal 0 HcmV?d00001 diff --git a/max-effort/Sprites/bench_press1.png.import b/max-effort/Sprites/bench_press1.png.import new file mode 100644 index 0000000..1788ef4 --- /dev/null +++ b/max-effort/Sprites/bench_press1.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dya801bkqxdpa" +path="res://.godot/imported/bench_press1.png-5e3c7fb368ba97d9829feb84755273cb.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/bench_press1.png" +dest_files=["res://.godot/imported/bench_press1.png-5e3c7fb368ba97d9829feb84755273cb.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 diff --git a/max-effort/Sprites/bench_press2.png b/max-effort/Sprites/bench_press2.png new file mode 100644 index 0000000000000000000000000000000000000000..46be780d8c472e7dc18f9f09790b1682003206fd GIT binary patch literal 2287 zcmeHJYfuwc6kb4!gJO7SL8?ZqBsze^1Ox&kqQL+Ph#+90yfG>QLINcT1ga=dkVr?1 zJWQC#XdMv{7*Z4ot<;DF(qQEkA-oer2$=AShIE(CwBtC=^iTi!W9QyI_kQQ>`Of{$ z-P~i|M14IoJpcgoJ=_V$0YFOyKJ0aCK+86ZUQ2M;5#@f|3jk;c0LaV&0B{}1lmS38 z3IJY*0|5300GOOFd+6&7E@(#{Arb&hHdDX@-*hP+UT(UtwM+pWOaH)lUC?AfaSNhE zM^Iw0QAsi20H9Im{nn^`)@Y1B8iTcSz}nebqEJ{As(W_f@dtpogy=J;sGkPhx$mt7 z0(SosfpR7;hD?cwJO3}n)*teX!P;W}4k8K*hy%a#g$KdaKec~)K%CU?zUhE3#!jPY z7hG)5jm>vmSM!ooJ%7zJ&G&lKyZT*`-ctMWF}4H;43ToTM-pKBIN7G6L-{iE!%Bm% zX*q^2tvR2~A9Aw1$c1IHDcCTTSTV_E=CLWucQO;>*{3H1b8zABJicUnFUx+US+hO^ zD`GY*D)lnZBIbPW-RtTQ4*c~NWWW-J>W%LrcPAM~AVjcT0ab=Bfk8Ngk=jA1e_}zA z!!RvO%Ig_KroSqZ)Dp@%XGVlORlW^`_m0Dhc=5LS-a&pyNk4*`=f=1ij8xEG_29&{ zs9X=WdB|Yn?Jxn~x!Gpe8lH~pTd;Ewu3x6r;`nK5|M=it%^I^Je1^oRRgRu4O5F48 z1$Amu#`N4dmyHE2cIvm@QhxlV@=XCWC$vl)HlmyDZsx4wMK))g?om-9NI16w#ji2UiYwg{P1%v;^~3#n6VEI@*6 zs8bg^Q!x7Qs@i2V&bWrLrdi6+*;}=_D6J z-Q-YQsbc?<8+0<5^=jH+r5x%lj2(;9jfa)g{Y!QnIKNDa6-9OPK>?6i!33fHDYY#J z9wRT~>h50Me3e)w9S}?zK)`&WTwFT88S)1kUUm)!Q#d#K6#;+2QJBJk4^jPkD{Tza z=O>&sNY!|83s{U>19)lNtkf7nCklB93Ee)cX>~DHmYYuUa3aMeep+2FBO)}Lznvr1 zwpSpG)wKfZf}x8^@jN+~;XC0>hl!ZwWcwR=b;7B*dPk8N6>0qSPwIZ@f9V4BCw<5E84Aid0B~3rbV3V}BJSUKmz*QEs zwoyAJSnax%C8(%j0=bYHfTX3=C@YUDb(QJIBS#ZCVNaJS6=O__7070`(r!=ToE58P zYcIde@$767Bej55`F>uW00$(-2G!woVf@~M-JqB*7BCEd(|}~1lYhQdKJF_2g_9MX Ya-$&sR?|Q#_)7qIxOo$*4u)U&3-m1)mjD0& literal 0 HcmV?d00001 diff --git a/max-effort/Sprites/bench_press2.png.import b/max-effort/Sprites/bench_press2.png.import new file mode 100644 index 0000000..abbf81f --- /dev/null +++ b/max-effort/Sprites/bench_press2.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bbxviq4c0pyju" +path="res://.godot/imported/bench_press2.png-26912d86e95ea594a6ede3ddf7d888d5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/bench_press2.png" +dest_files=["res://.godot/imported/bench_press2.png-26912d86e95ea594a6ede3ddf7d888d5.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 diff --git a/max-effort/Sprites/bench_press3.png b/max-effort/Sprites/bench_press3.png new file mode 100644 index 0000000000000000000000000000000000000000..78adda4371341e4272bc5fbdcf63b85196179bf0 GIT binary patch literal 2241 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 literal 0 HcmV?d00001 diff --git a/max-effort/Sprites/bench_press4.png.import b/max-effort/Sprites/bench_press4.png.import new file mode 100644 index 0000000..00dc741 --- /dev/null +++ b/max-effort/Sprites/bench_press4.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bg06qtcl207do" +path="res://.godot/imported/bench_press4.png-6bdb5e12c718169046447626c4f714d2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/bench_press4.png" +dest_files=["res://.godot/imported/bench_press4.png-6bdb5e12c718169046447626c4f714d2.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 diff --git a/max-effort/Sprites/bench_press5.png b/max-effort/Sprites/bench_press5.png new file mode 100644 index 0000000000000000000000000000000000000000..f1902d11ab7c5e5fd1c3c3ce33e625ca673c16af GIT binary patch literal 2409 zcmeHJeNacP&*iqU2q*Bd`NH>CE>%0A>mydBC?UCgpWi*2zgK! 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 Wn4DqGT!cL{fHVe^-ul+AL;nSo)?23l literal 0 HcmV?d00001 diff --git a/max-effort/Sprites/bench_press7.png.import b/max-effort/Sprites/bench_press7.png.import new file mode 100644 index 0000000..3260f58 --- /dev/null +++ b/max-effort/Sprites/bench_press7.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://yrorih7pbt0q" +path="res://.godot/imported/bench_press7.png-f40d47f75275caf6823ff7e34d3d17bb.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/bench_press7.png" +dest_files=["res://.godot/imported/bench_press7.png-f40d47f75275caf6823ff7e34d3d17bb.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 diff --git a/max-effort/Sprites/chad_walk0.png b/max-effort/Sprites/chad_walk0.png new file mode 100644 index 0000000000000000000000000000000000000000..99af52fb7c33d858d304464daa96c368fa5e8a1c GIT binary patch literal 2322 zcmeHJ|5FoZ8eeN26pMnX-#8&a5NHt-uqsj@P!=&+~cSXRAI=jB#>wbp!ywDRv+D2>>j!Qnza5+my#`>wrJCcnJ1=k^lfjJ^)Z! z4ggdfD8&Kba}EGJPX~Yy1psW!Z@7IRlnT6+5f=jj_6k_vK|MK$V-unso-f-3toI(s ze;7%*wu+-u#hHAuFho!&q!u8E6SOOU6BrQmK{AIE5=31={*=MtcqgOwKLC#9W#(i_ z{udC)Spvjw=2uYwzt=m6bB+l`V*auGKVt$zcI;ZhJo#`lo62)O7K}_jHDr9+S=gWI z9C1K;&Tbc?WvkxK=xzPU+iX>;5s%XA4`fd-MHSv@D7{p2XK@9p6Yo>HyLabC~YvzQ=YZ z^I=~4Xp*lLQ)+*?r-~;8+7mfKt{krj8N26L;$!NE#ri|Xz4YGJ(+?hPz|@_yfi<{p z&#vS_lx5|EkHW$i!Y7Ryo02tFJo|3R1`KZX9a~ssx3w6rbQLj0$8zh(1J+m~XO8HN zZMUFX0{*(%@TfMMx3#?20?n;C>xjWEHf43uZSg+jKHYdO&B3=9yN9o;didc(W_ikQqB`Qcu==0JeRoVQcW>`5 zQza5E;iF&gM%E7A8MxG(pQIWsHu%!ww7>~hKBDw#T`6kV{YtQmG%{;ryw__bGjG__ zo*t2%UQ)7kwrScHOV~PH0#&a(qfJw`1X|=TGj=NyiSJe^;8*fDpRO+(1i6Y+npaIg zrZ#U|IR1_gV~IEJS1TG1gXpJgzSMxIQ>$t}!E$3XO=r`zDxI=O5Mkoo$wDrSYog}+ zE1`yGtjpv!I!{qZ<936Qw|mOhh2$KT9REIGaSf)foxbKw`k{T6u#UcW5yM7*=nO82 znO}i0$1hJnCS4CCLky9vyhdCXoYBX%wlwV{iqpGP3B+ffi#;Is!GT`VrG#nELk!{o z{>gb!6;zHY%m;0M1JOzGZRHI*wZCL?YjB6)EKSMw^ucDTBy$mY?ikyo9%)jKC9#Si z&E@9lY!_L#q3gZH%au@pZu<1>p^)Ko7}zRdy$@0=L{xvFqIKC}}2F zOOL*9I&$~1brM9Qjtfn}sTH{Vg@hrI`c^MI2hscCStgIv9=ds&@WPkcwJV{W6hANC zLFJ1jUks!OwY+}{Fw6MnVM;%}7R9RRYDFBe+8ps^cH1@HHx9X>eH%8;>d&6IpwHA& z6#D+EG#~E&)it=5-aTh#=sZXz)%@RHRfq2-mff2O!$cJJa!(#%gG)csnQ@N-+0#}FTf!r^iC}kkG{E1QvGCd^2 z407c`={$o34oclUt)t%P2-p#NJq&gs$C~Ct_Y-Gid*|lQy{Lk6RPrls{OuT9pNsAQ zxnGTIqKV$ZlaEDUhu`%ubR8LSDf>Jw&%9}nAiU})%9KiIQ;!J7<${}roe1v&<*9W4?EQ% zbSDqy8)rvPcKD=CaPtb}x(YQlgqjxK45X!l=Kq<-W_I~vN-)U%v7P#B0AiyP!Jj`$ GFZ&PRXg+!X literal 0 HcmV?d00001 diff --git a/max-effort/Sprites/chad_walk0.png.import b/max-effort/Sprites/chad_walk0.png.import new file mode 100644 index 0000000..eb77a19 --- /dev/null +++ b/max-effort/Sprites/chad_walk0.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c43wo6u2c0d43" +path="res://.godot/imported/chad_walk0.png-8e4fc165652b5af437c3106b59f93650.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/chad_walk0.png" +dest_files=["res://.godot/imported/chad_walk0.png-8e4fc165652b5af437c3106b59f93650.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 diff --git a/max-effort/Sprites/chad_walk1.png b/max-effort/Sprites/chad_walk1.png new file mode 100644 index 0000000000000000000000000000000000000000..64fe665600dff51bbfa1b2011b25a490681b4b18 GIT binary patch literal 2242 zcmeHI`%@EF6kf14R;4@wMFj;Fhy@7=Fj$ZzqKm))Mid1Eio8Op0%C9=U>3v&$)H4` zVyKd|87u9;$Y2DFC|Ga=6~we7ZwMfoASMK|Lfn|9yM@-V{iT0^GrO~Q&%NKd=YHpW z_i%Ub3NTr|W;p-=CP9JV9sn>x&{w$Z6V$TSvCjql*e3?=2?c;$Cjclo1pw$gP@n*S zV$RKk$+>zJ|12Rm}gs8yPdgCzrzX4}G6y)hWv zHRo-H&zU&Ij1L^5_=j1n_tu54#vk=vTTp5k(Hj@^T2StD)+K5j9C^*dp+ zjkz52kLC|K(afl<@9Avmm!P?<bP4DA!zOJW0r@qZtMwhTqcyAzNx4gJ@~jV?owS`wjBUC(m07D#Z*Og` zfWumq7VM{!ITTh=YmCV5+cZjxQjqSQH-Ad!gxK%B6AF8m*5WC}wx%9j>dub$$!4Yy%+t?>!ZAs9{9rh!l!(_y&gTa`n3>qk4}qhCQw_sg zRO)HwRbGR#n%oFoaMC#-Qb8swxg}de7#RO4?|p@WL=&G8(8NeJ?p?XVF~(oraE zy=s~ha{XnSrHGyb&N=BVOQz53+!{s+`kH)wxp- zi`hQ&3suQ3Y0P|uC5A_qFP5kzE`V3#UiN|`oYIh z{;-@;Y*7E`!6VfvSVE{1=8q*y^9`V|?n<@cM6*8{0>Y`UA9^&h0Xe0Na&yy`aPHzM zs?kKy?w}WQ7yLXn7}8zI=DfbFcwS!C2-6*rv5@3u3;j2|IAuRgS`-^RlGs!M()gYd z5RTffbC&Yzsd9rCEBZdl+|TV`strF74oX1P5!fB8?B60ag*$X5?{2H28U%YD*7DpC~TUE;Wqd~@$%M14Ba#0|QW= zq2UDsL#Y7+!>a@a2CEqi4B`cIb_Lo1C76=D-CY>|xA&jf59G0zc>21szhabN5LLNR zaLf@Xq*~${QIe8al4_M)lnSI6j0}v-bPWu3jZ8ue46KZR$VeN=FfdRFIsYF;LvDUb zW?Cht215gg1|P}9PM`)2xD6$lxv9k^iMa*ndJL_M%^-TNT1)CPFtDBRba4!+xb^n# z?X24Y0uF(@pZu@CS*xMyw`g|o)^+LYzlu0P{I{jbD zqJGPL4-U=u`l8sczwLv%Q0=ku=}|u}ci25VKP~dx<_^0DJ+5N^WZqrwFF#j#w`7L% zm&2V?&%2y=^pg+nsM}KPJoPWnB6*)BIv?NE-g|%kY5yFhb>{OQ?YFzwU#jxxcT4@> zoN|NtZ)<|M0xud#x^RK2VonbdlY2m+u$n+W)GO*Jn>Yl(VQm%KP{Edpizm7X-<_*%+Q| z_e;q)Zt4s6-_qUMzptzRx_B-&?%??cvw+?*HdRa$ux+3D#n_?}=yM_NI=;zudy0!p zWuFPu9+12_`%AG!V|q>fN>=-B&-owkmZ;kIddh#k(ZpS+bdkOC!8YG7f!W;p-+sni zMoN~olg{U#MvWPi)XM+KCT=z;5#Ra9)ysr6L7)F<6E_!EI#0Hl)eP3YkzYdqmBpZOIDGT}MH<~kvejOCFv^PNF@ z_>5jJ2RQ~gpIW{stNkWezz0z{2dGd+;isp|dA*b8KY^0!|Ki>I>`SzNRN4g0Eh^c$ z)NbZmxC!Zv{Z(pEhXXB4pSb$hPMF&dvDIsV%!HH!VLMkroDD7z=JBq3rH)cywEu|c zJMH>q0?=PSyv@NLlTXSk-q|5nwa;3qRnj=`<^E^ zm45}QoVUBk|LAs!jN>mGg#+!Zqf_eJuF zwmBz1&wSxN*(ScTu48@W{dJSlPu||l->~`4y7$}PJvnD}v0tg|+s%9MK*A_2lc&wU z`B^2t6BLM+-uI7Je>423|8ufN;J*IrK$|!29W82cYN LtDnm{r-UW|YK3tH literal 0 HcmV?d00001 diff --git a/max-effort/Sprites/chad_walk2.png.import b/max-effort/Sprites/chad_walk2.png.import new file mode 100644 index 0000000..3e65adf --- /dev/null +++ b/max-effort/Sprites/chad_walk2.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://by265t6kx8us4" +path="res://.godot/imported/chad_walk2.png-6275d1149cbf6b3a53f8cc57ae4023c9.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/chad_walk2.png" +dest_files=["res://.godot/imported/chad_walk2.png-6275d1149cbf6b3a53f8cc57ae4023c9.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 diff --git a/max-effort/Sprites/chad_walk3.png b/max-effort/Sprites/chad_walk3.png new file mode 100644 index 0000000000000000000000000000000000000000..af138722d899c7a4cde0889fc03acf857cfb066e GIT binary patch literal 2211 zcmeHIiBl6-7++hJ7OO!rRPi7vAXXGYY>^{}=+clHZ#<&5fPg7g0ZFV9NVFAAQq(9+ zC1}{4K?Ttu#Y|hklTk>K;C4lk5ER6bET9BTfDj1jF49hq>3`tN?!5P1@B7~G{l53) z>(;QRI?r+j0AMO765Id)6Kwboe=rf(%=KyV!w1i}$PKFjK(qh=4rc-YZU+uy0I;75 z09`Qv5UK=#87ZpD^>p0u-p*BQ5O7Epy4$$qB;>4)aO#>c6L9lxN~sCQRX)Oqt-|26u_D+_t*)N0t=)w(Ur%sd7oQcyhO6; zjC-VIOAmfr8ww&_9c#nzjuXnTd#aHf=g{^>33AD4SIs@T8w9!!=vetsRp>=rjYd=yk`6vR=w8jn6bncjW-+wH-j zIZRG@LIF~tO7=AsQu8o&^ESj3hL-S6;6Y&l5?I|0QoPbY#Q9fgF$m9(2T3908{6oS zrtJ}rL=mD^*(#G8s(n`4}&TqU2h_vy;g7b%^8CadY+R*dUZ$a?!4V z%kNGvFD4B%DQYq-PKl{e1(a9GJ9g+PFvd0vzHydJ=G)ML`bU|{a7#=51-Pm{{f5}T ztj$R6)Ea!ZG{jCronD>3$ze%nAFMIwZtK-3E$&F6-%ujgrqueEx8WF`N-p150d!z|YhH^7Gh7ItDwUB$5c_>y z8k3AGBy<5(N-RQopfa8%_@5AolOrSGdzs- zzM`vJ`-;enEVWgD>(y3`9Ga93aV_fRv;B>Z7p{z~q25 z!|sw4_Q(`{+wxiI==L&Fj^q-9uPL%>%Arqo=MJZi>XCcKNUlh7djCTEB_jMlAvd@^H-+L|MWqEcW>gF^6u=#{5TG;Ai<%Qo@( z8!48ST{Oxj&Rcvo@k?(T;42y<8eRpZ18nuS^{KF-FD!df>y$()n;Oo?7^Gl-l*DJe zB_OU`$baLHDmp;qPyXigFwig$uD7kqyUrCgPeeu)Tq4?2P`TO?7lLXCiO6}9EY8QI z%`ZSx@g43s`QrwH(eynZ z7wL`zZsM0c!(HapfxPF4F3m9)Dx`j*mYr%xC z^nM?k+yhtw4}7n{_rP!NU*%+pX?B?XgN({wp4LpY$jmpFs@HBURe*e53! zHn6%%aj7WlN69Muqcf!!<;YIg;V;aP!)k#%a?v9syxZas4*^syF36UCmN7X(N35rlT zUGS81!$up;!@Lo6<>KR|jVw;duE8LyqIbYgicFb91hHI8vQmSrmk$oS;a)_y)wKr? z214B1;;wFP6maS?184L#$)@10X>U-J6H7a*PcSQ)jz2(kOuSl$vc{*OW|-n*Qsgt= zehnh%&9+X>_)MX=D%4^W#Ey4h(TfE{LN~kToGny}R2gv;A*W(z731(+Bey<-Ak?dg zP@cqg#;QNN+vbW}pHLPTzxM=h>euAC7)7+@L&;>Z@uzXalte$EytMakaZd;CGl z7dVOj<~JE~ZxF4;dZ}9^M3Y}5YHka`@VJE{)ZcttElV(^Ftr0kdzONUD!X#q;gIE3 zQpyiywEgEgz3^M>Vm@uLH@n*+e8Zb$3;04$$aWIdUehjEiK?_~lzP46Nae)vb4_Ke zL|^^tc#vTtWC8!EuYfCNulS5~$dEgPp3EPgPvQ*l>@^`1vAFIq-LnhR{e@#iqgHO$ zWHKXm%65d4en75E9_eAJ+=k`q|8y=#1LaYer3#h}bvU=JuP@X(a5sS>UEjXh^Dys- zY=tD*lrhtM+d)o(>6$2i7&s=3Rq-fr7i2%UzEG@?B$=)hof+nh`NNG7l`*UHU=Pio z8s$-7hb^l;<9-;Nx9Vyi7mg7AZ2a-Y4hJqo&flYVyKqjyuEHz@l)8lXR3^)Ms)Fhc zaVp*xYM}|l>7f<}SnHFX)|;V+Qmtz#RYEz5<0L-c+8WkffP< zEQ$wp0j#6nkEcT?y*N@=w6YCWND%0l*WK}s2!cQEp)B3>wid?~a#lsw6cLdn8thC- zM!lYYqwKV=lh)J5n0p=qie^X7Yj`j_Cs${G0J@DQU=4n(O<4*G1ky1%mYPyShLds^ zKgAs7$swkA4qSf_eSgYqK*7?tw|`??&a>g9lp4d0lX}t|PE{(U3>$SzMp;FQfOAQs zWM=kkmQv0I4}42htwG>JJZ+V}iE3H1;meG{C~1BG|K2-Nd;%R}%%fMOL1q!C3xp+zJ_5R_yKBz2SS;$w!f{s;cBbN8Hk&$;J(=R4<$ zzhMV1GPf}Y0ANwjMsOqNCXt&1LBJ?1kjqfXEIlZAz1b*k8L))Zll+Gts&YzSzau?5 zB0a`CDm4aO02-A>r%>G~G|vz!)tlz-?M`2f{!pn`w+r3p7;uxK6Jq%vH)vYOJc=5u zcz;8B0yictJ%XG3p^eAeOCGLW?uN!09R&J?@cPF4m5F_u7O&ez{I62!Y#2$v}Xj;I|rd{WQF zL|!F@aQiE@!vinFI+@7z8TPbn;j)p*Lxs>GwW&mQx5do@Nq+2hc(jNaU=;$+}>8 zL6LUo8O3}_1u=@7X?U_S@$1aWrXWxn{-c%+<4%s0sv9EtD=ZM6zsm7_f%TJhH}6a! zGbWhERGxHM3>~SxrjoQnx{Ei*y~JwW@6cI)*z%<6sM?H=1kgH{=KBlP0fqMsea;if zp4KxFby=ROZv6dd6D3~j=K9NvI7?*BzhPUO6+q7 zPcNn!bX8B)n1JU&2h0AMS240Oak#@lKgmjBSRwP<(|F%&3PrlNJy#H0-APg6U-|yf z-7k~+W8KF{A)z_twiRW9*}Tray>HtTx`c4xFRVO7hQIUfZm$?Qe8W&JMthg}Q$mN8 zl2}UceT<2U&oitEB8cQHC=?r-4E;}P<5^?@yKbC<#gC6p>$Fi4yQe5RyE2~Hfgubf zN!RoAwavDcDl247YRnlmel(5^v+UnY2dMZF2Ua8+Z3)NNu<#kE7y}h1FHKMoO=-0{ zb7jGAo@Xcov@WP0*$XopFnis!*JM$3XcCGJj=bg(n7#3u2eOByJ8yfNV;s|!?qMP( zypG}5jOLiT))^2k)KxPwuT{~jh`L`eUAwRUSfrg&d%Pzu#SxEYS6)WnPsTza_AHk> zV+D#=(XWBTVQ#%ERwG^OiEwWvzOKBgBdY|PUpp^komSsTrH?R_W+jtc6e!=8Szh3W z$Gr%@{TRixL+3K}<@MjB!o}N34 z6{{4_I%cU**@Yf*!gBcF5JqLSA(w6^8}w3Yh36~$VaNUptHK6m9DZ#caGlULXB#rE wgs?~gMsH(CvJ2`Y?oF9LJpvyC6vJ6=ES2Cqx0ycVqi-}2w4M!K_76Y!AHVv|KmY&$ literal 0 HcmV?d00001 diff --git a/max-effort/Sprites/chad_wave0.png.import b/max-effort/Sprites/chad_wave0.png.import new file mode 100644 index 0000000..10c63d0 --- /dev/null +++ b/max-effort/Sprites/chad_wave0.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://664m2cxtmmur" +path="res://.godot/imported/chad_wave0.png-7452b570847815d288a291f1ec8574e6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/chad_wave0.png" +dest_files=["res://.godot/imported/chad_wave0.png-7452b570847815d288a291f1ec8574e6.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 diff --git a/max-effort/Sprites/chad_wave1.png b/max-effort/Sprites/chad_wave1.png new file mode 100644 index 0000000000000000000000000000000000000000..7354989b651a28ae28f84eb16a31901da6a522e8 GIT binary patch literal 2245 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 Dsg}-P literal 0 HcmV?d00001 diff --git a/max-effort/Sprites/chad_wave2.png.import b/max-effort/Sprites/chad_wave2.png.import new file mode 100644 index 0000000..f5d0c10 --- /dev/null +++ b/max-effort/Sprites/chad_wave2.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b28aaketyf0t1" +path="res://.godot/imported/chad_wave2.png-2c28d86e420f732e4cc32daf20b49920.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/chad_wave2.png" +dest_files=["res://.godot/imported/chad_wave2.png-2c28d86e420f732e4cc32daf20b49920.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 diff --git a/max-effort/Sprites/chad_wave3.png b/max-effort/Sprites/chad_wave3.png new file mode 100644 index 0000000000000000000000000000000000000000..eb227dc97ac92cef1e16da83453679795cda18fc GIT binary patch literal 2223 zcmeHI`Bzg%6n=;n3$=jQ3be9nur4V91zCgmC~{ark$S2kJ5q(1NFqysM-@3C)rcAi zXn<6tLXYfdB?tsWR*`3*6antu06hnOlmftMQvewC z2LS7I0N6;)sQA_vJy;d!>I?#l%#>Ckx>KRMxI3wgDrp0sZSJNv>_tsm=uY3$g9GRx z)==meOVnpx~LCG0fYPpG9~!Y6Xba`q{{2h&{8zm z62~aPye3a9}L4wdV{zM)did5t1n&Hg~aqKSmZB$b2H`T#{@n}Z&vD74rM#YZBCC6 zE3WQvO@=zSl&LP&z6S*U?OElusm|&0`>(hN!eh8L(JxL7E9MO&gpdWtKKOVmt~R`F z#Mq5upDyRkG73|KpVZ~^-Q)w;Ud}(Bfp*o(QeA|~@Go;cU%UvPl9-J+n~4Q&Ir>du z1c8(Mez9#(QNggDNWC<2>X^bUyPp+n#hco(1<|bD9$f|*i6$HF7C(;GGe$O9!E+P0 zC)NA%`Hk^N=9>&V+m;*&HCBl*mWxp}t4{3yM;bmltiaYHle6vras=I!XcIv8(18Y}r5JGRZx;n28(Dlp5!>sEBAu zyvPGAGwG;LRR;Nh01dW z_Bljui=ETmG2o47g#)@GX0y-*dmox~C-2u%AMv%yUzY;Q+W#r)6g zMoP3XqwmnRZ6L9|%e(%ON&>jMyRr7D-n_(5#kC&HmT(%=RAGYXiEoNoIJonNB^^b0oiT%kN^Mx literal 0 HcmV?d00001 diff --git a/max-effort/Sprites/chad_wave3.png.import b/max-effort/Sprites/chad_wave3.png.import new file mode 100644 index 0000000..2d5cce1 --- /dev/null +++ b/max-effort/Sprites/chad_wave3.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://jyr4f2p7jbk8" +path="res://.godot/imported/chad_wave3.png-c5f30d3e0f297bd9fc2597ab6e730b5a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/chad_wave3.png" +dest_files=["res://.godot/imported/chad_wave3.png-c5f30d3e0f297bd9fc2597ab6e730b5a.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 diff --git a/max-effort/Sprites/chad_wave4.png b/max-effort/Sprites/chad_wave4.png new file mode 100644 index 0000000000000000000000000000000000000000..58bcd4dc477baa8d0262f4f498e805dd21d32c66 GIT binary patch literal 2237 zcmeHI_g9lw82%6`DB3WpSP=rUEF%ml3YdTrjA;^(Q47kFfDu~`E6S3DQA^?}MxbD9 z7&X%3X)7%vD8ob!2vSW_D6+y7OQ=F95D5tx{XX1Q88B6fheyXtz*kU=5*s&iJS&@B1$T7#su^zro;{n|6O6G%k`GDg;TQ6d6iFNnwS3FNOkFEoEBaw zQHHVMrwTOf6qm!Q;c?~l!)PW}qDe0aLJKyOGU#Y8e$$mdD5l*oi$H$TTvkuNXaQGB zo8?z8*U>27S?SN&DCWOx&f6+nVfq9KEfZ?*!;-~O6&F@|#~SSM(LE%cOE9+oK)k>v zA>f*xa$9wS=mG!n1=5^-qCvL}^RdE04s_M|OJ-{KeMF<|GhZx!m1AYvr7&VDlH(1g zTn;R-VxGHrMSU(@;-BhHfE~@>7X9 z@TnUZVuaj`V6CTglJ5QCMy0Q0^4H8mT3(D4c~T#*H<*c$l*RN2h~}W{ZMMso@$$mH zu18P^e6APX!FmEbkgj<+y2@O<7@i>YNMl#> z_6)Za&cPa5#!57bqufLi*nFXIyL030H^)MI;o^BmS*$--DNAK`EU6~W2s=NpisaPY zp`L%s*3WlbdJd6S}37c)8JyzSfXuM@(^@c+iZ{NqpqB zGGY(6Dib;Vw1?Vn;8KWH7a=NT3o)M*tNy+&o2-H>55por=>k8i$q|PDFBdBF>V*-D z_Ths2_o}FNV~d6s{Yi63)?d0b-nc8&#&v^VJ(L?j-7Jgg`vPijK_p_G+v>u!4otWG ztXDMz@Df1IJ)x%g`i>z2rY&=QX6Q?;!R1{OJ!g~fHso$8jJE?zJhWXQF#*5QrV1) zwvlLoK4OSq1p=~ic}VpO>z6b)Lm+MD_>3VEW5PKp3LI@VgmfcC++Rk^s8ni&QY$gx zR(bbagIcB4Dlp678?4wjNWsdU2&qKMDmcFuQNb2$BFq+i5x!9GKsRpA3~z zos0F2j?km12RDB+P=@e%?s&=m6K7e|vU{e--5_9oa^nRe8g8w&hIa0EG3mv0iX}<1 z19C9y`^HF1c}`hj%K7Oa{24UNoh>q})=8nG+NUab2PNrSb4?-GI}|I@kv@6haYg3B zsn_Xv<6_0t;o?2T5cIZ<QybTl^P0QB4<5k!`k`wMMCJYmhGF#{ literal 0 HcmV?d00001 diff --git a/max-effort/Sprites/chad_wave4.png.import b/max-effort/Sprites/chad_wave4.png.import new file mode 100644 index 0000000..df3686c --- /dev/null +++ b/max-effort/Sprites/chad_wave4.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://f013utfdsqqe" +path="res://.godot/imported/chad_wave4.png-d9dcca2f7e8dd0d27166f8047669505f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/chad_wave4.png" +dest_files=["res://.godot/imported/chad_wave4.png-d9dcca2f7e8dd0d27166f8047669505f.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 diff --git a/max-effort/Sprites/chad_wave5.png b/max-effort/Sprites/chad_wave5.png new file mode 100644 index 0000000000000000000000000000000000000000..ff841caa0005347f357475e43e7e4ae617530877 GIT binary patch literal 2259 zcmeH|`Bzg%6vrP3qF4?{+!rFU*@8d-i2@-m!4QcAx2na%550B008I_+;RH>Km&q5)*>y~vfixK5^gpGxbNQ!0I}u(kaPwB;Bg>H0sueQ0>C>z z0C36&fR*8l2m4&$0Zp<89tWsWGWlG%rxQ)s>!$NgV->L6v^D(M4%lQC?RF$O&_6oJ zDIhWkZU8%5JIBqosLgf`2W@Sg>`+c9M@#s}*0%iH6x3&eP)cCPaoYb29xuWE1PeC( z;~_dEG$<YjI8z8&0VZyL(7vA85=-NXX7t($jcNQ`$Y3`}BEmtyKtjmS8C6gy?r7xTYj zq6$-L9CsICMCoEnRl;y+8Em~xsM&D2#nJKwnD@SEX>S>`@D_D3%ZR*b;b;4Du zte(j>>x++AnYf}kv%<75b1_%hHhk&nxa&asD@UHUmHc#k3<|7I0J(Rqh-6{#qC7O4 zRLS6yy4YUE5NbG7kXPIn77Q-inkGRIBj|{PB=MBHBHoX-$v{cnIY9cD-nSTeM(60H zraIdT_!L(|<*Esz#?1}0MO|TJ)@QEX6V>9iQTW>YKI+%}FbOZ?n0mew_mb^nB z>vY&%D~hi=Ec9(#LmpsJ@7q4W}H*-R`H zO=mHSM#4TgJ$f@1fA?Tl+m#yBT?o@=NcQ zj_1y)!JZ>nLRVweeIm4r>aYXB6u~RCn$tM+Z*u5^e5y}lN%x)lY*pLWv!$w-3r|YA z%kgac-lH!{x^H4kDJ`TxAt*FT4u)r^i0HN)2x^w(&MsJIwH=AcfbVFvto@5Sx~YHNQyG&mb*+^ z$0Og1p%{_9^sp&ye7oWy=P7}{cmganP@c$j;|O{RaEgZ&DdLF_t0#+aT$9KEz2PqK zOwZAD0=F>ks0VW_m9AqdD8zBuLlH;|n!fCK_!ZyR{WH$RZ|j<@*uI^!0bE9-f_D=9 zgeFX#${O@3HD8XEtLo3YkQ9uQBJVlEq*Rd+;D+#cbvZ^k6<2$PPk@7lFoRrcLm23} zBAp77j(4MaB{-zB2zV}2)u!*DrWVpKc{EFMUn=2-=M1Sm z44wwLWnB!cEBDTiRjgu(GEzpv3GUUorpsU*eQV~>BvFmMS-)UgmU@eq3q9d1w?1a`7A95$D;?M<5N^9%|C}{sFfDx<9+;u z!UDZ6-rq-c0mZN9=Q5gRK`~c58S(U)pW;y|F>-TtOqn?`^6%yX|2grQ536#}nd$&A zJS{-+#ra*q5xX>G(@s^ML&H??a62o(LxtC=w85gQ3*)$z4X0Hz{eIW-Va&)U_t%ue ni!h|06vCHhW!@y~qf{CVZsz3TT{pboXCENAdE$QC>6iQ`VB!{< literal 0 HcmV?d00001 diff --git a/max-effort/Sprites/chad_wave5.png.import b/max-effort/Sprites/chad_wave5.png.import new file mode 100644 index 0000000..83d2a28 --- /dev/null +++ b/max-effort/Sprites/chad_wave5.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://duryxgc54alp5" +path="res://.godot/imported/chad_wave5.png-aa21a1c7a76438f4a886d5f1b68bbcc5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/chad_wave5.png" +dest_files=["res://.godot/imported/chad_wave5.png-aa21a1c7a76438f4a886d5f1b68bbcc5.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 diff --git a/max-effort/Sprites/chad_wave6.png b/max-effort/Sprites/chad_wave6.png new file mode 100644 index 0000000000000000000000000000000000000000..a63c2b9fa08442b00819512b1422d65d52273751 GIT binary patch literal 2177 zcmeHI`BM{T7+xqHD|iqn#*2g$5>O!|P?!P<5e)`}aCj6LISm9BV%2Ztr#0Ko$z5=bK>ML;NWBzS<3RLF*y?lMm8LHif@!_IfU-+MjJvx2Y? z#%lA8<^TY!4h*300RR&S{zRXc!8^A2{%!DJ#|qfP1b}P;0OS_{0DKPQs{!CR2>_nQ z1AuoK0HC=Qx56p#f$6~@1|2XK7R#mZYDH!s(|^Ttll6d&LqGSvAH0Rn^pDI;Ovp^~ zW*tj{2f&Tw=IKHrySRP6k3{lzBYTrQx4{z7IEjbYy#F?6x1gPd4V?b; zka;LADI+r>jr(sK_jgVn`)qK9<4g*q`|bOB;MGu9`rvNM?S8t?jK;287BT_W3Ljo{ zdTQ^_=5yOu{gRyhef96hd`<91gBA^(a8>RsQsZ`ME$y@UDC#{v<{*77SzNgO!}dRF zA_XCf-+WptTn*E@i5e-ft#@L^^nP>h#Y=HGC|~bd|Js618yZ7LF7yh(o2{i03qk>S zRYkn^Qe|ZbV?;-eD#pDG0kW$Tgge1vY{1o26m^p`)>;5ouy&RhC}Qlc>Y-;(_0S*dA?8J~_A#qbucmC~{7*&-eSIyF^lo@_464w@~HGv2p%j5=5JRI^}; zbo(PYXV}`X{y_2Mbk|#GWUilMrPP!gwx3knJ9KYSuB|ujbc^j-cXExgFgi%z96FTX zv2Gy&qfe1DXaT~Nbede+bfI44uN~W*6ZkQ$*xm4jjD2{k+&M_?u2W`|bg&4@V*CA#0_(7S~ftBag`v9kMjU=bV!S%a;Ow)aW_S_AC{^ z{FBzsRBEP2LU9NqMNMc@rMh&2fYBq|lsaWpwIUg)(lGbhPnj8iyu6G?@Ekb=B=p&k*yTmH;kFOYdMTYwAD+wdjtDd3 z-AiI!(+gk1FMA1rxO(oCXRLIzM6K)I6OMy^XuG^Mc6b4I<@PXf+HgDX?N_z?V4VB% pPW%*)cuGe4|3Ux%|K}$+zOk|Jj(K@F2L4F{f&L-%>pSAV{R3Cw&)fh2 literal 0 HcmV?d00001 diff --git a/max-effort/Sprites/chad_wave6.png.import b/max-effort/Sprites/chad_wave6.png.import new file mode 100644 index 0000000..e9cea02 --- /dev/null +++ b/max-effort/Sprites/chad_wave6.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://yy2yrm4gq6w4" +path="res://.godot/imported/chad_wave6.png-3d42c992783b312c1ab7802034e07a03.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/chad_wave6.png" +dest_files=["res://.godot/imported/chad_wave6.png-3d42c992783b312c1ab7802034e07a03.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 diff --git a/max-effort/Sprites/stick-bench-bend.png b/max-effort/Sprites/stick-bench-bend.png new file mode 100644 index 0000000000000000000000000000000000000000..56726c62569824217fd4b737375260ccc2a7d1bc GIT binary patch literal 4021 zcmbVPc{CJ!_y5jV$7J79L}edYBV>>4OJkRvNC;W7jAkqkh7_{I$d-N0QsKdjkg;TY zkV1sA8)P?lz305Y-@orU@BN&6@40{6KR)N&dq3x5O^meZ=`PU$0O)mfG?C{S^KYl6 zK93zLPJQPI=Bs1v4}kdfe>)_&NHqumMt5CJb+cgm^*5ezJi6@NVcP@znJqFsM)n3Q z4^j+oejZDU6K`|iJ5o0plAse6U%K{;Nz)94nK3gX=gqKbs{4h{yQoJxa|k>hZK?11 zU5gFD^SLx|Bbus#@hGI=5Uga3z50U`}B6f5Z?iY>iF4 zw9ViS%z$oiE7U^e%xJ|FNmG)qbg6IqIJ(|J@1$ll3Y$f#PX04fw0`>%BF%#^Q4-zF z$!Z*u{>fpe;iUa$lKH$9`7xv`xBp?7;?cTg;wzIVuFyKncD-2S(RyYnzUHQtTcY#& zVG0B=z0eGQ?3G%`(%=6O_&cy&kuxLE@a3UOBiq6=1oURDsEpC5*Aoucs@f`21U7r( z(`qoAZ&H@`rqlQ%?gPhjD{$r`7xRZ!t$yBBAaL_5DkvzJ)VjKxPoZa;pK^hh*ipA} z{w6Ki>5{$4#tWF2qrz4Bmq_NTRkqXwPtVj*^8Xcd{Ic#w^7N&3Q#Eyep6#zo1C4qm zf45)%U}#P(kZJo**?|Omet!j0vbIebJYoq*o)j}FK5LKa-K|%nbxCMS?lOlX}jdt!R1Wx^94wPPOXGl2M$3AcDK3i$N zH@)x24qTief}WIwoMv{@uP3%t1maYaKg~tzQQJJ{2xU9Jv+&g)x}ZN-6`j8ZVl*ya zxl(NtoG5!nJD>|XW!v1oWT}CB0<qSl2o%_3dQnx)d_y(rnLPPTNaZ`8+C0gma*keI>3efrXGv=0rL@Qq(hf;n41 z@!q*>a{V{(GxV8hQ?~lxW$nAaG5tYScts4VnYz3BHG}F}#j)Qwbg58LPL9KCx>?o{ z8z-C86giwO6$ZZ`@U_|wexs*3aJACH*1A(xdfakcM;vMjF)mHE=U9UVexsd z!_1+2UI8(v{vD03GetWwE&PGz@XV`tnHVmGmlEjVrD)+dG7!O7-kO2Z&M zYf<+k(ZrDw1STR;!>a|W?BPT3>9!r=i0LOM>pG1Ww##}`OP)fzx)8=Ua}yZg(pzv+ zd!TL25q9H?0ZZtn(h8<%sgP&qcqEF_NXz()E0NH#l{;gSYH;*jwk+6`kJyaAQ){b@ z9}eFXEi2(>S{k^jA%R!N%M`811Zq)jX*bQ%b8$-1(9RQXc}*}?+Wj4*XF7f=k7l@{ zG*P?Oca4%}s5cGK5l(5rDh3k?+go$;Ix8Dx)H|sh9n=?Ks4|Q#o>A@D_YvzwseYea zfT7TZWCmWehOqFN!uX0uZ^?~b7X@vs#Bso<2g}5iq%Zs}v3iFh>v+K#X6(@|DhKt*uGx#hw78;c>)UH=fAGN-t$B!`mGwO^9bjkK(15pgd#dW$)hVi^x= z+a{nu(5U8>-k$jMJ>CKp$qxNGfH}kmuBIoSIe09do@n5nbzfHuxFtau=l;zU$GfMbrH@6gz3rL;mXX2sCQax+{1w3WkK50B-l4ZFx&l5Fyqohk)N-H; zPwRZ0i~>uPg0tc_9sg3ZuDlGrc)azKQ$c*30_4#&2Ux(L&GxN`xyV^zo@yJXh>zVz zG+(D3Sd3Wi=SrXJijNn!K*T~V5ut41J^DXs;1KjU$7P_Fb&Jfbs9sK*l)`w7ER=QA zm^27`wlCB=-rI2Kz(^N0@1muth@w)HJo6h({)w*D5^!p;djT@nq( zBXN@ebR~KC_Qrv{j^SrV@y2ZeHQnZ;UN3C3L z;AfzvO0Yz<5J#LTfMkC2d`ng9^mrdnZrTxX?OXli{dam>vaWDLQ{EjlPOafgFB*rC zJDLvpP88soFbm(brH$EVmctyT%8$DAGJ$b*lYLt6_i7$7@M(9|El?;AQH2j>ifvN- zhbE=XlNk75=J({Q5`(;jbyLUB3_{_Zw#MJ0YUse6jog-@8gGC`O|K9o@BjD62htWy zA=pV=^CHFrxWZE{QJ*cdcqnE%W@(Kf`BEjO zX2~{UW5@XE$cIhQ46vz}JYxt^(|+POu)X^TLQA7hovM@jno^b0iqb}*2cI<7nj^*34!vcfn0Q>`}JHQR~F*InaszW#ktXDN=%an2S_)s#yloN zF*I<#o{}hpWpy-5syW1I(d*ZduA`rUc~F;z-?!pW@t!{!N~{E&=Ea$N)rzO=B?jIC zG69Z|gRogb#O%sg1&H{PZDX%(k=bzJc2E~oNtBK!6>GmDl0D!3GM4Un6edvVx1B(e zSv{)gz!lK)oKPqqiP2g$?Qgl^l1zKHO^(wDNItA+KXbJ=on@N%2&)uH@WLuwF&ff$u@8P(7-Yl6h+i-_L$v z|1{d*0mn-+T~TWQ!Hq0Wfhl}T&5B2#olaS`9f(}3gp|$Jr$2`>vHRBjgX2pzqo@1EW3+$oWx$um@AQ{EVP@lArB)kOzY1W|93Z+$$4} zp5L%0%?v!zx(o5i4nly19CtT98Ozd9UVRs5bMK-Xn-g+kLK$KSB>6-fKe4ulFcb8) ztVyT${G(dhuH`{MdUPkhTy-N9q=<7A$dcas@W)zIJ5yA##GiUc1r5lG@Q&q{ zmS1X8z$xqs>|r{&brKO<+akP0-8Y$O3=G%cGSYi<&Kfj_caAa;oR zPznB3N?%vhMYY#`_2X=-tEB&6+YxJQQ2tt%-T6g3kLr2Zyx9OaiqE3vUNW_IJ3hBHQAUj6}e+by(yFh zg-!wj?0$5Ge!Gg+#-r(%(lF)>!jJ(Vs%YHC1Duv!%q#pDMcyTt5_@1pAAZu$l3P*i zc;e4YtxGJk)|}y*j^r>EX#5du{YcY{_wqM42(ipP;1Ug5B@7x&4q6XwbP_5-1;B6` zQbO)0YZvYov9n}54Ct~NiO3dAP=a);?7jXkhw&pYI<6~M7=kvYzSZVr{IYku%K)QY z-V_13AwwiU$UM_Z`zUr?s}W)^Cg2h{!!xoqgeV+scDsG4()+xZ*EGrQR-rk*#Hw3o^G?}^m&fYNFrJ}da7I=xsI16DF{?V$8MDs+@FfC1Wx?g8X z9c&`ia=ZISwgmgEV8B*g>>}U4_L2qvOV;_!4F2}4Sf)-n&T>8d;W(5T`eQc JY7NK8e*vL;b`}5t literal 0 HcmV?d00001 diff --git a/max-effort/Sprites/stick-bench-bend.png.import b/max-effort/Sprites/stick-bench-bend.png.import new file mode 100644 index 0000000..15b8ae2 --- /dev/null +++ b/max-effort/Sprites/stick-bench-bend.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://mc8luxtg4rio" +path="res://.godot/imported/stick-bench-bend.png-7c99c74f55cf267d5d337b54b20aa912.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/stick-bench-bend.png" +dest_files=["res://.godot/imported/stick-bench-bend.png-7c99c74f55cf267d5d337b54b20aa912.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 diff --git a/max-effort/Sprites/stick-bench-straight.png b/max-effort/Sprites/stick-bench-straight.png new file mode 100644 index 0000000000000000000000000000000000000000..18e7778d71d167d3f79e04207f942bb04613024f GIT binary patch literal 3750 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 literal 0 HcmV?d00001 diff --git a/max-effort/Sprites/stick-bench-straight.png.import b/max-effort/Sprites/stick-bench-straight.png.import new file mode 100644 index 0000000..dd0679b --- /dev/null +++ b/max-effort/Sprites/stick-bench-straight.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cqkxhms26hdx2" +path="res://.godot/imported/stick-bench-straight.png-d6eb50859d8b64f084f45e07fee5f895.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/stick-bench-straight.png" +dest_files=["res://.godot/imported/stick-bench-straight.png-d6eb50859d8b64f084f45e07fee5f895.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 diff --git a/max-effort/icon.svg b/max-effort/icon.svg new file mode 100644 index 0000000..c6bbb7d --- /dev/null +++ b/max-effort/icon.svg @@ -0,0 +1 @@ + diff --git a/max-effort/icon.svg.import b/max-effort/icon.svg.import new file mode 100644 index 0000000..224967c --- /dev/null +++ b/max-effort/icon.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d1exufucxsjrq" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/max-effort/project.godot b/max-effort/project.godot new file mode 100644 index 0000000..d22a3e9 --- /dev/null +++ b/max-effort/project.godot @@ -0,0 +1,30 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="max-effort" +run/main_scene="uid://bg4uaukekjbx" +config/features=PackedStringArray("4.5", "GL Compatibility") +config/icon="res://icon.svg" + +[input] + +lift_action={ +"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":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":0,"pressure":0.0,"pressed":false,"script":null) +] +} + +[rendering] + +renderer/rendering_method="gl_compatibility" +renderer/rendering_method.mobile="gl_compatibility" diff --git a/rust/.gitignore b/rust/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/rust/.gitignore @@ -0,0 +1 @@ +/target diff --git a/rust/Cargo.lock b/rust/Cargo.lock new file mode 100644 index 0000000..cab65e8 --- /dev/null +++ b/rust/Cargo.lock @@ -0,0 +1,203 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "gdextension-api" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc8107360153162c579a6d44503710720b55f6686fec83aa14750a3e60a55274" + +[[package]] +name = "glam" +version = "0.30.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19fc433e8437a212d1b6f1e68c7824af3aed907da60afa994e7f542d18d12aa9" + +[[package]] +name = "godot" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5599d03afd17a511e11d0bf9e06c88d4095a9120f10cf00a74f50b300f53413e" +dependencies = [ + "godot-core", + "godot-macros", +] + +[[package]] +name = "godot-bindings" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38b6e65306c05e3c3f0131ee8dbf7394691e53268d72019007ec20687f2280f" +dependencies = [ + "gdextension-api", +] + +[[package]] +name = "godot-cell" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "738efef92fdcf1d92f0ed5a29c6f3cdce58e64029d08928c20e08771e1239c16" + +[[package]] +name = "godot-codegen" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b9a59f603f354c54d83fb74071209203d0ebe396b2419acc731c90ebf94680" +dependencies = [ + "godot-bindings", + "heck", + "nanoserde", + "proc-macro2", + "quote", + "regex", +] + +[[package]] +name = "godot-core" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "989e80dfb58d2048ae0dca60bec32129dc1f96510f904b992ad170d84e950c33" +dependencies = [ + "glam", + "godot-bindings", + "godot-cell", + "godot-codegen", + "godot-ffi", +] + +[[package]] +name = "godot-ffi" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6237b26c52c5baa6566705a73cd8804ea4ef83a666540939dd5a4e068c242666" +dependencies = [ + "godot-bindings", + "godot-codegen", + "godot-macros", + "libc", +] + +[[package]] +name = "godot-macros" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d696b67ba99ff7d75e07546b04c3a711651d2c9e5851c9225dea3b64f8bb5af6" +dependencies = [ + "godot-bindings", + "proc-macro2", + "quote", + "venial", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "libc" +version = "0.2.180" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" + +[[package]] +name = "max-effort-lib" +version = "1.0.0" +dependencies = [ + "godot", +] + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "nanoserde" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a36fb3a748a4c9736ed7aeb5f2dfc99665247f1ce306abbddb2bf0ba2ac530a4" +dependencies = [ + "nanoserde-derive", +] + +[[package]] +name = "nanoserde-derive" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a846cbc04412cf509efcd8f3694b114fc700a035fb5a37f21517f9fb019f1ebc" + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "venial" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a42528baceab6c7784446df2a10f4185078c39bf73dc614f154353f1a6b1229" +dependencies = [ + "proc-macro2", + "quote", +] diff --git a/rust/Cargo.toml b/rust/Cargo.toml new file mode 100644 index 0000000..5b4c2ed --- /dev/null +++ b/rust/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "max-effort-lib" +version = "1.0.0" +edition = "2024" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +godot = "0.4.5" diff --git a/rust/src/core/game_state.rs b/rust/src/core/game_state.rs new file mode 100644 index 0000000..d1ae367 --- /dev/null +++ b/rust/src/core/game_state.rs @@ -0,0 +1,161 @@ +use godot::prelude::*; +use std::sync::RwLock; + +use crate::data::hazard_def::HazardType; + +#[derive(Clone, Debug)] +pub enum GameEvent { + HazardSpawned, + HazardResolved, + TraumaApplied(f32), + LiftCompleted(bool), +} + +#[derive(Default)] +pub struct InnerState { + pub current_focus: f32, // 0.0 to 1.0 + pub lift_effort: f32, // 0.0 to 1.0 + pub is_lifting: bool, + pub active_hazards: Vec, + pub lift_progress: f32, // 0.0 to 1.0 + pub visual_height: f32, + pub is_lift_complete: bool, + pub is_lift_failed: bool, + pub camera_trauma: f32, + pub event_queue: Vec, +} + +#[derive(GodotClass)] +#[class(base=Resource)] +pub struct GameState { + pub inner: RwLock, + + base: Base, +} + +#[godot_api] +impl IResource for GameState { + fn init(base: Base) -> Self { + Self { + inner: RwLock::new(InnerState::default()), + base, + } + } +} + +#[godot_api] +impl GameState { + // --- WRITERS (Updated to push events) --- + + #[func] + pub fn apply_effort(&self, delta: f32) { + let mut guard = self.inner.write().unwrap(); + guard.is_lifting = true; + guard.lift_effort += delta; + } + + #[func] + pub fn release_focus(&self) { + let mut guard = self.inner.write().unwrap(); + guard.is_lifting = false; + } + + #[func] + pub fn set_focus_intensity(&self, intensity: f32) { + let mut guard = self.inner.write().unwrap(); + guard.current_focus = intensity; + } + + #[func] + pub fn set_lift_state(&self, progress: f32, visual_height: f32) { + let mut guard = self.inner.write().unwrap(); + guard.lift_progress = progress; + guard.visual_height = visual_height; + } + + #[func] + pub fn set_complete(&self, complete: bool) { + let mut guard = self.inner.write().unwrap(); + if complete { + guard.is_lift_complete = true; + } else { + guard.is_lift_failed = true; + } + + guard.event_queue.push(GameEvent::LiftCompleted(complete)); + } + + #[func] + pub fn add_trauma(&self, amount: f32) { + let mut guard = self.inner.write().unwrap(); + guard.camera_trauma = (guard.camera_trauma + amount).clamp(0.0, 1.0); + guard.event_queue.push(GameEvent::TraumaApplied(amount)); + } + + #[func] + pub fn add_active_hazard(&self, type_: HazardType) { + let mut guard = self.inner.write().unwrap(); + guard.active_hazards.push(type_); + guard.event_queue.push(GameEvent::HazardSpawned); + } + + #[func] + pub fn remove_active_hazard(&self, type_: HazardType) { + let mut guard = self.inner.write().unwrap(); + if let Some(index) = guard.active_hazards.iter().position(|t| *t == type_) { + guard.active_hazards.remove(index); + guard.event_queue.push(GameEvent::HazardResolved); + } + } + + // --- READERS --- + + #[func] + pub fn consume_effort(&self) -> f32 { + let mut guard = self.inner.write().unwrap(); + let effort = guard.lift_effort; + guard.lift_effort = 0.0; + effort + } + + #[func] + pub fn get_active_hazard_count(&self) -> i32 { + self.inner.read().unwrap().active_hazards.len() as i32 + } + + #[func] + pub fn get_focus(&self) -> f32 { + self.inner.read().unwrap().current_focus + } + + #[func] + pub fn consume_trauma(&self, decay: f32) -> f32 { + let mut guard = self.inner.write().unwrap(); + let t = guard.camera_trauma; + guard.camera_trauma = (t - decay).max(0.0); + t + } + + pub fn pop_events(&self) -> Vec { + let mut guard = self.inner.write().unwrap(); + let events = guard.event_queue.clone(); + guard.event_queue.clear(); + events + } + + pub fn get_lift_progress(&self) -> f32 { + self.inner.read().unwrap().lift_progress + } + + pub fn get_is_lifting(&self) -> bool { + self.inner.read().unwrap().is_lifting + } + + pub fn get_is_lift_complete(&self) -> bool { + self.inner.read().unwrap().is_lift_complete + } + + pub fn get_is_lift_failed(&self) -> bool { + self.inner.read().unwrap().is_lift_failed + } +} diff --git a/rust/src/core/mod.rs b/rust/src/core/mod.rs new file mode 100644 index 0000000..3e51989 --- /dev/null +++ b/rust/src/core/mod.rs @@ -0,0 +1 @@ +pub mod game_state; diff --git a/rust/src/data/day_config.rs b/rust/src/data/day_config.rs new file mode 100644 index 0000000..28c6ceb --- /dev/null +++ b/rust/src/data/day_config.rs @@ -0,0 +1,37 @@ +use godot::prelude::*; + +use crate::data::hazard_def::HazardDef; + +#[derive(GodotClass)] +#[class(base=Resource)] +pub struct DayConfig { + #[export] + pub day_number: i32, + #[export] + pub day_title: GString, + #[export] + pub target_weight: f32, + #[export] + pub gravity: f32, + #[export] + pub mini_game_scene: Option>, + #[export] + pub available_hazards: Array>, + + base: Base, +} + +#[godot_api] +impl IResource for DayConfig { + fn init(base: Base) -> Self { + Self { + day_number: 0, + day_title: "Day 1".into(), + target_weight: 100.0, + gravity: 2.0, + mini_game_scene: None, + available_hazards: Array::new(), + base, + } + } +} diff --git a/rust/src/data/hazard_def.rs b/rust/src/data/hazard_def.rs new file mode 100644 index 0000000..faf5229 --- /dev/null +++ b/rust/src/data/hazard_def.rs @@ -0,0 +1,55 @@ +use godot::{classes::SpriteFrames, prelude::*}; + +#[derive(GodotConvert, Export, Var, Default, Clone, PartialEq, Eq, Debug)] +#[godot(via=GString)] +pub enum HazardType { + #[default] + None, + GymBro, + LoosePlate, + PhoneDistraction, + Manager, +} + +#[derive(GodotClass)] +#[class(base=Resource)] +pub struct HazardDef { + #[export] + pub hazard_type: HazardType, + #[export] + pub display_name: GString, + #[export] + pub animations: Option>, + #[export] + pub idle_anim_name: GString, + #[export] + pub walk_anim_name: GString, + #[export] + pub time_to_fail: f32, + #[export] + pub spawn_weight: f32, + #[export] + pub min_focus_to_spawn: f32, + #[export] + pub clicks_to_resolve: i32, + + base: Base, +} + +#[godot_api] +impl IResource for HazardDef { + fn init(base: Base) -> Self { + Self { + hazard_type: HazardType::None, + display_name: "Unnamed Hazard".into(), + animations: None, + idle_anim_name: "idle".into(), + walk_anim_name: "walk".into(), + time_to_fail: 5.0, + spawn_weight: 1.0, + min_focus_to_spawn: 0.0, + clicks_to_resolve: 1, + base, + } + } +} diff --git a/rust/src/data/mod.rs b/rust/src/data/mod.rs new file mode 100644 index 0000000..fbedc00 --- /dev/null +++ b/rust/src/data/mod.rs @@ -0,0 +1,4 @@ +pub mod day_config; +pub mod hazard_def; +pub mod sound_bank; +pub mod tunnel_config; diff --git a/rust/src/data/sound_bank.rs b/rust/src/data/sound_bank.rs new file mode 100644 index 0000000..aab5de9 --- /dev/null +++ b/rust/src/data/sound_bank.rs @@ -0,0 +1,48 @@ +use godot::{classes::AudioStream, prelude::*}; + +#[derive(GodotClass)] +#[class(base=Resource)] +pub struct SoundBank { + #[export] + pub strain_loop: Option>, + #[export] + pub effort_exhale: Option>, + #[export] + pub win_stinger: Option>, + #[export] + pub fail_stinger: Option>, + #[export] + pub heartbeat_loop: Option>, + #[export] + pub hazard_spawn: Option>, + #[export] + pub hazard_resolve: Option>, + #[export] + pub camera_trauma: Option>, + + #[export] + pub menu_music: Option>, + #[export] + pub game_music: Option>, + + base: Base, +} + +#[godot_api] +impl IResource for SoundBank { + fn init(base: Base) -> Self { + Self { + strain_loop: None, + effort_exhale: None, + win_stinger: None, + fail_stinger: None, + heartbeat_loop: None, + hazard_spawn: None, + hazard_resolve: None, + camera_trauma: None, + menu_music: None, + game_music: None, + base, + } + } +} diff --git a/rust/src/data/tunnel_config.rs b/rust/src/data/tunnel_config.rs new file mode 100644 index 0000000..f433d9b --- /dev/null +++ b/rust/src/data/tunnel_config.rs @@ -0,0 +1,29 @@ +use godot::{classes::Curve, prelude::*}; + +#[derive(GodotClass)] +#[class(base=Resource)] +pub struct TunnelConfig { + #[export] + pub vision_narrow_rate: f32, + #[export] + pub vision_recover_rate: f32, + #[export] + pub max_tunnel_intensity: f32, + #[export] + pub vision_curve: Option>, + + base: Base, +} + +#[godot_api] +impl IResource for TunnelConfig { + fn init(base: Base) -> Self { + Self { + vision_narrow_rate: 0.5, + vision_recover_rate: 2.0, + max_tunnel_intensity: 0.95, + vision_curve: None, + base, + } + } +} diff --git a/rust/src/lib.rs b/rust/src/lib.rs new file mode 100644 index 0000000..70a7e7f --- /dev/null +++ b/rust/src/lib.rs @@ -0,0 +1,12 @@ +use godot::prelude::*; + +mod core; +mod data; +mod systems; +mod ui; +mod visuals; + +struct MaxEffort; + +#[gdextension] +unsafe impl ExtensionLibrary for MaxEffort {} diff --git a/rust/src/systems/bench_press_system.rs b/rust/src/systems/bench_press_system.rs new file mode 100644 index 0000000..c673a2d --- /dev/null +++ b/rust/src/systems/bench_press_system.rs @@ -0,0 +1,70 @@ +use crate::core::game_state::GameState; +use godot::prelude::*; + +#[derive(GodotClass)] +#[class(base=Node)] +pub struct BenchPressSystem { + #[export] + power_per_click: f32, + #[export] + gravity: f32, + #[export] + target_value: f32, + + #[export] + game_state: Option>, + + current_progress: f32, + is_lift_complete: bool, + + base: Base, +} + +#[godot_api] +impl INode for BenchPressSystem { + fn init(base: Base) -> Self { + Self { + power_per_click: 5.0, + gravity: 2.0, + target_value: 100.0, + game_state: None, + current_progress: 0.0, + is_lift_complete: false, + base, + } + } + + fn process(&mut self, delta: f64) { + if self.is_lift_complete { + return; + } + + let Some(state) = &self.game_state else { + return; + }; + let dt = delta as f32; + + let state_bind = state.bind(); + let effort = state_bind.consume_effort(); + let hazard_count = state_bind.get_active_hazard_count(); + drop(state_bind); + + if self.current_progress > 0.0 { + self.current_progress -= self.gravity * dt; + self.current_progress = self.current_progress.max(0.0); + } + + if hazard_count == 0 { + self.current_progress += self.power_per_click * effort; + } + + if self.current_progress >= self.target_value { + self.is_lift_complete = true; + state.bind().set_complete(true); + } + + let ratio = self.current_progress / self.target_value; + + state.bind().set_lift_state(ratio, ratio); + } +} diff --git a/rust/src/systems/camera_shake_system.rs b/rust/src/systems/camera_shake_system.rs new file mode 100644 index 0000000..806c9c7 --- /dev/null +++ b/rust/src/systems/camera_shake_system.rs @@ -0,0 +1,86 @@ +use crate::core::game_state::GameState; +use godot::{ + classes::{Camera2D, RandomNumberGenerator}, + prelude::*, +}; + +#[derive(GodotClass)] +#[class(base=Node)] +pub struct CameraShakeSystem { + #[export] + camera: Option>, + + #[export] + game_state: Option>, + + #[export] + decay_rate: f32, + #[export] + max_offset: f32, + #[export] + max_roll: f32, + #[export] + min_focus_for_shake: f32, + + trauma: f32, + rng: Gd, + + base: Base, +} + +#[godot_api] +impl INode for CameraShakeSystem { + fn init(base: Base) -> Self { + Self { + camera: None, + game_state: None, + decay_rate: 0.8, + max_offset: 20.0, + max_roll: 0.1, + trauma: 0.0, + min_focus_for_shake: 0.1, + rng: RandomNumberGenerator::new_gd(), + base, + } + } + + fn process(&mut self, delta: f64) { + let Some(camera) = &mut self.camera else { + godot_error!("CameraShakeSystem: No camera assigned"); + return; + }; + let Some(state) = &self.game_state else { + godot_error!("CameraShakeSystem: No game state assigned"); + return; + }; + + let dt = delta as f32; + + let focus = state.bind().get_focus(); + + if focus > self.min_focus_for_shake { + state.bind().add_trauma(1.5 * dt); + } + + let new_trauma = state.bind().consume_trauma(self.decay_rate * dt); + self.trauma = new_trauma; + + if self.trauma > 0.0 { + let shake = self.trauma * self.trauma; + + let offset_x = self.max_offset * shake * self.rng.randf_range(-1.0, 1.0); + let offset_y = self.max_offset * shake * self.rng.randf_range(-1.0, 1.0); + let rotation = self.max_roll * shake * self.rng.randf_range(-1.0, 1.0); + + camera.set_offset(Vector2::new(offset_x, offset_y)); + camera.set_rotation(rotation); + } else { + if camera.get_offset() != Vector2::ZERO { + let curr_off = camera.get_offset(); + let curr_rot = camera.get_rotation(); + camera.set_offset(curr_off.lerp(Vector2::ZERO, dt * 5.0)); + camera.set_rotation(curr_rot.lerp(0.0, dt * 5.0)); + } + } + } +} diff --git a/rust/src/systems/deadlift_system.rs b/rust/src/systems/deadlift_system.rs new file mode 100644 index 0000000..d401843 --- /dev/null +++ b/rust/src/systems/deadlift_system.rs @@ -0,0 +1,105 @@ +use crate::core::game_state::GameState; +use godot::prelude::*; + +#[derive(GodotClass)] +#[class(base=Node)] +pub struct DeadliftSystem { + #[export] + power_per_click: f32, + #[export] + gravity: f32, + #[export] + target_value: f32, + + #[export] + bar_height: f32, + #[export] + hold_zone_threshold: f32, + #[export] + bar_visual: Option>, + #[export] + start_pos: Vector2, + #[export] + end_pos: Vector2, + + #[export] + game_state: Option>, + + current_bar_height: f32, + hold_timer: f32, + is_lift_complete: bool, + + base: Base, +} + +#[godot_api] +impl INode for DeadliftSystem { + fn init(base: Base) -> Self { + Self { + power_per_click: 5.0, + gravity: 2.0, + target_value: 5.0, + + bar_height: 100.0, + hold_zone_threshold: 0.8, + bar_visual: None, + start_pos: Vector2::ZERO, + end_pos: Vector2::ZERO, + + game_state: None, + + current_bar_height: 0.0, + hold_timer: 0.0, + is_lift_complete: false, + base, + } + } + + fn process(&mut self, delta: f64) { + if self.is_lift_complete { + return; + } + + let Some(state) = &self.game_state else { + return; + }; + let dt = delta as f32; + + let state_bind = state.bind(); + let effort = state_bind.consume_effort(); + let hazard_count = state_bind.get_active_hazard_count(); + drop(state_bind); + + if self.current_bar_height > 0.0 { + self.current_bar_height -= self.gravity * dt; + self.current_bar_height = self.current_bar_height.max(0.0); + } + + if hazard_count == 0 { + self.current_bar_height += self.power_per_click * effort; + self.current_bar_height = self.current_bar_height.min(self.bar_height); + } + + let visual_ratio = self.current_bar_height / self.bar_height; + + if visual_ratio >= self.hold_zone_threshold && hazard_count == 0 { + self.hold_timer += dt; + + state.bind().add_trauma(0.15 * dt); + } + + if let Some(visual) = &mut self.bar_visual { + let new_pos = self.start_pos.lerp(self.end_pos, visual_ratio); + visual.set_position(new_pos); + } + + let progress = self.hold_timer / self.target_value; + state.bind().set_lift_state(progress, visual_ratio); + + if self.hold_timer >= self.target_value { + self.is_lift_complete = true; + state.bind().add_trauma(1.0); + state.bind().set_complete(true); + } + } +} diff --git a/rust/src/systems/game_manager.rs b/rust/src/systems/game_manager.rs new file mode 100644 index 0000000..ae364ac --- /dev/null +++ b/rust/src/systems/game_manager.rs @@ -0,0 +1,207 @@ +use crate::{ + core::game_state::GameState, data::day_config::DayConfig, systems::hazard_system::HazardSystem, +}; +use godot::{ + classes::{Control, Label}, + prelude::*, +}; + +#[derive(GodotClass)] +#[class(base=Node)] +pub struct GameManager { + #[export] + days: Array>, + + #[export] + game_state: Option>, + + #[export] + hazard_system: Option>, + #[export] + minigame_container: Option>, + + #[export] + win_screen: Option>, + #[export] + lose_screen: Option>, + #[export] + game_complete_screen: Option>, + + #[export] + day_label: Option>, + #[export] + main_menu_scene: Option>, + + current_day_index: i32, + current_mini_game: Option>, + + level_ended: bool, + + base: Base, +} + +#[godot_api] +impl INode for GameManager { + fn init(base: Base) -> Self { + Self { + days: Array::new(), + game_state: None, + hazard_system: None, + minigame_container: None, + win_screen: None, + lose_screen: None, + game_complete_screen: None, + day_label: None, + main_menu_scene: None, + current_day_index: 0, + current_mini_game: None, + level_ended: false, + base, + } + } + + fn ready(&mut self) { + let idx = self.current_day_index; + self.base_mut() + .call_deferred("start_day", &[idx.to_variant()]); + } + + fn process(&mut self, _delta: f64) { + if self.level_ended { + return; + } + + let (won, lost) = if let Some(state) = &self.game_state { + let bind = state.bind(); + (bind.get_is_lift_complete(), bind.get_is_lift_failed()) + } else { + (false, false) + }; + + if won { + self.handle_win(); + self.level_ended = true; + } else if lost { + self.handle_loss(); + self.level_ended = true; + } + } +} + +#[godot_api] +impl GameManager { + #[func] + fn start_day(&mut self, index: i32) { + self.level_ended = false; + + if let Some(state) = &self.game_state { + let bind = state.bind(); + + if let Ok(mut inner) = bind.inner.write() { + inner.is_lift_complete = false; + inner.is_lift_failed = false; + + inner.lift_progress = 0.0; + inner.visual_height = 0.0; + inner.lift_effort = 0.0; + inner.active_hazards.clear(); + } + } + + if index >= self.days.len() as i32 { + self.cleanup_level(); + if let Some(s) = &mut self.game_complete_screen { + s.set_visible(true); + } + return; + } + + self.cleanup_level(); + + let config = self.days.get(index as usize).expect("Invalid Day Index"); + let config_bind = config.bind(); + + if let Some(prefab) = &config_bind.mini_game_scene { + if let Some(instance) = prefab.instantiate() { + if let Some(container) = &mut self.minigame_container { + container.add_child(&instance.clone()); + } + + if let Some(mut system) = instance.get_node_or_null("System") { + system.set("target_value", &config_bind.target_weight.to_variant()); + system.set("gravity", &config_bind.gravity.to_variant()); + + if let Some(state) = &self.game_state { + system.set("game_state", &state.to_variant()); + } + } + self.current_mini_game = Some(instance); + } + } + + if let Some(hs) = &mut self.hazard_system { + hs.bind_mut() + .set_available_hazards(config_bind.available_hazards.clone()); + } + + if let Some(l) = &mut self.day_label { + l.set_text(&config_bind.day_title); + } + if let Some(s) = &mut self.win_screen { + s.set_visible(false); + } + if let Some(s) = &mut self.lose_screen { + s.set_visible(false); + } + } + + fn cleanup_level(&mut self) { + if let Some(game) = &mut self.current_mini_game { + game.queue_free(); + self.current_mini_game = None; + } + if let Some(hs) = &mut self.hazard_system { + hs.bind_mut().clear_hazards(); + } + } + + fn handle_win(&mut self) { + if let Some(s) = &mut self.win_screen { + s.set_visible(true); + } + } + + fn handle_loss(&mut self) { + if let Some(s) = &mut self.lose_screen { + s.set_visible(true); + } + } + + #[func] + pub fn on_next_day_pressed(&mut self) { + self.current_day_index += 1; + let idx = self.current_day_index; + self.base_mut() + .call_deferred("start_day", &[idx.to_variant()]); + } + + #[func] + pub fn on_retry_pressed(&mut self) { + let idx = self.current_day_index; + self.base_mut() + .call_deferred("start_day", &[idx.to_variant()]); + } + + #[func] + pub fn on_menu_pressed(&mut self) { + if let Some(menu) = &self.main_menu_scene { + let menu_ref = menu.clone(); + self.base() + .get_tree() + .unwrap() + .change_scene_to_packed(&menu_ref); + } else { + self.base().get_tree().unwrap().quit(); + } + } +} diff --git a/rust/src/systems/hazard_controller.rs b/rust/src/systems/hazard_controller.rs new file mode 100644 index 0000000..8109de9 --- /dev/null +++ b/rust/src/systems/hazard_controller.rs @@ -0,0 +1,209 @@ +use godot::{ + classes::{ + AnimatedSprite2D, Area2D, CollisionShape2D, InputEvent, InputEventMouseButton, Label, + RectangleShape2D, + }, + global::MouseButton, + prelude::*, +}; + +use crate::{core::game_state::GameState, data::hazard_def::HazardDef}; + +#[derive(GodotClass)] +#[class(base=Node2D)] +pub struct HazardController { + #[export] + anim_sprite: Option>, + #[export] + click_area: Option>, + #[export] + click_shape: Option>, + #[export] + name_label: Option>, + + #[export] + game_state: Option>, + + data: Option>, + time_active: f32, + is_resolved: bool, + current_health: i32, + + base: Base, +} + +#[godot_api] +impl INode2D for HazardController { + fn init(base: Base) -> Self { + Self { + anim_sprite: None, + click_area: None, + click_shape: None, + name_label: None, + game_state: None, + data: None, + time_active: 0.0, + is_resolved: false, + current_health: 1, + base, + } + } + + fn ready(&mut self) { + if let Some(mut area) = self.click_area.clone() { + let callable = self.base_mut().callable("on_input_event"); + area.connect("input_event", &callable); + } + } + + fn process(&mut self, delta: f64) { + if self.is_resolved { + return; + } + + let Some(data) = &self.data.clone() else { + return; + }; + let data_bind = data.bind(); + + self.time_active += delta as f32; + + if self.time_active >= data_bind.time_to_fail { + if let Some(state) = &self.game_state { + state.bind().set_complete(false); + } + self.base_mut().queue_free(); + } + } +} + +#[godot_api] +impl HazardController { + #[func] + pub fn initialize(&mut self, data: Gd) { + let data_bind = data.bind(); + self.current_health = data_bind.clicks_to_resolve; + + if let Some(sprite) = &mut self.anim_sprite { + if let Some(frames) = &data_bind.animations { + sprite.set_sprite_frames(frames); + + let anim_name = StringName::from(&data_bind.idle_anim_name); + + if let Some(texture) = frames.get_frame_texture(&anim_name, 0) { + if let Some(shape) = &mut self.click_shape { + let mut rect = RectangleShape2D::new_gd(); + rect.set_size(texture.get_size()); + shape.set_shape(&rect.upcast::()); + } + } + + sprite.play_ex().name(&anim_name).done(); + } + } + + if let Some(label) = &mut self.name_label { + label.set_text(&data_bind.display_name); + } + + self.base_mut().set_scale(Vector2::ZERO); + + let node = self.base().clone(); + + if let Some(mut tween) = self.base_mut().create_tween() { + tween + .set_trans(godot::classes::tween::TransitionType::BACK) + .unwrap() + .set_ease(godot::classes::tween::EaseType::OUT); + + tween.tween_property( + &node.upcast::(), + "scale", + &Vector2::ONE.to_variant(), + 0.4, + ); + } + + drop(data_bind); + self.data = Some(data); + } + + #[func] + fn on_input_event(&mut self, _viewport: Gd, event: Gd, _shape_idx: i64) { + if self.is_resolved { + return; + } + + if let Ok(mouse_event) = event.try_cast::() { + if mouse_event.is_pressed() && mouse_event.get_button_index() == MouseButton::LEFT { + self.take_damage(); + } + } + } + + fn take_damage(&mut self) { + self.current_health -= 1; + + if let Some(sprite) = &mut self.anim_sprite { + sprite.set_modulate(Color::RED); + } + + let node = self.base().clone(); + let sprite_opt = self.anim_sprite.clone(); + + if let Some(mut tween) = self.base_mut().create_tween() { + tween.tween_property( + &node.clone().upcast::(), + "scale", + &Vector2::new(1.2, 0.8).to_variant(), + 0.05, + ); + tween.tween_property( + &node.clone().upcast::(), + "scale", + &Vector2::ONE.to_variant(), + 0.05, + ); + + // Flash Red + if let Some(sprite) = sprite_opt { + if let Some(mut parallel) = tween.parallel() { + parallel.tween_property( + &sprite.upcast::(), + "modulate", + &Color::WHITE.to_variant(), + 0.1, + ); + } + } + } + + if self.current_health <= 0 { + self.resolve(); + } + } + + fn resolve(&mut self) { + self.is_resolved = true; + + if let Some(data) = &self.data { + let hazard_type = data.bind().hazard_type.clone(); + + if let Some(state) = &self.game_state { + state.bind().remove_active_hazard(hazard_type); + } + } + + let node = self.base().clone(); + + if let Some(mut tween) = self.base_mut().create_tween() { + tween.tween_property( + &node.clone().upcast::(), + "scale", + &Vector2::ZERO.to_variant(), + 0.2, + ); + tween.tween_callback(&node.callable("queue_free")); + } + } +} diff --git a/rust/src/systems/hazard_system.rs b/rust/src/systems/hazard_system.rs new file mode 100644 index 0000000..c986562 --- /dev/null +++ b/rust/src/systems/hazard_system.rs @@ -0,0 +1,144 @@ +use godot::{classes::RandomNumberGenerator, prelude::*}; + +use crate::{ + core::game_state::GameState, data::hazard_def::HazardDef, + systems::hazard_controller::HazardController, +}; + +#[derive(GodotClass)] +#[class(base=Node)] +pub struct HazardSystem { + #[export] + possible_hazards: Array>, + #[export] + spawn_locations: Array>, + #[export] + hazard_prefab: Option>, + #[export] + check_interval: f32, + + #[export] + game_state: Option>, + + timer: f32, + rng: Gd, + + base: Base, +} + +#[godot_api] +impl INode for HazardSystem { + fn init(base: Base) -> Self { + Self { + possible_hazards: Array::new(), + spawn_locations: Array::new(), + hazard_prefab: None, + check_interval: 1.0, + game_state: None, + timer: 0.0, + rng: RandomNumberGenerator::new_gd(), + base, + } + } + + fn process(&mut self, delta: f64) { + self.timer += delta as f32; + if self.timer >= self.check_interval { + self.timer = 0.0; + self.try_spawn_hazard(); + } + } +} + +#[godot_api] +impl HazardSystem { + #[func] + pub fn clear_hazards(&mut self) { + for location in self.spawn_locations.iter_shared() { + for mut child in location.get_children().iter_shared() { + child.queue_free(); + } + } + self.timer = 0.0; + } + + #[func] + pub fn set_available_hazards(&mut self, hazards: Array>) { + self.possible_hazards = hazards; + } + + fn try_spawn_hazard(&mut self) { + let Some(state) = &self.game_state else { + return; + }; + + let current_focus = state.bind().get_focus(); + + if current_focus < 0.2 { + return; + } + + let spawn_chance = current_focus * 0.5; + if self.rng.randf() < spawn_chance { + self.spawn_random_hazard(current_focus); + } + } + + fn spawn_random_hazard(&mut self, current_focus: f32) { + if self.possible_hazards.is_empty() + || self.spawn_locations.is_empty() + || self.hazard_prefab.is_none() + { + return; + } + + let empty_locations: Vec> = self + .spawn_locations + .iter_shared() + .filter(|loc| loc.get_child_count() == 0) + .collect(); + + if empty_locations.is_empty() { + return; + } + + let loc_idx = self.rng.randi() as usize % empty_locations.len(); + let mut target_loc = empty_locations[loc_idx].clone(); + + let valid_hazards: Vec> = self + .possible_hazards + .iter_shared() + .filter(|h| h.bind().min_focus_to_spawn <= current_focus) + .collect(); + + if valid_hazards.is_empty() { + return; + } + + let haz_idx = self.rng.randi() as usize % valid_hazards.len(); + let selected_hazard = valid_hazards[haz_idx].clone(); + let hazard_type = selected_hazard.bind().hazard_type.clone(); + + if let Some(prefab) = &self.hazard_prefab { + if let Some(instance) = prefab.instantiate() { + if let Ok(mut hazard_node) = instance.try_cast::() { + hazard_node + .clone() + .upcast::() + .set_position(Vector2::ZERO); + + target_loc.add_child(&hazard_node.clone().upcast::()); + + hazard_node.bind_mut().initialize(selected_hazard); + + if let Some(state) = &self.game_state { + hazard_node.bind_mut().set_game_state(Some(state.clone())); + state.bind().add_active_hazard(hazard_type); + } + } else { + godot_print!("Error: Hazard Prefab root is not a HazardController!"); + } + } + } + } +} diff --git a/rust/src/systems/mod.rs b/rust/src/systems/mod.rs new file mode 100644 index 0000000..2df866a --- /dev/null +++ b/rust/src/systems/mod.rs @@ -0,0 +1,9 @@ +pub mod bench_press_system; +pub mod camera_shake_system; +pub mod deadlift_system; +pub mod game_manager; +pub mod hazard_controller; +pub mod hazard_system; +pub mod player_input_system; +pub mod sound_manager; +pub mod tunnel_system; diff --git a/rust/src/systems/player_input_system.rs b/rust/src/systems/player_input_system.rs new file mode 100644 index 0000000..fd7ac0d --- /dev/null +++ b/rust/src/systems/player_input_system.rs @@ -0,0 +1,40 @@ +use godot::{classes::Input, prelude::*}; + +use crate::core::game_state::GameState; + +const LIFT_ACTION: &str = "lift_action"; + +#[derive(GodotClass)] +#[class(base=Node)] +pub struct PlayerInputSystem { + #[export] + game_state: Option>, + base: Base, +} + +#[godot_api] +impl INode for PlayerInputSystem { + fn init(base: Base) -> Self { + Self { + game_state: None, + base, + } + } + + fn process(&mut self, delta: f64) { + let Some(state) = &self.game_state else { + return; + }; + let state_bind = state.bind(); + + let input = Input::singleton(); + + if input.is_action_pressed(LIFT_ACTION) { + state_bind.apply_effort(delta as f32); + } + + if input.is_action_just_released(LIFT_ACTION) { + state_bind.release_focus(); + } + } +} diff --git a/rust/src/systems/sound_manager.rs b/rust/src/systems/sound_manager.rs new file mode 100644 index 0000000..b9beaa5 --- /dev/null +++ b/rust/src/systems/sound_manager.rs @@ -0,0 +1,213 @@ +use crate::{ + core::game_state::{GameEvent, GameState}, + data::sound_bank::SoundBank, +}; +use godot::{ + classes::{AudioStream, AudioStreamPlayer}, + prelude::*, +}; + +#[derive(GodotClass)] +#[class(base=Node)] +pub struct SoundManager { + #[export] + bank: Option>, + #[export] + game_state: Option>, + + #[export] + pool_size: i32, + + sfx_pool: Vec>, + strain_player: Option>, + heartbeat_player: Option>, + music_player: Option>, + + was_lifting: bool, + + base: Base, +} + +#[godot_api] +impl INode for SoundManager { + fn init(base: Base) -> Self { + Self { + bank: None, + game_state: None, + pool_size: 8, + sfx_pool: Vec::new(), + strain_player: None, + heartbeat_player: None, + music_player: None, + was_lifting: false, + base, + } + } + + fn ready(&mut self) { + self.initialize_pool(); + + // FIX: Clone bank to release borrow on self + if let Some(bank) = self.bank.clone() { + if let Some(music) = &bank.bind().game_music { + self.play_music(music.clone()); + } + } + } + + fn process(&mut self, _delta: f64) { + let Some(state) = self.game_state.clone() else { + return; + }; + + let events = state.bind().pop_events(); + + for event in events { + match event { + GameEvent::HazardSpawned => self.play_bank_sfx(|b| b.hazard_spawn.clone()), + GameEvent::HazardResolved => self.play_bank_sfx(|b| b.hazard_resolve.clone()), + GameEvent::LiftCompleted(success) => { + self.stop_strain(); + if success { + self.play_bank_sfx(|b| b.win_stinger.clone()); + } else { + self.play_bank_sfx(|b| b.fail_stinger.clone()); + } + } + GameEvent::TraumaApplied(amount) => { + if amount > 0.5 { + self.play_bank_sfx(|b| b.camera_trauma.clone()); + } + } + } + } + + let is_lifting = state.bind().get_is_lifting(); + let progress = state.bind().get_lift_progress(); + let focus = state.bind().get_focus(); + + if is_lifting != self.was_lifting { + if is_lifting { + self.play_strain_loop(); + } else { + self.stop_strain(); + self.play_bank_sfx(|b| b.effort_exhale.clone()); + } + self.was_lifting = is_lifting; + } + + if is_lifting { + self.update_strain_pitch(progress); + } + + self.update_heartbeat(focus); + } +} + +impl SoundManager { + fn initialize_pool(&mut self) { + for _ in 0..self.pool_size { + let mut p = AudioStreamPlayer::new_alloc(); + p.set_bus("Sfx"); + self.base_mut().add_child(&p.clone().upcast::()); + self.sfx_pool.push(p); + } + + let mut strain = AudioStreamPlayer::new_alloc(); + strain.set_bus("Sfx"); + self.base_mut().add_child(&strain.clone().upcast::()); + self.strain_player = Some(strain); + + let mut hb = AudioStreamPlayer::new_alloc(); + hb.set_bus("Sfx"); + self.base_mut().add_child(&hb.clone().upcast::()); + self.heartbeat_player = Some(hb); + + let mut mus = AudioStreamPlayer::new_alloc(); + mus.set_bus("Music"); + self.base_mut().add_child(&mus.clone().upcast::()); + self.music_player = Some(mus); + + if let Some(bank) = self.bank.clone() { + let bank_bind = bank.bind(); + if let Some(clip) = &bank_bind.heartbeat_loop { + if let Some(hb_player) = &mut self.heartbeat_player { + hb_player.set_stream(&clip.clone()); + hb_player.set_volume_db(-80.0); + hb_player.play(); + } + } + } + } + + fn play_music(&mut self, clip: Gd) { + if let Some(p) = &mut self.music_player { + p.set_stream(&clip); + p.play(); + } + } + + fn play_bank_sfx(&mut self, selector: F) + where + F: FnOnce(&SoundBank) -> Option>, + { + let clip = self.bank.as_ref().and_then(|b| selector(&b.bind())); + + if let Some(c) = clip { + self.play_sfx(c); + } + } + + fn play_sfx(&mut self, clip: Gd) { + for p in &mut self.sfx_pool { + if !p.is_playing() { + p.set_stream(&clip); + p.set_pitch_scale(1.0); + p.play(); + return; + } + } + if let Some(p) = self.sfx_pool.first_mut() { + p.set_stream(&clip); + p.play(); + } + } + + fn play_strain_loop(&mut self) { + if let Some(bank) = self.bank.clone() { + if let Some(clip) = &bank.bind().strain_loop { + if let Some(p) = &mut self.strain_player { + p.set_stream(&clip.clone()); + p.play(); + } + } + } + } + + fn stop_strain(&mut self) { + if let Some(p) = &mut self.strain_player { + p.stop(); + } + } + + fn update_strain_pitch(&mut self, progress: f32) { + if let Some(p) = &mut self.strain_player { + let pitch = 1.0 + (progress * 0.3); + p.set_pitch_scale(pitch); + } + } + + fn update_heartbeat(&mut self, focus: f32) { + if let Some(p) = &mut self.heartbeat_player { + if focus < 0.1 { + p.set_volume_db(-80.0); + } else { + let t = (focus - 0.1) / 0.9; + let vol = -30.0 + (t * (5.0 - (-30.0))); + let pitch = 1.0 + (t * 0.4); + p.set_volume_db(vol); + p.set_pitch_scale(pitch); + } + } + } +} diff --git a/rust/src/systems/tunnel_system.rs b/rust/src/systems/tunnel_system.rs new file mode 100644 index 0000000..cbf97e0 --- /dev/null +++ b/rust/src/systems/tunnel_system.rs @@ -0,0 +1,82 @@ +use godot::{ + classes::{ColorRect, ShaderMaterial}, + prelude::*, +}; + +use crate::{core::game_state::GameState, data::tunnel_config::TunnelConfig}; + +#[derive(GodotClass)] +#[class(base=Node)] +pub struct TunnelSystem { + #[export] + game_state: Option>, + #[export] + config: Option>, + #[export] + vignette_overlay: Option>, + + base: Base, +} + +#[godot_api] +impl INode for TunnelSystem { + fn init(base: Base) -> Self { + Self { + game_state: None, + config: None, + vignette_overlay: None, + base, + } + } + + fn process(&mut self, delta: f64) { + let Some(state) = &self.game_state else { + return; + }; + let Some(config) = &self.config else { + return; + }; + + let state_bind = state.bind(); + let is_lifting = state_bind.get_is_lifting(); + let current_focus = state_bind.get_focus(); + + drop(state_bind); + + let config_bind = config.bind(); + let dt = delta as f32; + + let mut new_focus = current_focus; + + if is_lifting { + new_focus += config_bind.vision_narrow_rate * dt; + } else { + new_focus -= config_bind.vision_recover_rate * dt; + } + + new_focus = new_focus.clamp(0.0, 1.0); + + let max_intensity = config_bind.max_tunnel_intensity; + + let visual_raw = if let Some(curve) = &config_bind.vision_curve { + curve.sample(new_focus) + } else { + new_focus + }; + + let visual_value = visual_raw * max_intensity; + + if let Some(overlay) = &mut self.vignette_overlay { + if let Some(material) = overlay + .get_material() + .and_then(|m| Some(m.try_cast::())) + { + if let Ok(mut mat) = material { + mat.set_shader_parameter("vignette_intensity", &visual_value.to_variant()); + } + } + } + + state.bind().set_focus_intensity(new_focus); + } +} diff --git a/rust/src/ui/lift_progress_bar.rs b/rust/src/ui/lift_progress_bar.rs new file mode 100644 index 0000000..081a57b --- /dev/null +++ b/rust/src/ui/lift_progress_bar.rs @@ -0,0 +1,37 @@ +use crate::core::game_state::GameState; +use godot::{ + classes::{IProgressBar, ProgressBar}, + prelude::*, +}; + +#[derive(GodotClass)] +#[class(base=ProgressBar)] +pub struct LiftProgressBar { + #[export] + game_state: Option>, + + base: Base, +} + +#[godot_api] +impl IProgressBar for LiftProgressBar { + fn init(base: Base) -> Self { + Self { + game_state: None, + base, + } + } + + fn ready(&mut self) { + self.base_mut().set_min(0.0); + self.base_mut().set_max(1.0); + self.base_mut().set_value(0.0); + } + + fn process(&mut self, _delta: f64) { + if let Some(state) = &self.game_state { + let progress = state.bind().get_lift_progress(); + self.base_mut().set_value(progress as f64); + } + } +} diff --git a/rust/src/ui/main_menu.rs b/rust/src/ui/main_menu.rs new file mode 100644 index 0000000..f93b617 --- /dev/null +++ b/rust/src/ui/main_menu.rs @@ -0,0 +1,59 @@ +use godot::{ + classes::{AudioServer, CheckButton, Control, IControl}, + prelude::*, +}; + +#[derive(GodotClass)] +#[class(base=Control)] +pub struct MainMenu { + #[export] + game_scene: Option>, + + #[export] + mute_button: Option>, + + base: Base, +} + +#[godot_api] +impl IControl for MainMenu { + fn init(base: Base) -> Self { + Self { + game_scene: None, + mute_button: None, + base, + } + } + + fn ready(&mut self) { + let mut audio_server = AudioServer::singleton(); + let master_bus = audio_server.get_bus_index("Master"); + audio_server.set_bus_mute(master_bus, false); + } +} + +#[godot_api] +impl MainMenu { + #[func] + fn on_play_pressed(&mut self) { + if let Some(scene) = &self.game_scene { + if let Some(mut tree) = self.base().get_tree() { + tree.change_scene_to_packed(&scene.clone()); + } + } + } + + #[func] + fn on_quit_pressed(&mut self) { + if let Some(mut tree) = self.base().get_tree() { + tree.quit(); + } + } + + #[func] + fn on_mute_toggled(&mut self, toggled_on: bool) { + let mut audio_server = AudioServer::singleton(); + let master_bus = audio_server.get_bus_index("Master"); + audio_server.set_bus_mute(master_bus, toggled_on); + } +} diff --git a/rust/src/ui/mod.rs b/rust/src/ui/mod.rs new file mode 100644 index 0000000..f4e5d9f --- /dev/null +++ b/rust/src/ui/mod.rs @@ -0,0 +1,2 @@ +pub mod lift_progress_bar; +pub mod main_menu; diff --git a/rust/src/visuals/lift_sync_controller.rs b/rust/src/visuals/lift_sync_controller.rs new file mode 100644 index 0000000..f2cb613 --- /dev/null +++ b/rust/src/visuals/lift_sync_controller.rs @@ -0,0 +1,107 @@ +use crate::core::game_state::GameState; +use godot::{ + classes::{AnimatedSprite2D, Sprite2D}, + prelude::*, +}; + +#[derive(GodotClass)] +#[class(base=Node)] +pub struct LiftSyncController { + #[export] + player_anim: Option>, + #[export] + barbell: Option>, + #[export] + game_state: Option>, + + #[export] + animation_name: GString, + #[export] + bar_positions: Array, + #[export] + simulate_reps: bool, + #[export] + rep_speed: f32, + + current_rep_progress: f32, + + base: Base, +} + +#[godot_api] +impl INode for LiftSyncController { + fn init(base: Base) -> Self { + Self { + player_anim: None, + barbell: None, + game_state: None, + animation_name: "lift".into(), + bar_positions: Array::new(), + simulate_reps: true, + rep_speed: 2.0, + current_rep_progress: 0.0, + base, + } + } + + fn process(&mut self, delta: f64) { + let Some(state) = &self.game_state else { + godot_error!("LiftSyncController: No game state assigned"); + return; + }; + + let state_bind = state.bind(); + let is_lifting = state_bind.get_is_lifting(); + + let visual_height = state_bind.inner.read().unwrap().visual_height; + drop(state_bind); + + let dt = delta as f32; + + if self.simulate_reps { + if is_lifting { + self.current_rep_progress += self.rep_speed * dt; + } else { + if self.current_rep_progress > 0.0 { + self.current_rep_progress -= self.rep_speed * dt; + self.current_rep_progress = self.current_rep_progress.max(0.0); + } + } + + let ping_pong_val = + godot::global::pingpong(self.current_rep_progress as f64, 1.0) as f32; + self.update_visuals(ping_pong_val); + } else { + self.update_visuals(visual_height); + } + } +} + +impl LiftSyncController { + fn update_visuals(&mut self, normalized_height: f32) { + if self.player_anim.is_none() || self.barbell.is_none() || self.bar_positions.is_empty() { + godot_error!("LiftSyncController: Missing visuals or bar positions"); + return; + } + + let total_frames = self.bar_positions.len() as i32; + let frame_index_f = normalized_height * (total_frames as f32 - 0.01); + let frame_index = (frame_index_f.floor() as i32).clamp(0, total_frames - 1); + + if let Some(anim) = &mut self.player_anim { + anim.set_frame(frame_index); + + let current_anim = anim.get_animation(); + if current_anim != StringName::from(&self.animation_name) { + let anim_name_sn = StringName::from(&self.animation_name); + anim.play_ex().name(&anim_name_sn).done(); + } + } + + if let Some(bar) = &mut self.barbell { + if let Some(pos) = self.bar_positions.get(frame_index as usize) { + bar.set_position(pos); + } + } + } +} diff --git a/rust/src/visuals/mod.rs b/rust/src/visuals/mod.rs new file mode 100644 index 0000000..3c8575e --- /dev/null +++ b/rust/src/visuals/mod.rs @@ -0,0 +1 @@ +pub mod lift_sync_controller;