Compare commits

..

26 Commits

Author SHA1 Message Date
9207295a99 basic tests for a wider variety of files
Some checks failed
Create tag and build when new code gets to main / BumpTag (push) Successful in 20s
Create tag and build when new code gets to main / Test (push) Failing after 7m29s
Create tag and build when new code gets to main / Export (push) Successful in 8m18s
2026-02-20 16:58:17 +01:00
4474ba22fa added xunit and a few tests with gdunit 2026-02-20 15:41:43 +01:00
6101406f45 trying out something to fix CI
Some checks failed
Create tag and build when new code gets to main / BumpTag (push) Successful in 22s
Create tag and build when new code gets to main / Test (push) Failing after 6m50s
Create tag and build when new code gets to main / Export (push) Successful in 8m1s
2026-02-17 23:22:03 +01:00
c792c98ad2 fixed a flaky test and let the godot bin be defined by env variable
Some checks failed
Create tag and build when new code gets to main / BumpTag (push) Successful in 18s
Create tag and build when new code gets to main / Test (push) Failing after 7m4s
Create tag and build when new code gets to main / Export (push) Successful in 7m53s
2026-02-17 23:08:10 +01:00
74876a9a5d started proper testing
Some checks failed
Create tag and build when new code gets to main / BumpTag (push) Successful in 19s
Create tag and build when new code gets to main / Test (push) Failing after 6m42s
Create tag and build when new code gets to main / Export (push) Successful in 8m7s
2026-02-17 22:51:58 +01:00
bbb5149184 made it that inputting a direction when hanging makes us leave the wall
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 22s
Create tag and build when new code gets to main / Test (push) Successful in 7m25s
Create tag and build when new code gets to main / Export (push) Successful in 8m55s
Create tag and build when new code gets to main / ReleaseName (push) Successful in 3s
Create tag and build when new code gets to main / Release (push) Successful in 16m7s
2026-02-17 15:33:07 +01:00
9e39528b9a redid tutorials 2026-02-17 15:28:04 +01:00
1d2290b025 new tuto triggers ready to be setup 2026-02-17 11:24:14 +01:00
b9ae83cd92 finally cleaned up input method detection
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 21s
Create tag and build when new code gets to main / Test (push) Successful in 6m46s
Create tag and build when new code gets to main / Export (push) Successful in 8m3s
2026-02-16 23:15:25 +01:00
759d972b6d removed automatic itch upload on every main run because it costs too much
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 20s
Create tag and build when new code gets to main / Test (push) Successful in 6m54s
Create tag and build when new code gets to main / Export (push) Successful in 8m21s
2026-02-13 19:21:44 +01:00
4df4585149 fixed escape menu input on keyboard
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 21s
Create tag and build when new code gets to main / Test (push) Successful in 7m14s
Create tag and build when new code gets to main / Export (push) Successful in 8m46s
2026-02-13 15:20:54 +01:00
88b0911c6c removed wall run tutorial and fixed wall run leave auto dash 2026-02-13 15:00:25 +01:00
81ce45a0dc Merge branch 'main' of https://git.game-dev.space/minimata/MovementTests
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 21s
Create tag and build when new code gets to main / Test (push) Successful in 7m13s
Create tag and build when new code gets to main / Export (push) Successful in 9m11s
2026-02-13 12:32:12 +01:00
1caf202310 fine tuned wall jump and run again 2026-02-13 12:31:51 +01:00
22c4301244 fix forge issue 2026-02-13 11:11:03 +01:00
032e059826 wall run is easier to control and triggers more consistently 2026-02-13 10:24:25 +01:00
a8683b77e8 Update .gitea/workflows/release-branch.yaml
Some checks failed
Create tag and build when new code gets to main / Export (push) Has been cancelled
Create tag and build when new code gets to main / Test (push) Has been cancelled
Create tag and build when new code gets to main / BumpTag (push) Has been cancelled
Create tag and build when new code gets to main / ReleaseName (push) Successful in 31s
Create tag and build when new code gets to main / Release (push) Successful in 15m21s
2026-02-11 18:46:16 +00:00
90e6cdbcde Update .gitea/workflows/release-branch.yaml
Some checks failed
Create tag and build when new code gets to main / Export (push) Has been cancelled
Create tag and build when new code gets to main / BumpTag (push) Has been cancelled
Create tag and build when new code gets to main / Test (push) Has been cancelled
Create tag and build when new code gets to main / ReleaseName (push) Successful in 3s
Create tag and build when new code gets to main / Release (push) Failing after 6m12s
2026-02-11 18:38:00 +00:00
c09dfd1e7b more tuts, respawn mechanic when falling, reworked wall run again
Some checks failed
Create tag and build when new code gets to main / BumpTag (push) Successful in 19s
Create tag and build when new code gets to main / Test (push) Successful in 7m37s
Create tag and build when new code gets to main / Export (push) Has been cancelled
Create tag and build when new code gets to main / ReleaseName (push) Successful in 10s
Create tag and build when new code gets to main / Release (push) Failing after 4m53s
2026-02-11 17:06:18 +01:00
9db0056c5d more tut 2026-02-11 10:30:21 +01:00
7f1d33e4fc more sword tutorial 2026-02-10 22:33:16 +01:00
aaa9b102c1 started working on sword dash tutorial and bullet time is now unlimited while aiming in air
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 20s
Create tag and build when new code gets to main / Test (push) Successful in 6m44s
Create tag and build when new code gets to main / Export (push) Successful in 8m17s
2026-02-10 16:44:45 +01:00
cb348667f5 recover weapon if walking on it 2026-02-10 15:27:30 +01:00
8d23a95c68 ci back
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 18s
Create tag and build when new code gets to main / Test (push) Successful in 6m13s
Create tag and build when new code gets to main / Export (push) Successful in 8m45s
2026-02-10 09:41:44 +01:00
a9809abc27 removing sa mere
Some checks failed
Create tag and build when new code gets to main / BumpTag (push) Successful in 20s
Create tag and build when new code gets to main / Test (push) Failing after 5m10s
2026-02-10 09:35:26 +01:00
db65c02e75 trying a simpler workflow 2026-02-10 09:26:09 +01:00
79 changed files with 4533 additions and 714 deletions

View File

@@ -91,26 +91,26 @@ jobs:
${{ steps.setup-godot.outputs.godot_bin }} --headless --verbose --export-release "Windows Desktop" build/windows/${{ env.GAME_NAME }}.exe
zip -r Windows.zip build/windows
- name: Setup Butler
shell: bash
env:
BUTLER_API_KEY: ${{ secrets.BUTLER_TOKEN }}
run: |
mkdir ./tools 2>/dev/null || true
pushd tools
curl -sSLfo ./butler.zip "https://broth.itch.zone/butler/linux-amd64/LATEST/archive/default"
unzip butler.zip
chmod +x ./butler
popd
./tools/butler -V
- name: Upload to itch.io
shell: bash
env:
BUTLER_API_KEY: ${{ secrets.BUTLER_TOKEN }}
run: |
versionArgument="--userversion ${{ needs.BumpTag.outputs.tag_name }}"
./tools/butler push \
"Windows.zip" \
${{ env.ITCHIO_USERNAME }}/${{ env.ITCHIO_GAMEID }}:windows ${versionArgument}
# - name: Setup Butler
# shell: bash
# env:
# BUTLER_API_KEY: ${{ secrets.BUTLER_TOKEN }}
# run: |
# mkdir ./tools 2>/dev/null || true
# pushd tools
# curl -sSLfo ./butler.zip "https://broth.itch.zone/butler/linux-amd64/LATEST/archive/default"
# unzip butler.zip
# chmod +x ./butler
# popd
# ./tools/butler -V
#
# - name: Upload to itch.io
# shell: bash
# env:
# BUTLER_API_KEY: ${{ secrets.BUTLER_TOKEN }}
# run: |
# versionArgument="--userversion ${{ needs.BumpTag.outputs.tag_name }}"
# ./tools/butler push \
# "Windows.zip" \
# ${{ env.ITCHIO_USERNAME }}/${{ env.ITCHIO_GAMEID }}:windows ${versionArgument}

View File

@@ -55,10 +55,14 @@ jobs:
popd
./tools/butler -V
- name: Remove GDUnit addon
run: |
rm -rf ${{ gitea.workspace }}/addons/gdUnit4
- name: Build Windows
run: |
mkdir -v -p build/windows
godot --headless --verbose --build-solutions --export-release "Windows Desktop" build/windows/${{ env.GAME_NAME }}.exe
${{ steps.setup-godot.outputs.godot_bin }} --headless --verbose --build-solutions --export-release "Windows Desktop" build/windows/${{ env.GAME_NAME }}.exe
zip -r Windows.zip build/windows
- name: Upload Windows to itch.io
shell: bash
@@ -73,7 +77,7 @@ jobs:
- name: Build Windows ARM
run: |
mkdir -v -p build/windowsArm
godot --headless --verbose --build-solutions --export-release "Windows ARM" build/windowsArm/${{ env.GAME_NAME }}.exe
${{ steps.setup-godot.outputs.godot_bin }} --headless --verbose --build-solutions --export-release "Windows ARM" build/windowsArm/${{ env.GAME_NAME }}.exe
zip -r WindowsArm.zip build/windowsArm
- name: Upload Windows to itch.io
shell: bash
@@ -88,7 +92,7 @@ jobs:
- name: Linux Build
run: |
mkdir -v -p build/linux
godot --headless --verbose --export-release "Linux/X11" build/linux/${{ env.GAME_NAME }}.x86_64
${{ steps.setup-godot.outputs.godot_bin }} --headless --verbose --export-release "Linux/X11" build/linux/${{ env.GAME_NAME }}.x86_64
zip -r Linux.zip build/linux
- name: Upload Windows to itch.io
shell: bash
@@ -103,7 +107,7 @@ jobs:
- name: Mac Build
run: |
mkdir -v -p build/mac
godot --headless --verbose --export-release "macOS" build/mac/${{ env.GAME_NAME }}.zip
${{ steps.setup-godot.outputs.godot_bin }} --headless --verbose --export-release "macOS" build/mac/${{ env.GAME_NAME }}.zip
zip -r Mac.zip build/mac
- name: Upload Windows to itch.io
shell: bash

2
.gitignore vendored
View File

@@ -14,3 +14,5 @@
# Imported translations (automatically generated from CSV files)
*.translation
.output.txt

View File

@@ -6,9 +6,6 @@
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<TestSessionTimeout>180000</TestSessionTimeout>
<TreatNoTestsAsError>true</TreatNoTestsAsError>
<EnvironmentVariables>
<GODOT_BIN>d:\development\Godot_v4.5-stable_mono_win64\Godot_v4.5-stable_mono_win64.exe</GODOT_BIN>
</EnvironmentVariables>
</RunConfiguration>
<LoggerRunSettings>

View File

@@ -5,139 +5,153 @@
<RootNamespace>Movementtests</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Content Include=".runsettings"/>
<Content Include="export_presets.cfg"/>
<Content Include="menus\assets\git_logo\Git-Logo-2Color.png"/>
<Content Include="menus\assets\git_logo\Git-Logo-2Color.png.import"/>
<Content Include="menus\assets\git_logo\LICENSE.txt"/>
<Content Include="menus\assets\godot_engine_logo\LICENSE.txt"/>
<Content Include="menus\assets\godot_engine_logo\logo_vertical_color_dark.png"/>
<Content Include="menus\assets\godot_engine_logo\logo_vertical_color_dark.png.import"/>
<Content Include="menus\assets\icon.png"/>
<Content Include="menus\assets\icon.png.import"/>
<Content Include="menus\ATTRIBUTION.md"/>
<Content Include="menus\resources\themes\expedition.tres"/>
<Content Include="menus\resources\themes\gravity.tres"/>
<Content Include="menus\resources\themes\grow.tres"/>
<Content Include="menus\resources\themes\lab.tres"/>
<Content Include="menus\resources\themes\lore.tres"/>
<Content Include="menus\resources\themes\steal_this_theme.tres"/>
<Content Include="menus\scenes\credits\scrollable_credits.gd"/>
<Content Include="menus\scenes\credits\scrollable_credits.gd.uid"/>
<Content Include="menus\scenes\credits\scrollable_credits.tscn"/>
<Content Include="menus\scenes\credits\scrolling_credits.gd"/>
<Content Include="menus\scenes\credits\scrolling_credits.gd.uid"/>
<Content Include="menus\scenes\credits\scrolling_credits.tscn"/>
<Content Include="menus\scenes\end_credits\end_credits.gd"/>
<Content Include="menus\scenes\end_credits\end_credits.gd.uid"/>
<Content Include="menus\scenes\end_credits\end_credits.tscn"/>
<Content Include="menus\scenes\game_scene\configurable_sub_viewport.gd"/>
<Content Include="menus\scenes\game_scene\configurable_sub_viewport.gd.uid"/>
<Content Include="menus\scenes\game_scene\game_ui.tscn"/>
<Content Include="menus\scenes\game_scene\input_display_label.gd"/>
<Content Include="menus\scenes\game_scene\input_display_label.gd.uid"/>
<Content Include="menus\scenes\game_scene\levels\level.gd"/>
<Content Include="menus\scenes\game_scene\levels\level.gd.uid"/>
<Content Include="menus\scenes\game_scene\levels\level_1.tscn"/>
<Content Include="menus\scenes\game_scene\levels\level_2.tscn"/>
<Content Include="menus\scenes\game_scene\levels\level_3.tscn"/>
<Content Include="menus\scenes\game_scene\tutorials\tutorial_1.tscn"/>
<Content Include="menus\scenes\game_scene\tutorials\tutorial_2.tscn"/>
<Content Include="menus\scenes\game_scene\tutorials\tutorial_3.tscn"/>
<Content Include="menus\scenes\game_scene\tutorial_manager.gd"/>
<Content Include="menus\scenes\game_scene\tutorial_manager.gd.uid"/>
<Content Include="menus\scenes\loading_screen\level_loading_screen.tscn"/>
<Content Include="menus\scenes\loading_screen\loading_screen.gd"/>
<Content Include="menus\scenes\loading_screen\loading_screen.gd.uid"/>
<Content Include="menus\scenes\loading_screen\loading_screen.tscn"/>
<Content Include="menus\scenes\loading_screen\loading_screen_with_shader_caching.gd"/>
<Content Include="menus\scenes\loading_screen\loading_screen_with_shader_caching.gd.uid"/>
<Content Include="menus\scenes\loading_screen\loading_screen_with_shader_caching.tscn"/>
<Content Include="menus\scenes\menus\level_select_menu\level_select_menu.gd"/>
<Content Include="menus\scenes\menus\level_select_menu\level_select_menu.gd.uid"/>
<Content Include="menus\scenes\menus\level_select_menu\level_select_menu.tscn"/>
<Content Include="menus\scenes\menus\main_menu\main_menu.gd"/>
<Content Include="menus\scenes\menus\main_menu\main_menu.gd.uid"/>
<Content Include="menus\scenes\menus\main_menu\main_menu.tscn"/>
<Content Include="menus\scenes\menus\main_menu\main_menu_with_animations.gd"/>
<Content Include="menus\scenes\menus\main_menu\main_menu_with_animations.gd.uid"/>
<Content Include="menus\scenes\menus\main_menu\main_menu_with_animations.tscn"/>
<Content Include="menus\scenes\menus\options_menu\audio\audio_input_option_control.gd"/>
<Content Include="menus\scenes\menus\options_menu\audio\audio_input_option_control.gd.uid"/>
<Content Include="menus\scenes\menus\options_menu\audio\audio_input_option_control.tscn"/>
<Content Include="menus\scenes\menus\options_menu\audio\audio_options_menu.gd"/>
<Content Include="menus\scenes\menus\options_menu\audio\audio_options_menu.gd.uid"/>
<Content Include="menus\scenes\menus\options_menu\audio\audio_options_menu.tscn"/>
<Content Include="menus\scenes\menus\options_menu\game\game_options_menu.gd"/>
<Content Include="menus\scenes\menus\options_menu\game\game_options_menu.gd.uid"/>
<Content Include="menus\scenes\menus\options_menu\game\game_options_menu.tscn"/>
<Content Include="menus\scenes\menus\options_menu\game\reset_game_control\reset_game_control.gd"/>
<Content Include="menus\scenes\menus\options_menu\game\reset_game_control\reset_game_control.gd.uid"/>
<Content Include="menus\scenes\menus\options_menu\game\reset_game_control\reset_game_control.tscn"/>
<Content Include="menus\scenes\menus\options_menu\input\input_extras_menu.tscn"/>
<Content Include="menus\scenes\menus\options_menu\input\input_options_menu.gd"/>
<Content Include="menus\scenes\menus\options_menu\input\input_options_menu.gd.uid"/>
<Content Include="menus\scenes\menus\options_menu\input\input_options_menu.tscn"/>
<Content Include="menus\scenes\menus\options_menu\input\input_options_menu_with_mouse_sensitivity.tscn"/>
<Content Include="menus\scenes\menus\options_menu\master_options_menu.gd"/>
<Content Include="menus\scenes\menus\options_menu\master_options_menu.gd.uid"/>
<Content Include="menus\scenes\menus\options_menu\master_options_menu.tscn"/>
<Content Include="menus\scenes\menus\options_menu\master_options_menu_with_tabs.tscn"/>
<Content Include="menus\scenes\menus\options_menu\mini_options_menu.gd"/>
<Content Include="menus\scenes\menus\options_menu\mini_options_menu.gd.uid"/>
<Content Include="menus\scenes\menus\options_menu\mini_options_menu.tscn"/>
<Content Include="menus\scenes\menus\options_menu\mini_options_menu_with_reset.gd"/>
<Content Include="menus\scenes\menus\options_menu\mini_options_menu_with_reset.gd.uid"/>
<Content Include="menus\scenes\menus\options_menu\mini_options_menu_with_reset.tscn"/>
<Content Include="menus\scenes\menus\options_menu\video\video_options_menu.gd"/>
<Content Include="menus\scenes\menus\options_menu\video\video_options_menu.gd.uid"/>
<Content Include="menus\scenes\menus\options_menu\video\video_options_menu.tscn"/>
<Content Include="menus\scenes\menus\options_menu\video\video_options_menu_with_extras.tscn"/>
<Content Include="menus\scenes\opening\opening.gd"/>
<Content Include="menus\scenes\opening\opening.gd.uid"/>
<Content Include="menus\scenes\opening\opening.tscn"/>
<Content Include="menus\scenes\opening\opening_with_logo.tscn"/>
<Content Include="menus\scenes\overlaid_menus\game_won_menu.gd"/>
<Content Include="menus\scenes\overlaid_menus\game_won_menu.gd.uid"/>
<Content Include="menus\scenes\overlaid_menus\game_won_menu.tscn"/>
<Content Include="menus\scenes\overlaid_menus\level_lost_menu.gd"/>
<Content Include="menus\scenes\overlaid_menus\level_lost_menu.gd.uid"/>
<Content Include="menus\scenes\overlaid_menus\level_lost_menu.tscn"/>
<Content Include="menus\scenes\overlaid_menus\level_won_menu.gd"/>
<Content Include="menus\scenes\overlaid_menus\level_won_menu.gd.uid"/>
<Content Include="menus\scenes\overlaid_menus\level_won_menu.tscn"/>
<Content Include="menus\scenes\overlaid_menus\mini_options_overlaid_menu.tscn"/>
<Content Include="menus\scenes\overlaid_menus\overlaid_menu.gd"/>
<Content Include="menus\scenes\overlaid_menus\overlaid_menu.gd.uid"/>
<Content Include="menus\scenes\overlaid_menus\overlaid_menu.tscn"/>
<Content Include="menus\scenes\overlaid_menus\overlaid_menu_container.gd"/>
<Content Include="menus\scenes\overlaid_menus\overlaid_menu_container.gd.uid"/>
<Content Include="menus\scenes\overlaid_menus\overlaid_menu_container.tscn"/>
<Content Include="menus\scenes\overlaid_menus\pause_menu.gd"/>
<Content Include="menus\scenes\overlaid_menus\pause_menu.gd.uid"/>
<Content Include="menus\scenes\overlaid_menus\pause_menu.tscn"/>
<Content Include="menus\scripts\game_state.gd"/>
<Content Include="menus\scripts\game_state.gd.uid"/>
<Content Include="menus\scripts\level_list_and_state_manager.gd"/>
<Content Include="menus\scripts\level_list_and_state_manager.gd.uid"/>
<Content Include="menus\scripts\level_state.gd"/>
<Content Include="menus\scripts\level_state.gd.uid"/>
<Content Include=".runsettings" />
<Content Include="export_presets.cfg" />
<Content Include="menus\assets\git_logo\Git-Logo-2Color.png" />
<Content Include="menus\assets\git_logo\Git-Logo-2Color.png.import" />
<Content Include="menus\assets\git_logo\LICENSE.txt" />
<Content Include="menus\assets\godot_engine_logo\LICENSE.txt" />
<Content Include="menus\assets\godot_engine_logo\logo_vertical_color_dark.png" />
<Content Include="menus\assets\godot_engine_logo\logo_vertical_color_dark.png.import" />
<Content Include="menus\assets\icon.png" />
<Content Include="menus\assets\icon.png.import" />
<Content Include="menus\ATTRIBUTION.md" />
<Content Include="menus\resources\themes\expedition.tres" />
<Content Include="menus\resources\themes\gravity.tres" />
<Content Include="menus\resources\themes\grow.tres" />
<Content Include="menus\resources\themes\lab.tres" />
<Content Include="menus\resources\themes\lore.tres" />
<Content Include="menus\resources\themes\steal_this_theme.tres" />
<Content Include="menus\scenes\credits\scrollable_credits.gd" />
<Content Include="menus\scenes\credits\scrollable_credits.gd.uid" />
<Content Include="menus\scenes\credits\scrollable_credits.tscn" />
<Content Include="menus\scenes\credits\scrolling_credits.gd" />
<Content Include="menus\scenes\credits\scrolling_credits.gd.uid" />
<Content Include="menus\scenes\credits\scrolling_credits.tscn" />
<Content Include="menus\scenes\end_credits\end_credits.gd" />
<Content Include="menus\scenes\end_credits\end_credits.gd.uid" />
<Content Include="menus\scenes\end_credits\end_credits.tscn" />
<Content Include="menus\scenes\game_scene\configurable_sub_viewport.gd" />
<Content Include="menus\scenes\game_scene\configurable_sub_viewport.gd.uid" />
<Content Include="menus\scenes\game_scene\game_ui.tscn" />
<Content Include="menus\scenes\game_scene\input_display_label.gd" />
<Content Include="menus\scenes\game_scene\input_display_label.gd.uid" />
<Content Include="menus\scenes\game_scene\levels\level.gd" />
<Content Include="menus\scenes\game_scene\levels\level.gd.uid" />
<Content Include="menus\scenes\game_scene\levels\level_1.tscn" />
<Content Include="menus\scenes\game_scene\levels\level_2.tscn" />
<Content Include="menus\scenes\game_scene\levels\level_3.tscn" />
<Content Include="menus\scenes\game_scene\tutorials\tutorial_1.tscn" />
<Content Include="menus\scenes\game_scene\tutorials\tutorial_2.tscn" />
<Content Include="menus\scenes\game_scene\tutorials\tutorial_3.tscn" />
<Content Include="menus\scenes\game_scene\tutorial_manager.gd" />
<Content Include="menus\scenes\game_scene\tutorial_manager.gd.uid" />
<Content Include="menus\scenes\loading_screen\level_loading_screen.tscn" />
<Content Include="menus\scenes\loading_screen\loading_screen.gd" />
<Content Include="menus\scenes\loading_screen\loading_screen.gd.uid" />
<Content Include="menus\scenes\loading_screen\loading_screen.tscn" />
<Content Include="menus\scenes\loading_screen\loading_screen_with_shader_caching.gd" />
<Content Include="menus\scenes\loading_screen\loading_screen_with_shader_caching.gd.uid" />
<Content Include="menus\scenes\loading_screen\loading_screen_with_shader_caching.tscn" />
<Content Include="menus\scenes\menus\level_select_menu\level_select_menu.gd" />
<Content Include="menus\scenes\menus\level_select_menu\level_select_menu.gd.uid" />
<Content Include="menus\scenes\menus\level_select_menu\level_select_menu.tscn" />
<Content Include="menus\scenes\menus\main_menu\main_menu.gd" />
<Content Include="menus\scenes\menus\main_menu\main_menu.gd.uid" />
<Content Include="menus\scenes\menus\main_menu\main_menu.tscn" />
<Content Include="menus\scenes\menus\main_menu\main_menu_with_animations.gd" />
<Content Include="menus\scenes\menus\main_menu\main_menu_with_animations.gd.uid" />
<Content Include="menus\scenes\menus\main_menu\main_menu_with_animations.tscn" />
<Content Include="menus\scenes\menus\options_menu\audio\audio_input_option_control.gd" />
<Content Include="menus\scenes\menus\options_menu\audio\audio_input_option_control.gd.uid" />
<Content Include="menus\scenes\menus\options_menu\audio\audio_input_option_control.tscn" />
<Content Include="menus\scenes\menus\options_menu\audio\audio_options_menu.gd" />
<Content Include="menus\scenes\menus\options_menu\audio\audio_options_menu.gd.uid" />
<Content Include="menus\scenes\menus\options_menu\audio\audio_options_menu.tscn" />
<Content Include="menus\scenes\menus\options_menu\game\game_options_menu.gd" />
<Content Include="menus\scenes\menus\options_menu\game\game_options_menu.gd.uid" />
<Content Include="menus\scenes\menus\options_menu\game\game_options_menu.tscn" />
<Content Include="menus\scenes\menus\options_menu\game\reset_game_control\reset_game_control.gd" />
<Content Include="menus\scenes\menus\options_menu\game\reset_game_control\reset_game_control.gd.uid" />
<Content Include="menus\scenes\menus\options_menu\game\reset_game_control\reset_game_control.tscn" />
<Content Include="menus\scenes\menus\options_menu\input\input_extras_menu.tscn" />
<Content Include="menus\scenes\menus\options_menu\input\input_options_menu.gd" />
<Content Include="menus\scenes\menus\options_menu\input\input_options_menu.gd.uid" />
<Content Include="menus\scenes\menus\options_menu\input\input_options_menu.tscn" />
<Content Include="menus\scenes\menus\options_menu\input\input_options_menu_with_mouse_sensitivity.tscn" />
<Content Include="menus\scenes\menus\options_menu\master_options_menu.gd" />
<Content Include="menus\scenes\menus\options_menu\master_options_menu.gd.uid" />
<Content Include="menus\scenes\menus\options_menu\master_options_menu.tscn" />
<Content Include="menus\scenes\menus\options_menu\master_options_menu_with_tabs.tscn" />
<Content Include="menus\scenes\menus\options_menu\mini_options_menu.gd" />
<Content Include="menus\scenes\menus\options_menu\mini_options_menu.gd.uid" />
<Content Include="menus\scenes\menus\options_menu\mini_options_menu.tscn" />
<Content Include="menus\scenes\menus\options_menu\mini_options_menu_with_reset.gd" />
<Content Include="menus\scenes\menus\options_menu\mini_options_menu_with_reset.gd.uid" />
<Content Include="menus\scenes\menus\options_menu\mini_options_menu_with_reset.tscn" />
<Content Include="menus\scenes\menus\options_menu\video\video_options_menu.gd" />
<Content Include="menus\scenes\menus\options_menu\video\video_options_menu.gd.uid" />
<Content Include="menus\scenes\menus\options_menu\video\video_options_menu.tscn" />
<Content Include="menus\scenes\menus\options_menu\video\video_options_menu_with_extras.tscn" />
<Content Include="menus\scenes\opening\opening.gd" />
<Content Include="menus\scenes\opening\opening.gd.uid" />
<Content Include="menus\scenes\opening\opening.tscn" />
<Content Include="menus\scenes\opening\opening_with_logo.tscn" />
<Content Include="menus\scenes\overlaid_menus\game_won_menu.gd" />
<Content Include="menus\scenes\overlaid_menus\game_won_menu.gd.uid" />
<Content Include="menus\scenes\overlaid_menus\game_won_menu.tscn" />
<Content Include="menus\scenes\overlaid_menus\level_lost_menu.gd" />
<Content Include="menus\scenes\overlaid_menus\level_lost_menu.gd.uid" />
<Content Include="menus\scenes\overlaid_menus\level_lost_menu.tscn" />
<Content Include="menus\scenes\overlaid_menus\level_won_menu.gd" />
<Content Include="menus\scenes\overlaid_menus\level_won_menu.gd.uid" />
<Content Include="menus\scenes\overlaid_menus\level_won_menu.tscn" />
<Content Include="menus\scenes\overlaid_menus\mini_options_overlaid_menu.tscn" />
<Content Include="menus\scenes\overlaid_menus\overlaid_menu.gd" />
<Content Include="menus\scenes\overlaid_menus\overlaid_menu.gd.uid" />
<Content Include="menus\scenes\overlaid_menus\overlaid_menu.tscn" />
<Content Include="menus\scenes\overlaid_menus\overlaid_menu_container.gd" />
<Content Include="menus\scenes\overlaid_menus\overlaid_menu_container.gd.uid" />
<Content Include="menus\scenes\overlaid_menus\overlaid_menu_container.tscn" />
<Content Include="menus\scenes\overlaid_menus\pause_menu.gd" />
<Content Include="menus\scenes\overlaid_menus\pause_menu.gd.uid" />
<Content Include="menus\scenes\overlaid_menus\pause_menu.tscn" />
<Content Include="menus\scripts\game_state.gd" />
<Content Include="menus\scripts\game_state.gd.uid" />
<Content Include="menus\scripts\level_list_and_state_manager.gd" />
<Content Include="menus\scripts\level_list_and_state_manager.gd.uid" />
<Content Include="menus\scripts\level_state.gd" />
<Content Include="menus\scripts\level_state.gd.uid" />
</ItemGroup>
<ItemGroup>
<Folder Include="addons\"/>
<Folder Include="addons\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="RustyOptions" Version="0.10.1"/>
<PackageReference Include="RustyOptions" Version="0.10.1" />
</ItemGroup>
<Import Project="addons/forge/Forge.props" />
<!-- XUnit -->
<ItemGroup>
<Content Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="xunit.v3.mtp-v2" Version="3.2.2" />
</ItemGroup>
<!-- gdUnit4 package dependencies -->
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.0"/>
<PackageReference Include="gdUnit4.api" Version="5.1.0-rc3"/>
<PackageReference Include="gdUnit4.test.adapter" Version="3.0.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.0" />
<PackageReference Include="gdUnit4.api" Version="5.1.0-rc3" />
<PackageReference Include="gdUnit4.test.adapter" Version="3.0.0" />
<PackageReference Include="gdUnit4.analyzers" Version="1.0.0">
<PrivateAssets>none</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<Import Project="addons/forge/Forge.props"/>
</Project>

