Compare commits

..

5 Commits

Author SHA1 Message Date
aafd3cbfbf Merge pull request 'main' (#8) from main into release/playtest-04-26
All checks were successful
Create tag and build when new code gets to main / ReleaseName (push) Successful in 5s
Create tag and build when new code gets to main / Release (push) Successful in 14m28s
Reviewed-on: #8
2026-04-25 08:21:19 +00:00
26f6a619cb dependency injection test
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 28s
Create tag and build when new code gets to main / Export (push) Successful in 6m50s
2026-04-25 10:18:41 +02:00
30817576b9 Merge pull request 'main' (#7) from main into release/playtest-04-26
All checks were successful
Create tag and build when new code gets to main / ReleaseName (push) Successful in 4s
Create tag and build when new code gets to main / Release (push) Successful in 16m18s
Reviewed-on: #7
2026-04-22 14:20:37 +00:00
70d0f66df3 Merge pull request 'ground slam damage depends on height' (#6) from main into release/playtest-04-26
All checks were successful
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 14m25s
Reviewed-on: #6
2026-04-21 16:48:45 +00:00
c145c709e3 Merge pull request 'main' (#5) from main into release/playtest-04-26
All checks were successful
Create tag and build when new code gets to main / ReleaseName (push) Successful in 4s
Create tag and build when new code gets to main / Release (push) Successful in 13m49s
Reviewed-on: #5
2026-04-21 12:36:33 +00:00
6 changed files with 200 additions and 156 deletions

View File

@@ -39,110 +39,110 @@ jobs:
INITIAL_VERSION: 0.1.0 INITIAL_VERSION: 0.1.0
DEFAULT_BUMP: patch DEFAULT_BUMP: patch
Test: # Test:
runs-on: godot # runs-on: godot
env: # env:
RUNNER_TOOL_CACHE: /toolcache # Runner Tool Cache # RUNNER_TOOL_CACHE: /toolcache # Runner Tool Cache
steps: # steps:
- name: Checkout with LFS # - name: Checkout with LFS
uses: https://git.game-dev.space/minimata/checkout-with-lfs.git@main # uses: https://git.game-dev.space/minimata/checkout-with-lfs.git@main
#
- name: Setup Godot # - name: Setup Godot
id: setup-godot # id: setup-godot
uses: https://git.game-dev.space/minimata/setup-godot.git@main # uses: https://git.game-dev.space/minimata/setup-godot.git@main
with:
godot-version: ${GODOT_VERSION}
dotnet-version: ${DOTNET_VERSION}
- name: 🔬 Verify Setup
run: |
dotnet --version
${{ steps.setup-godot.outputs.godot_bin }} --version
- name: 🧑‍🔬 Generate .NET Bindings
run: ${{ steps.setup-godot.outputs.godot_bin }} --headless --build-solutions --quit || exit 0
- name: Run C# Tests
env:
GODOT_BIN: ${{ steps.setup-godot.outputs.godot_bin }}
shell: bash
run: |
dotnet test --no-build --settings .runsettings --results-directory ./reports --logger "console;verbosity=normal" --logger "trx;LogFileName=results.xml" -- GdUnit4.Parameters="--verbose --headless --import"
# - name: Run tests
# uses: godot-gdunit-labs/gdUnit4-action@v1
# with: # with:
# godot-version: ${GODOT_VERSION} # godot-version: ${GODOT_VERSION}
# godot-net: true
# godot-force-mono: true
# dotnet-version: ${DOTNET_VERSION} # dotnet-version: ${DOTNET_VERSION}
# paths: | #
# res://tests/ # - name: 🔬 Verify Setup
# publish-report: false # run: |
# upload-report: false # dotnet --version
# console-verbosity: 'normal' # ${{ steps.setup-godot.outputs.godot_bin }} --version
# arguments: "--verbose --headless --import" #
# - name: 🧑‍🔬 Generate .NET Bindings
- name: Upload test report # run: ${{ steps.setup-godot.outputs.godot_bin }} --headless --build-solutions --quit || exit 0
uses: actions/upload-artifact@v3-node20 #
with: # - name: Run C# Tests
name: Test Report # env:
path: ${{ github.workspace }}/reports/test-result.html # GODOT_BIN: ${{ steps.setup-godot.outputs.godot_bin }}
# shell: bash
OtherTest: # run: |
runs-on: godot # dotnet test --no-build --settings .runsettings --results-directory ./reports --logger "console;verbosity=normal" --logger "trx;LogFileName=results.xml" -- GdUnit4.Parameters="--verbose --headless --import"
env: #
RUNNER_TOOL_CACHE: /toolcache # Runner Tool Cache # # - name: Run tests
steps: # # uses: godot-gdunit-labs/gdUnit4-action@v1
- name: Checkout with LFS # # with:
uses: https://git.game-dev.space/minimata/checkout-with-lfs.git@main # # godot-version: ${GODOT_VERSION}
# # godot-net: true
- uses: actions/setup-dotnet@v5 # # godot-force-mono: true
name: 💽 Setup .NET SDK # # dotnet-version: ${DOTNET_VERSION}
with: # # paths: |
dotnet-version: ${DOTNET_VERSION} # # res://tests/
# # publish-report: false
- name: 📦 Restore Dependencies # # upload-report: false
run: | # # console-verbosity: 'normal'
dotnet --version # # arguments: "--verbose --headless --import"
dotnet restore #
dotnet build # - name: Upload test report
dotnet list package # uses: actions/upload-artifact@v3-node20
# with:
- uses: chickensoft-games/setup-godot@v2 # name: Test Report
name: 🤖 Setup Godot # path: ${{ github.workspace }}/reports/test-result.html
with: #
# Version must include major, minor, and patch, and be >= 4.0.0 # OtherTest:
# Pre-release label is optional. # runs-on: godot
version: ${GODOT_VERSION} # env:
# Use .NET-enabled version of Godot (the default is also true). # RUNNER_TOOL_CACHE: /toolcache # Runner Tool Cache
use-dotnet: true # steps:
# Include the Godot Export Templates (the default is false). # - name: Checkout with LFS
include-templates: true # uses: https://git.game-dev.space/minimata/checkout-with-lfs.git@main
#
- name: 🔬 Verify Setup # - uses: actions/setup-dotnet@v5
run: | # name: 💽 Setup .NET SDK
dotnet --version # with:
godot --version # dotnet-version: ${DOTNET_VERSION}
#
- name: 🧑‍🔬 Generate .NET Bindings # - name: 📦 Restore Dependencies
run: godot --headless --build-solutions --quit || exit 0 # run: |
# dotnet --version
- name: 🦺 Build Projects # dotnet restore
run: dotnet build --configuration Release # dotnet build
# dotnet list package
- name: Run C# Tests #
env: # - uses: chickensoft-games/setup-godot@v2
GODOT_BIN: godot # name: 🤖 Setup Godot
shell: bash # with:
run: | # # Version must include major, minor, and patch, and be >= 4.0.0
dotnet test --no-build --settings .runsettings --results-directory ./reports --logger "console;verbosity=normal" --logger "trx;LogFileName=results.xml" -- GdUnit4.Parameters="--verbose --headless --import" # # Pre-release label is optional.
# version: ${GODOT_VERSION}
- name: Upload test report # # Use .NET-enabled version of Godot (the default is also true).
uses: actions/upload-artifact@v3-node20 # use-dotnet: true
with: # # Include the Godot Export Templates (the default is false).
name: Test Report # include-templates: true
path: ${{ github.workspace }}/reports/test-result.html #
# - name: 🔬 Verify Setup
# run: |
# dotnet --version
# godot --version
#
# - name: 🧑‍🔬 Generate .NET Bindings
# run: godot --headless --build-solutions --quit || exit 0
#
# - name: 🦺 Build Projects
# run: dotnet build --configuration Release
#
# - name: Run C# Tests
# env:
# GODOT_BIN: godot
# shell: bash
# run: |
# dotnet test --no-build --settings .runsettings --results-directory ./reports --logger "console;verbosity=normal" --logger "trx;LogFileName=results.xml" -- GdUnit4.Parameters="--verbose --headless --import"
#
# - name: Upload test report
# uses: actions/upload-artifact@v3-node20
# with:
# name: Test Report
# path: ${{ github.workspace }}/reports/test-result.html
Export: Export:
runs-on: godot runs-on: godot

View File

@@ -26,11 +26,8 @@ public partial class InventoryManager : Node
public Dictionary<WeaponSystem.WeaponEvent, HashSet<Resource>> WeaponEventsInventory { get; } = []; public Dictionary<WeaponSystem.WeaponEvent, HashSet<Resource>> WeaponEventsInventory { get; } = [];
public static InventoryManager Instance { get; private set; }
public override void _Ready() public override void _Ready()
{ {
Instance = this;
WeaponEventsInventory[WeaponSystem.WeaponEvent.FlyingTick] = new HashSet<Resource>(); WeaponEventsInventory[WeaponSystem.WeaponEvent.FlyingTick] = new HashSet<Resource>();
WeaponEventsInventory[WeaponSystem.WeaponEvent.StartedFlying] = new HashSet<Resource>(); WeaponEventsInventory[WeaponSystem.WeaponEvent.StartedFlying] = new HashSet<Resource>();
WeaponEventsInventory[WeaponSystem.WeaponEvent.StoppedFlying] = new HashSet<Resource>(); WeaponEventsInventory[WeaponSystem.WeaponEvent.StoppedFlying] = new HashSet<Resource>();

View File

@@ -1,26 +1,37 @@
using Godot; using Godot;
using System; using System;
using Movementtests.interfaces; using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Movementtests.interfaces;using Movementtests.managers;
using Movementtests.systems; using Movementtests.systems;
public partial class MainSceneTemplate : Node3D [Meta(
typeof(IAutoOn),
typeof(IAutoConnect),
typeof(IProvider)
)]
public partial class MainSceneTemplate : Node3D, IProvide<InventoryManager>
{ {
private Marker3D? _playerRespawnMarker; public override void _Notification(int what) => this.Notify(what);
[Node("PlayerFellRespawn")] private Marker3D? PlayerRespawnMarker { get; set; }
private AnimationPlayer? _animationPlayer; private AnimationPlayer? _animationPlayer;
private Node3D? _respawnabble; private Node3D? _respawnabble;
private Area3D? _playerFellPlane; private Area3D? _playerFellPlane;
private Area3D? _deathPlane; private Area3D? _deathPlane;
public override void _Ready() public required InventoryManager InventoryManager { get; set; }
InventoryManager IProvide<InventoryManager>.Value() => InventoryManager;
public void OnReady()
{ {
_playerRespawnMarker = GetNode<Marker3D>("PlayerFellRespawn");
_animationPlayer = GetNode<AnimationPlayer>("AnimationPlayer"); _animationPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
_playerFellPlane = GetNode<Area3D>("PlayerFellTP"); _playerFellPlane = GetNode<Area3D>("PlayerFellTP");
_deathPlane = GetNode<Area3D>("DeathPlane"); _deathPlane = GetNode<Area3D>("DeathPlane");
if (_playerRespawnMarker == null) throw new Exception("Player respawn marker is null"); if (PlayerRespawnMarker == null) throw new Exception("Player respawn marker is null");
if (_animationPlayer == null) throw new Exception("Animation player is null"); if (_animationPlayer == null) throw new Exception("Animation player is null");
if (_playerFellPlane == null) throw new Exception("Player reset plane is null"); if (_playerFellPlane == null) throw new Exception("Player reset plane is null");
if (_deathPlane == null) throw new Exception("Enemy death plane is null"); if (_deathPlane == null) throw new Exception("Enemy death plane is null");
@@ -28,20 +39,30 @@ public partial class MainSceneTemplate : Node3D
_playerFellPlane.BodyEntered += StartResetPlayerAnimation; _playerFellPlane.BodyEntered += StartResetPlayerAnimation;
_deathPlane.BodyEntered += KillEnemy; _deathPlane.BodyEntered += KillEnemy;
InventoryManager = new InventoryManager();
AddChild(InventoryManager);
this.Provide();
}
public void OnProvided()
{
// You can optionally implement this method. It gets called once you call
// this.Provide() to inform AutoInject that the provided values are now
// available.
} }
public void ResetPlayerPosition() public void ResetPlayerPosition()
{ {
if (_respawnabble == null || _playerRespawnMarker == null) throw new Exception("Player or respawn marker is null"); if (_respawnabble == null || PlayerRespawnMarker == null) throw new Exception("Player or respawn marker is null");
_respawnabble.GlobalPosition = _playerRespawnMarker.GlobalPosition; _respawnabble.GlobalPosition = PlayerRespawnMarker.GlobalPosition;
} }
public void StartResetPlayerAnimation(Node3D body) public void StartResetPlayerAnimation(Node3D body)
{ {
if (body is WeaponSystem weapon) if (body is WeaponSystem weapon)
{ {
if (_playerRespawnMarker == null) throw new Exception("Respawn marker is null"); if (PlayerRespawnMarker == null) throw new Exception("Respawn marker is null");
weapon.GlobalPosition = _playerRespawnMarker.GlobalPosition; weapon.GlobalPosition = PlayerRespawnMarker.GlobalPosition;
weapon.SetLinearVelocity(Vector3.Down); weapon.SetLinearVelocity(Vector3.Down);
return; return;
} }

View File

@@ -1,54 +1,67 @@
using System.Collections.Generic; using System.Collections.Generic;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Gamesmiths.Forge.Effects; using Gamesmiths.Forge.Effects;
using Gamesmiths.Forge.Godot.Resources.Abilities; using Gamesmiths.Forge.Godot.Resources.Abilities;
using Godot; using Godot;
using Movementtests.managers; using Movementtests.managers;
using Movementtests.systems; using Movementtests.systems;
[Tool, GlobalClass, Icon("res://assets/ui/IconGodotNode/control/icon_crate.png")]
[Tool, GlobalClass, Icon("res://assets/ui/IconGodotNode/control/icon_crate.png"), Meta(typeof(IAutoNode))]
public partial class InventoryUi : Control public partial class InventoryUi : Control
{ {
private AbilitySelection _startedFlyingSelection; public override void _Notification(int what) => this.Notify(what);
private AbilitySelection _whileFlyingSelection;
private AbilitySelection _stoppedFlyingSelection;
public override void _Ready() #region Dependencies
[Dependency]
public InventoryManager InventoryManager => this.DependOn<InventoryManager>();
#endregion Dependencies
#region Nodes
[Node]
public required AbilitySelection StartedFlying { get; set; }
[Node]
public required AbilitySelection WhileFlying { get; set; }
[Node]
public required AbilitySelection StoppedFlying { get; set; }
#endregion Nodes
public void OnReady()
{ {
_startedFlyingSelection = GetNode<AbilitySelection>("%StartedFlying"); StartedFlying.AbilityAdded += AddAbilityForEvent;
_whileFlyingSelection = GetNode<AbilitySelection>("%WhileFlying"); WhileFlying.AbilityAdded += AddAbilityForEvent;
_stoppedFlyingSelection = GetNode<AbilitySelection>("%StoppedFlying"); StoppedFlying.AbilityAdded += AddAbilityForEvent;
_startedFlyingSelection.Initialize(InventoryManager.Instance.WeaponEventsInventory[WeaponSystem.WeaponEvent.StartedFlying]); StartedFlying.AbilityRemoved += RemoveAbilityForEvent;
_whileFlyingSelection.Initialize(InventoryManager.Instance.WeaponEventsInventory[WeaponSystem.WeaponEvent.FlyingTick]); WhileFlying.AbilityRemoved += RemoveAbilityForEvent;
_stoppedFlyingSelection.Initialize(InventoryManager.Instance.WeaponEventsInventory[WeaponSystem.WeaponEvent.StoppedFlying]); StoppedFlying.AbilityRemoved += RemoveAbilityForEvent;
_startedFlyingSelection.AbilityAdded += AddAbilityForEvent;
_whileFlyingSelection.AbilityAdded += AddAbilityForEvent;
_stoppedFlyingSelection.AbilityAdded += AddAbilityForEvent;
_startedFlyingSelection.AbilityRemoved += RemoveAbilityForEvent;
_whileFlyingSelection.AbilityRemoved += RemoveAbilityForEvent;
_stoppedFlyingSelection.AbilityRemoved += RemoveAbilityForEvent;
InventoryManager.Instance.WeaponEventAbilityAdded += OnWeaponEventInventoryAdded;
InventoryManager.Instance.WeaponEventAbilityRemoved += OnWeaponEventInventoryRemoved;
} }
public override void _ExitTree() public void OnResolved()
{ {
InventoryManager.Instance.WeaponEventAbilityAdded -= OnWeaponEventInventoryAdded; StartedFlying.Initialize(InventoryManager.WeaponEventsInventory[WeaponSystem.WeaponEvent.StartedFlying]);
InventoryManager.Instance.WeaponEventAbilityRemoved -= OnWeaponEventInventoryRemoved; WhileFlying.Initialize(InventoryManager.WeaponEventsInventory[WeaponSystem.WeaponEvent.FlyingTick]);
base._ExitTree(); StoppedFlying.Initialize(InventoryManager.WeaponEventsInventory[WeaponSystem.WeaponEvent.StoppedFlying]);
InventoryManager.WeaponEventAbilityAdded += OnWeaponEventInventoryAdded;
InventoryManager.WeaponEventAbilityRemoved += OnWeaponEventInventoryRemoved;
}
public void OnExitTree()
{
InventoryManager.WeaponEventAbilityAdded -= OnWeaponEventInventoryAdded;
InventoryManager.WeaponEventAbilityRemoved -= OnWeaponEventInventoryRemoved;
} }
public void AddAbilityForEvent(WeaponSystem.WeaponEvent forEvent, ForgeAbilityBehavior abilityBehavior) public void AddAbilityForEvent(WeaponSystem.WeaponEvent forEvent, ForgeAbilityBehavior abilityBehavior)
{ {
InventoryManager.Instance.AddAbilityForWeaponEvent(forEvent, abilityBehavior); InventoryManager.AddAbilityForWeaponEvent(forEvent, abilityBehavior);
} }
public void RemoveAbilityForEvent(WeaponSystem.WeaponEvent forEvent, ForgeAbilityBehavior abilityBehavior) public void RemoveAbilityForEvent(WeaponSystem.WeaponEvent forEvent, ForgeAbilityBehavior abilityBehavior)
{ {
InventoryManager.Instance.RemoveAbilityForWeaponEvent(forEvent, abilityBehavior); InventoryManager.RemoveAbilityForWeaponEvent(forEvent, abilityBehavior);
} }
public void OnWeaponEventInventoryAdded(WeaponEventAbilityData data) public void OnWeaponEventInventoryAdded(WeaponEventAbilityData data)
@@ -71,9 +84,9 @@ public partial class InventoryUi : Control
{ {
var abilitiesSelectionsMap = new Dictionary<WeaponSystem.WeaponEvent, AbilitySelection> var abilitiesSelectionsMap = new Dictionary<WeaponSystem.WeaponEvent, AbilitySelection>
{ {
{ WeaponSystem.WeaponEvent.StartedFlying, _startedFlyingSelection }, { WeaponSystem.WeaponEvent.StartedFlying, StartedFlying },
{ WeaponSystem.WeaponEvent.StoppedFlying, _stoppedFlyingSelection }, { WeaponSystem.WeaponEvent.StoppedFlying, StoppedFlying },
{ WeaponSystem.WeaponEvent.FlyingTick, _whileFlyingSelection }, { WeaponSystem.WeaponEvent.FlyingTick, WhileFlying },
}; };
return abilitiesSelectionsMap[forEvent]; return abilitiesSelectionsMap[forEvent];

View File

@@ -30,7 +30,6 @@ Shaker="*uid://c7flmumgr5w3u"
CsgToolkitAutoload="*uid://w8ad8q4lneis" CsgToolkitAutoload="*uid://w8ad8q4lneis"
"Forge Bootstrap"="*uid://ba8fquhtwu5mu" "Forge Bootstrap"="*uid://ba8fquhtwu5mu"
GlobalHelpers="*uid://dqcm83o8e66a2" GlobalHelpers="*uid://dqcm83o8e66a2"
InventoryManager="*uid://cgwhrwfqsiing"
[display] [display]

View File

@@ -1,5 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Gamesmiths.Forge.Abilities; using Gamesmiths.Forge.Abilities;
using Gamesmiths.Forge.Attributes; using Gamesmiths.Forge.Attributes;
using Gamesmiths.Forge.Core; using Gamesmiths.Forge.Core;
@@ -35,7 +37,8 @@ using Node = Godot.Node;
public record struct EmpoweredActionPayload; public record struct EmpoweredActionPayload;
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_character.png")]
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_character.png"), Meta(typeof(IAutoNode))]
public partial class PlayerController : CharacterBody3D, public partial class PlayerController : CharacterBody3D,
IDamageable, IDamageable,
IDamageDealer, IDamageDealer,
@@ -43,6 +46,11 @@ public partial class PlayerController : CharacterBody3D,
IKnockbackable, IKnockbackable,
IForgeEntity IForgeEntity
{ {
public override void _Notification(int what) => this.Notify(what);
[Dependency]
public InventoryManager InventoryManager => this.DependOn<InventoryManager>();
// Enums // Enums
public enum AllowedInputs public enum AllowedInputs
{ {
@@ -426,7 +434,7 @@ public partial class PlayerController : CharacterBody3D,
private AbilityHandle? _empoweredActionHandle; private AbilityHandle? _empoweredActionHandle;
public override void _Ready() public void OnReady()
{ {
LoadSettings(); LoadSettings();
@@ -716,15 +724,21 @@ public partial class PlayerController : CharacterBody3D,
_parryStandard.StateEntered += OnStandardParryStarted; _parryStandard.StateEntered += OnStandardParryStarted;
_parryDash.StateEntered += OnDashParryStarted; _parryDash.StateEntered += OnDashParryStarted;
// Inventory Management
InventoryManager.Instance.WeaponEventAbilityAdded += OnWeaponEventAbilityAdded;
InventoryManager.Instance.WeaponEventAbilityRemoved += OnWeaponEventAbilityRemoved;
// Forge events // Forge events
var weaponLeftToken = WeaponSystem.Events.Subscribe(WeaponSystem.WeaponStartedFlyingEventTag, OnWeaponLeft); var weaponLeftToken = WeaponSystem.Events.Subscribe(WeaponSystem.WeaponStartedFlyingEventTag, OnWeaponLeft);
var weaponLandedToken = WeaponSystem.Events.Subscribe(WeaponSystem.WeaponStoppedFlyingEventTag, OnWeaponLanded); var weaponLandedToken = WeaponSystem.Events.Subscribe(WeaponSystem.WeaponStoppedFlyingEventTag, OnWeaponLanded);
} }
public void OnResolved()
{
// All of my dependencies are now available! Do whatever you want with
// them here.
// Inventory Management
InventoryManager.WeaponEventAbilityAdded += OnWeaponEventAbilityAdded;
InventoryManager.WeaponEventAbilityRemoved += OnWeaponEventAbilityRemoved;
}
public void OnWeaponLeft(EventData data) public void OnWeaponLeft(EventData data)
{ {
var target = data.Target; var target = data.Target;