View File

@@ -5,6 +5,7 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANode_002Ecs_002Fl_003AC_0021_003FUsers_003FMinimata_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F716d154fef5cbe863cd637bd32beda6e3cec5f12e8fed2dc5b2d8149a0d558ab_003FNode_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANode_002Ecs_002Fl_003AC_0021_003FUsers_003FMinimata_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fdf73a4db74df89d59655c5fb6326406f47fbfa9af1fa81518fe0a07c49d34133_003FNode_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASceneTree_002Ecs_002Fl_003AC_0021_003FUsers_003FMinimata_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F8d6960554e939a669841b1ece03d27df4ab42f92bb80be3767eaec8cdaccf84b_003FSceneTree_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=dd9a7ac6_002Dbb9b_002D4001_002Db145_002D15e6509b7e78/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from Solution" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;
&lt;Solution /&gt;&#xD;
&lt;/SessionState&gt;</s:String>

View File

@@ -13,22 +13,27 @@ public partial class CueHandlerInspectorPlugin : EditorInspectorPlugin
public override bool _CanHandle(GodotObject @object)
{
// Find out if its an implementation of CueHandler without having to add [Tool] attribute to them.
if (@object?.GetScript().As<CSharpScript>() is CSharpScript script)
try
{
StringName className = script.GetGlobalName();
Type baseType = typeof(ForgeCueHandler);
System.Reflection.Assembly assembly = baseType.Assembly;
Type? implementationType =
Array.Find(assembly.GetTypes(), x =>
x.Name == className &&
baseType.IsAssignableFrom(x));
return implementationType is not null;
if (@object.GetScript().As<CSharpScript>() is not { }) return false;
}
catch (Exception e)
{
return false;
}
return false;
var script = @object.GetScript().As<CSharpScript>();
StringName className = script.GetGlobalName();
Type baseType = typeof(ForgeCueHandler);
System.Reflection.Assembly assembly = baseType.Assembly;
Type? implementationType =
Array.Find(assembly.GetTypes(), x =>
x.Name == className &&
baseType.IsAssignableFrom(x));
return implementationType is not null;
}
public override bool _ParseProperty(

28
agents.md Normal file
View File

@@ -0,0 +1,28 @@
### Project Overview: Godot C# Movement Tests
This project is a high-performance 3D character controller for Godot 4.x using C# 13 and .NET 9. It focuses on modular movement systems (Dash, Mantle, Stairs) and robust combat mechanics (Damage, Health, Knockback) decoupled through interfaces.
### Core Architecture
- **Modular Systems**: The `PlayerController.cs` acts as a central hub for multiple specialized "Systems" (e.g., `DashSystem`, `MantleSystem`, `HeadSystem`, `StairsSystem`).
- **State Management**: Uses `GodotStateCharts` for complex movement and action states. Look for state transitions and triggers within the system scripts.
- **Interface-Driven Design**: Located in `/interfaces/`, these define how objects interact (e.g., `IDamageable`, `IHealthable`, `IKnockbackable`). Always implement these interfaces for new interactable entities.
- **Node Composition**: Most systems are attached to the `PlayerController` scene as child nodes and initialized via their respective `Init()` methods or exported fields.
### Key Directories
- `/scenes/player_controller/`: Contains the main player scene, the central `PlayerController.cs`, and its sub-systems.
- `/scenes/player_controller/components/`: Modular logic for specific features like Dash, Mantle, and Weapons.
- `/interfaces/`: Core C# interfaces and shared records (e.g., `DamageRecord`, `HealthChangedRecord`).
- `/tests/`: Automated unit and integration tests using `GdUnit4` and `xUnit`.
### Coding Standards & Idioms
- **C# 13 & .NET 9**: Use modern C# features (records, primary constructors, collection expressions).
- **Godot Partial Classes**: All Godot scripts must be `partial` and use `[GlobalClass]` where appropriate for editor visibility.
- **RustyOptions**: The project uses `RustyOptions` for safer null handling and result types (`Option<T>`, `Result<T, E>`).
- **Signals**: Use `[Signal]` and the `EventHandler` pattern for Godot signals.
- **Dependency Injection**: Systems are typically assigned to fields in `PlayerController` via the editor or `GetNode<T>()` in `_Ready()`.
### LLM Interaction Tips
1. **Partial Classes**: When suggesting changes to `PlayerController.cs` or systems, remember they are `partial`. Large files like `PlayerController.cs` (2500+ lines) are often split or contain many regions.
2. **Node Hierarchy**: Always check `PlayerController.tscn` or system scenes (`head_system.tscn`) when dealing with node references (`GetNode`).
3. **GdUnit4**: For testing, follow the pattern in `tests/PlayerMovementTest.cs`. Use `ISceneRunner` to simulate inputs and await frames/milliseconds.
4. **Vector Operations**: Use Godot's built-in `Vector3` methods for movement logic. The project often uses `GlobalPosition` and `DirectionTo`.
5. **Boilerplate**: When creating new systems, mirror the `Init()` and `_PhysicsProcess` patterns found in existing systems like `DashSystem.cs` or `MantleSystem.cs`.

View File

@@ -3,19 +3,21 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://crw70luu8rge"
path="res://.godot/imported/keyboard_arrows_up_outline.svg-aafaf4b2d7e165925a5a6f57129acf05.ctex"
path.s3tc="res://.godot/imported/keyboard_arrows_up_outline.svg-aafaf4b2d7e165925a5a6f57129acf05.s3tc.ctex"
path.etc2="res://.godot/imported/keyboard_arrows_up_outline.svg-aafaf4b2d7e165925a5a6f57129acf05.etc2.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/ui/input-prompts/Keyboard & Mouse/Vector/keyboard_arrows_up_outline.svg"
dest_files=["res://.godot/imported/keyboard_arrows_up_outline.svg-aafaf4b2d7e165925a5a6f57129acf05.ctex"]
dest_files=["res://.godot/imported/keyboard_arrows_up_outline.svg-aafaf4b2d7e165925a5a6f57129acf05.s3tc.ctex", "res://.godot/imported/keyboard_arrows_up_outline.svg-aafaf4b2d7e165925a5a6f57129acf05.etc2.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +25,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +39,7 @@ 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
detect_3d/compress_to=0
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -3,19 +3,21 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://cseyilgg2iwnk"
path="res://.godot/imported/keyboard_ctrl_outline.svg-4cd77d73fedb6d8a91f633c33a63524c.ctex"
path.s3tc="res://.godot/imported/keyboard_ctrl_outline.svg-4cd77d73fedb6d8a91f633c33a63524c.s3tc.ctex"
path.etc2="res://.godot/imported/keyboard_ctrl_outline.svg-4cd77d73fedb6d8a91f633c33a63524c.etc2.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/ui/input-prompts/Keyboard & Mouse/Vector/keyboard_ctrl_outline.svg"
dest_files=["res://.godot/imported/keyboard_ctrl_outline.svg-4cd77d73fedb6d8a91f633c33a63524c.ctex"]
dest_files=["res://.godot/imported/keyboard_ctrl_outline.svg-4cd77d73fedb6d8a91f633c33a63524c.s3tc.ctex", "res://.godot/imported/keyboard_ctrl_outline.svg-4cd77d73fedb6d8a91f633c33a63524c.etc2.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +25,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +39,7 @@ 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
detect_3d/compress_to=0
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -3,19 +3,21 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://ybwqghk70io"
path="res://.godot/imported/keyboard_f_outline.svg-b058b2f7ef3b61453846db2e3d1f7f04.ctex"
path.s3tc="res://.godot/imported/keyboard_f_outline.svg-b058b2f7ef3b61453846db2e3d1f7f04.s3tc.ctex"
path.etc2="res://.godot/imported/keyboard_f_outline.svg-b058b2f7ef3b61453846db2e3d1f7f04.etc2.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/ui/input-prompts/Keyboard & Mouse/Vector/keyboard_f_outline.svg"
dest_files=["res://.godot/imported/keyboard_f_outline.svg-b058b2f7ef3b61453846db2e3d1f7f04.ctex"]
dest_files=["res://.godot/imported/keyboard_f_outline.svg-b058b2f7ef3b61453846db2e3d1f7f04.s3tc.ctex", "res://.godot/imported/keyboard_f_outline.svg-b058b2f7ef3b61453846db2e3d1f7f04.etc2.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +25,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +39,7 @@ 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
detect_3d/compress_to=0
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -3,19 +3,21 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://bsxtadecl3657"
path="res://.godot/imported/keyboard_shift_outline.svg-b2954174b97e4b2e82a8cdd72f79d4d5.ctex"
path.s3tc="res://.godot/imported/keyboard_shift_outline.svg-b2954174b97e4b2e82a8cdd72f79d4d5.s3tc.ctex"
path.etc2="res://.godot/imported/keyboard_shift_outline.svg-b2954174b97e4b2e82a8cdd72f79d4d5.etc2.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/ui/input-prompts/Keyboard & Mouse/Vector/keyboard_shift_outline.svg"
dest_files=["res://.godot/imported/keyboard_shift_outline.svg-b2954174b97e4b2e82a8cdd72f79d4d5.ctex"]
dest_files=["res://.godot/imported/keyboard_shift_outline.svg-b2954174b97e4b2e82a8cdd72f79d4d5.s3tc.ctex", "res://.godot/imported/keyboard_shift_outline.svg-b2954174b97e4b2e82a8cdd72f79d4d5.etc2.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +25,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +39,7 @@ 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
detect_3d/compress_to=0
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -3,19 +3,21 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://b1rhan716dxw0"
path="res://.godot/imported/keyboard_space_outline.svg-53ff196166ac0ee9f4b558e0b10199b9.ctex"
path.s3tc="res://.godot/imported/keyboard_space_outline.svg-53ff196166ac0ee9f4b558e0b10199b9.s3tc.ctex"
path.etc2="res://.godot/imported/keyboard_space_outline.svg-53ff196166ac0ee9f4b558e0b10199b9.etc2.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/ui/input-prompts/Keyboard & Mouse/Vector/keyboard_space_outline.svg"
dest_files=["res://.godot/imported/keyboard_space_outline.svg-53ff196166ac0ee9f4b558e0b10199b9.ctex"]
dest_files=["res://.godot/imported/keyboard_space_outline.svg-53ff196166ac0ee9f4b558e0b10199b9.s3tc.ctex", "res://.godot/imported/keyboard_space_outline.svg-53ff196166ac0ee9f4b558e0b10199b9.etc2.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +25,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +39,7 @@ 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
detect_3d/compress_to=0
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -3,19 +3,21 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://bhlrmh5v3fa2n"
path="res://.godot/imported/mouse_left_outline.svg-82caa661d58d820c50e229162b6f0b05.ctex"
path.s3tc="res://.godot/imported/mouse_left_outline.svg-82caa661d58d820c50e229162b6f0b05.s3tc.ctex"
path.etc2="res://.godot/imported/mouse_left_outline.svg-82caa661d58d820c50e229162b6f0b05.etc2.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/ui/input-prompts/Keyboard & Mouse/Vector/mouse_left_outline.svg"
dest_files=["res://.godot/imported/mouse_left_outline.svg-82caa661d58d820c50e229162b6f0b05.ctex"]
dest_files=["res://.godot/imported/mouse_left_outline.svg-82caa661d58d820c50e229162b6f0b05.s3tc.ctex", "res://.godot/imported/mouse_left_outline.svg-82caa661d58d820c50e229162b6f0b05.etc2.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +25,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +39,7 @@ 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
detect_3d/compress_to=0
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -3,19 +3,21 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://dlt8uv1mtq4a0"
path="res://.godot/imported/mouse_right.svg-66cb44804e2971b729668b5953fcbd42.ctex"
path.s3tc="res://.godot/imported/mouse_right.svg-66cb44804e2971b729668b5953fcbd42.s3tc.ctex"
path.etc2="res://.godot/imported/mouse_right.svg-66cb44804e2971b729668b5953fcbd42.etc2.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/ui/input-prompts/Keyboard & Mouse/Vector/mouse_right.svg"
dest_files=["res://.godot/imported/mouse_right.svg-66cb44804e2971b729668b5953fcbd42.ctex"]
dest_files=["res://.godot/imported/mouse_right.svg-66cb44804e2971b729668b5953fcbd42.s3tc.ctex", "res://.godot/imported/mouse_right.svg-66cb44804e2971b729668b5953fcbd42.etc2.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +25,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +39,7 @@ 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
detect_3d/compress_to=0
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -3,19 +3,21 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://dx2mk8qd6g8uh"
path="res://.godot/imported/mouse_right_outline.svg-054f7e0a0342193a0b801bac0edb20cf.ctex"
path.s3tc="res://.godot/imported/mouse_right_outline.svg-054f7e0a0342193a0b801bac0edb20cf.s3tc.ctex"
path.etc2="res://.godot/imported/mouse_right_outline.svg-054f7e0a0342193a0b801bac0edb20cf.etc2.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/ui/input-prompts/Keyboard & Mouse/Vector/mouse_right_outline.svg"
dest_files=["res://.godot/imported/mouse_right_outline.svg-054f7e0a0342193a0b801bac0edb20cf.ctex"]
dest_files=["res://.godot/imported/mouse_right_outline.svg-054f7e0a0342193a0b801bac0edb20cf.s3tc.ctex", "res://.godot/imported/mouse_right_outline.svg-054f7e0a0342193a0b801bac0edb20cf.etc2.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +25,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +39,7 @@ 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
detect_3d/compress_to=0
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -3,19 +3,21 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://cywwtfvguv5e6"
path="res://.godot/imported/xbox_button_back_icon_outline.svg-2773343c084e1613d54e400e515d6edb.ctex"
path.s3tc="res://.godot/imported/xbox_button_back_icon_outline.svg-2773343c084e1613d54e400e515d6edb.s3tc.ctex"
path.etc2="res://.godot/imported/xbox_button_back_icon_outline.svg-2773343c084e1613d54e400e515d6edb.etc2.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/ui/input-prompts/Xbox Series/Vector/xbox_button_back_icon_outline.svg"
dest_files=["res://.godot/imported/xbox_button_back_icon_outline.svg-2773343c084e1613d54e400e515d6edb.ctex"]
dest_files=["res://.godot/imported/xbox_button_back_icon_outline.svg-2773343c084e1613d54e400e515d6edb.s3tc.ctex", "res://.godot/imported/xbox_button_back_icon_outline.svg-2773343c084e1613d54e400e515d6edb.etc2.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +25,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +39,7 @@ 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
detect_3d/compress_to=0
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -3,19 +3,21 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://db6uqhcmcfs5t"
path="res://.godot/imported/xbox_lb_outline.svg-609923d5fb24f594348efed4ab529ec6.ctex"
path.s3tc="res://.godot/imported/xbox_lb_outline.svg-609923d5fb24f594348efed4ab529ec6.s3tc.ctex"
path.etc2="res://.godot/imported/xbox_lb_outline.svg-609923d5fb24f594348efed4ab529ec6.etc2.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/ui/input-prompts/Xbox Series/Vector/xbox_lb_outline.svg"
dest_files=["res://.godot/imported/xbox_lb_outline.svg-609923d5fb24f594348efed4ab529ec6.ctex"]
dest_files=["res://.godot/imported/xbox_lb_outline.svg-609923d5fb24f594348efed4ab529ec6.s3tc.ctex", "res://.godot/imported/xbox_lb_outline.svg-609923d5fb24f594348efed4ab529ec6.etc2.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +25,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +39,7 @@ 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
detect_3d/compress_to=0
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -3,19 +3,21 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://nrhxjdpuje3f"
path="res://.godot/imported/xbox_lt_outline.svg-7aebefa9684921bfb5211975ae57164f.ctex"
path.s3tc="res://.godot/imported/xbox_lt_outline.svg-7aebefa9684921bfb5211975ae57164f.s3tc.ctex"
path.etc2="res://.godot/imported/xbox_lt_outline.svg-7aebefa9684921bfb5211975ae57164f.etc2.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/ui/input-prompts/Xbox Series/Vector/xbox_lt_outline.svg"
dest_files=["res://.godot/imported/xbox_lt_outline.svg-7aebefa9684921bfb5211975ae57164f.ctex"]
dest_files=["res://.godot/imported/xbox_lt_outline.svg-7aebefa9684921bfb5211975ae57164f.s3tc.ctex", "res://.godot/imported/xbox_lt_outline.svg-7aebefa9684921bfb5211975ae57164f.etc2.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +25,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +39,7 @@ 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
detect_3d/compress_to=0
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -3,19 +3,21 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://dyjvbsvbriii4"
path="res://.godot/imported/xbox_rb_outline.svg-da022b434843043fffdf7deef5f634f4.ctex"
path.s3tc="res://.godot/imported/xbox_rb_outline.svg-da022b434843043fffdf7deef5f634f4.s3tc.ctex"
path.etc2="res://.godot/imported/xbox_rb_outline.svg-da022b434843043fffdf7deef5f634f4.etc2.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/ui/input-prompts/Xbox Series/Vector/xbox_rb_outline.svg"
dest_files=["res://.godot/imported/xbox_rb_outline.svg-da022b434843043fffdf7deef5f634f4.ctex"]
dest_files=["res://.godot/imported/xbox_rb_outline.svg-da022b434843043fffdf7deef5f634f4.s3tc.ctex", "res://.godot/imported/xbox_rb_outline.svg-da022b434843043fffdf7deef5f634f4.etc2.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +25,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +39,7 @@ 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
detect_3d/compress_to=0
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -3,19 +3,21 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://2h3y7dj0iwet"
path="res://.godot/imported/xbox_stick_l_up.svg-975fb97f7402ac676369ec43294b0bdd.ctex"
path.s3tc="res://.godot/imported/xbox_stick_l_up.svg-975fb97f7402ac676369ec43294b0bdd.s3tc.ctex"
path.etc2="res://.godot/imported/xbox_stick_l_up.svg-975fb97f7402ac676369ec43294b0bdd.etc2.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://assets/ui/input-prompts/Xbox Series/Vector/xbox_stick_l_up.svg"
dest_files=["res://.godot/imported/xbox_stick_l_up.svg-975fb97f7402ac676369ec43294b0bdd.ctex"]
dest_files=["res://.godot/imported/xbox_stick_l_up.svg-975fb97f7402ac676369ec43294b0bdd.s3tc.ctex", "res://.godot/imported/xbox_stick_l_up.svg-975fb97f7402ac676369ec43294b0bdd.etc2.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +25,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +39,7 @@ 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
detect_3d/compress_to=0
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,14 @@
// Copyright (c) 2025 Mike Schulze
// MIT License - See LICENSE file in the repository root for full license text
// ReSharper disable once CheckNamespace
namespace GdUnit4.TestRunner;
using Core.Runners;
/// <summary>
/// The GdUnit4Net test runner scene.
/// </summary>
public partial class GdUnit4TestRunnerScene : GdUnit4TestRunnerSceneCore
{
}

View File

@@ -0,0 +1 @@
uid://40hk5xnli78u

5
global.json Normal file
View File

@@ -0,0 +1,5 @@
{
"test": {
"runner": "Microsoft.Testing.Platform"
}
}

View File

@@ -35,6 +35,7 @@
[ext_resource type="Resource" uid="uid://spo3pbqjx0eb" path="res://inputs/base_mode/parry.tres" id="30_rvpjj"]
[ext_resource type="Resource" uid="uid://dxy0071ic1wdj" path="res://inputs/base_mode/slam.tres" id="32_s8kjn"]
[ext_resource type="Resource" uid="uid://s1l0n1iitc6m" path="res://inputs/base_mode/move_back.tres" id="33_fykw6"]
[ext_resource type="Script" uid="uid://c76fmncyucwqc" path="res://addons/guide/triggers/guide_trigger_tap.gd" id="34_2ienm"]
[ext_resource type="Resource" uid="uid://brswsknpgwal2" path="res://inputs/base_mode/move_front.tres" id="34_rvpjj"]
[ext_resource type="Resource" uid="uid://ca68r7n3bwba3" path="res://inputs/base_mode/toolbox.tres" id="34_s8kjn"]
[ext_resource type="Resource" uid="uid://f3vs6l4m623s" path="res://inputs/base_mode/move_left.tres" id="35_s8kjn"]
@@ -456,17 +457,17 @@ script = ExtResource("1_qmhk6")
action = ExtResource("32_s8kjn")
input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_v2ywt"), SubResource("Resource_s6d3g")])
[sub_resource type="Resource" id="Resource_s4bc4"]
[sub_resource type="Resource" id="Resource_vp8bw"]
script = ExtResource("30_cvxqo")
key = 4194305
[sub_resource type="Resource" id="Resource_3exnu"]
script = ExtResource("15_fykw6")
[sub_resource type="Resource" id="Resource_78qyx"]
script = ExtResource("34_2ienm")
[sub_resource type="Resource" id="Resource_ai85f"]
script = ExtResource("3_yp12v")
input = SubResource("Resource_s4bc4")
triggers = Array[ExtResource("8_2tfaw")]([SubResource("Resource_3exnu")])
input = SubResource("Resource_vp8bw")
triggers = Array[ExtResource("8_2tfaw")]([SubResource("Resource_78qyx")])
[sub_resource type="Resource" id="Resource_jjamb"]
script = ExtResource("19_qkgmj")
@@ -498,10 +499,22 @@ script = ExtResource("3_yp12v")
input = SubResource("Resource_8e1uk")
triggers = Array[ExtResource("8_2tfaw")]([SubResource("Resource_k8i2y")])
[sub_resource type="Resource" id="Resource_qrtf1"]
script = ExtResource("30_cvxqo")
key = 84
[sub_resource type="Resource" id="Resource_2ienm"]
script = ExtResource("15_fykw6")
[sub_resource type="Resource" id="Resource_4uwbh"]
script = ExtResource("3_yp12v")
input = SubResource("Resource_qrtf1")
triggers = Array[ExtResource("8_2tfaw")]([SubResource("Resource_2ienm")])
[sub_resource type="Resource" id="Resource_o5fur"]
script = ExtResource("1_qmhk6")
action = ExtResource("34_s8kjn")
input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_ilhhf")])
input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_ilhhf"), SubResource("Resource_4uwbh")])
[sub_resource type="Resource" id="Resource_kcylj"]
script = ExtResource("30_cvxqo")

View File

@@ -31,7 +31,7 @@ class_name InputController
@export var slam:GUIDEAction
signal input_device_changed(is_gamepad: bool)
var _using_gamepad = false
var current_input_method = GlobalHelpers.GamepadDetectionEvent.GAMEPAD
signal input_move(value: Vector3)
signal input_rotate_y(value: float)
@@ -74,6 +74,8 @@ func _ready() -> void:
dash.triggered.connect(on_input_dash)
slam.triggered.connect(on_input_slam)
input_device_changed.emit(current_input_method == GlobalHelpers.GamepadDetectionEvent.GAMEPAD)
func on_input_hit():
input_hit.emit()
@@ -103,20 +105,17 @@ func on_input_slide_started():
func on_input_slide_ended():
input_slide_ended.emit()
func _input(event: InputEvent) -> void:
if event is InputEventKey:
if _using_gamepad:
_using_gamepad = false
input_device_changed.emit(_using_gamepad)
elif event is InputEventJoypadMotion:
if !_using_gamepad:
if abs(event.axis_value) > 0.5:
_using_gamepad = true
input_device_changed.emit(_using_gamepad)
elif event is InputEventJoypadButton:
if !_using_gamepad:
_using_gamepad = true
input_device_changed.emit(_using_gamepad)
var event_gamepad = GlobalHelpers.is_event_gamepad(event)
if event_gamepad == GlobalHelpers.GamepadDetectionEvent.IRRELEVANT:
return
if current_input_method == event_gamepad:
return
current_input_method = event_gamepad
input_device_changed.emit(current_input_method == GlobalHelpers.GamepadDetectionEvent.GAMEPAD)
func _process(_delta: float) -> void:
var value_horizontal = -move_left.value_axis_1d + move_right.value_axis_1d

View File

@@ -7,7 +7,7 @@
[ext_resource type="Script" uid="uid://rvttn472ix6v" path="res://addons/guide/inputs/guide_input_joy_button.gd" id="4_q6ncx"]
[ext_resource type="Script" uid="uid://bl8rjl4oaldje" path="res://addons/guide/modifiers/guide_modifier.gd" id="5_vnf02"]
[ext_resource type="Script" uid="uid://x74mnwgr08a7" path="res://addons/guide/triggers/guide_trigger.gd" id="6_c647i"]
[ext_resource type="Script" uid="uid://biiggjw6tv4uq" path="res://addons/guide/triggers/guide_trigger_released.gd" id="7_725x1"]
[ext_resource type="Script" uid="uid://c76fmncyucwqc" path="res://addons/guide/triggers/guide_trigger_tap.gd" id="7_725x1"]
[ext_resource type="Script" uid="uid://b52rqq28tuqpg" path="res://addons/guide/triggers/guide_trigger_pressed.gd" id="7_m88dc"]
[ext_resource type="Script" uid="uid://cw71o87tvdx3q" path="res://addons/guide/inputs/guide_input_key.gd" id="8_yfqfy"]
[ext_resource type="Resource" uid="uid://ds8quw8a7uh2u" path="res://inputs/menu_mode/select.tres" id="9_dsdj3"]

View File

@@ -0,0 +1,21 @@
extends Node3D
@onready var player_fell_respawn: Marker3D = $PlayerFellRespawn
@onready var animation_player: AnimationPlayer = $AnimationPlayer
var _player: Node3D
func _on_player_fell_tp_body_entered(body: Node3D) -> void:
_player = body
animation_player.play("player_fell")
func reset_player_position() -> void:
if _player == null:
return
_player.position = player_fell_respawn.position
func _on_death_plane_body_entered(body: Node3D) -> void:
body.queue_free()

View File

@@ -0,0 +1 @@
uid://beof168aw2acj

View File

@@ -1,5 +1,6 @@
[gd_scene format=3 uid="uid://55wehh6xombr"]
[ext_resource type="Script" uid="uid://beof168aw2acj" path="res://maps/_templates/main_scene_template.gd" id="1_5g5a0"]
[ext_resource type="PackedScene" uid="uid://bkcsjsk2ciff" path="res://addons/maaacks_game_template/base/scenes/music_players/background_music_player.tscn" id="2_roiv2"]
[ext_resource type="AudioStream" uid="uid://f8cvr5s041ej" path="res://assets/audio/ambiance/637083__nox_sound__ambiance_nature_night_cricket_calm_loop_stereo.wav" id="3_boadi"]
[ext_resource type="Script" uid="uid://cupqhe3qv7ero" path="res://tools/general_manager.gd" id="3_k6got"]
@@ -68,13 +69,188 @@ fog_enabled = true
fog_light_color = Color(1, 1, 1, 1)
fog_sun_scatter = 0.5
fog_density = 0.002
fog_aerial_perspective = 1.0
fog_sky_affect = 0.184
volumetric_fog_density = 0.004
volumetric_fog_emission = Color(1, 1, 1, 1)
volumetric_fog_anisotropy = 0.6
adjustment_enabled = true
[sub_resource type="Animation" id="Animation_nyvgt"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("WorldEnvironment:environment:fog_density")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.002]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("WorldEnvironment:environment:fog_sun_scatter")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.5]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("WorldEnvironment:environment:fog_light_energy")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [1.0]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("WorldEnvironment:environment:fog_aerial_perspective")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [1.0]
}
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("WorldEnvironment:environment:fog_height")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}
tracks/5/type = "value"
tracks/5/imported = false
tracks/5/enabled = true
tracks/5/path = NodePath("WorldEnvironment:environment:fog_height_density")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}
[sub_resource type="Animation" id="Animation_5g5a0"]
resource_name = "player_fell"
length = 2.0
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("WorldEnvironment:environment:fog_density")
tracks/0/interp = 2
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 1, 2),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [0.002, 1.0, 0.002]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("WorldEnvironment:environment:fog_sun_scatter")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 1, 2),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [0.5, 1.0, 0.5]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("WorldEnvironment:environment:fog_light_energy")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 1, 2),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [1.0, 10.0, 1.0]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("WorldEnvironment:environment:fog_aerial_perspective")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0, 1, 2),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [1.0, 0.0, 1.0]
}
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("WorldEnvironment:environment:fog_height")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0, 1, 2),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [0.0, 1024.0, 0.0]
}
tracks/5/type = "value"
tracks/5/imported = false
tracks/5/enabled = true
tracks/5/path = NodePath("WorldEnvironment:environment:fog_height_density")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/keys = {
"times": PackedFloat32Array(0, 2),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [0.0, 0.0]
}
tracks/6/type = "method"
tracks/6/imported = false
tracks/6/enabled = true
tracks/6/path = NodePath(".")
tracks/6/interp = 1
tracks/6/loop_wrap = true
tracks/6/keys = {
"times": PackedFloat32Array(1),
"transitions": PackedFloat32Array(1),
"values": [{
"args": [],
"method": &"reset_player_position"
}]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_nyvgt"]
_data = {
&"RESET": SubResource("Animation_nyvgt"),
&"player_fell": SubResource("Animation_5g5a0")
}
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_gm8ij"]
[node name="Main" type="Node3D" unique_id=955321579]
script = ExtResource("1_5g5a0")
[node name="DebugLayer" type="CanvasLayer" parent="." unique_id=294370189]
@@ -104,6 +280,9 @@ shadow_enabled = true
shadow_opacity = 0.95
shadow_blur = 2.435
[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=511897109]
libraries/ = SubResource("AnimationLibrary_nyvgt")
[node name="Player" parent="." unique_id=1309399929 instance=ExtResource("17_clkha")]
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, 0, 0, 0)
TutorialDone = true
@@ -113,4 +292,26 @@ AccelerationAir = 1.5
visible = false
Radius = 2.0
[node name="PlayerFellRespawn" type="Marker3D" parent="." unique_id=479136076]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 300, 0)
[node name="PlayerFellTP" type="Area3D" parent="." unique_id=1277888169]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -200, 0)
collision_layer = 0
monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="PlayerFellTP" unique_id=1866249040]
shape = SubResource("WorldBoundaryShape3D_gm8ij")
[node name="DeathPlane" type="Area3D" parent="." unique_id=1766360237]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -100, 0)
collision_layer = 0
collision_mask = 16
monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="DeathPlane" unique_id=835637700]
shape = SubResource("WorldBoundaryShape3D_gm8ij")
[connection signal="PlayerDied" from="Player" to="GeneralManager" method="on_player_died"]
[connection signal="body_entered" from="PlayerFellTP" to="." method="_on_player_fell_tp_body_entered"]
[connection signal="body_entered" from="DeathPlane" to="." method="_on_death_plane_body_entered"]

View File

@@ -24,9 +24,6 @@ use_collision = true
size = Vector3(1, 17.5, 9.5)
material = ExtResource("3_1qo78")
[node name="Player" parent="." index="7" unique_id=1309399929]
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, 3, 0, 0)
[node name="GroundedSpawner" parent="." index="8" unique_id=580981173 node_paths=PackedStringArray("Target") instance=ExtResource("4_jaqjx")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.5, 1, -42.5)
EnemyToSpawn = ExtResource("5_iq67o")
@@ -103,3 +100,6 @@ transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 27, 13.5, -9)
[node name="FixedDashthroughTarget3" parent="Targets" index="9" unique_id=1106453232 instance=ExtResource("13_iq67o")]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 43, 6, -8.5)
[node name="Player" parent="." index="14" unique_id=1309399929]
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, 3, 0, 0)

File diff suppressed because it is too large Load Diff

View File

@@ -8,6 +8,16 @@
[ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://scenes/components/movement/RMovement.cs" id="6_cgfmf"]
[ext_resource type="Script" uid="uid://baiapod3csndf" path="res://scenes/components/health/RHealth.cs" id="7_hr4qv"]
[ext_resource type="PackedScene" uid="uid://cmlud1hwkd6sv" path="res://scenes/enemies/flying_enemy/flying_enemy.tscn" id="8_dkfm7"]
[ext_resource type="Script" uid="uid://jitubgv6judn" path="res://scenes/components/damage/RDamage.cs" id="9_ofbe2"]
[ext_resource type="PackedScene" uid="uid://b8aet6m4m2i83" path="res://scenes/tuto_trigger/TutoTrigger.tscn" id="10_dkfm7"]
[ext_resource type="Texture2D" uid="uid://nrhxjdpuje3f" path="res://assets/ui/input-prompts/Xbox Series/Vector/xbox_lt_outline.svg" id="11_xy0m1"]
[ext_resource type="Texture2D" uid="uid://dx2mk8qd6g8uh" path="res://assets/ui/input-prompts/Keyboard & Mouse/Vector/mouse_right_outline.svg" id="12_t5o40"]
[ext_resource type="Texture2D" uid="uid://cjh5cnvdbq5ku" path="res://assets/ui/input-prompts/Xbox Series/Vector/xbox_button_b_outline.svg" id="13_t5o40"]
[ext_resource type="Texture2D" uid="uid://bsxtadecl3657" path="res://assets/ui/input-prompts/Keyboard & Mouse/Vector/keyboard_shift_outline.svg" id="14_prjj8"]
[ext_resource type="Texture2D" uid="uid://dyjvbsvbriii4" path="res://assets/ui/input-prompts/Xbox Series/Vector/xbox_rb_outline.svg" id="15_05lnh"]
[ext_resource type="Texture2D" uid="uid://bhlrmh5v3fa2n" path="res://assets/ui/input-prompts/Keyboard & Mouse/Vector/mouse_left_outline.svg" id="16_t5o40"]
[ext_resource type="Texture2D" uid="uid://db6uqhcmcfs5t" path="res://assets/ui/input-prompts/Xbox Series/Vector/xbox_lb_outline.svg" id="17_prjj8"]
[ext_resource type="Texture2D" uid="uid://ybwqghk70io" path="res://assets/ui/input-prompts/Keyboard & Mouse/Vector/keyboard_f_outline.svg" id="18_1opdv"]
[sub_resource type="Resource" id="Resource_nwk5u"]
script = ExtResource("6_cgfmf")
@@ -19,13 +29,48 @@ script = ExtResource("7_hr4qv")
StartingHealth = 100.0
metadata/_custom_type_script = "uid://baiapod3csndf"
[sub_resource type="Resource" id="Resource_invhv"]
script = ExtResource("7_hr4qv")
StartingHealth = 1.0
metadata/_custom_type_script = "uid://baiapod3csndf"
[sub_resource type="Resource" id="Resource_cgfmf"]
script = ExtResource("9_ofbe2")
DamageType = 2
metadata/_custom_type_script = "uid://jitubgv6judn"
[sub_resource type="Resource" id="Resource_05lnh"]
script = ExtResource("7_hr4qv")
StartingHealth = 100.0
metadata/_custom_type_script = "uid://baiapod3csndf"
[sub_resource type="Resource" id="Resource_t5o40"]
script = ExtResource("7_hr4qv")
StartingHealth = 100.0
metadata/_custom_type_script = "uid://baiapod3csndf"
[sub_resource type="BoxShape3D" id="BoxShape3D_xy0m1"]
size = Vector3(3, 3.75, 3)
[sub_resource type="BoxShape3D" id="BoxShape3D_05lnh"]
size = Vector3(9, 11, 19)
[sub_resource type="BoxShape3D" id="BoxShape3D_dkfm7"]
size = Vector3(5, 2.25, 3.75)
[sub_resource type="BoxShape3D" id="BoxShape3D_nwk5u"]
size = Vector3(5.5, 4.5, 2)
[sub_resource type="BoxShape3D" id="BoxShape3D_prjj8"]
size = Vector3(2, 3.25, 5.25)
[sub_resource type="BoxShape3D" id="BoxShape3D_1opdv"]
size = Vector3(8.25, 3.25, 2.75)
[node name="Main" unique_id=955321579 instance=ExtResource("1_8n6bu")]
[node name="Player" parent="." index="6" unique_id=1309399929]
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, 59.5, 0, 0)
[node name="Playground" type="Node3D" parent="." index="7" unique_id=2099606598]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 57.5, 0, 0)
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, -8.25, 13, 58.5)
[node name="PlaytestArena" parent="Playground" index="0" unique_id=664535670 instance=ExtResource("2_wsc2c")]
@@ -245,31 +290,37 @@ Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy10" parent="Playground/GroundedEnemies" index="19" unique_id=836898496 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
[node name="Enemy27" parent="Playground/GroundedEnemies" index="19" unique_id=854456486 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 20, 0, -44.836807)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy10" parent="Playground/GroundedEnemies" index="20" unique_id=836898496 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 30.5, 11, -33.336807)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy8" parent="Playground/GroundedEnemies" index="20" unique_id=1015624071 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
[node name="Enemy8" parent="Playground/GroundedEnemies" index="21" unique_id=1015624071 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 34.5, 1.5, -27.33681)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy9" parent="Playground/GroundedEnemies" index="21" unique_id=827865590 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
[node name="Enemy9" parent="Playground/GroundedEnemies" index="22" unique_id=827865590 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 46.5, 0, -27.33681)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy5" parent="Playground/GroundedEnemies" index="22" unique_id=1267116862 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
[node name="Enemy5" parent="Playground/GroundedEnemies" index="23" unique_id=1267116862 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 4, 0, -18.33681)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy6" parent="Playground/GroundedEnemies" index="23" unique_id=1147823180 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
[node name="Enemy6" parent="Playground/GroundedEnemies" index="24" unique_id=1147823180 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 16.5, 7, -17.33681)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
@@ -280,20 +331,427 @@ use_collision = true
collision_layer = 256
collision_mask = 65553
[node name="CSGBox3D109" type="CSGBox3D" parent="Tutorial" index="0" unique_id=531736596]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -4.75, -2.25)
[node name="FixedDashthroughTarget11" parent="Tutorial" index="0" unique_id=2053952229 instance=ExtResource("4_invhv")]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, -7.25, 20.5, -27.5)
[node name="FixedDashthroughTarget13" parent="Tutorial" index="1" unique_id=1470128508 instance=ExtResource("4_invhv")]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 1.3647223, 23.75, -13.75)
[node name="Enemy28" parent="Tutorial" index="2" unique_id=1765389924 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -5, 22, 16.5)
Target = NodePath("../../Player")
RHealth = SubResource("Resource_invhv")
RDamage = SubResource("Resource_cgfmf")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy29" parent="Tutorial" index="3" unique_id=1071267369 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -10, 22, 28.75)
Target = NodePath("../../Player")
RHealth = SubResource("Resource_05lnh")
RDamage = SubResource("Resource_cgfmf")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy30" parent="Tutorial" index="4" unique_id=1982933011 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 0.25, 22, 28.75)
Target = NodePath("../../Player")
RHealth = SubResource("Resource_t5o40")
RDamage = SubResource("Resource_cgfmf")
RMovement = SubResource("Resource_nwk5u")
[node name="Triggers" type="Node3D" parent="Tutorial" index="5" unique_id=1531131828]
[node name="TutoTrigger5" parent="Tutorial/Triggers" index="0" unique_id=840713937 instance=ExtResource("10_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.25, 23.25, -24.25)
first_input_icon = ExtResource("11_xy0m1")
first_input_icon_keyboard = ExtResource("12_t5o40")
second_input_icon = ExtResource("13_t5o40")
second_input_icon_keyboard = ExtResource("14_prjj8")
input_related_text = "while aiming at target"
tuto_text = "Blink through"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Tutorial/Triggers/TutoTrigger5" index="1" unique_id=1895232009]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.75, 0.625, 1.75)
shape = SubResource("BoxShape3D_xy0m1")
[node name="TutoTrigger" parent="Tutorial/Triggers" index="1" unique_id=1215265305 instance=ExtResource("10_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.25, 0, -4.5)
first_input_icon = ExtResource("11_xy0m1")
first_input_icon_keyboard = ExtResource("12_t5o40")
second_input_icon = ExtResource("13_t5o40")
second_input_icon_keyboard = ExtResource("14_prjj8")
tuto_text = "Blink"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Tutorial/Triggers/TutoTrigger" index="1" unique_id=1774867326]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.25, -3.75, -6.75)
shape = SubResource("BoxShape3D_05lnh")
[node name="TutoTrigger3" parent="Tutorial/Triggers" index="2" unique_id=460767120 instance=ExtResource("10_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.75, 7, -49)
first_input_icon = ExtResource("11_xy0m1")
first_input_icon_keyboard = ExtResource("12_t5o40")
input_related_text = "in air"
tuto_text = "slows down time"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Tutorial/Triggers/TutoTrigger3" index="1" unique_id=768845413]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.25, 0.625, 0.875)
shape = SubResource("BoxShape3D_dkfm7")
[node name="TutoTrigger4" parent="Tutorial/Triggers" index="3" unique_id=321542244 instance=ExtResource("10_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -11.5, 17.75, -27.5)
first_input_icon = ExtResource("15_05lnh")
first_input_icon_keyboard = ExtResource("16_t5o40")
input_related_text = "at target"
tuto_text = "dash through"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Tutorial/Triggers/TutoTrigger4" index="1" unique_id=1601250256]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 1.75, 0)
shape = SubResource("BoxShape3D_nwk5u")
[node name="TutoTrigger6" parent="Tutorial/Triggers" index="4" unique_id=26112457 instance=ExtResource("10_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.75, 22.75, 11.25)
first_input_icon = ExtResource("15_05lnh")
first_input_icon_keyboard = ExtResource("16_t5o40")
input_related_text = "at enemy"
tuto_text = "dash through"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Tutorial/Triggers/TutoTrigger6" index="1" unique_id=1214410006]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.625, 1.75, -0.75)
shape = SubResource("BoxShape3D_prjj8")
[node name="TutoTrigger7" parent="Tutorial/Triggers" index="5" unique_id=271532103 instance=ExtResource("10_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 22.75, 30.25)
first_input_icon = ExtResource("11_xy0m1")
first_input_icon_keyboard = ExtResource("12_t5o40")
second_input_icon = ExtResource("15_05lnh")
second_input_icon_keyboard = ExtResource("16_t5o40")
tuto_text = "throw weapon"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Tutorial/Triggers/TutoTrigger7" index="1" unique_id=1932556219]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.875, 4)
shape = SubResource("BoxShape3D_prjj8")
[node name="TutoTrigger8" parent="Tutorial/Triggers" index="6" unique_id=36196488 instance=ExtResource("10_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 21.75, 28.25)
first_input_icon = ExtResource("17_prjj8")
first_input_icon_keyboard = ExtResource("18_1opdv")
input_related_text = "at enemy"
tuto_text = "knockback"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Tutorial/Triggers/TutoTrigger8" index="1" unique_id=929676345]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.125, 1.875, 0.375)
shape = SubResource("BoxShape3D_1opdv")
[node name="DashWithMantle" type="CSGCombiner3D" parent="Tutorial" index="6" unique_id=128667834]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9, 0, -36.5)
[node name="CSGBox3D109" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="0" unique_id=531736596]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, -4.75, 4)
use_collision = true
size = Vector3(19.5, 8.5, 14)
size = Vector3(9, 8.5, 6)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D110" type="CSGBox3D" parent="Tutorial" index="1" unique_id=731833071]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4.5, -29.25)
[node name="CSGBox3D112" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="1" unique_id=565292599]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, -6.25, 0)
use_collision = true
size = Vector3(19.5, 27, 14)
size = Vector3(9, 5.5, 2)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D111" type="CSGBox3D" parent="Tutorial" index="2" unique_id=923535141]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -21.75, -18.75)
[node name="CSGBox3D113" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="2" unique_id=28433553]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, -7.75, -2)
use_collision = true
size = Vector3(19.5, 25.5, 35)
size = Vector3(9, 2.5, 2)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D110" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="3" unique_id=731833071]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 6, -12.125)
use_collision = true
size = Vector3(5, 1, 4.75)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D115" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="4" unique_id=173458015]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 5.625, -14)
use_collision = true
size = Vector3(9, 29.25, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D116" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="5" unique_id=1750512788]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 7, -12.125)
use_collision = true
size = Vector3(1, 1, 4.75)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D117" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="6" unique_id=391729778]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.5, 7, -12.125)
use_collision = true
size = Vector3(1, 1, 4.75)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D134" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="7" unique_id=1136091363]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 21.5, 46.125)
use_collision = true
size = Vector3(5, 1, 4.75)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D135" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="8" unique_id=748140231]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 22.5, 46.125)
use_collision = true
size = Vector3(1, 1, 4.75)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D136" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="9" unique_id=436209430]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 22.5, 46.125)
use_collision = true
size = Vector3(1, 1, 4.75)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D137" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="10" unique_id=1930091014]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 22.5, 58)
use_collision = true
size = Vector3(1, 1, 11)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D138" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="11" unique_id=1299444131]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 22.5, 58)
use_collision = true
size = Vector3(1, 1, 11)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D139" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="12" unique_id=1708119368]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 22.5, 68.625)
use_collision = true
size = Vector3(1, 1, 3.25)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D140" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="13" unique_id=762102441]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 22.5, 68.625)
use_collision = true
size = Vector3(1, 1, 3.25)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D120" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="14" unique_id=1446497915]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.5, 17, 6.75)
use_collision = true
size = Vector3(1, 2, 6.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D127" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="15" unique_id=1731176595]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7, 17, 10.5)
use_collision = true
size = Vector3(4, 2, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D119" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="16" unique_id=1284139577]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.5, 0.625, 10)
use_collision = true
size = Vector3(3, 2.25, 6)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D114" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="17" unique_id=1204742131]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 16.5, 4.75)
use_collision = true
size = Vector3(12, 1, 2.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D118" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="18" unique_id=1985192046]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 23.125, 6.5)
use_collision = true
size = Vector3(18, 12.25, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D130" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="19" unique_id=1502907002]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.25, 23.125, 44)
use_collision = true
size = Vector3(7.5, 12.25, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D131" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="20" unique_id=632272709]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.25, 23.125, 43)
use_collision = true
size = Vector3(7.5, 12.25, 3)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D123" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="21" unique_id=696789507]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.375, 23.125, 10.5)
use_collision = true
size = Vector3(7.25, 12.25, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D125" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="22" unique_id=1937274848]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.375, 23.125, 7.5)
use_collision = true
size = Vector3(7.25, 12.25, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D132" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="23" unique_id=249644458]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 29.625, 25.25)
use_collision = true
size = Vector3(18, 0.75, 38.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D126" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="24" unique_id=1606556480]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.125, 18.25, 9)
use_collision = true
size = Vector3(7.75, 2.5, 4)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D128" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="25" unique_id=1927103381]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.375, 25.375, 9)
use_collision = true
size = Vector3(7.25, 7.75, 2)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D124" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="26" unique_id=1068505352]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.5, 19.487345, 11.25)
use_collision = true
size = Vector3(3, 5, 8.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D129" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="27" unique_id=302301078]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.25, 19.487345, 38.625)
use_collision = true
size = Vector3(9.5, 5, 11.75)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D133" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="28" unique_id=672467040]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 21.487345, 58)
use_collision = true
size = Vector3(5, 1, 11)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D141" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="29" unique_id=1207463075]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 21.487345, 70.5)
use_collision = true
size = Vector3(5, 1, 7)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D121" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="30" unique_id=302433684]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.875, 23.125, 26.25)
use_collision = true
size = Vector3(13.75, 12.25, 30.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D122" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="31" unique_id=1125662345]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12.5, 23.125, 25.25)
use_collision = true
size = Vector3(1, 12.25, 36.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D111" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="32" unique_id=923535141]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, -11.125, -3.75)
use_collision = true
size = Vector3(9, 4.25, 21.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D142" type="CSGBox3D" parent="Tutorial" index="7" unique_id=886061699]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 22, 34)
use_collision = true
size = Vector3(2, 2, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D145" type="CSGBox3D" parent="Tutorial" index="8" unique_id=1440927327]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 12.25, 34)
use_collision = true
size = Vector3(12, 17.5, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D139" type="CSGBox3D" parent="Tutorial" index="9" unique_id=1561729125]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 21.5, 28.75)
use_collision = true
size = Vector3(12, 1, 3.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D146" type="CSGBox3D" parent="Tutorial" index="10" unique_id=1614862969]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.75, 23, 55.75)
use_collision = true
size = Vector3(19.5, 1, 3.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D147" type="CSGBox3D" parent="Tutorial" index="11" unique_id=1320459108]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -16.875, 23, 67.25)
use_collision = true
size = Vector3(3.25, 1, 19.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D140" type="CSGBox3D" parent="Tutorial" index="12" unique_id=124463390]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.5, 25.125, 34)
use_collision = true
size = Vector3(5, 8.25, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D141" type="CSGBox3D" parent="Tutorial" index="13" unique_id=164888540]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.5, 25.125, 34)
use_collision = true
size = Vector3(5, 8.25, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D114" type="CSGBox3D" parent="Tutorial" index="14" unique_id=1217279859]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, -4.75, 0)
use_collision = true
size = Vector3(9, 8.5, 14)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D116" type="CSGBox3D" parent="Tutorial" index="15" unique_id=720911926]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 9.375, -11.75)
use_collision = true
size = Vector3(18, 15.25, 37.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D115" type="CSGBox3D" parent="Tutorial" index="16" unique_id=995233474]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, -1, -26.5)
use_collision = true
size = Vector3(18, 1, 6)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D119" type="CSGBox3D" parent="Tutorial" index="17" unique_id=1412582714]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.875, -3.75, -30)
use_collision = true
size = Vector3(11.75, 11, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D121" type="CSGBox3D" parent="Tutorial" index="18" unique_id=697302898]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -12.5, 0.125, -30)
use_collision = true
size = Vector3(3, 3.25, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D117" type="CSGBox3D" parent="Tutorial" index="19" unique_id=603171965]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, -6.25, -8)
use_collision = true
size = Vector3(9, 5.5, 2)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D123" type="CSGBox3D" parent="Tutorial" index="20" unique_id=765166179]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 0.625, 6)
use_collision = true
size = Vector3(9, 2.25, 2)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D118" type="CSGBox3D" parent="Tutorial" index="21" unique_id=1950738925]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, -7.75, -10)
use_collision = true
size = Vector3(9, 2.5, 2)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D120" type="CSGBox3D" parent="Tutorial" index="22" unique_id=1024529143]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, -21.75, -11.75)
use_collision = true
size = Vector3(9, 25.5, 37.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D122" type="CSGBox3D" parent="Tutorial" index="23" unique_id=1261455320]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15.5, 16.5, -28.5)
use_collision = true
size = Vector3(3, 1, 4)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D143" type="CSGBox3D" parent="Tutorial" index="24" unique_id=1090375546]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 27.625, 34)
use_collision = true
size = Vector3(2, 3.25, 1)
material = ExtResource("3_wsc2c")
[node name="Player" parent="." index="9" unique_id=1309399929]
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, -0.5, 0, 0)
[node name="PlayerFellRespawn" parent="." index="10" unique_id=479136076]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 1.5, 0)

View File

@@ -0,0 +1,739 @@
[gd_scene format=3 uid="uid://e81wsmpen58r"]
[ext_resource type="PackedScene" uid="uid://55wehh6xombr" path="res://maps/_templates/main_scene_template.tscn" id="1_8n6bu"]
[ext_resource type="PackedScene" uid="uid://y77cdg7gg3y7" path="res://maps/levels/_arenas/playtest_1.tscn" id="2_wsc2c"]
[ext_resource type="Material" uid="uid://31aulub2nqov" path="res://assets/materials/greybox/m_greybox.tres" id="3_wsc2c"]
[ext_resource type="PackedScene" uid="uid://qup00a7x2sji" path="res://scenes/fixed_dash_target/fixed_dashthrough_target.tscn" id="4_invhv"]
[ext_resource type="PackedScene" uid="uid://dxt0e2ugmttqq" path="res://scenes/enemies/grounded_enemy/grounded_enemy.tscn" id="5_ofbe2"]
[ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://scenes/components/movement/RMovement.cs" id="6_cgfmf"]
[ext_resource type="Script" uid="uid://baiapod3csndf" path="res://scenes/components/health/RHealth.cs" id="7_hr4qv"]
[ext_resource type="PackedScene" uid="uid://cmlud1hwkd6sv" path="res://scenes/enemies/flying_enemy/flying_enemy.tscn" id="8_dkfm7"]
[ext_resource type="Script" uid="uid://jitubgv6judn" path="res://scenes/components/damage/RDamage.cs" id="9_ofbe2"]
[ext_resource type="PackedScene" uid="uid://b8aet6m4m2i83" path="res://scenes/tuto_trigger/TutoTrigger.tscn" id="10_dkfm7"]
[ext_resource type="Resource" uid="uid://c3e0ivgaxrsyb" path="res://inputs/base_mode/aim_down.tres" id="11_dkfm7"]
[ext_resource type="Resource" uid="uid://d2r0ur8k3cuu3" path="res://inputs/base_mode/dash.tres" id="12_nwk5u"]
[sub_resource type="Resource" id="Resource_nwk5u"]
script = ExtResource("6_cgfmf")
GravityModifier = 5.0
metadata/_custom_type_script = "uid://dtpxijlnb2c5"
[sub_resource type="Resource" id="Resource_xy0m1"]
script = ExtResource("7_hr4qv")
StartingHealth = 100.0
metadata/_custom_type_script = "uid://baiapod3csndf"
[sub_resource type="Resource" id="Resource_invhv"]
script = ExtResource("7_hr4qv")
StartingHealth = 1.0
metadata/_custom_type_script = "uid://baiapod3csndf"
[sub_resource type="Resource" id="Resource_cgfmf"]
script = ExtResource("9_ofbe2")
DamageType = 2
metadata/_custom_type_script = "uid://jitubgv6judn"
[sub_resource type="Resource" id="Resource_05lnh"]
script = ExtResource("7_hr4qv")
StartingHealth = 100.0
metadata/_custom_type_script = "uid://baiapod3csndf"
[sub_resource type="Resource" id="Resource_t5o40"]
script = ExtResource("7_hr4qv")
StartingHealth = 100.0
metadata/_custom_type_script = "uid://baiapod3csndf"
[sub_resource type="BoxShape3D" id="BoxShape3D_xy0m1"]
size = Vector3(3, 3.75, 3)
[sub_resource type="BoxShape3D" id="BoxShape3D_05lnh"]
size = Vector3(9, 11, 19)
[sub_resource type="BoxShape3D" id="BoxShape3D_t5o40"]
size = Vector3(9, 2.25, 5)
[sub_resource type="BoxShape3D" id="BoxShape3D_dkfm7"]
size = Vector3(5, 2.25, 3.75)
[sub_resource type="BoxShape3D" id="BoxShape3D_nwk5u"]
size = Vector3(5.5, 4.5, 2)
[sub_resource type="BoxShape3D" id="BoxShape3D_prjj8"]
size = Vector3(2, 3.25, 5.25)
[sub_resource type="BoxShape3D" id="BoxShape3D_1opdv"]
size = Vector3(8.25, 3.25, 2.75)
[node name="Main" unique_id=955321579 instance=ExtResource("1_8n6bu")]
[node name="Player" parent="." index="7" unique_id=1309399929]
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, -0.5, 0, -2.5)
[node name="PlayerFellRespawn" parent="." index="8" unique_id=479136076]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 1.5, 0)
[node name="Playground" type="Node3D" parent="." index="11" unique_id=2099606598]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, -8.25, 13, 58.5)
[node name="PlaytestArena" parent="Playground" index="0" unique_id=664535670 instance=ExtResource("2_wsc2c")]
[node name="CSGBox3D108" type="CSGBox3D" parent="Playground/PlaytestArena" index="88" unique_id=47922109]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 8.75, 2.25)
use_collision = true
size = Vector3(1, 17.5, 9.5)
material = ExtResource("3_wsc2c")
[node name="Targets" type="Node3D" parent="Playground" index="1" unique_id=1727473773]
[node name="FixedDashthroughTarget" parent="Playground/Targets" index="0" unique_id=1291663508 instance=ExtResource("4_invhv")]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 17, 13.5, -9)
[node name="FixedDashthroughTarget8" parent="Playground/Targets" index="1" unique_id=475406577 instance=ExtResource("4_invhv")]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 17, 23, -34)
[node name="FixedDashthroughTarget9" parent="Playground/Targets" index="2" unique_id=168635463 instance=ExtResource("4_invhv")]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 35.5, 30.5, -42.5)
[node name="FixedDashthroughTarget10" parent="Playground/Targets" index="3" unique_id=119396227 instance=ExtResource("4_invhv")]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 26, 30.5, -42.5)
[node name="FixedDashthroughTarget7" parent="Playground/Targets" index="4" unique_id=282429016 instance=ExtResource("4_invhv")]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 10.5, 5.5, -9)
[node name="FixedDashthroughTarget6" parent="Playground/Targets" index="5" unique_id=437890277 instance=ExtResource("4_invhv")]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 8, 6, -30.5)
[node name="FixedDashthroughTarget4" parent="Playground/Targets" index="6" unique_id=1484691271 instance=ExtResource("4_invhv")]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 30.5, 5, -33.5)
[node name="FixedDashthroughTarget5" parent="Playground/Targets" index="7" unique_id=434257222 instance=ExtResource("4_invhv")]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 26.5, 9.5, -44)
[node name="FixedDashthroughTarget2" parent="Playground/Targets" index="8" unique_id=272400108 instance=ExtResource("4_invhv")]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 27, 13.5, -9)
[node name="FixedDashthroughTarget3" parent="Playground/Targets" index="9" unique_id=1008201593 instance=ExtResource("4_invhv")]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 43, 6, -8.5)
[node name="FlyingEnemies" type="Node3D" parent="Playground" index="2" unique_id=1518759273]
[node name="FlyingEnemy" parent="Playground/FlyingEnemies" index="0" unique_id=2090203407 node_paths=PackedStringArray("Target") instance=ExtResource("8_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 15.5, 7, -9)
Target = NodePath("../../../Player")
RMovement = SubResource("Resource_nwk5u")
[node name="FlyingEnemy10" parent="Playground/FlyingEnemies" index="1" unique_id=1610354388 node_paths=PackedStringArray("Target") instance=ExtResource("8_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 32.5, 7, 0.5)
Target = NodePath("../../../Player")
RMovement = SubResource("Resource_nwk5u")
[node name="FlyingEnemy11" parent="Playground/FlyingEnemies" index="2" unique_id=1671862122 node_paths=PackedStringArray("Target") instance=ExtResource("8_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 28, 7, 1.5)
Target = NodePath("../../../Player")
RMovement = SubResource("Resource_nwk5u")
[node name="FlyingEnemy4" parent="Playground/FlyingEnemies" index="3" unique_id=665537400 node_paths=PackedStringArray("Target") instance=ExtResource("8_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 33, 6, -12)
Target = NodePath("../../../Player")
RMovement = SubResource("Resource_nwk5u")
[node name="FlyingEnemy5" parent="Playground/FlyingEnemies" index="4" unique_id=1592183094 node_paths=PackedStringArray("Target") instance=ExtResource("8_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 45, 6, -12)
Target = NodePath("../../../Player")
RMovement = SubResource("Resource_nwk5u")
[node name="FlyingEnemy9" parent="Playground/FlyingEnemies" index="5" unique_id=842890582 node_paths=PackedStringArray("Target") instance=ExtResource("8_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 45, 6, -1.5)
Target = NodePath("../../../Player")
RMovement = SubResource("Resource_nwk5u")
[node name="FlyingEnemy2" parent="Playground/FlyingEnemies" index="6" unique_id=188061312 node_paths=PackedStringArray("Target") instance=ExtResource("8_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.5, 11, -24)
Target = NodePath("../../../Player")
RMovement = SubResource("Resource_nwk5u")
[node name="FlyingEnemy12" parent="Playground/FlyingEnemies" index="7" unique_id=821624940 node_paths=PackedStringArray("Target") instance=ExtResource("8_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4.5, 8.5, -24)
Target = NodePath("../../../Player")
RMovement = SubResource("Resource_nwk5u")
[node name="FlyingEnemy3" parent="Playground/FlyingEnemies" index="8" unique_id=412581083 node_paths=PackedStringArray("Target") instance=ExtResource("8_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7, 14, -32.5)
Target = NodePath("../../../Player")
RMovement = SubResource("Resource_nwk5u")
[node name="FlyingEnemy6" parent="Playground/FlyingEnemies" index="9" unique_id=779578466 node_paths=PackedStringArray("Target") instance=ExtResource("8_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 26, 23.5, -23)
Target = NodePath("../../../Player")
RMovement = SubResource("Resource_nwk5u")
[node name="FlyingEnemy7" parent="Playground/FlyingEnemies" index="10" unique_id=1163439326 node_paths=PackedStringArray("Target") instance=ExtResource("8_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 34, 23.5, -23)
Target = NodePath("../../../Player")
RMovement = SubResource("Resource_nwk5u")
[node name="FlyingEnemy8" parent="Playground/FlyingEnemies" index="11" unique_id=1979706254 node_paths=PackedStringArray("Target") instance=ExtResource("8_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 43, 23.5, -23)
Target = NodePath("../../../Player")
RMovement = SubResource("Resource_nwk5u")
[node name="GroundedEnemies" type="Node3D" parent="Playground" index="3" unique_id=1101330520]
[node name="Enemy3" parent="Playground/GroundedEnemies" index="0" unique_id=1159989424 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 25, 0, -8.336809)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy11" parent="Playground/GroundedEnemies" index="1" unique_id=1747444936 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 17, 8, 3.6631908)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy12" parent="Playground/GroundedEnemies" index="2" unique_id=283117081 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 36.5, 11, -4.836809)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy13" parent="Playground/GroundedEnemies" index="3" unique_id=970022638 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 36.5, 12, -19.33681)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy18" parent="Playground/GroundedEnemies" index="4" unique_id=2077088475 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 30.5, 12, -19.33681)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy19" parent="Playground/GroundedEnemies" index="5" unique_id=2023773341 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 36.5, 7.5, -19.33681)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy25" parent="Playground/GroundedEnemies" index="6" unique_id=1101329723 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 46, 7.5, -19.33681)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy26" parent="Playground/GroundedEnemies" index="7" unique_id=855220553 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 46, 12, -35.336807)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy20" parent="Playground/GroundedEnemies" index="8" unique_id=1255215986 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 30.5, 7.5, -19.33681)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy21" parent="Playground/GroundedEnemies" index="9" unique_id=2098915426 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 36.5, 0.5, -19.33681)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy22" parent="Playground/GroundedEnemies" index="10" unique_id=246912749 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 30.5, 0.5, -19.33681)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy14" parent="Playground/GroundedEnemies" index="11" unique_id=211015190 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 41, 17.5, -33.336807)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy15" parent="Playground/GroundedEnemies" index="12" unique_id=1164179421 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 31, 17.5, -33.336807)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy16" parent="Playground/GroundedEnemies" index="13" unique_id=1169725422 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 24.5, 17.5, -33.336807)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy17" parent="Playground/GroundedEnemies" index="14" unique_id=1951666189 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 17.5, 17.5, -22.836807)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy23" parent="Playground/GroundedEnemies" index="15" unique_id=1348057502 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 17.5, 24.5, -43.336807)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy24" parent="Playground/GroundedEnemies" index="16" unique_id=2068813971 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 45, 24.5, -43.336807)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy4" parent="Playground/GroundedEnemies" index="17" unique_id=366059658 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 10.5, 0, -18.33681)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy7" parent="Playground/GroundedEnemies" index="18" unique_id=1389063523 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 25.5, 4, -27.33681)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy27" parent="Playground/GroundedEnemies" index="19" unique_id=854456486 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 20, 0, -44.836807)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy10" parent="Playground/GroundedEnemies" index="20" unique_id=836898496 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 30.5, 11, -33.336807)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy8" parent="Playground/GroundedEnemies" index="21" unique_id=1015624071 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 34.5, 1.5, -27.33681)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy9" parent="Playground/GroundedEnemies" index="22" unique_id=827865590 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 46.5, 0, -27.33681)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy5" parent="Playground/GroundedEnemies" index="23" unique_id=1267116862 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 4, 0, -18.33681)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy6" parent="Playground/GroundedEnemies" index="24" unique_id=1147823180 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 16.5, 7, -17.33681)
Target = NodePath("../../../Player")
RHealth = SubResource("Resource_xy0m1")
RMovement = SubResource("Resource_nwk5u")
[node name="Tutorial" type="CSGCombiner3D" parent="." index="12" unique_id=1168290062]
use_collision = true
collision_layer = 256
collision_mask = 65553
[node name="FixedDashthroughTarget11" parent="Tutorial" index="0" unique_id=2053952229 instance=ExtResource("4_invhv")]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, -7.25, 20.5, -27.5)
[node name="FixedDashthroughTarget13" parent="Tutorial" index="1" unique_id=1470128508 instance=ExtResource("4_invhv")]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 1.3647223, 23.75, -13.75)
[node name="Enemy28" parent="Tutorial" index="2" unique_id=1765389924 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -5, 22, 16.5)
Target = NodePath("../../Player")
RHealth = SubResource("Resource_invhv")
RDamage = SubResource("Resource_cgfmf")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy29" parent="Tutorial" index="3" unique_id=1071267369 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -10, 22, 28.75)
Target = NodePath("../../Player")
RHealth = SubResource("Resource_05lnh")
RDamage = SubResource("Resource_cgfmf")
RMovement = SubResource("Resource_nwk5u")
[node name="Enemy30" parent="Tutorial" index="4" unique_id=1982933011 node_paths=PackedStringArray("Target") instance=ExtResource("5_ofbe2")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 0.25, 22, 28.75)
Target = NodePath("../../Player")
RHealth = SubResource("Resource_t5o40")
RDamage = SubResource("Resource_cgfmf")
RMovement = SubResource("Resource_nwk5u")
[node name="Triggers" type="Node3D" parent="Tutorial" index="5" unique_id=1531131828]
[node name="TutoTrigger5" parent="Tutorial/Triggers" index="0" unique_id=840713937 instance=ExtResource("10_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.25, 23.25, -24.25)
input = ExtResource("11_dkfm7")
second_input = ExtResource("12_nwk5u")
tuto_text = "Dash to target"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Tutorial/Triggers/TutoTrigger5" index="1" unique_id=1895232009]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.75, 0.625, 1.75)
shape = SubResource("BoxShape3D_xy0m1")
[node name="TutoTrigger" parent="Tutorial/Triggers" index="1" unique_id=1215265305 instance=ExtResource("10_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.25, 0, -4.5)
tuto_text = "Aimed dash"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Tutorial/Triggers/TutoTrigger" index="1" unique_id=1774867326]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.25, -3.75, -6.75)
shape = SubResource("BoxShape3D_05lnh")
[node name="TutoTrigger2" parent="Tutorial/Triggers" index="2" unique_id=386301715 instance=ExtResource("10_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.75, 0, -34.25)
tuto_text = "mantle after dash"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Tutorial/Triggers/TutoTrigger2" index="1" unique_id=525906537]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.25, 0.625, 1.25)
shape = SubResource("BoxShape3D_t5o40")
[node name="TutoTrigger3" parent="Tutorial/Triggers" index="3" unique_id=460767120 instance=ExtResource("10_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.75, 7, -49)
tuto_text = "slows down time"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Tutorial/Triggers/TutoTrigger3" index="1" unique_id=768845413]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.25, 0.625, 0.875)
shape = SubResource("BoxShape3D_dkfm7")
[node name="TutoTrigger4" parent="Tutorial/Triggers" index="4" unique_id=321542244 instance=ExtResource("10_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -11.5, 17.75, -27.5)
tuto_text = "dash through"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Tutorial/Triggers/TutoTrigger4" index="1" unique_id=1601250256]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 1.75, 0)
shape = SubResource("BoxShape3D_nwk5u")
[node name="TutoTrigger6" parent="Tutorial/Triggers" index="5" unique_id=26112457 instance=ExtResource("10_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.75, 22.75, 11.25)
tuto_text = "dash through"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Tutorial/Triggers/TutoTrigger6" index="1" unique_id=1214410006]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.625, 1.75, -0.75)
shape = SubResource("BoxShape3D_prjj8")
[node name="TutoTrigger7" parent="Tutorial/Triggers" index="6" unique_id=271532103 instance=ExtResource("10_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 22.75, 30.25)
tuto_text = "throw weapon"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Tutorial/Triggers/TutoTrigger7" index="1" unique_id=1932556219]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.875, 4)
shape = SubResource("BoxShape3D_prjj8")
[node name="TutoTrigger8" parent="Tutorial/Triggers" index="7" unique_id=36196488 instance=ExtResource("10_dkfm7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 21.75, 28.25)
tuto_text = "knockback"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Tutorial/Triggers/TutoTrigger8" index="1" unique_id=929676345]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.125, 1.875, 0.375)
shape = SubResource("BoxShape3D_1opdv")
[node name="DashWithMantle" type="CSGCombiner3D" parent="Tutorial" index="6" unique_id=128667834]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9, 0, -36.5)
[node name="CSGBox3D109" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="0" unique_id=531736596]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, -4.75, 4)
use_collision = true
size = Vector3(9, 8.5, 6)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D112" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="1" unique_id=565292599]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, -6.25, 0)
use_collision = true
size = Vector3(9, 5.5, 2)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D113" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="2" unique_id=28433553]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, -7.75, -2)
use_collision = true
size = Vector3(9, 2.5, 2)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D110" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="3" unique_id=731833071]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 6, -12.125)
use_collision = true
size = Vector3(5, 1, 4.75)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D115" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="4" unique_id=173458015]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 5.625, -14)
use_collision = true
size = Vector3(9, 29.25, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D116" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="5" unique_id=1750512788]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 7, -12.125)
use_collision = true
size = Vector3(1, 1, 4.75)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D117" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="6" unique_id=391729778]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.5, 7, -12.125)
use_collision = true
size = Vector3(1, 1, 4.75)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D134" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="7" unique_id=1136091363]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 21.5, 46.125)
use_collision = true
size = Vector3(5, 1, 4.75)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D135" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="8" unique_id=748140231]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 22.5, 46.125)
use_collision = true
size = Vector3(1, 1, 4.75)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D136" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="9" unique_id=436209430]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 22.5, 46.125)
use_collision = true
size = Vector3(1, 1, 4.75)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D137" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="10" unique_id=1930091014]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 22.5, 58)
use_collision = true
size = Vector3(1, 1, 11)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D138" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="11" unique_id=1299444131]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 22.5, 58)
use_collision = true
size = Vector3(1, 1, 11)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D139" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="12" unique_id=1708119368]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 22.5, 68.625)
use_collision = true
size = Vector3(1, 1, 3.25)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D140" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="13" unique_id=762102441]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 22.5, 68.625)
use_collision = true
size = Vector3(1, 1, 3.25)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D120" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="14" unique_id=1446497915]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.5, 17, 6.75)
use_collision = true
size = Vector3(1, 2, 6.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D127" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="15" unique_id=1731176595]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7, 17, 10.5)
use_collision = true
size = Vector3(4, 2, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D119" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="16" unique_id=1284139577]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.5, 0.625, 10.375)
use_collision = true
size = Vector3(3, 2.25, 6.75)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D114" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="17" unique_id=1204742131]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 16.5, 4.75)
use_collision = true
size = Vector3(12, 1, 2.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D118" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="18" unique_id=1985192046]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 23.125, 6.5)
use_collision = true
size = Vector3(18, 12.25, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D130" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="19" unique_id=1502907002]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.25, 23.125, 44)
use_collision = true
size = Vector3(7.5, 12.25, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D131" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="20" unique_id=632272709]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.25, 23.125, 43)
use_collision = true
size = Vector3(7.5, 12.25, 3)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D123" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="21" unique_id=696789507]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.375, 23.125, 10.5)
use_collision = true
size = Vector3(7.25, 12.25, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D125" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="22" unique_id=1937274848]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.375, 23.125, 7.5)
use_collision = true
size = Vector3(7.25, 12.25, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D132" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="23" unique_id=249644458]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 29.625, 25.25)
use_collision = true
size = Vector3(18, 0.75, 38.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D126" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="24" unique_id=1606556480]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.125, 18.25, 9)
use_collision = true
size = Vector3(7.75, 2.5, 4)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D128" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="25" unique_id=1927103381]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.375, 25.375, 9)
use_collision = true
size = Vector3(7.25, 7.75, 2)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D124" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="26" unique_id=1068505352]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.5, 19.487345, 11.25)
use_collision = true
size = Vector3(3, 5, 8.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D129" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="27" unique_id=302301078]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.25, 19.487345, 38.625)
use_collision = true
size = Vector3(9.5, 5, 11.75)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D133" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="28" unique_id=672467040]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 21.487345, 58)
use_collision = true
size = Vector3(5, 1, 11)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D141" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="29" unique_id=1207463075]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 21.487345, 70.125)
use_collision = true
size = Vector3(5, 1, 6.25)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D121" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="30" unique_id=302433684]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.875, 23.125, 26.25)
use_collision = true
size = Vector3(13.75, 12.25, 30.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D122" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="31" unique_id=1125662345]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12.5, 23.125, 25.25)
use_collision = true
size = Vector3(1, 12.25, 36.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D111" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="32" unique_id=923535141]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, -11.125, -3.75)
use_collision = true
size = Vector3(9, 4.25, 21.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D142" type="CSGBox3D" parent="Tutorial" index="7" unique_id=886061699]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 22, 34)
use_collision = true
size = Vector3(2, 2, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D145" type="CSGBox3D" parent="Tutorial" index="8" unique_id=1440927327]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 12.25, 34)
use_collision = true
size = Vector3(12, 17.5, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D139" type="CSGBox3D" parent="Tutorial" index="9" unique_id=1561729125]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 21.5, 28.75)
use_collision = true
size = Vector3(12, 1, 3.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D146" type="CSGBox3D" parent="Tutorial" index="10" unique_id=1614862969]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.75, 23, 55.75)
use_collision = true
size = Vector3(19.5, 1, 3.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D147" type="CSGBox3D" parent="Tutorial" index="11" unique_id=1320459108]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -16.875, 23, 67.25)
use_collision = true
size = Vector3(3.25, 1, 19.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D140" type="CSGBox3D" parent="Tutorial" index="12" unique_id=124463390]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.5, 25.125, 34)
use_collision = true
size = Vector3(5, 8.25, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D141" type="CSGBox3D" parent="Tutorial" index="13" unique_id=164888540]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.5, 25.125, 34)
use_collision = true
size = Vector3(5, 8.25, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D114" type="CSGBox3D" parent="Tutorial" index="14" unique_id=1217279859]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, -4.75, 0)
use_collision = true
size = Vector3(9, 8.5, 14)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D116" type="CSGBox3D" parent="Tutorial" index="15" unique_id=720911926]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 9.375, -11.75)
use_collision = true
size = Vector3(18, 15.25, 37.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D115" type="CSGBox3D" parent="Tutorial" index="16" unique_id=995233474]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, -1, -26.125)
use_collision = true
size = Vector3(18, 1, 6.75)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D119" type="CSGBox3D" parent="Tutorial" index="17" unique_id=1412582714]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.875, -3.75, -30)
use_collision = true
size = Vector3(11.75, 11, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D121" type="CSGBox3D" parent="Tutorial" index="18" unique_id=697302898]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -12.5, 0.125, -30)
use_collision = true
size = Vector3(3, 3.25, 1)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D117" type="CSGBox3D" parent="Tutorial" index="19" unique_id=603171965]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, -6.25, -8)
use_collision = true
size = Vector3(9, 5.5, 2)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D123" type="CSGBox3D" parent="Tutorial" index="20" unique_id=765166179]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 0.625, 6)
use_collision = true
size = Vector3(9, 2.25, 2)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D118" type="CSGBox3D" parent="Tutorial" index="21" unique_id=1950738925]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, -7.75, -10)
use_collision = true
size = Vector3(9, 2.5, 2)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D120" type="CSGBox3D" parent="Tutorial" index="22" unique_id=1024529143]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, -21.75, -11.75)
use_collision = true
size = Vector3(9, 25.5, 37.5)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D122" type="CSGBox3D" parent="Tutorial" index="23" unique_id=1261455320]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15.5, 16.5, -28.5)
use_collision = true
size = Vector3(3, 1, 4)
material = ExtResource("3_wsc2c")
[node name="CSGBox3D143" type="CSGBox3D" parent="Tutorial" index="24" unique_id=1090375546]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 27.625, 34)
use_collision = true
size = Vector3(2, 3.25, 1)
material = ExtResource("3_wsc2c")

View File

@@ -0,0 +1,79 @@
{
"format": 1,
"restore": {
"D:\\Godot\\Projects\\movement-tests\\movement-tests.csproj": {}
},
"projects": {
"D:\\Godot\\Projects\\movement-tests\\movement-tests.csproj": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "D:\\Godot\\Projects\\movement-tests\\movement-tests.csproj",
"projectName": "movement-tests",
"projectPath": "D:\\Godot\\Projects\\movement-tests\\movement-tests.csproj",
"packagesPath": "C:\\Users\\Minimata\\.nuget\\packages\\",
"outputPath": "D:\\Godot\\Projects\\movement-tests\\obj\\",
"projectStyle": "PackageReference",
"fallbackFolders": [
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
],
"configFilePaths": [
"C:\\Users\\Minimata\\AppData\\Roaming\\NuGet\\NuGet.Config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
],
"originalTargetFrameworks": [
"net8.0"
],
"sources": {
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
"https://api.nuget.org/v3/index.json": {}
},
"frameworks": {
"net8.0": {
"targetAlias": "net8.0",
"projectReferences": {}
}
},
"warningProperties": {
"warnAsError": [
"NU1605"
]
},
"restoreAuditProperties": {
"enableAudit": "true",
"auditLevel": "low",
"auditMode": "direct"
},
"SdkAnalysisLevel": "9.0.300"
},
"frameworks": {
"net8.0": {
"targetAlias": "net8.0",
"dependencies": {
"xunit.v3.mtp-v2": {
"target": "Package",
"version": "[3.2.2, )"
}
},
"imports": [
"net461",
"net462",
"net47",
"net471",
"net472",
"net48",
"net481"
],
"assetTargetFallback": true,
"warn": true,
"frameworkReferences": {
"Microsoft.NETCore.App": {
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.301/PortableRuntimeIdentifierGraph.json"
}
}
}
}
}

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\Minimata\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.14.0</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="C:\Users\Minimata\.nuget\packages\" />
<SourceRoot Include="C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages\" />
</ItemGroup>
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)microsoft.testing.platform\2.0.2\buildTransitive\net8.0\Microsoft.Testing.Platform.props" Condition="Exists('$(NuGetPackageRoot)microsoft.testing.platform\2.0.2\buildTransitive\net8.0\Microsoft.Testing.Platform.props')" />
<Import Project="$(NuGetPackageRoot)microsoft.testing.platform.msbuild\2.0.2\buildTransitive\Microsoft.Testing.Platform.MSBuild.props" Condition="Exists('$(NuGetPackageRoot)microsoft.testing.platform.msbuild\2.0.2\buildTransitive\Microsoft.Testing.Platform.MSBuild.props')" />
<Import Project="$(NuGetPackageRoot)microsoft.testing.extensions.telemetry\2.0.2\buildTransitive\net8.0\Microsoft.Testing.Extensions.Telemetry.props" Condition="Exists('$(NuGetPackageRoot)microsoft.testing.extensions.telemetry\2.0.2\buildTransitive\net8.0\Microsoft.Testing.Extensions.Telemetry.props')" />
<Import Project="$(NuGetPackageRoot)xunit.v3.core.mtp-v2\3.2.2\buildTransitive\xunit.v3.core.mtp-v2.props" Condition="Exists('$(NuGetPackageRoot)xunit.v3.core.mtp-v2\3.2.2\buildTransitive\xunit.v3.core.mtp-v2.props')" />
</ImportGroup>
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Pkgxunit_analyzers Condition=" '$(Pkgxunit_analyzers)' == '' ">C:\Users\Minimata\.nuget\packages\xunit.analyzers\1.27.0</Pkgxunit_analyzers>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)microsoft.testing.platform\2.0.2\buildTransitive\net8.0\Microsoft.Testing.Platform.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.testing.platform\2.0.2\buildTransitive\net8.0\Microsoft.Testing.Platform.targets')" />
<Import Project="$(NuGetPackageRoot)microsoft.testing.platform.msbuild\2.0.2\buildTransitive\Microsoft.Testing.Platform.MSBuild.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.testing.platform.msbuild\2.0.2\buildTransitive\Microsoft.Testing.Platform.MSBuild.targets')" />
<Import Project="$(NuGetPackageRoot)xunit.v3.core.mtp-v2\3.2.2\buildTransitive\xunit.v3.core.mtp-v2.targets" Condition="Exists('$(NuGetPackageRoot)xunit.v3.core.mtp-v2\3.2.2\buildTransitive\xunit.v3.core.mtp-v2.targets')" />
</ImportGroup>
</Project>

1160
obj/project.assets.json Normal file

File diff suppressed because it is too large Load Diff

28
obj/project.nuget.cache Normal file
View File

@@ -0,0 +1,28 @@
{
"version": 2,
"dgSpecHash": "C+vE0OBbgVo=",
"success": true,
"projectFilePath": "D:\\Godot\\Projects\\movement-tests\\movement-tests.csproj",
"expectedPackageFiles": [
"C:\\Users\\Minimata\\.nuget\\packages\\microsoft.applicationinsights\\2.23.0\\microsoft.applicationinsights.2.23.0.nupkg.sha512",
"C:\\Users\\Minimata\\.nuget\\packages\\microsoft.bcl.asyncinterfaces\\6.0.0\\microsoft.bcl.asyncinterfaces.6.0.0.nupkg.sha512",
"C:\\Users\\Minimata\\.nuget\\packages\\microsoft.netcore.platforms\\5.0.0\\microsoft.netcore.platforms.5.0.0.nupkg.sha512",
"C:\\Users\\Minimata\\.nuget\\packages\\microsoft.testing.extensions.telemetry\\2.0.2\\microsoft.testing.extensions.telemetry.2.0.2.nupkg.sha512",
"C:\\Users\\Minimata\\.nuget\\packages\\microsoft.testing.extensions.trxreport.abstractions\\2.0.2\\microsoft.testing.extensions.trxreport.abstractions.2.0.2.nupkg.sha512",
"C:\\Users\\Minimata\\.nuget\\packages\\microsoft.testing.platform\\2.0.2\\microsoft.testing.platform.2.0.2.nupkg.sha512",
"C:\\Users\\Minimata\\.nuget\\packages\\microsoft.testing.platform.msbuild\\2.0.2\\microsoft.testing.platform.msbuild.2.0.2.nupkg.sha512",
"C:\\Users\\Minimata\\.nuget\\packages\\microsoft.win32.registry\\5.0.0\\microsoft.win32.registry.5.0.0.nupkg.sha512",
"C:\\Users\\Minimata\\.nuget\\packages\\system.diagnostics.diagnosticsource\\5.0.0\\system.diagnostics.diagnosticsource.5.0.0.nupkg.sha512",
"C:\\Users\\Minimata\\.nuget\\packages\\system.security.accesscontrol\\5.0.0\\system.security.accesscontrol.5.0.0.nupkg.sha512",
"C:\\Users\\Minimata\\.nuget\\packages\\system.security.principal.windows\\5.0.0\\system.security.principal.windows.5.0.0.nupkg.sha512",
"C:\\Users\\Minimata\\.nuget\\packages\\xunit.analyzers\\1.27.0\\xunit.analyzers.1.27.0.nupkg.sha512",
"C:\\Users\\Minimata\\.nuget\\packages\\xunit.v3.assert\\3.2.2\\xunit.v3.assert.3.2.2.nupkg.sha512",
"C:\\Users\\Minimata\\.nuget\\packages\\xunit.v3.common\\3.2.2\\xunit.v3.common.3.2.2.nupkg.sha512",
"C:\\Users\\Minimata\\.nuget\\packages\\xunit.v3.core.mtp-v2\\3.2.2\\xunit.v3.core.mtp-v2.3.2.2.nupkg.sha512",
"C:\\Users\\Minimata\\.nuget\\packages\\xunit.v3.extensibility.core\\3.2.2\\xunit.v3.extensibility.core.3.2.2.nupkg.sha512",
"C:\\Users\\Minimata\\.nuget\\packages\\xunit.v3.mtp-v2\\3.2.2\\xunit.v3.mtp-v2.3.2.2.nupkg.sha512",
"C:\\Users\\Minimata\\.nuget\\packages\\xunit.v3.runner.common\\3.2.2\\xunit.v3.runner.common.3.2.2.nupkg.sha512",
"C:\\Users\\Minimata\\.nuget\\packages\\xunit.v3.runner.inproc.console\\3.2.2\\xunit.v3.runner.inproc.console.3.2.2.nupkg.sha512"
],
"logs": []
}

View File

@@ -28,7 +28,8 @@ ProjectMusicController="*uid://r5t485lr3p7t"
ProjectUISoundController="*uid://cc37235kj4384"
Shaker="*uid://c7flmumgr5w3u"
CsgToolkitAutoload="*uid://w8ad8q4lneis"
"Forge Bootstrap"="uid://ba8fquhtwu5mu"
"Forge Bootstrap"="*uid://ba8fquhtwu5mu"
GlobalHelpers="*uid://dqcm83o8e66a2"
[display]

View File

@@ -7,7 +7,7 @@ using Movementtests.systems.damage;
[GlobalClass]
public partial class RDamageModifier : Resource, IDamageable
{
public event Action<IDamageable, DamageRecord> DamageTaken;
public event Action<IDamageable, DamageRecord> DamageTaken = null!;
[Export]
public EDamageTypes DamageType { get; set;}

View File

@@ -5,11 +5,11 @@ using Movementtests.interfaces;
[GlobalClass, Icon("res://assets/ui/IconGodotNode/white/icon_heart.png")]
public partial class CHealth : Node, IHealthable
{
public event Action<IHealthable, HealthChangedRecord> HealthChanged;
public event Action<IHealthable> HealthDepleted;
public event Action<IHealthable, HealthChangedRecord> HealthChanged = null!;
public event Action<IHealthable> HealthDepleted = null!;
[Export]
public RHealth RHealth { get; set; }
public RHealth RHealth { get; set; } = null!;
public float CurrentHealth { get; set; }

View File

@@ -5,9 +5,9 @@ using Movementtests.interfaces;
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_wind.png")]
public partial class CKnockback : Node3D, IKnockbackable
{
[Export] public RKnockback RKnockback { get; set;}
[Export] public RKnockback RKnockback { get; set;} = null!;
private KnockbackRecord _knockbackRecord = null;
private KnockbackRecord _knockbackRecord = null!;
public void RegisterKnockback(KnockbackRecord knockbackRecord)
{
@@ -20,7 +20,7 @@ public partial class CKnockback : Node3D, IKnockbackable
var knockbackDirection = GlobalPosition - _knockbackRecord.DamageRecord.SourceLocation;
var finalKnockback = knockbackDirection.Normalized() * RKnockback.Modifier * _knockbackRecord.ForceMultiplier;
_knockbackRecord = null;
_knockbackRecord = null!;
return finalKnockback;
}
}

View File

@@ -6,10 +6,9 @@ namespace Movementtests.scenes.movement;
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_path_follow.png")]
public partial class CGroundedMovement : Node3D, IMoveable
{
[Export] public RMovement RMovement { get; set; }
[Export] public RMovement RMovement { get; set; } = null!;
[Export]
public RayCast3D WallInFrontRayCast { get; set; }
[Export] public RayCast3D WallInFrontRayCast { get; set; } = null!;
public Vector3 ComputeVelocity(MovementInputs inputs)

View File

@@ -16,36 +16,37 @@ public partial class Enemy : CharacterBody3D,
IStunnable
{
// Signals and events
public event Action<IDamageable, DamageRecord> DamageTaken;
public event Action<IHealthable, HealthChangedRecord> HealthChanged;
public event Action<IHealthable> HealthDepleted;
public event Action<IDamageable, DamageRecord> DamageTaken = null!;
public event Action<IHealthable, HealthChangedRecord> HealthChanged = null!;
public event Action<IHealthable> HealthDepleted = null!;
// Public export components
[Export]
public Node3D Target { get; set; }
public Node3D Target { get; set; } = null!;
[Export]
public float EnemyHeight { get; set; } = 1f;
[ExportGroup("Health")]
[Export]
public RHealth RHealth { get; set; }
public RHealth RHealth { get; set; } = null!;
[Export]
public RDeathEffect[] DeathEffects { get; set; }
public IHealthable CHealth { get; set; }
public RDeathEffect[] DeathEffects { get; set; } = null!;
public IHealthable CHealth { get; set; } = null!;
[ExportGroup("Damage")]
[Export]
public RDamage RDamage { get; set; }
public IDamageable CDamageable { get; set; }
public RDamage RDamage { get; set; } = null!;
public IDamageable CDamageable { get; set; } = null!;
[Export]
public RKnockback RKnockback { get; set; }
public IKnockbackable CKnockback { get; set; }
public RKnockback RKnockback { get; set; } = null!;
public IKnockbackable CKnockback { get; set; } = null!;
[ExportGroup("Movement")]
[Export]
public RMovement RMovement { get; set; }
public IMoveable CMovement { get; set; }
public RMovement RMovement { get; set; } = null!;
public IMoveable CMovement { get; set; } = null!;
// Public stuff
public float CurrentHealth
@@ -55,9 +56,9 @@ public partial class Enemy : CharacterBody3D,
}
// Private stuff
private Area3D _damageBox;
private Node3D _target;
private Healthbar _healthbar;
private Area3D _damageBox = null!;
internal Node3D _target = null!;
private Healthbar _healthbar = null!;
public override void _Ready()
{
@@ -70,34 +71,28 @@ public partial class Enemy : CharacterBody3D,
_damageBox = GetNode<Area3D>("DamageBox");
_target = GetNode<Node3D>("CTarget");
CDamageable = GetNode<Node>("CDamageable") as IDamageable;
CMovement = GetNode<Node>("CMovement") as IMoveable;
CHealth = GetNode<Node>("CHealth") as IHealthable;
CKnockback = GetNode<Node>("CKnockback") as IKnockbackable;
if (CDamageable is null) GD.PrintErr("This node needs a 'CDamage' child of type IDamageable!");
if (CMovement is null) GD.PrintErr("This node needs a 'CMovement' child of type IMoveable!");
if (CHealth is null) GD.PrintErr("This node needs a 'CHealth' child of type IHealthable!");
if (CKnockback is null) GD.PrintErr("This node needs a 'CKnockback' child of type IKnockbackable!");
CDamageable = (GetNode<Node>("CDamageable") as IDamageable)!;
CMovement = (GetNode<Node>("CMovement") as IMoveable)!;
CHealth = (GetNode<Node>("CHealth") as IHealthable)!;
CKnockback = (GetNode<Node>("CKnockback") as IKnockbackable)!;
_healthbar = GetNode<CHealthbar>("CHealthBar").Healthbar;
if (RMovement != null) CMovement!.RMovement = RMovement;
if (RHealth != null)
{
CHealth!.RHealth = RHealth;
CHealth.CurrentHealth = RHealth.StartingHealth;
}
if (RKnockback != null) CKnockback!.RKnockback = RKnockback;
_healthbar.Initialize(CHealth!.CurrentHealth);
CMovement.RMovement = RMovement;
CHealth.RHealth = RHealth;
CHealth.CurrentHealth = RHealth.StartingHealth;
CKnockback.RKnockback = RKnockback;
_healthbar.Initialize(CHealth.CurrentHealth);
}
public void SetupSignals()
{
// Anonymous function call to erase return values of ReduceHealth
CDamageable.DamageTaken += (source, record) => ReduceHealth(source, record);
CDamageable.DamageTaken += (source, record) => RegisterKnockback(new KnockbackRecord(record));
CDamageable.DamageTaken += (_, record) => RegisterKnockback(new KnockbackRecord(record));
CHealth.HealthDepleted += Kill;
HealthChanged += (source, record) => _healthbar.SetHealth(record.CurrentHealth);
HealthChanged += (_, record) => _healthbar.SetHealth(record.CurrentHealth);
}
public override void _PhysicsProcess(double delta)
@@ -187,24 +182,21 @@ public partial class Enemy : CharacterBody3D,
public void RegisterKnockback(KnockbackRecord knockbackRecord)
{
if (CKnockback is null) return;
CKnockback.RegisterKnockback(knockbackRecord);
}
public Vector3 ComputeKnockback()
{
if (CKnockback is null) return Vector3.Zero;
return CKnockback.ComputeKnockback();
}
public Vector3 GetTargetGlobalPosition()
{
if (_target is null) return GlobalPosition;
return _target.GlobalPosition;
return _target == null ? GlobalPosition : _target.GlobalPosition;
}
// Stun management
public bool IsStunned { get; set; } = false;
public bool IsStunned { get; set; }
[Export(PropertyHint.Range, "0.1, 2, 0.1, or_greater")]
public float StunDuration { get; set; } = 1f;

View File

@@ -77,6 +77,9 @@ radius = 0.45
[sub_resource type="SphereShape3D" id="SphereShape3D_q14ux"]
radius = 1.0
[sub_resource type="SphereShape3D" id="SphereShape3D_u8rdp"]
radius = 1.5
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_nodcl"]
transparency = 1
albedo_color = Color(0, 0.627451, 0.6313726, 0.49019608)
@@ -156,8 +159,9 @@ WallHugDownwardMaxSpeed = 4.0
WallHugHorizontalDeceleration = 1.0
WallRunUpwardVelocityFactor = 0.5
MinimumWallRunUpwardSpeed = 4.0
MinimumWallRunHorizontalSpeed = 8.0
WallRunAltitudeLossSpeed = 8.0
WallRunSpeedThreshold = 7.0
WallRunSpeedThreshold = 1.0
[node name="CHealth" parent="." unique_id=1244478698 instance=ExtResource("3_q7bng")]
RHealth = ExtResource("4_m8gvy")
@@ -328,6 +332,14 @@ gravity_scale = 3.0
ThrowForce = 300.0
StraightThrowDuration = 0.05
[node name="SwordPickup" type="Area3D" parent="." unique_id=1990087390]
collision_layer = 0
collision_mask = 65536
[node name="CollisionShape3D" type="CollisionShape3D" parent="SwordPickup" unique_id=547241277]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
shape = SubResource("SphereShape3D_u8rdp")
[node name="DashIndicator" type="Node3D" parent="." unique_id=1279477982]
visible = false
@@ -384,6 +396,10 @@ shape = SubResource("SphereShape3D_ue7xq")
[node name="InvincibilityTime" type="Timer" parent="." unique_id=1244463585]
one_shot = true
[node name="WeaponThrowUncatchable" type="Timer" parent="." unique_id=2141801011]
wait_time = 0.2
one_shot = true
[node name="AttackCooldown" type="Timer" parent="." unique_id=1620959518]
wait_time = 0.3
one_shot = true
@@ -400,7 +416,7 @@ wait_time = 2.0
one_shot = true
[node name="TimeScaleAimInAir" type="Timer" parent="." unique_id=1346687662]
wait_time = 2.0
wait_time = 5.0
one_shot = true
ignore_time_scale = true
@@ -409,6 +425,7 @@ offset_left = 1524.0
offset_top = 1.0
offset_right = -8.0
offset_bottom = 1.0
enabled = false
initial_node_to_watch = NodePath("../StateChart")
[node name="UI" type="Control" parent="." unique_id=856532641]
@@ -1103,8 +1120,8 @@ delay_in_seconds = "0.0"
[node name="OnJump" type="Node" parent="StateChart/Root/Movement/OnWall" unique_id=342055859]
script = ExtResource("28_n7qhm")
to = NodePath("../../Jump/SimpleJump")
event = &"jump"
to = NodePath("../../Jump/DoubleJump")
event = &"wall_jump"
delay_in_seconds = "0.0"
[node name="OnDash" type="Node" parent="StateChart/Root/Movement/OnWall" unique_id=43147957]
@@ -1113,6 +1130,18 @@ to = NodePath("../../Dashing/Dash")
event = &"dash"
delay_in_seconds = "0.0"
[node name="OnSlam" type="Node" parent="StateChart/Root/Movement/OnWall" unique_id=448306362]
script = ExtResource("28_n7qhm")
to = NodePath("../../Slamming")
event = &"slam"
delay_in_seconds = "0.0"
[node name="OnMantle2" type="Node" parent="StateChart/Root/Movement/OnWall" unique_id=7136911]
script = ExtResource("28_n7qhm")
to = NodePath("../../Mantling")
event = &"mantle"
delay_in_seconds = "0.0"
[node name="Hugging" type="Node" parent="StateChart/Root/Movement/OnWall" unique_id=162057636]
script = ExtResource("27_34snm")
@@ -1125,9 +1154,21 @@ delay_in_seconds = "0.0"
[node name="Hanging" type="Node" parent="StateChart/Root/Movement/OnWall" unique_id=1208015492]
script = ExtResource("27_34snm")
[node name="OnMove" type="Node" parent="StateChart/Root/Movement/OnWall/Hanging" unique_id=751408886]
script = ExtResource("28_n7qhm")
to = NodePath("../../Hugging")
event = &"move"
delay_in_seconds = "0.0"
[node name="Running" type="Node" parent="StateChart/Root/Movement/OnWall" unique_id=766545186]
script = ExtResource("27_34snm")
[node name="OnJump" type="Node" parent="StateChart/Root/Movement/OnWall/Running" unique_id=1699673966]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Jump/SimpleJump")
event = &"wall_jump"
delay_in_seconds = "0.0"
[node name="OnLeaveWall" type="Node" parent="StateChart/Root/Movement/OnWall/Running" unique_id=73239479]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Airborne/CoyoteEnabled")
@@ -1158,3 +1199,4 @@ delay_in_seconds = "0.0"
[connection signal="input_slide_ended" from="InputController" to="." method="OnInputSlideEnded"]
[connection signal="input_slide_started" from="InputController" to="." method="OnInputSlideStarted"]
[connection signal="WallDetected" from="WallHugSystem" to="." method="OnWallDetected"]
[connection signal="body_entered" from="SwordPickup" to="." method="WalkOnWeapon"]

View File

@@ -5,7 +5,7 @@ using Movementtests.interfaces;
[GlobalClass, Icon("res://assets/ui/IconGodotNode/control/icon_text_panel.png")]
public partial class PlayerUi : Control
{
private TextureRect[] _dashIcons = new TextureRect[3];
internal TextureRect[] _dashIcons = new TextureRect[3];
private TextureRect _enemyTarget;
private Healthbar _healthbar;

View File

@@ -26,18 +26,18 @@ public partial class DashSystem: Node3D
public Vector3 PlannedMantleLocation { get; set; }
public MantleSystem MantleSystem { get; set; }
private HeadSystem _head;
internal HeadSystem _head;
public ShapeCast3D DashCast3D;
private Camera3D _camera;
private Vector3 _dashDirection = Vector3.Zero;
internal Camera3D _camera;
internal Vector3 _dashDirection = Vector3.Zero;
private ShapeCast3D _dashCastDrop;
private MeshInstance3D _dashDropIndicator;
private MeshInstance3D _dashDropLocationIndicator;
internal ShapeCast3D _dashCastDrop;
internal MeshInstance3D _dashDropIndicator;
internal MeshInstance3D _dashDropLocationIndicator;
private MeshInstance3D _dashTarget;
private CpuParticles3D _dashIndicator;
private AnimationPlayer _dashIndicatorAnim;
internal MeshInstance3D _dashTarget;
internal CpuParticles3D _dashIndicator;
internal AnimationPlayer _dashIndicatorAnim;
[Export]
public PackedScene DashIndicatorScene { get; set; }
@@ -77,7 +77,7 @@ public partial class DashSystem: Node3D
_dashIndicatorAnim = GetNode<AnimationPlayer>("DashIndicator/AnimationPlayer");
}
private DashLocation ComputeDashLocation()
internal DashLocation ComputeDashLocation()
{
var targetLocation = DashCast3D.ToGlobal(DashCast3D.TargetPosition);
var hasHit = DashCast3D.IsColliding();

View File

@@ -39,10 +39,10 @@ public partial class HeadSystem : Node3D
float BobbingMultiplier,
float FovMultiplier);
private Camera3D _camera;
private Marker3D _cameraAnchor;
private AnimationPlayer _animationPlayer;
private AnimationTree _animationTree;
internal Camera3D _camera;
internal Marker3D _cameraAnchor;
internal AnimationPlayer _animationPlayer;
internal AnimationTree _animationTree;
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
public float LookSensitivity { get; set; } = 1f;
@@ -63,11 +63,11 @@ public partial class HeadSystem : Node3D
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float SlidingJitterAmplitude { get; set; } = 0.1f;
private FastNoiseLite _slidingNoise = new FastNoiseLite();
internal FastNoiseLite _slidingNoise = new FastNoiseLite();
[ExportGroup("Bobbing")]
private float _bobbingAccumulator; // Constantly increases when player moves in X or/and Z axis
internal float _bobbingAccumulator; // Constantly increases when player moves in X or/and Z axis
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
public float BobbingFrequency { set; get; } = 2.4f;
[Export(PropertyHint.Range, "0,0.4,0.01,or_greater")]
@@ -84,11 +84,11 @@ public partial class HeadSystem : Node3D
public float FovMaxedOutSpeed { get; set; } = 20f;
[ExportGroup("First Person rig")]
private Node3D _fpRig;
private Node3D _rightHandedWeapon;
private Node3D _leftHandedWeapon;
private Node3D _fpDisplacedRig;
private Vector3 _fpDisplacedRigInitialRotation;
internal Node3D _fpRig;
internal Node3D _rightHandedWeapon;
internal Node3D _leftHandedWeapon;
internal Node3D _fpDisplacedRig;
internal Vector3 _fpDisplacedRigInitialRotation;
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
public float WeaponSway { get; set; } = 5f;
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
@@ -190,8 +190,13 @@ public partial class HeadSystem : Node3D
EmitSignalHitboxDeactivated();
}
private bool _footstepEmitted;
private bool _isPlayingForcingAnim;
internal bool _footstepEmitted;
internal bool _isPlayingForcingAnim;
public void ResetHeadBobbing()
{
_bobbingAccumulator = 0;
}
public void LookAround(CameraParameters inputs)
{

View File

@@ -372,7 +372,7 @@ tracks/3/keys = {
}
tracks/4/type = "method"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/enabled = false
tracks/4/path = NodePath("../..")
tracks/4/interp = 1
tracks/4/loop_wrap = true
@@ -579,7 +579,7 @@ tracks/3/keys = {
}
tracks/4/type = "method"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/enabled = false
tracks/4/path = NodePath("../..")
tracks/4/interp = 1
tracks/4/loop_wrap = true

View File

@@ -245,7 +245,7 @@ public partial class PlayerController : CharacterBody3D,
public float MinimumWallRunHorizontalSpeed { get; set; } = 12f;
[Export(PropertyHint.Range, "1,20,0.1,or_greater")]
public float WallRunAltitudeLossSpeed { get; set; } = 10f;
[Export(PropertyHint.Range, "1,20,0.1,or_greater")]
[Export(PropertyHint.Range, "0,20,0.1,or_greater")]
public float WallRunSpeedThreshold { get; set; } = 8f;
///////////////////////////
@@ -265,8 +265,8 @@ public partial class PlayerController : CharacterBody3D,
private float _inputRotateFloorplane;
// Basic falling
private float _targetSpeed;
private float _gravity;
internal float _targetSpeed;
internal float _gravity;
// Jump stuff
private int _currentInputBufferFrames;
@@ -290,7 +290,7 @@ public partial class PlayerController : CharacterBody3D,
private Vector3 _currentWallContactPoint = Vector3.Zero;
// Dash stuff
private bool _canDash = true;
internal bool _canDash = true;
private bool _canDashAirborne = true;
private float _playerHeight;
private float _playerRadius;
@@ -317,6 +317,7 @@ public partial class PlayerController : CharacterBody3D,
// Timers
private Timer _timeScaleAimInAirTimer;
private Timer _weaponThrowUncatchableTimer;
private Timer _simpleDashCooldownTimer;
private Timer _airborneDashCooldownTimer;
private Timer _powerCooldownTimer;
@@ -359,6 +360,7 @@ public partial class PlayerController : CharacterBody3D,
private Transition _onJumpFromWall;
private Transition _onJumpFromWallFalling;
private Transition _onJumpFromWallRunning;
private Transition _onLeaveWallFromRun;
private Transition _onAirborneToGrounded;
@@ -501,6 +503,7 @@ public partial class PlayerController : CharacterBody3D,
_mantling = StateChartState.Of(GetNode("StateChart/Root/Movement/Mantling"));
_onJumpFromWall = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/OnJump"));
_onJumpFromWallFalling = Transition.Of(GetNode("StateChart/Root/Movement/Airborne/Falling/OnWallJump"));
_onJumpFromWallRunning = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/Running/OnJump"));
_onWall = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall"));
_onWallHugging = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall/Hugging"));
_onWallHanging = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall/Hanging"));
@@ -516,6 +519,7 @@ public partial class PlayerController : CharacterBody3D,
// State timers
_powerCooldownTimer = GetNode<Timer>("PowerCooldown");
_weaponThrowUncatchableTimer = GetNode<Timer>("WeaponThrowUncatchable");
_timeScaleAimInAirTimer = GetNode<Timer>("TimeScaleAimInAir");
_simpleDashCooldownTimer = GetNode<Timer>("DashCooldown");
_airborneDashCooldownTimer = GetNode<Timer>("AirborneDashCooldown");
@@ -562,6 +566,7 @@ public partial class PlayerController : CharacterBody3D,
_grounded.StateEntered += OnGrounded;
_grounded.StatePhysicsProcessing += HandleGrounded;
_airborne.StateEntered += OnAirborne;
_airborne.StatePhysicsProcessing += HandleAirborne;
_onWall.StatePhysicsProcessing += HandleOnWall;
@@ -626,6 +631,7 @@ public partial class PlayerController : CharacterBody3D,
_onJumpFromWall.Taken += OnJumpFromWall;
_onJumpFromWallFalling.Taken += OnJumpFromWall;
_onJumpFromWallRunning.Taken += OnJumpFromWall;
_onLeaveWallFromRun.Taken += OnLeaveWallFromRun;
_onAirborneToGrounded.Taken += OnAirborneToGrounded;
@@ -711,11 +717,11 @@ public partial class PlayerController : CharacterBody3D,
{
_isWallJumpAvailable = true;
_canDashAirborne = true;
ResetTimeScale();
if (_simpleDashCooldownTimer.IsStopped())
_simpleDashCooldownTimer.Start();
if (_bufferedAction == BufferedActions.MantleJump)
{
_playerState.SendEvent("jump");
@@ -852,6 +858,13 @@ public partial class PlayerController : CharacterBody3D,
///////////////////////////
// Airborne management //
///////////////////////////
public void OnAirborne()
{
if (_aiming.Active)
ReduceTimeScaleWhileAiming();
}
public void HandleAirborne(float delta)
{
MoveInAir(delta, IsGroundLike());
@@ -866,9 +879,9 @@ public partial class PlayerController : CharacterBody3D,
return;
}
// Going upwards, we stay simply airborne
if (Velocity.AngleTo(Vector3.Up) < Math.PI / 4)
return;
// // Going upwards, we stay simply airborne
// if (Velocity.AngleTo(Vector3.Up) < Math.PI / 4)
// return;
// Should we start a wall run
if (ShouldStartWallRun())
@@ -1178,13 +1191,15 @@ public partial class PlayerController : CharacterBody3D,
}
public void OnWallDetected()
{
if (!_onWall.Active)
return;
// if (!_onWall.Active)
// return;
var newWallNormal = WallHugSystem.WallHugNormal.UnwrapOr(Vector3.Up);
if (newWallNormal.AngleTo(_wallHugStartNormal) > Mathf.Pi/4) return;
if (newWallNormal.AngleTo(_wallHugStartNormal) > Mathf.Pi/4 && _onWall.Active) return;
_wallHugStartNormal = newWallNormal;
}
public void OnWallStarted()
{
if (_simpleDashCooldownTimer.IsStopped())
@@ -1212,15 +1227,18 @@ public partial class PlayerController : CharacterBody3D,
// _canDash = true;
// _canDashAirborne = true;
WallHug(delta);
if (ShouldStartWallRun())
{
_playerState.SendEvent("wall_run");
return;
}
if (IsInputTowardsWall(_wallHugStartNormal))
WallHug(delta);
else
MoveInAir(delta, IsGroundLike());
// if (ShouldStartWallRun())
// {
// _playerState.SendEvent("wall_run");
// return;
// }
if (isOnFloorCustom())
_playerState.SendEvent("grounded");
if (!WallHugSystem.IsWallHugging() || !IsInputTowardsWall(_wallHugStartNormal))
if (!WallHugSystem.IsWallHugging())
_playerState.SendEvent("start_falling");
}
public void HandleWallHanging(float delta)
@@ -1253,15 +1271,17 @@ public partial class PlayerController : CharacterBody3D,
// Adapt vertical speed
var verticalSpeed = Velocity.Y - WallRunAltitudeLossSpeed * delta;
Velocity = finalHVel + Vector3.Up*verticalSpeed;
// Velocity *= 0.999f;
Velocity *= 0.999f;
_currentWallContactPoint = WallHugSystem.WallHugLocation.UnwrapOr(Vector3.Zero);
if (MantleSystem.IsMantlePossible && IsPlayerInputtingForward())
_playerState.SendEvent("mantle");
if (isOnFloorCustom())
_playerState.SendEvent("grounded");
if (!WallHugSystem.IsWallHugging())
_playerState.SendEvent("start_falling");
if (Velocity.Length() < WallRunSpeedThreshold / 2f)
if (!CanKeepWallRun())
_playerState.SendEvent("wall_hug");
}
@@ -1274,27 +1294,88 @@ public partial class PlayerController : CharacterBody3D,
public bool ShouldStartWallRun()
{
var wallNormal = WallHugSystem.WallHugNormal.UnwrapOr(Vector3.Zero);
var isIndeedWall = wallNormal.Y < 0.1;
if (_wallHugStartNormal.Length() < Mathf.Epsilon)
{
// GD.Print("No wall normal");
return false;
}
var isIndeedWall = _wallHugStartNormal.Y < 0.1;
if (!isIndeedWall)
{
// GD.Print("Not a wall");
return false;
}
var isThereInput = GetMoveInput().Length() > Mathf.Epsilon;
if (!isThereInput)
{
// GD.Print("No input");
return false;
}
if (!IsInputForwardOrTowardsWall())
{
// GD.Print("Input isn't forward or towards wall");
return false;
}
var canUseVelocity = Velocity.Length() > WallRunSpeedThreshold;
if (!canUseVelocity)
{
// GD.Print("Not enough speed");
return false;
}
var hvel = new Vector3(Velocity.X, 0, Velocity.Z);
var hvelProjected = hvel.Slide(_wallHugStartNormal);
var haveEnoughSpeed = hvelProjected.Length() > WallRunSpeedThreshold;
if (!haveEnoughSpeed)
{
// GD.Print("Not enough projected speed");
return false;
}
var isCoplanarEnough = Math.Abs(Velocity.Normalized().Dot(_wallHugStartNormal)) < 0.9;
if (!isCoplanarEnough)
{
// GD.Print("Not coplanar enough");
return false;
}
var isGoingDownwards = Velocity.Normalized().Dot(Vector3.Down) > 0.7;
if (isGoingDownwards)
{
// GD.Print("Going down");
return false;
}
var isLookingInDirectionOfRun = hvelProjected.Normalized().Dot(-HeadSystem.GetForwardHorizontalVector()) > 0.5;
if (!isLookingInDirectionOfRun)
{
// GD.Print("Not looking in direction of run");
return false;
}
return true;
}
public bool IsInputForwardOrTowardsWall()
{
return IsPlayerInputtingForward() || IsInputTowardsWall(_wallHugStartNormal);
}
public bool CanKeepWallRun()
{
var isThereInput = GetMoveInput().Length() > Mathf.Epsilon;
if (!isThereInput) return false;
if (!IsInputForwardOrTowardsWall()) return false;
var haveEnoughSpeed = Velocity.Length() > WallRunSpeedThreshold;
var isCoplanarEnough = Velocity.AngleTo(wallNormal) > Math.PI/4 && Velocity.AngleTo(wallNormal) < 3*Math.PI/4;
var isGoingDownwards = Velocity.AngleTo(Vector3.Down) < Math.PI/4;
var isLookingInDirectionOfRun = hvelProjected.AngleTo(-HeadSystem.GetForwardHorizontalVector()) < Math.PI/2;
var shouldStart = haveEnoughSpeed && !isGoingDownwards && isIndeedWall && isCoplanarEnough && isLookingInDirectionOfRun;
if (!haveEnoughSpeed) return false;
var debugText = "--------------\n";
debugText += shouldStart ? "WALL RUN STARTED\n" : "NO WALL RUN\n";
debugText += $"Enough speed? {haveEnoughSpeed}\n";
debugText += $"Coplanar enough? {isCoplanarEnough}\n";
debugText += $"Going downwards? {isGoingDownwards} with angle {Velocity.AngleTo(Vector3.Down)}\n";
debugText += $"Is looking in direction of run? {isLookingInDirectionOfRun} with angle {hvelProjected.AngleTo(-HeadSystem.GetForwardHorizontalVector())}\n";
debugText += $"HVelocity on wall: {hvelProjected} - Forward H Vector: {-HeadSystem.GetForwardHorizontalVector()}\n";
debugText += "--------------\n";
//GD.Print(debugText);
return shouldStart;
return true;
}
public void WallHug(float delta)
@@ -1309,6 +1390,8 @@ public partial class PlayerController : CharacterBody3D,
{
Velocity = Vector3.Zero;
GlobalPosition = _wallHugStartLocation;
if (GetGlobalMoveInput().Length() > Mathf.Epsilon)
_playerState.SendEvent("move");
}
public bool IsFacingWall()
{
@@ -1354,10 +1437,14 @@ public partial class PlayerController : CharacterBody3D,
return;
}
if (WallHugSystem.IsWallHugging())
if (_onWall.Active) // Always allow jumping out of wall run and hang
{
_playerState.SendEvent("wall_jump");
return;
}
// Regular jump
_playerState.SendEvent("jump");
}
@@ -1453,13 +1540,13 @@ public partial class PlayerController : CharacterBody3D,
SetHorizontalVelocity(currentHorizontalVelocity + wallJumpHorizontalVelocity);
}
public void OnJumpFromWall()
{
if (!IsFacingWall() || (!_isWallJumpAvailable && IsFacingWall()))
{
if (!IsFacingWall() || (!_isWallJumpAvailable && IsFacingWall()) || _onWallRunning.Active)
ComputeJumpFromWallHSpeed(WallJumpStartVelocity);
}
// OnJumpStarted(DoubleJumpStartVelocity);
// Remove the ability to dash straight away so you cannot scale up the wall
// _canDashAirborne = false;
_airborneDashCooldownTimer.Start();
@@ -1514,6 +1601,10 @@ public partial class PlayerController : CharacterBody3D,
// SimpleDashInDirection(directionHorizontal.Normalized());
SetVelocity(directionHorizontal.Normalized() * _velocityOnMantleStarted.Length());
}
else
{
SetVelocity(Vector3.Zero);
}
_customMantle = false;
_playerState.SendEvent("grounded");
@@ -1825,7 +1916,7 @@ public partial class PlayerController : CharacterBody3D,
public void ReduceTimeScaleWhileAiming()
{
Engine.SetTimeScale(TimeScaleAimInAir);
_timeScaleAimInAirTimer.Start();
// _timeScaleAimInAirTimer.Start();
}
public void ResetTimeScale()
{
@@ -1892,7 +1983,7 @@ public partial class PlayerController : CharacterBody3D,
var plannedDashLocation = targetable.GetTargetGlobalPosition() + Vector3.Down*_playerHeight/2;
travel = plannedDashLocation - GlobalPosition;
_dashDirection = travel.Normalized();
var postDashLocation = plannedDashLocation + 2*_dashDirection;
var postDashLocation = plannedDashLocation + _dashDirection;
var wallBehindQuery = PhysicsRayQueryParameters3D.Create(GlobalPosition + Vector3.Up*HeadSystem.Position.Y, postDashLocation, GroundDetector.CollisionMask);
var wallBehindResult = _spaceState.IntersectRay(wallBehindQuery);
shouldRebound = wallBehindResult.Count > 0;
@@ -1960,6 +2051,7 @@ public partial class PlayerController : CharacterBody3D,
public void ThrowWeapon()
{
_audioStream.SwitchToClipByName("attacks");
_weaponThrowUncatchableTimer.Start();
_playerState.SendEvent("cancel_aim");
RemoveChildNode(WeaponSystem);
@@ -1980,6 +2072,7 @@ public partial class PlayerController : CharacterBody3D,
HeadSystem.ShowWeapon();
WeaponSystem.ResetWeapon();
RecoverChildNode(WeaponSystem);
_audioStream.SwitchToClipByName("parry");
}
public void DashToFlyingWeapon()
@@ -2041,6 +2134,8 @@ public partial class PlayerController : CharacterBody3D,
}
public void DashToPlantedWeaponTweenEnded()
{
HeadSystem.ResetHeadBobbing();
// Store the weapon state before resetting it
var isPlantedOnWall = WeaponSystem.IsPlantedInWall();
var isPlantedUnderPlatform = WeaponSystem.IsPlantedUnderPlatform();
@@ -2061,6 +2156,16 @@ public partial class PlayerController : CharacterBody3D,
_playerState.SendEvent(resultingEvent);
}
public void WalkOnWeapon(Node3D other)
{
if (_weaponDash.Active) return; // Don't recover weapon if already dashing to it
if (WeaponSystem.InHandState.Active) return; // Don't recover weapon if in hand
if (!_weaponThrowUncatchableTimer.IsStopped()) return; // Don't get weapon back if timer is still running
if (WeaponSystem.PlantObject is ITargetable) return; // Don't recover weapon planted in target
RecoverWeapon();
WeaponSystem.PlantObject = null;
}
public void ManageAttackedEnemyPostDash(Node enemy)
{
@@ -2213,6 +2318,9 @@ public partial class PlayerController : CharacterBody3D,
private PhysicsDirectSpaceState3D _spaceState;
public void StartDashAction(bool isParry)
{
if (isParry) HeadSystem.OnParry();
else HeadSystem.OnHit();
var streamName = isParry ? "parry" : "attacks";
_audioStream!.SwitchToClipByName(streamName);
IsInvincible = true;
@@ -2229,7 +2337,7 @@ public partial class PlayerController : CharacterBody3D,
var travel = plannedDashLocation - GlobalPosition;
_dashDirection = travel.Normalized();
var postDashLocation = plannedDashLocation + 2*_dashDirection;
var postDashLocation = plannedDashLocation + _dashDirection;
var wallBehindQuery = PhysicsRayQueryParameters3D.Create(GlobalPosition + Vector3.Up*HeadSystem.Position.Y, postDashLocation, GroundDetector.CollisionMask);
var wallBehindResult = _spaceState.IntersectRay(wallBehindQuery);
var shouldRebound = wallBehindResult.Count > 0;
@@ -2293,7 +2401,7 @@ public partial class PlayerController : CharacterBody3D,
if (_onWallHanging.Active) return;
if (_aiming.Active && WeaponSystem.InHandState.Active)
if (_aiming.Active && WeaponSystem.InHandState.Active && CanPerformEmpoweredAction())
{
ThrowWeapon();
return;

View File

@@ -1,6 +1,8 @@
[gd_scene format=3 uid="uid://b8aet6m4m2i83"]
[ext_resource type="Script" uid="uid://bnqhh6b5iusam" path="res://scenes/tuto_trigger/tuto_trigger.gd" id="1_w8mpv"]
[ext_resource type="Texture2D" uid="uid://dl73t0kxkaxp0" path="res://assets/ui/input-prompts/Xbox Series/Vector/xbox_button_a_outline.svg" id="2_w8mpv"]
[ext_resource type="Texture2D" uid="uid://cjh5cnvdbq5ku" path="res://assets/ui/input-prompts/Xbox Series/Vector/xbox_button_b_outline.svg" id="3_njayx"]
[sub_resource type="LabelSettings" id="LabelSettings_4vbx1"]
font_size = 30
@@ -50,19 +52,43 @@ theme_override_constants/separation = 0
[node name="FirstInput" type="TextureRect" parent="Control/PanelContainer/MarginContainer/HBoxContainer/MultipleInputsContainer" unique_id=490808492]
unique_name_in_owner = true
layout_mode = 2
texture = ExtResource("2_w8mpv")
stretch_mode = 3
[node name="ComplexInputLabel" type="Label" parent="Control/PanelContainer/MarginContainer/HBoxContainer/MultipleInputsContainer" unique_id=103193503]
[node name="first_plus_sign" type="Label" parent="Control/PanelContainer/MarginContainer/HBoxContainer/MultipleInputsContainer" unique_id=1236204840]
unique_name_in_owner = true
layout_mode = 2
text = "+"
label_settings = SubResource("LabelSettings_4vbx1")
[node name="SecondInput" type="TextureRect" parent="Control/PanelContainer/MarginContainer/HBoxContainer/MultipleInputsContainer" unique_id=523697392]
unique_name_in_owner = true
layout_mode = 2
texture = ExtResource("3_njayx")
stretch_mode = 3
[node name="second_plus_sign" type="Label" parent="Control/PanelContainer/MarginContainer/HBoxContainer/MultipleInputsContainer" unique_id=632487691]
unique_name_in_owner = true
layout_mode = 2
text = "+"
label_settings = SubResource("LabelSettings_4vbx1")
[node name="ThirdInput" type="TextureRect" parent="Control/PanelContainer/MarginContainer/HBoxContainer/MultipleInputsContainer" unique_id=150712319]
unique_name_in_owner = true
layout_mode = 2
texture = ExtResource("3_njayx")
stretch_mode = 3
[node name="ComplexInputLabel" type="Label" parent="Control/PanelContainer/MarginContainer/HBoxContainer/MultipleInputsContainer" unique_id=103193503]
unique_name_in_owner = true
layout_mode = 2
text = "while airborne"
label_settings = SubResource("LabelSettings_4vbx1")
[node name="TutoText" type="Label" parent="Control/PanelContainer/MarginContainer/HBoxContainer" unique_id=970615593]
unique_name_in_owner = true
layout_mode = 2
text = "jump"
label_settings = SubResource("LabelSettings_g04tr")
[connection signal="body_entered" from="." to="." method="_on_body_entered"]

View File

@@ -1,37 +1,69 @@
extends Area3D
class_name TutoTrigger
@onready var control: Control = $Control
@export_group("First input")
@export var first_input_icon: Texture
@export var first_input_icon_keyboard: Texture
@export_group("Second input")
@export var second_input_icon: Texture
@export var second_input_icon_keyboard: Texture
@export_group("Third input")
@export var third_input_icon: Texture
@export var third_input_icon_keyboard: Texture
@onready var multiple_inputs_container: HBoxContainer = %MultipleInputsContainer
@onready var first_input: TextureRect = %FirstInput
@onready var complex_input_label: Label = %ComplexInputLabel
@onready var second_input: TextureRect = %SecondInput
@onready var tuto_label: Label = %TutoText
@export var first_input_texture: CompressedTexture2D
@export var second_input_texture: CompressedTexture2D
@export var complex_input_text: String
@export_group("Text")
@export var input_related_text: String
@export var tuto_text: String
@onready var control: Control = $Control
@onready var inputs_container: HBoxContainer = %MultipleInputsContainer
@onready var first_input: TextureRect = %FirstInput
@onready var first_plus_sign: Label = %first_plus_sign
@onready var second_input: TextureRect = %SecondInput
@onready var second_plus_sign: Label = %second_plus_sign
@onready var third_input: TextureRect = %ThirdInput
@onready var complex_input_label: Label = %ComplexInputLabel
@onready var tuto_text_label: Label = %TutoText
var current_input_method = GlobalHelpers.GamepadDetectionEvent.GAMEPAD
func _ready() -> void:
tuto_label.text = tuto_text
first_input.texture = first_input_texture
second_input.texture = second_input_texture
complex_input_label.text = complex_input_text
complex_input_label.visible = !input_related_text.is_empty()
complex_input_label.text = input_related_text
tuto_text_label.text = tuto_text
if second_input_texture != null:
complex_input_label.text = "+"
_on_input_mappings_changed()
if second_input_texture == null and complex_input_text.is_empty():
complex_input_label.visible = false
second_input.visible = false
func _input(event: InputEvent) -> void:
var event_gamepad = GlobalHelpers.is_event_gamepad(event)
if event_gamepad == GlobalHelpers.GamepadDetectionEvent.IRRELEVANT:
return
if current_input_method == event_gamepad:
return
current_input_method = event_gamepad
_on_input_mappings_changed()
func _on_input_mappings_changed():
var is_gamepad = current_input_method == GlobalHelpers.GamepadDetectionEvent.GAMEPAD
first_input.visible = first_input_icon != null
if first_input.visible:
first_input.texture = first_input_icon if is_gamepad else first_input_icon_keyboard
second_input.visible = second_input_icon != null
first_plus_sign.visible = second_input.visible
if second_input.visible:
second_input.texture = second_input_icon if is_gamepad else second_input_icon_keyboard
third_input.visible = third_input_icon != null
second_plus_sign.visible = third_input.visible
if third_input.visible:
third_input.texture = third_input_icon if is_gamepad else third_input_icon_keyboard
func _on_body_entered(body: Node3D) -> void:
control.visible = true
func _on_body_exited(body: Node3D) -> void:
control.visible = false

View File

@@ -1,28 +0,0 @@
namespace Movementtests.tests;
using GdUnit4;
using static GdUnit4.Assertions;
[TestSuite]
public class ExampleTest
{
[Before]
public void Setup() {
// Setup suite-level shared resources, expensive setup
}
[After]
public void Cleanup() {
// Cleanup suite-level shared resources, expensive setup
}
[TestCase]
public void StringToLower() {
AssertString("AbcD".ToLower()).IsEqual("abcd");
}
[TestCase]
public void StringToUpper() {
AssertString("AbcD".ToUpper()).IsEqual("ABCD");
}
}

View File

@@ -1 +0,0 @@
uid://cs8i2bp4wr00u

View File

@@ -0,0 +1,59 @@
using Godot;
using GdUnit4;
using static GdUnit4.Assertions;
using Movementtests.interfaces;
using Movementtests.systems.damage;
namespace Movementtests.tests;
[TestSuite, RequireGodotRuntime]
public class DamageComponentUnitTest
{
[TestCase]
public void DamageModifier_Applies_WhenTypeMatches()
{
var modifier = new RDamageModifier(EDamageTypes.Normal, 2.0f);
var input = new DamageRecord(Vector3.Zero, new RDamage(10.0f, EDamageTypes.Normal));
var result = modifier.TakeDamage(input);
AssertFloat(result.Damage.DamageDealt).IsEqual(20.0f);
}
[TestCase]
public void DamageModifier_Ignores_WhenTypeDifferent()
{
var modifier = new RDamageModifier(EDamageTypes.Fire, 3.0f);
var input = new DamageRecord(Vector3.Zero, new RDamage(10.0f, EDamageTypes.Normal));
var result = modifier.TakeDamage(input);
AssertFloat(result.Damage.DamageDealt).IsEqual(0.0f);
}
[TestCase]
public void CDamageable_Sums_All_Modifiers()
{
var mod1 = new RDamageModifier(EDamageTypes.Normal, 1.0f);
var mod2 = new RDamageModifier(EDamageTypes.Normal, 0.5f);
var cDamageable = new CDamageable();
cDamageable.DamageModifiers = new[] { mod1, mod2 };
var input = new DamageRecord(Vector3.Zero, new RDamage(10.0f, EDamageTypes.Normal));
var result = cDamageable.TakeDamage(input);
// 10*1.0 + 10*0.5 = 15
AssertFloat(result.Damage.DamageDealt).IsEqual(15.0f);
}
[TestCase]
public void CDamageable_ComputeDamage_DoesNotEmit()
{
var mod = new RDamageModifier(EDamageTypes.Normal, 2.0f);
var cDamageable = new CDamageable();
cDamageable.DamageModifiers = new[] { mod };
var input = new DamageRecord(Vector3.Zero, new RDamage(5.0f, EDamageTypes.Normal));
var result = cDamageable.ComputeDamage(input);
AssertFloat(result.Damage.DamageDealt).IsEqual(10.0f);
}
}

View File

@@ -0,0 +1 @@
uid://db6rva7uccppc

View File

@@ -0,0 +1,56 @@
using Godot;
using GdUnit4;
using static GdUnit4.Assertions;
using Movementtests.interfaces;
using Movementtests.systems.damage;
namespace Movementtests.tests;
[TestSuite, RequireGodotRuntime]
public class HealthComponentUnitTest
{
[TestCase]
public void ReadyInitializesCurrentHealth()
{
var cHealth = new CHealth();
cHealth.RHealth = new RHealth(150.0f);
// Simulate Godot ready
cHealth._Ready();
AssertFloat(cHealth.CurrentHealth).IsEqual(150.0f);
}
[TestCase]
public void ReduceHealthDecreasesAndDoesNotDeplete()
{
var cHealth = new CHealth();
cHealth.RHealth = new RHealth(100.0f);
cHealth.CurrentHealth = 100.0f;
var damage = new DamageRecord(Vector3.Zero, new RDamage(25.0f, EDamageTypes.Normal));
var record = cHealth.ReduceHealth(source: null!, damageRecord: damage);
AssertFloat(cHealth.CurrentHealth).IsEqual(75.0f);
AssertFloat(record.CurrentHealth).IsEqual(75.0f);
AssertFloat(record.PreviousHealth).IsEqual(100.0f);
AssertFloat(record.MaxHealth).IsEqual(100.0f);
}
[TestCase]
public void ReduceHealthTriggersDepletionToZero()
{
var cHealth = new CHealth();
cHealth.RHealth = new RHealth(50.0f);
cHealth.CurrentHealth = 50.0f;
bool depleted = false;
cHealth.HealthDepleted += _ => depleted = true;
var damage = new DamageRecord(Vector3.Zero, new RDamage(100.0f, EDamageTypes.Normal));
var record = cHealth.ReduceHealth(source: null!, damageRecord: damage);
AssertBool(depleted).IsTrue();
AssertFloat(cHealth.CurrentHealth).IsEqual(0.0f);
AssertFloat(record.CurrentHealth).IsEqual(-50.0f);
AssertFloat(record.MaxHealth).IsEqual(50.0f);
}
}

View File

@@ -0,0 +1 @@
uid://bd52i51hncgmf

View File

@@ -0,0 +1,31 @@
using Godot;
using GdUnit4;
using static GdUnit4.Assertions;
using Movementtests.interfaces;
namespace Movementtests.tests;
[TestSuite, RequireGodotRuntime]
public class KnockbackComponentUnitTest
{
[TestCase]
public void RegisterAndComputeKnockback_Works_And_Resets()
{
var cKnock = new CKnockback();
cKnock.RKnockback = new RKnockback(2.0f);
cKnock.GlobalPosition = Vector3.Zero;
var damage = new DamageRecord(new Vector3(10, 0, 0), new RDamage(0, Movementtests.systems.damage.EDamageTypes.Normal));
var record = new KnockbackRecord(damage, 1.5f);
cKnock.RegisterKnockback(record);
var force = cKnock.ComputeKnockback();
// Direction from source(10,0,0) to target(0,0,0) is (-1,0,0), scaled by modifier(2) and multiplier(1.5) => (-3,0,0)
AssertVector(force).IsEqual(new Vector3(-3, 0, 0));
// Second call returns zero since internal state resets
var second = cKnock.ComputeKnockback();
AssertVector(second).IsEqual(Vector3.Zero);
}
}

View File

@@ -0,0 +1 @@
uid://bv0eionbgbig5

View File

@@ -0,0 +1,32 @@
using Godot;
using GdUnit4;
using static GdUnit4.Assertions;
using Movementtests.interfaces;
using Movementtests.scenes.movement;
namespace Movementtests.tests;
[TestSuite, RequireGodotRuntime]
public class MovementSystemUnitTest
{
[TestCase]
public void GroundedMovement_Accelerates_And_Applies_Gravity()
{
var move = new CGroundedMovement();
move.RMovement = new RMovement(speed: 10.0f, acceleration: 1.0f, gravityModifier: 0.5f, targetHeight: 0.0f);
move.WallInFrontRayCast = new RayCast3D();
move.GlobalPosition = Vector3.Zero;
var inputs = new MovementInputs(
Velocity: Vector3.Zero,
TargetLocation: new Vector3(10, 0, 0),
isOnFloor: false,
gravity: Vector3.Down * 9.8f,
delta: 1.0
);
var v = move.ComputeVelocity(inputs);
AssertVector(v).IsEqualApprox(new Vector3(10, -4.9f, 0), new Vector3(0.0001f, 0.0001f, 0.0001f));
}
}

View File

@@ -0,0 +1 @@
uid://cofj5s4x74ay

View File

@@ -0,0 +1,78 @@
using Godot;
using GdUnit4;
using static GdUnit4.Assertions;
using Movementtests.interfaces;
using Movementtests.systems.damage;
namespace Movementtests.tests;
[TestSuite, RequireGodotRuntime]
public class EnemyUnitTest
{
[TestCase]
public void ComputeDamage_NoComponent_ReturnsZero()
{
var enemy = new Enemy();
var input = new DamageRecord(Vector3.Zero, new RDamage(10.0f, EDamageTypes.Normal));
var result = enemy.ComputeDamage(input);
AssertFloat(result.Damage.DamageDealt).IsEqual(0.0f);
}
[TestCase]
public void TakeDamage_WithCDamageable_AggregatesDamage()
{
var enemy = new Enemy();
var cDamage = new CDamageable();
cDamage.DamageModifiers = new[]
{
new RDamageModifier(EDamageTypes.Normal, 1.0f),
new RDamageModifier(EDamageTypes.Normal, 2.0f)
};
enemy.CDamageable = cDamage;
var input = new DamageRecord(Vector3.Zero, new RDamage(10.0f, EDamageTypes.Normal));
var result = enemy.TakeDamage(input);
AssertFloat(result.Damage.DamageDealt).IsEqual(30.0f);
}
[TestCase]
public void ReduceHealth_WithCHealth_Decreases()
{
var enemy = new Enemy();
var health = new CHealth { RHealth = new RHealth(100.0f), CurrentHealth = 100.0f };
enemy.CHealth = health;
var input = new DamageRecord(Vector3.Zero, new RDamage(25.0f, EDamageTypes.Normal));
var record = enemy.ReduceHealth(enemy, input);
AssertFloat(health.CurrentHealth).IsEqual(75.0f);
AssertFloat(record.CurrentHealth).IsEqual(75.0f);
}
[TestCase]
public void Knockback_Register_And_Compute()
{
var enemy = new Enemy();
var cKnock = new CKnockback { RKnockback = new RKnockback(1.0f) };
enemy.CKnockback = cKnock;
enemy.GlobalPosition = Vector3.Zero;
cKnock.GlobalPosition = Vector3.Zero;
var dmg = new DamageRecord(new Vector3(5, 0, 0), new RDamage(0, EDamageTypes.Normal));
var krec = new KnockbackRecord(dmg, 2.0f);
enemy.RegisterKnockback(krec);
var k = enemy.ComputeKnockback();
AssertVector(k).IsEqual(new Vector3(-2, 0, 0));
}
[TestCase]
public void Unstun_ResetsFlag()
{
var enemy = new Enemy();
enemy.IsStunned = true;
enemy.Unstun();
AssertBool(enemy.IsStunned).IsFalse();
}
}

View File

@@ -0,0 +1 @@
uid://cojxgcs6xqqoq

View File

@@ -0,0 +1,55 @@
using Godot;
using GdUnit4;
using static GdUnit4.Assertions;
using Movementtests.systems;
namespace Movementtests.tests;
[TestSuite, RequireGodotRuntime]
public class DashSystemUnitTest
{
private DashSystem _dashSystem;
[BeforeTest]
public void SetupTest()
{
_dashSystem = new DashSystem();
_dashSystem.DashCast3D = new ShapeCast3D();
_dashSystem.AddChild(_dashSystem.DashCast3D);
_dashSystem._dashCastDrop = new ShapeCast3D();
_dashSystem.AddChild(_dashSystem._dashCastDrop);
_dashSystem._dashTarget = new MeshInstance3D();
_dashSystem.AddChild(_dashSystem._dashTarget);
_dashSystem._dashDropIndicator = new MeshInstance3D();
_dashSystem.AddChild(_dashSystem._dashDropIndicator);
_dashSystem._dashDropLocationIndicator = new MeshInstance3D();
_dashSystem.AddChild(_dashSystem._dashDropLocationIndicator);
}
[AfterTest]
public void CleanupTest()
{
_dashSystem?.Free();
}
[TestCase]
public void TestStopPreparingDash()
{
_dashSystem.CanDashThroughTarget = true;
_dashSystem._dashTarget.Visible = true;
_dashSystem._dashDropIndicator.Visible = true;
_dashSystem._dashDropLocationIndicator.Visible = true;
_dashSystem.StopPreparingDash();
AssertBool(_dashSystem.CanDashThroughTarget).IsFalse();
AssertBool(_dashSystem._dashTarget.Visible).IsFalse();
AssertBool(_dashSystem._dashDropIndicator.Visible).IsFalse();
AssertBool(_dashSystem._dashDropLocationIndicator.Visible).IsFalse();
}
}

View File

@@ -0,0 +1 @@
uid://pv570go4cxws

View File

@@ -0,0 +1,91 @@
using Godot;
using GdUnit4;
using static GdUnit4.Assertions;
using Movementtests.systems;
namespace Movementtests.tests;
[TestSuite, RequireGodotRuntime]
public class HeadSystemUnitTest
{
private HeadSystem _head;
[BeforeTest]
public void SetupTest()
{
_head = new HeadSystem();
_head._camera = new Camera3D();
_head.AddChild(_head._camera);
_head._cameraAnchor = new Marker3D();
_head.AddChild(_head._cameraAnchor);
_head._fpRig = new Node3D();
_head.AddChild(_head._fpRig);
_head._fpDisplacedRig = new Node3D();
_head.AddChild(_head._fpDisplacedRig);
}
[AfterTest]
public void CleanupTest()
{
_head?.Free();
}
[TestCase]
public void TestResetHeadBobbing()
{
_head._bobbingAccumulator = 10.0f;
_head.ResetHeadBobbing();
AssertFloat(_head._bobbingAccumulator).IsEqual(0.0f);
}
[TestCase]
public void TestComputeHowMuchInputForward()
{
Vector3 forwardInput = new Vector3(0, 0, -1);
AssertFloat(_head.ComputeHowMuchInputForward(forwardInput)).IsEqual(1.0f);
Vector3 backwardInput = new Vector3(0, 0, 1);
AssertFloat(_head.ComputeHowMuchInputForward(backwardInput)).IsEqual(-1.0f);
}
[TestCase]
public void TestComputeHowMuchInputSideways()
{
Vector3 rightInput = new Vector3(1, 0, 0);
AssertFloat(_head.ComputeHowMuchInputSideways(rightInput)).IsEqual(1.0f);
Vector3 leftInput = new Vector3(-1, 0, 0);
AssertFloat(_head.ComputeHowMuchInputSideways(leftInput)).IsEqual(-1.0f);
}
[TestCase]
public void TestGetForwardHorizontalVector()
{
Vector3 forward = _head.GetForwardHorizontalVector();
AssertVector(forward).IsEqualApprox(Vector3.Back, new Vector3(0.001f, 0.001f, 0.001f));
}
[TestCase]
public void TestLookAroundRotation()
{
var inputs = new HeadSystem.CameraParameters(
Delta: 0.016,
LookDir: new Vector2(1, 0),
PlayerInput: Vector3.Zero,
PlayerVelocity: Vector3.Zero,
WallContactPoint: Vector3.Zero,
SensitivitMultiplier: 1.0f,
WithCameraJitter: false,
WithCameraBobbing: false,
BobbingMultiplier: 1.0f,
FovMultiplier: 1.0f
);
float initialY = _head.Rotation.Y;
_head.LookAround(inputs);
AssertFloat(_head.Rotation.Y).IsEqual(initialY + 1.0f);
}
}

View File

@@ -0,0 +1 @@
uid://bp0xn8k3dmfkg

View File

@@ -0,0 +1,149 @@
using Godot;
using GdUnit4;
using static GdUnit4.Assertions;
using Movementtests.interfaces;
using Movementtests.systems.damage;
namespace Movementtests.tests;
[TestSuite, RequireGodotRuntime]
public class PlayerControllerUnitTest
{
private PlayerController _player;
[BeforeTest]
public void SetupTest()
{
_player = new PlayerController();
_player._targetSpeed = 7.0f;
_player._gravity = 9.8f;
var rHealth = new RHealth(100.0f);
_player.RHealth = rHealth;
_player.CHealth = new CHealth { RHealth = rHealth, CurrentHealth = 100.0f };
}
[AfterTest]
public void CleanupTest()
{
_player?.Free();
}
[TestCase]
public void TestCalculateGravityForce()
{
_player.Weight = 3.0f;
// gravity is 9.8f
AssertFloat(_player.CalculateGravityForce()).IsEqualApprox(29.4f, 0.001f);
}
[TestCase]
public void TestIsPlayerInputtingForward()
{
// Test Keyboard Input
_player.InputDeviceChanged(false);
_player.OnInputMoveKeyboard(Vector3.Forward);
AssertBool(_player.IsPlayerInputtingForward()).IsTrue();
_player.OnInputMoveKeyboard(Vector3.Back);
AssertBool(_player.IsPlayerInputtingForward()).IsFalse();
// Test Gamepad Input
_player.InputDeviceChanged(true);
_player.OnInputMove(new Vector3(0, 0, -1));
AssertBool(_player.IsPlayerInputtingForward()).IsTrue();
}
[TestCase]
public void TestSetVerticalVelocity()
{
_player.Velocity = new Vector3(1, 0, 2);
_player.SetVerticalVelocity(5.0f);
AssertVector(_player.Velocity).IsEqual(new Vector3(1, 5, 2));
}
[TestCase]
public void TestComputeHVelocityGround()
{
_player.Velocity = Vector3.Zero;
_player.AccelerationFloor = 10.0f;
float delta = 0.1f;
Vector3 newVelocity = _player.ComputeHVelocity(delta, _player.AccelerationFloor, _player.DecelerationFloor, Vector3.Forward);
AssertVector(newVelocity).IsEqual(new Vector3(0, 0, -7.0f));
}
[TestCase]
public void TestComputeHVelocityAir()
{
_player.Velocity = new Vector3(5, 0, 0);
_player.AccelerationAir = 2.0f;
_player.DecelerationAir = 2.0f;
float delta = 0.5f;
Vector3 newVelocity = _player.ComputeHVelocity(delta, _player.AccelerationAir, _player.DecelerationAir, Vector3.Zero);
AssertVector(newVelocity).IsEqual(Vector3.Zero);
}
[TestCase]
public void TestReduceHealth()
{
var damageRecord = new DamageRecord(Vector3.Zero, new RDamage(25.0f, EDamageTypes.Normal));
_player.ReduceHealth(_player, damageRecord);
AssertFloat(_player.CHealth.CurrentHealth).IsEqual(75.0f);
}
[TestCase]
public void TestEmpoweredActionsLeft()
{
var mockUi = new PlayerUi();
var dashIcons = new TextureRect[3] { new TextureRect(), new TextureRect(), new TextureRect() };
mockUi._dashIcons = dashIcons;
_player.PlayerUi = mockUi;
_player.EmpoweredActionsLeft = 2;
AssertInt(_player.EmpoweredActionsLeft).IsEqual(2);
AssertBool(dashIcons[0].Visible).IsTrue();
AssertBool(dashIcons[1].Visible).IsTrue();
AssertBool(dashIcons[2].Visible).IsFalse();
}
[TestCase]
public void TestDashCooldownTimeout()
{
_player._canDash = false;
_player.DashCooldownTimeout();
AssertBool(_player._canDash).IsTrue();
}
[TestCase]
public void TestGetInputLocalHDirection()
{
_player.InputDeviceChanged(false);
_player.OnInputMoveKeyboard(new Vector3(1, 0, 1));
Vector3 expected = new Vector3(1, 0, 1).Normalized();
AssertVector(_player.GetInputLocalHDirection()).IsEqualApprox(expected, new Vector3(0.001f, 0.001f, 0.001f));
}
[TestCase]
public void TestComputeKnockback()
{
var cKnockback = new CKnockback();
cKnockback.RKnockback = new RKnockback(10.0f);
_player.CKnockback = cKnockback;
var damageRecord = new DamageRecord(new Vector3(10, 0, 0), new RDamage(0, EDamageTypes.Normal));
var knockbackRecord = new KnockbackRecord(damageRecord, 1.0f);
_player.GlobalPosition = Vector3.Zero;
cKnockback.GlobalPosition = Vector3.Zero;
_player.RegisterKnockback(knockbackRecord);
Vector3 knockback = cKnockback.ComputeKnockback();
AssertVector(knockback).IsEqual(new Vector3(-10, 0, 0));
}
}

View File

@@ -0,0 +1 @@
uid://kmphtu0ovixi

View File

@@ -0,0 +1,51 @@
using Godot;
using GdUnit4;
using static GdUnit4.Assertions;
using Movementtests.systems;
using Movementtests.systems.damage;
namespace Movementtests.tests;
[TestSuite, RequireGodotRuntime]
public class WeaponSystemUnitTest
{
private WeaponSystem _weapon;
[BeforeTest]
public void SetupTest()
{
_weapon = new WeaponSystem();
_weapon.RDamage = new RDamage(5.0f, EDamageTypes.Normal);
_weapon.WeaponMesh = new MeshInstance3D();
_weapon.AddChild(_weapon.WeaponMesh);
_weapon.WeaponLocationIndicator = new MeshInstance3D();
_weapon.AddChild(_weapon.WeaponLocationIndicator);
}
[AfterTest]
public void CleanupTest()
{
_weapon?.Free();
}
[TestCase]
public void TestWeaponLeftAndBackVisibility()
{
_weapon.Visible = false;
_weapon.WeaponLeft();
AssertBool(_weapon.Visible).IsTrue();
_weapon.WeaponBack();
AssertBool(_weapon.Visible).IsFalse();
}
[TestCase]
public void TestThrowWeaponOnCurveSetsUnfrozen()
{
_weapon.Freeze = true;
_weapon.ThrowWeaponOnCurve();
AssertBool(_weapon.Freeze).IsFalse();
}
}

View File

@@ -0,0 +1 @@
uid://vkv8aderakcb

View File

@@ -0,0 +1,98 @@
using System.Threading.Tasks;
using Godot;
namespace Movementtests.tests;
using GdUnit4;
using static GdUnit4.Assertions;
[TestSuite, RequireGodotRuntime]
public class PlayerMovementTest
{
private ISceneRunner _runner;
private Node _scene;
private PlayerController _player;
private readonly float _tolerance = 0.01f;
private readonly Vector3 _vectorTolerance = new Vector3(0.01f, 0.01f, 0.01f);
[Before]
public void Setup() {}
[After]
public void Cleanup() {}
[BeforeTest]
public void SetupTest()
{
_runner = ISceneRunner.Load("res://tests/player/movement/player_movement_scene.tscn");
_scene = _runner.Scene()!;
var player = _scene.FindChild("Player") as PlayerController;
_player = player!;
}
[AfterTest]
public void CleanupTest() {}
[TestCase("BaseLocation")]
public async Task PlayerMoveForward(string markerName)
{
var marker = _scene.FindChild(markerName) as Marker3D;
AssertObject(marker).IsNotNull();
_player.GlobalPosition = marker!.GlobalPosition;
await _runner.AwaitIdleFrame();
var startPos = _player.GlobalPosition;
_runner.SimulateKeyPress(Key.W);
await _runner.AwaitMillis(300);
_runner.SimulateKeyRelease(Key.W);
var endPos = _player.GlobalPosition;
var direction = startPos.DirectionTo(endPos);
AssertVector(direction).IsEqualApprox(Vector3.Forward, _vectorTolerance);
}
[TestCase("BaseLocation")]
public async Task PlayerJump(string markerName)
{
var marker = _scene.FindChild(markerName) as Marker3D;
AssertObject(marker).IsNotNull();
_player.GlobalPosition = marker!.GlobalPosition;
await _runner.AwaitIdleFrame();
var startPos = _player.GlobalPosition;
_runner.SimulateKeyPress(Key.Space);
await _runner.AwaitMillis(100);
_runner.SimulateKeyRelease(Key.Space);
var endPos = _player.GlobalPosition;
var direction = startPos.DirectionTo(endPos);
AssertVector(direction).IsEqualApprox(Vector3.Up, _vectorTolerance);
AssertVector(_player.Velocity.Normalized()).IsEqualApprox(Vector3.Up, _vectorTolerance);
await _runner.AwaitMillis(500);
endPos = _player.GlobalPosition;
AssertVector(endPos - startPos).IsEqualApprox(Vector3.Zero, _vectorTolerance);
}
[TestCase("MantleLocation1")]
public async Task PlayerMantle(string markerName)
{
var marker = _scene.FindChild(markerName) as Marker3D;
AssertObject(marker).IsNotNull();
_player.GlobalPosition = marker!.GlobalPosition;
await _runner.AwaitMillis(100);
var startPos = _player.GlobalPosition;
_runner.SimulateKeyPress(Key.Space);
await _runner.AwaitMillis(100);
_runner.SimulateKeyRelease(Key.Space);
await _runner.AwaitMillis(500);
var endPos = _player.GlobalPosition;
AssertFloat((endPos - startPos).Length()).IsGreater(_tolerance);
AssertFloat(endPos.Y).IsEqualApprox(1.0f, _tolerance);
}
}

View File

@@ -0,0 +1 @@
uid://x5pj2ymam2gg

View File

@@ -0,0 +1,35 @@
[gd_scene format=3 uid="uid://i8kb38q7bdfk"]
[ext_resource type="Material" uid="uid://31aulub2nqov" path="res://assets/materials/greybox/m_greybox.tres" id="1_bdfhg"]
[ext_resource type="PackedScene" uid="uid://bei4nhkf8lwdo" path="res://scenes/player_controller/PlayerController.tscn" id="1_hg1sy"]
[node name="PlayerMovementScene" type="Node3D" unique_id=231040688]
[node name="CSGCombiner3D" type="CSGCombiner3D" parent="." unique_id=241909240]
use_collision = true
collision_layer = 256
collision_mask = 65553
[node name="Ground" type="CSGBox3D" parent="CSGCombiner3D" unique_id=432200143]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, -0.5, -3.25)
use_collision = true
collision_layer = 256
collision_mask = 65553
size = Vector3(1000, 1, 1000)
material = ExtResource("1_bdfhg")
[node name="Ground2" type="CSGBox3D" parent="CSGCombiner3D" unique_id=854660236]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.75, 0.5, -1.75)
use_collision = true
collision_layer = 256
collision_mask = 65553
size = Vector3(1.5, 1, 1.5)
material = ExtResource("1_bdfhg")
[node name="Player" parent="." unique_id=709076448 instance=ExtResource("1_hg1sy")]
TutorialDone = true
[node name="BaseLocation" type="Marker3D" parent="." unique_id=1793710692]
[node name="MantleLocation1" type="Marker3D" parent="." unique_id=550080845]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.75, 0, 0)

20
tools/global_helpers.gd Normal file
View File

@@ -0,0 +1,20 @@
extends Node
enum GamepadDetectionEvent {
GAMEPAD,
KEYBOARD,
IRRELEVANT
}
static func is_event_gamepad(event: InputEvent) -> GamepadDetectionEvent:
if event is InputEventKey || event is InputEventMouseButton:
return GamepadDetectionEvent.KEYBOARD
elif event is InputEventMouseMotion:
if not event.relative.is_zero_approx():
return GamepadDetectionEvent.KEYBOARD
elif event is InputEventJoypadMotion:
if abs(event.axis_value) > 0.5:
return GamepadDetectionEvent.GAMEPAD
elif event is InputEventJoypadButton:
return GamepadDetectionEvent.GAMEPAD
return GamepadDetectionEvent.IRRELEVANT

View File

@@ -0,0 +1 @@
uid://dqcm83o8e66a2

3
xunit.runner.json Normal file
View File

@@ -0,0 +1,3 @@
{
"$schema": "https://xunit.net/schema/current/xunit.runner.schema.json"
}