Compare commits

...

20 Commits

Author SHA1 Message Date
99f383be00 Damage dealing through meta attribute and custom exec
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 30s
Create tag and build when new code gets to main / Export (push) Successful in 6m8s
2026-05-03 10:47:56 +02:00
631935fdc8 added meta attribute set 2026-05-02 16:45:27 +02:00
852f265b9f made weapon into a dependant and used new forgeneitty node as a node3d 2026-05-02 16:13:23 +02:00
0e6211943d new forge entity node to benefit from autoinject 2026-05-02 15:24:28 +02:00
fb30a08b89 hitting is now an ability 2026-05-02 11:19:56 +02:00
24f057c15f used DI for forge managers where possible 2026-04-28 16:34:10 +02:00
ec44306d48 forge friendlier health and damage management
Removed knockback though
2026-04-28 11:22:24 +02:00
dcfd937e53 moved forge resources around 2026-04-26 18:19:45 +02:00
cd7a230615 made the initial inventory loadout into a resource to initialize the injected dependency with 2026-04-26 17:38:25 +02:00
319cbf722e changed ci
Some checks failed
Create tag and build when new code gets to main / BumpTag (push) Successful in 26s
Create tag and build when new code gets to main / OtherTest (push) Failing after 9m40s
Create tag and build when new code gets to main / Export (push) Successful in 9m16s
2026-04-26 12:45:33 +02:00
bb21920488 changed runsettings and workflow to always publish test reports
Some checks failed
Create tag and build when new code gets to main / BumpTag (push) Successful in 32s
Create tag and build when new code gets to main / Export (push) Successful in 9m31s
Create tag and build when new code gets to main / OtherTest (push) Failing after 11m57s
2026-04-26 12:24:51 +02:00
cd2b41b443 fix ci
Some checks failed
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 8m58s
Create tag and build when new code gets to main / OtherTest (push) Failing after 11m43s
2026-04-26 11:52:14 +02:00
d025618eb3 retrying new CI
Some checks failed
Create tag and build when new code gets to main / BumpTag (push) Successful in 29s
Create tag and build when new code gets to main / OtherTest (push) Failing after 1m47s
Create tag and build when new code gets to main / Export (push) Successful in 5m54s
2026-04-26 11:35:45 +02: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
ce48f3b9d7 fixed indent issue
Some checks failed
Create tag and build when new code gets to main / BumpTag (push) Successful in 1m21s
Create tag and build when new code gets to main / OtherTest (push) Failing after 1m32s
Create tag and build when new code gets to main / Export (push) Successful in 6m53s
Create tag and build when new code gets to main / Test (push) Failing after 8m42s
2026-04-24 19:07:20 +02:00
54796252ce retrying to CI tests
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
2026-04-24 19:06:31 +02:00
054115aa89 trying out autoinject on the CI
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 26s
Create tag and build when new code gets to main / Export (push) Successful in 5m46s
2026-04-24 18:48:10 +02:00
f5e47e9f5e minor fixes
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 26s
Create tag and build when new code gets to main / Export (push) Successful in 8m50s
2026-04-22 09:47:15 +02:00
99ed6375a2 fix: enemies dying from falling would remove the weapon from the world. Thrown weapon now respawn like the player. 2026-04-22 08:43:58 +02:00
6888499b78 ground slam damage depends on height
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 26s
Create tag and build when new code gets to main / Export (push) Successful in 7m2s
2026-04-21 18:47:58 +02:00
89 changed files with 2264 additions and 1160 deletions

View File

@@ -38,22 +38,30 @@ jobs:
PRERELEASE: false
INITIAL_VERSION: 0.1.0
DEFAULT_BUMP: patch
# Test:
# runs-on: godot
## env:
## RUNNER_TOOL_CACHE: /toolcache # Runner Tool Cache
# env:
# RUNNER_TOOL_CACHE: /toolcache # Runner Tool Cache
# steps:
# - name: Checkout with LFS
# uses: https://git.game-dev.space/minimata/checkout-with-lfs.git@main
#
#
# - name: Setup Godot
# id: setup-godot
# 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 }}
@@ -61,24 +69,80 @@ jobs:
# 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:
## godot-version: ${GODOT_VERSION}
## godot-net: true
## godot-force-mono: true
## dotnet-version: ${DOTNET_VERSION}
## paths: |
## res://tests/
## publish-report: false
## upload-report: false
## console-verbosity: 'normal'
## arguments: "--verbose --headless --import"
# # - name: Run tests
# # uses: godot-gdunit-labs/gdUnit4-action@v1
# # with:
# # godot-version: ${GODOT_VERSION}
# # godot-net: true
# # godot-force-mono: true
# # dotnet-version: ${DOTNET_VERSION}
# # paths: |
# # res://tests/
# # publish-report: false
# # upload-report: false
# # console-verbosity: 'normal'
# # arguments: "--verbose --headless --import"
#
# - name: Upload test report
# uses: actions/upload-artifact@v3-node20
# with:
# name: Test Report
# path: ${{ github.workspace }}/reports/test-result.html
#
# OtherTest:
# runs-on: godot
# env:
# RUNNER_TOOL_CACHE: /toolcache # Runner Tool Cache
# steps:
# - name: Checkout with LFS
# uses: https://git.game-dev.space/minimata/checkout-with-lfs.git@main
#
# - uses: actions/setup-dotnet@v5
# name: 💽 Setup .NET SDK
# with:
# dotnet-version: '9.0.x'
#
# - name: 📦 Restore Dependencies
# run: |
# dotnet --version
# dotnet restore
# dotnet build
# dotnet list package
#
# - uses: chickensoft-games/setup-godot@v2
# name: 🤖 Setup Godot
# with:
# # Version must include major, minor, and patch, and be >= 4.0.0
# # Pre-release label is optional.
# version: '4.6.2'
# # Use .NET-enabled version of Godot (the default is also true).
# use-dotnet: true
# # Include the Godot Export Templates (the default is false).
# include-templates: true
#
# - name: 🔬 Verify Setup
# run: |
# dotnet --version
# godot --version
#
# - name: 🧑‍🔬 Generate .NET Bindings
# run: godot --headless --build-solutions --import --quit || exit 0
#
# - name: 🦺 Build Projects
# run: dotnet build --configuration ExportRelease
#
# - name: Run C# Tests
# env:
# GODOT_BIN: /root/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="--headless --import --quit"
#
# - name: Upload test report
# uses: actions/upload-artifact@v3-node20
# if: always()
# with:
# name: Test Report
# path: ${{ github.workspace }}/reports/test-result.html
Export:

1
.gitignore vendored
View File

@@ -11,6 +11,7 @@
/builds
/communication
/reports
# Imported translations (automatically generated from CSV files)
*.translation

View File

@@ -4,7 +4,7 @@
<MaxCpuCount>1</MaxCpuCount>
<ResultsDirectory>./TestResults</ResultsDirectory>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<TestSessionTimeout>180000</TestSessionTimeout>
<TestSessionTimeout>60000</TestSessionTimeout>
<TreatNoTestsAsError>true</TreatNoTestsAsError>
</RunConfiguration>
@@ -30,7 +30,7 @@
<GdUnit4>
<!-- Additional Godot runtime parameters. These are passed to the Godot executable when running tests.-->
<Parameters>"--verbose"</Parameters>
<Parameters>"--verbose --headless --import --quit"</Parameters>
<!-- Controls the display name format of test cases in the test results.
Allowed values:

View File

@@ -3,6 +3,8 @@
<TargetFramework>net9.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading>
<RootNamespace>Movementtests</RootNamespace>
<!-- Catch compiler-mismatch issues with the Introspection generator -->
<WarningsAsErrors>CS9057</WarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<Content Include=".runsettings" />
@@ -126,11 +128,17 @@
<ItemGroup>
<Folder Include="addons\" />
<Folder Include="tests\" />
<Folder Include="tools\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="RustyOptions" Version="0.10.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Chickensoft.GodotNodeInterfaces" Version="3.0.12" />
<PackageReference Include="Chickensoft.Introspection" Version="3.0.2" />
<PackageReference Include="Chickensoft.Introspection.Generator" Version="3.0.2" PrivateAssets="all" OutputItemType="analyzer" />
<PackageReference Include="Chickensoft.AutoInject" Version="2.12.8" PrivateAssets="all" />
<PackageReference Include="Chickensoft.AutoInject.Analyzers" Version="2.12.8" PrivateAssets="all" OutputItemType="analyzer" />
</ItemGroup>
<Import Project="addons/forge/Forge.props" />
<!-- gdUnit4 package dependencies -->

View File

@@ -41,8 +41,8 @@ func _input(event : InputEvent) -> void:
if event.is_action_released("ui_cancel"):
if sub_menu:
_close_sub_menu()
else:
get_tree().quit()
# else:
# get_tree().quit()
if event.is_action_released("ui_accept") and get_viewport().gui_get_focus_owner() == null:
%MenuButtonsBoxContainer.focus_first()

72
forge/ForgeEntityNode.cs Normal file
View File

@@ -0,0 +1,72 @@
// Copyright © Gamesmiths Guild.
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Gamesmiths.Forge.Core;
using Gamesmiths.Forge.Cues;
using Gamesmiths.Forge.Effects;
using Gamesmiths.Forge.Events;
using Gamesmiths.Forge.Godot.Core;
using Gamesmiths.Forge.Godot.Resources;
using Gamesmiths.Forge.Statescript;
using Gamesmiths.Forge.Tags;
using Godot;
namespace Movementtests.tools;
[GlobalClass]
[Icon("uid://cu6ncpuumjo20")]
[Meta(typeof(IAutoNode))]
public partial class ForgeEntityNode : Node3D, IForgeEntity
{
public override void _Notification(int what) => this.Notify(what);
[Dependency]
public TagsManager TagsManager => this.DependOn<TagsManager>();
[Dependency]
public CuesManager CuesManager => this.DependOn<CuesManager>();
[Export]
public ForgeTagContainer? BaseTags { get; set; }
[Export]
public ForgeSharedVariableSet? SharedVariableDefinitions { get; set; }
public required EntityAttributes Attributes { get; set; }
public required EntityTags Tags { get; set; }
public required EffectsManager EffectsManager { get; set; }
public required EntityAbilities Abilities { get; set; }
public required EventManager Events { get; set; }
public required Variables SharedVariables { get; set; }
public void OnReady()
{
BaseTags ??= new ForgeTagContainer();
Tags = new EntityTags(BaseTags.GetTagContainer());
Attributes = new EntityAttributes([.. ForgeUtils.CollectAttributeList(this)]);
Abilities = new EntityAbilities(this);
Events = new EventManager();
SharedVariables = new Variables();
SharedVariableDefinitions?.PopulateVariables(SharedVariables);
}
public void OnResolved()
{
EffectsManager = new EffectsManager(this, CuesManager);
var effectApplier = new EffectApplier(this);
effectApplier.ApplyEffects(this, this, this);
}
public override void _Process(double delta)
{
base._Process(delta);
EffectsManager.UpdateEffects(delta);
Abilities.UpdateAbilities(delta);
}
}

View File

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

View File

@@ -29,7 +29,8 @@ public class ExplodingSwordBehavior(PackedScene explosion, float radius) : IAbil
return;
}
explo.Radius = radius;
GD.Print("explosion");
owner.GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, explo);
explo.CallDeferred(Node3D.MethodName.SetGlobalPosition, owner.GlobalPosition);

View File

@@ -0,0 +1,31 @@
using Gamesmiths.Forge.Abilities;
using Gamesmiths.Forge.Effects;
using Gamesmiths.Forge.Godot.Resources;
using Gamesmiths.Forge.Godot.Resources.Abilities;
using Godot;
namespace Movementtests.forge.abilities;
public class SimpleHitBehavior(ForgeEffectData? damage) : IAbilityBehavior
{
public void OnStarted(AbilityBehaviorContext context)
{
if (context.Target == null || damage == null) return;
var effect = new Effect(damage.GetEffectData(), new EffectOwnership(context.Owner, context.Owner));
context.Target.EffectsManager.ApplyEffect(effect);
context.AbilityHandle.CommitAbility();
context.InstanceHandle.End();
}
public void OnEnded(AbilityBehaviorContext context) {}
}
[Tool]
[GlobalClass]
public partial class ForgeSimpleHitBehavior : ForgeAbilityBehavior
{
[Export] public ForgeEffectData? DamageEffect { get; set; }
public override IAbilityBehavior GetBehavior() => new SimpleHitBehavior(DamageEffect);
}

View File

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

View File

@@ -0,0 +1,13 @@
using Gamesmiths.Forge.Attributes;
namespace Movementtests.forge.attribute_sets;
public class CharacterAttributeSet : AttributeSet
{
public EntityAttribute Health { get; }
public CharacterAttributeSet()
{
Health = InitializeAttribute(nameof(Health), 100, 0, 100);
}
}

View File

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

View File

@@ -1,15 +1,14 @@
using Gamesmiths.Forge.Attributes;
namespace Movementtests.scenes.enemies;
public class EnemyAttributeSet : AttributeSet
{
public EntityAttribute Health { get; }
public EntityAttribute Strength { get; }
public EntityAttribute Speed { get; }
public EnemyAttributeSet()
{
Health = InitializeAttribute(nameof(Health), 100, 0, 150);
Strength = InitializeAttribute(nameof(Strength), 10, 0, 99);
Speed = InitializeAttribute(nameof(Speed), 5, 0, 10);
}

View File

@@ -0,0 +1,12 @@
using Gamesmiths.Forge.Attributes;
namespace Movementtests.scenes.enemies;
public class MetaAttributeSet : AttributeSet
{
public EntityAttribute IncomingDamage { get; private set; }
public MetaAttributeSet()
{
IncomingDamage = InitializeAttribute(nameof(IncomingDamage), 0, 0, 1000, channels: 4);
}
}

View File

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

View File

@@ -4,16 +4,10 @@ namespace Movementtests.scenes.player_controller.scripts;
public class PlayerAttributeSet : AttributeSet
{
public EntityAttribute Health { get; }
public EntityAttribute Mana { get; }
public EntityAttribute Strength { get; }
public EntityAttribute Speed { get; }
public PlayerAttributeSet()
{
Health = InitializeAttribute(nameof(Health), 100, 0, 150);
Mana = InitializeAttribute(nameof(Mana), 100, 0, 100);
Strength = InitializeAttribute(nameof(Strength), 10, 0, 99);
Speed = InitializeAttribute(nameof(Speed), 5, 0, 10);
}
}

View File

@@ -0,0 +1,19 @@
namespace Movementtests.tools.calculators;
public enum DamageType
{
/// <summary>
/// Physical damage.
/// </summary>
Physical = 0,
/// <summary>
/// Magical damage.
/// </summary>
Magical = 1,
/// <summary>
/// Elemental damage.
/// </summary>
Elemental = 2,
}

View File

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

View File

@@ -0,0 +1,134 @@
using System.Collections.Generic;
using Gamesmiths.Forge.Attributes;
using Gamesmiths.Forge.Core;
using Gamesmiths.Forge.Effects;
using Gamesmiths.Forge.Effects.Calculator;
using Gamesmiths.Forge.Effects.Magnitudes;
using Gamesmiths.Forge.Effects.Modifiers;
using Gamesmiths.Forge.Events;
using Gamesmiths.Forge.Godot.Core;
using Gamesmiths.Forge.Godot.Resources;
using Gamesmiths.Forge.Godot.Resources.Calculators;
using Gamesmiths.Forge.Tags;
using Godot;
namespace Movementtests.tools.calculators;
public record DamageDone(DamageType DamageType, float Damage, float OverkillDamage);
public class DamageExecution : CustomExecution
{
private readonly DamageType _damageType;
private readonly ForgeTagContainer? _damageDealerEventTags;
private readonly ForgeTagContainer? _damageReceiverEventTags;
// Define attributes to capture and modify
public AttributeCaptureDefinition TargetHealth { get; }
public AttributeCaptureDefinition TargetIncomingDamage { get; }
public DamageExecution(DamageType damageType, ForgeTagContainer? damageDealerEventTags, ForgeTagContainer? damageReceiverEventTags)
{
// Capture target mana and magic resistance
TargetHealth = new AttributeCaptureDefinition(
"CharacterAttributeSet.Health",
AttributeCaptureSource.Target,
false);
TargetIncomingDamage = new AttributeCaptureDefinition(
"MetaAttributeSet.IncomingDamage",
AttributeCaptureSource.Target);
// Register attributes for capture
AttributesToCapture.Add(TargetHealth);
AttributesToCapture.Add(TargetIncomingDamage);
_damageType = damageType;
_damageDealerEventTags = damageDealerEventTags;
_damageReceiverEventTags = damageReceiverEventTags;
}
public override ModifierEvaluatedData[] EvaluateExecution(
Effect effect, IForgeEntity target, EffectEvaluatedData? effectEvaluatedData)
{
var results = new List<ModifierEvaluatedData>();
float targetIncomingDamage = CaptureAttributeMagnitude(
TargetIncomingDamage,
effect,
target,
effectEvaluatedData);
if (targetIncomingDamage <= 0)
{
return [.. results];
}
if (effectEvaluatedData?.TryGetContextData(out float multiplier) == true)
{
targetIncomingDamage *= multiplier;
}
// Apply health reduction to target if attribute exists
if (TargetHealth.TryGetAttribute(target, out EntityAttribute? targetHealthAttribute))
{
results.Add(new ModifierEvaluatedData(
targetHealthAttribute,
ModifierOperation.FlatBonus,
-targetIncomingDamage)); // Negative for damage
}
var finalDamage = targetIncomingDamage;
var overkillDamage = 0.0f;
if (targetHealthAttribute!.CurrentValue - targetIncomingDamage <= targetHealthAttribute.Min)
{
finalDamage = targetHealthAttribute.CurrentValue - targetHealthAttribute.Min;
overkillDamage = targetIncomingDamage - finalDamage;
}
if (_damageReceiverEventTags is null) return [.. results];
target.Events.Raise(new EventData<DamageDone>
{
EventTags = _damageReceiverEventTags.GetTagContainer(),
Source = effect.Ownership.Owner,
Target = target,
EventMagnitude = finalDamage,
Payload = new DamageDone(_damageType, finalDamage, overkillDamage)
});
if (effect.Ownership.Source is null || _damageDealerEventTags is null)
{
return [.. results];
}
effect.Ownership.Source.Events.Raise(new EventData<DamageDone>
{
EventTags = _damageDealerEventTags.GetTagContainer(),
Source = effect.Ownership.Owner,
Target = target,
EventMagnitude = finalDamage,
Payload = new DamageDone(_damageType, finalDamage, overkillDamage)
});
return [.. results];
}
}
[Tool]
[GlobalClass]
public partial class ForgeDamageExecution : ForgeCustomExecution
{
[Export]
public DamageType DamageType { get; set; } = DamageType.Physical;
[Export]
public ForgeTagContainer? DamageDealerEventTags { get; set; }
[Export]
public ForgeTagContainer? DamageReceiverEventTags { get; set; }
public override CustomExecution GetExecutionClass()
{
return new DamageExecution(DamageType, DamageDealerEventTags, DamageReceiverEventTags);
}
}

View File

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

View File

@@ -16,19 +16,33 @@ using Movementtests.systems;
namespace Movementtests.tools.calculators;
public class RaiseEventTagExecution(TagContainer eventTags) : CustomExecution
public class RaiseEventTagExecution(TagContainer? ownerEventTags, TagContainer? targetEventTags) : CustomExecution
{
public override ModifierEvaluatedData[] EvaluateExecution(Effect effect, IForgeEntity target, EffectEvaluatedData? effectEvaluatedData)
{
var owner = effect.Ownership.Owner;
if (owner == null) return [];
owner.Events.Raise(new EventData
var magnitude = effectEvaluatedData is { ModifiersEvaluatedData.Length: > 0 }
? effectEvaluatedData.ModifiersEvaluatedData[0].Magnitude
: 0f;
if (owner != null && ownerEventTags != null)
{
EventTags = eventTags,
Source = owner,
EventMagnitude = 12f
});
owner.Events.Raise(new EventData
{
EventTags = ownerEventTags,
Source = owner,
EventMagnitude = magnitude
});
}
if (targetEventTags != null)
{
target.Events.Raise(new EventData
{
EventTags = targetEventTags,
Source = owner,
EventMagnitude = magnitude
});
}
return [];
}
@@ -39,10 +53,11 @@ public class RaiseEventTagExecution(TagContainer eventTags) : CustomExecution
[GlobalClass]
public partial class ForgeRaiseEventTagExecution : ForgeCustomExecution
{
[Export] ForgeTagContainer EventTags { get; set; }
[Export] ForgeTagContainer? EventTags { get; set; }
[Export] ForgeTagContainer? TargetEventTags { get; set; }
public override CustomExecution GetExecutionClass()
{
return new RaiseEventTagExecution(EventTags.GetTagContainer());
return new RaiseEventTagExecution(EventTags?.GetTagContainer(), TargetEventTags?.GetTagContainer());
}
}

View File

@@ -4,4 +4,4 @@
[resource]
script = ExtResource("1_l686n")
RegisteredTags = Array[String](["character.player", "character.enemy", "weapon", "status.stunned", "status.burning", "status.frozen", "abilities.weapon.land", "abilities.weapon.flying", "abilities.weapon.left", "events.combat.damage", "events.combat.hit", "events.weapon.flyingTick", "events.weapon.startedFlying", "events.weapon.stoppedFlying", "events.weapon.handToFlying", "events.weapon.flyingToHand", "events.weapon.plantedToHand", "events.weapon.plantedToFlying", "events.weapon.planted", "cooldown.empoweredAction", "cooldown.empoweredSwordThrow", "cues.resources.mana", "events.player.empowered_action_used", "cues.resources.mana.inhibited"])
RegisteredTags = Array[String](["character.player", "character.enemy", "weapon", "status.stunned", "status.burning", "status.frozen", "abilities.weapon.land", "abilities.weapon.flying", "abilities.weapon.left", "events.combat.damage", "events.combat.hit", "events.weapon.flyingTick", "events.weapon.startedFlying", "events.weapon.stoppedFlying", "events.weapon.handToFlying", "events.weapon.flyingToHand", "events.weapon.plantedToHand", "events.weapon.plantedToFlying", "events.weapon.planted", "cooldown.empoweredAction", "cooldown.empoweredSwordThrow", "cues.resources.mana", "events.player.empowered_action_used", "cues.resources.mana.inhibited", "cues.resources.health", "cooldown.enemy.hit", "events.combat.death", "cooldown.hit", "events.player.hit", "cues.enemy.health", "immunity.damage", "status", "traits.damageable"])

View File

@@ -1,16 +1,85 @@
[gd_resource type="Resource" script_class="ForgeAbilityData" format=3 uid="uid://dccuj66egxfwh"]
[ext_resource type="Resource" uid="uid://crgwob8t8yysq" path="res://scenes/player_controller/resources/forge/instant_end_behavior.tres" id="1_x7d0c"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="2_prg0a"]
[ext_resource type="Script" uid="uid://dngf30hxy5go4" path="res://addons/forge/resources/components/ModifierTags.cs" id="3_k72m0"]
[ext_resource type="Script" uid="uid://cn3b4ya15fg7e" path="res://addons/forge/resources/magnitudes/ForgeScalableFloat.cs" id="4_5fdax"]
[ext_resource type="Script" uid="uid://2gm1hdhi8u08" path="res://addons/forge/resources/magnitudes/ForgeModifierMagnitude.cs" id="5_5qmmj"]
[ext_resource type="Script" uid="uid://1hgogislo1l6" path="res://addons/forge/resources/magnitudes/ForgeScalableInt.cs" id="6_yi0bg"]
[ext_resource type="Script" uid="uid://b83hf13nj37k3" path="res://addons/forge/resources/ForgeEffectData.cs" id="7_0rp6y"]
[ext_resource type="Resource" uid="uid://dn7b8frkoxpxr" path="res://scenes/player_controller/resources/forge/player_mana_changed_cue.tres" id="8_0olwd"]
[ext_resource type="Script" uid="uid://cl5hudinl1rex" path="res://forge/abilities/ForgeEffectApplicationBehavior.cs" id="7_ent4t"]
[ext_resource type="Resource" uid="uid://dn7b8frkoxpxr" path="res://forge/resources/cues/player_mana_changed_cue.tres" id="8_0olwd"]
[ext_resource type="Resource" uid="uid://cw2ytd34jsxj" path="res://forge/resources/tag_containers/immune_damage.tres" id="8_ent4t"]
[ext_resource type="Script" uid="uid://bdfcavbjyhxxa" path="res://addons/forge/resources/ForgeModifier.cs" id="9_wluo0"]
[ext_resource type="Script" uid="uid://dhxfbxh54pyxp" path="res://addons/forge/resources/abilities/ForgeAbilityData.cs" id="10_2sq4o"]
[sub_resource type="Resource" id="Resource_xltxv"]
script = ExtResource("3_k72m0")
TagsToAdd = ExtResource("8_ent4t")
metadata/_custom_type_script = "uid://dngf30hxy5go4"
[sub_resource type="Resource" id="Resource_60xl1"]
script = ExtResource("4_5fdax")
BaseValue = 1.0
[sub_resource type="Resource" id="Resource_2rev5"]
script = ExtResource("4_5fdax")
[sub_resource type="Resource" id="Resource_kxytj"]
script = ExtResource("4_5fdax")
[sub_resource type="Resource" id="Resource_e5nje"]
script = ExtResource("4_5fdax")
BaseValue = 1.0
[sub_resource type="Resource" id="Resource_xc8ja"]
script = ExtResource("4_5fdax")
[sub_resource type="Resource" id="Resource_tan32"]
script = ExtResource("4_5fdax")
[sub_resource type="Resource" id="Resource_l52b0"]
script = ExtResource("4_5fdax")
BaseValue = 0.3
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
[sub_resource type="Resource" id="Resource_6jn6y"]
script = ExtResource("5_5qmmj")
ScalableFloat = SubResource("Resource_l52b0")
Coefficient = SubResource("Resource_e5nje")
PreMultiplyAdditiveValue = SubResource("Resource_tan32")
PostMultiplyAdditiveValue = SubResource("Resource_xc8ja")
CalculatorCoefficient = SubResource("Resource_60xl1")
CalculatorPreMultiplyAdditiveValue = SubResource("Resource_kxytj")
CalculatorPostMultiplyAdditiveValue = SubResource("Resource_2rev5")
metadata/_custom_type_script = "uid://2gm1hdhi8u08"
[sub_resource type="Resource" id="Resource_ev6w4"]
script = ExtResource("6_yi0bg")
BaseValue = 1
[sub_resource type="Resource" id="Resource_u8xa8"]
script = ExtResource("6_yi0bg")
BaseValue = 1
[sub_resource type="Resource" id="Resource_xsfte"]
script = ExtResource("7_0rp6y")
Name = "ApplyInvincibility"
Modifiers = []
Components = Array[Object]([SubResource("Resource_xltxv")])
Executions = null
DurationType = 2
Duration = SubResource("Resource_6jn6y")
StackLimit = SubResource("Resource_u8xa8")
InitialStack = SubResource("Resource_ev6w4")
Cues = null
metadata/_custom_type_script = "uid://b83hf13nj37k3"
[sub_resource type="Resource" id="Resource_xh53a"]
script = ExtResource("7_ent4t")
EffectData = SubResource("Resource_xsfte")
Name = "Apply invincibility"
metadata/_custom_type_script = "uid://cl5hudinl1rex"
[sub_resource type="Resource" id="Resource_h116a"]
script = ExtResource("2_prg0a")
ContainerTags = Array[String](["cooldown.empoweredaction"])
@@ -78,6 +147,42 @@ InitialStack = SubResource("Resource_lmnuh")
Cues = []
metadata/_custom_type_script = "uid://b83hf13nj37k3"
[sub_resource type="Resource" id="Resource_3usj8"]
script = ExtResource("4_5fdax")
BaseValue = 1.0
[sub_resource type="Resource" id="Resource_5q60v"]
script = ExtResource("4_5fdax")
[sub_resource type="Resource" id="Resource_eo5h0"]
script = ExtResource("4_5fdax")
[sub_resource type="Resource" id="Resource_c7uae"]
script = ExtResource("4_5fdax")
BaseValue = 1.0
[sub_resource type="Resource" id="Resource_7d1b0"]
script = ExtResource("4_5fdax")
[sub_resource type="Resource" id="Resource_jiq0x"]
script = ExtResource("4_5fdax")
[sub_resource type="Resource" id="Resource_kpieu"]
script = ExtResource("4_5fdax")
BaseValue = 0.3
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
[sub_resource type="Resource" id="Resource_rwc4g"]
script = ExtResource("5_5qmmj")
ScalableFloat = SubResource("Resource_kpieu")
Coefficient = SubResource("Resource_c7uae")
PreMultiplyAdditiveValue = SubResource("Resource_jiq0x")
PostMultiplyAdditiveValue = SubResource("Resource_7d1b0")
CalculatorCoefficient = SubResource("Resource_3usj8")
CalculatorPreMultiplyAdditiveValue = SubResource("Resource_eo5h0")
CalculatorPostMultiplyAdditiveValue = SubResource("Resource_5q60v")
metadata/_custom_type_script = "uid://2gm1hdhi8u08"
[sub_resource type="Resource" id="Resource_8dsdw"]
script = ExtResource("6_yi0bg")
BaseValue = 1
@@ -129,6 +234,7 @@ Name = "Empowered Action Cost"
Modifiers = Array[Object]([SubResource("Resource_dhni4")])
Components = []
Executions = []
Duration = SubResource("Resource_rwc4g")
StackLimit = SubResource("Resource_w5rmc")
InitialStack = SubResource("Resource_8dsdw")
Cues = Array[Object]([ExtResource("8_0olwd")])
@@ -139,5 +245,5 @@ script = ExtResource("10_2sq4o")
Name = "Empowered Action"
CooldownEffects = [SubResource("Resource_egh2b")]
CostEffect = SubResource("Resource_mtef8")
AbilityBehavior = ExtResource("1_x7d0c")
AbilityBehavior = SubResource("Resource_xh53a")
metadata/_custom_type_script = "uid://dhxfbxh54pyxp"

View File

@@ -0,0 +1,158 @@
[gd_resource type="Resource" script_class="ForgeAbilityData" format=3 uid="uid://qpdw62ubaclc"]
[ext_resource type="Resource" uid="uid://bpovqvlqv5bs5" path="res://forge/resources/effect_components/damageable.tres" id="1_q2jt5"]
[ext_resource type="Resource" uid="uid://dlu7l5egpexnn" path="res://forge/resources/custom_executions/raise_damage_dealing_events.tres" id="2_2dxcu"]
[ext_resource type="Resource" uid="uid://4rkwr10pc6tp" path="res://forge/resources/custom_executions/physical_damage_calculator.tres" id="2_f6jpb"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="4_0mce3"]
[ext_resource type="Script" uid="uid://1hgogislo1l6" path="res://addons/forge/resources/magnitudes/ForgeScalableInt.cs" id="6_41lep"]
[ext_resource type="Script" uid="uid://cn3b4ya15fg7e" path="res://addons/forge/resources/magnitudes/ForgeScalableFloat.cs" id="7_jf6ii"]
[ext_resource type="Script" uid="uid://bdfcavbjyhxxa" path="res://addons/forge/resources/ForgeModifier.cs" id="8_51ikp"]
[ext_resource type="Script" uid="uid://b83hf13nj37k3" path="res://addons/forge/resources/ForgeEffectData.cs" id="9_bcnlx"]
[ext_resource type="Script" uid="uid://n6efm5o4uxvr" path="res://forge/abilities/ForgeSimpleHitBehavior.cs" id="10_m4f1m"]
[ext_resource type="Script" uid="uid://dngf30hxy5go4" path="res://addons/forge/resources/components/ModifierTags.cs" id="11_8c5sq"]
[ext_resource type="Script" uid="uid://2gm1hdhi8u08" path="res://addons/forge/resources/magnitudes/ForgeModifierMagnitude.cs" id="12_2x5q6"]
[ext_resource type="Script" uid="uid://dhxfbxh54pyxp" path="res://addons/forge/resources/abilities/ForgeAbilityData.cs" id="13_4nn3y"]
[sub_resource type="Resource" id="Resource_rjo6h"]
script = ExtResource("6_41lep")
BaseValue = 1
[sub_resource type="Resource" id="Resource_8qlid"]
script = ExtResource("7_jf6ii")
BaseValue = 1.0
[sub_resource type="Resource" id="Resource_lbthk"]
script = ExtResource("7_jf6ii")
[sub_resource type="Resource" id="Resource_hguc3"]
script = ExtResource("7_jf6ii")
[sub_resource type="Resource" id="Resource_ugrvo"]
script = ExtResource("7_jf6ii")
BaseValue = 1.0
[sub_resource type="Resource" id="Resource_6406e"]
script = ExtResource("7_jf6ii")
[sub_resource type="Resource" id="Resource_x0rol"]
script = ExtResource("7_jf6ii")
[sub_resource type="Resource" id="Resource_1s1j3"]
script = ExtResource("7_jf6ii")
BaseValue = 10.0
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
[sub_resource type="Resource" id="Resource_khx4r"]
script = ExtResource("8_51ikp")
Attribute = "MetaAttributeSet.IncomingDamage"
Operation = 2
ScalableFloat = SubResource("Resource_1s1j3")
Coefficient = SubResource("Resource_ugrvo")
PreMultiplyAdditiveValue = SubResource("Resource_x0rol")
PostMultiplyAdditiveValue = SubResource("Resource_6406e")
CalculatorCoefficient = SubResource("Resource_8qlid")
CalculatorPreMultiplyAdditiveValue = SubResource("Resource_hguc3")
CalculatorPostMultiplyAdditiveValue = SubResource("Resource_lbthk")
metadata/_custom_type_script = "uid://bdfcavbjyhxxa"
[sub_resource type="Resource" id="Resource_xmw7i"]
script = ExtResource("6_41lep")
BaseValue = 1
[sub_resource type="Resource" id="Resource_lj45k"]
script = ExtResource("9_bcnlx")
Name = "SimpleHitEffect"
Modifiers = Array[Object]([SubResource("Resource_khx4r")])
Components = [ExtResource("1_q2jt5")]
Executions = [ExtResource("2_f6jpb"), ExtResource("2_2dxcu")]
StackLimit = SubResource("Resource_xmw7i")
InitialStack = SubResource("Resource_rjo6h")
Cues = []
metadata/_custom_type_script = "uid://b83hf13nj37k3"
[sub_resource type="Resource" id="Resource_m0osh"]
script = ExtResource("10_m4f1m")
DamageEffect = SubResource("Resource_lj45k")
Name = "Simple hit"
Description = "This is a simple hit from an enemy"
metadata/_custom_type_script = "uid://n6efm5o4uxvr"
[sub_resource type="Resource" id="Resource_msmv1"]
script = ExtResource("4_0mce3")
ContainerTags = Array[String](["status.stunned"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[sub_resource type="Resource" id="Resource_xdbds"]
script = ExtResource("4_0mce3")
ContainerTags = Array[String](["cooldown.enemy.hit"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[sub_resource type="Resource" id="Resource_gna8g"]
script = ExtResource("11_8c5sq")
TagsToAdd = SubResource("Resource_xdbds")
metadata/_custom_type_script = "uid://dngf30hxy5go4"
[sub_resource type="Resource" id="Resource_oo2a1"]
script = ExtResource("7_jf6ii")
BaseValue = 1.0
[sub_resource type="Resource" id="Resource_q86ag"]
script = ExtResource("7_jf6ii")
[sub_resource type="Resource" id="Resource_5eesh"]
script = ExtResource("7_jf6ii")
[sub_resource type="Resource" id="Resource_5lf6m"]
script = ExtResource("7_jf6ii")
BaseValue = 1.0
[sub_resource type="Resource" id="Resource_bv3hg"]
script = ExtResource("7_jf6ii")
[sub_resource type="Resource" id="Resource_tb7hu"]
script = ExtResource("7_jf6ii")
[sub_resource type="Resource" id="Resource_bw6ul"]
script = ExtResource("7_jf6ii")
BaseValue = 1.0
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
[sub_resource type="Resource" id="Resource_g5uhf"]
script = ExtResource("12_2x5q6")
ScalableFloat = SubResource("Resource_bw6ul")
Coefficient = SubResource("Resource_5lf6m")
PreMultiplyAdditiveValue = SubResource("Resource_tb7hu")
PostMultiplyAdditiveValue = SubResource("Resource_bv3hg")
CalculatorCoefficient = SubResource("Resource_oo2a1")
CalculatorPreMultiplyAdditiveValue = SubResource("Resource_5eesh")
CalculatorPostMultiplyAdditiveValue = SubResource("Resource_q86ag")
metadata/_custom_type_script = "uid://2gm1hdhi8u08"
[sub_resource type="Resource" id="Resource_vl5ta"]
script = ExtResource("6_41lep")
BaseValue = 1
[sub_resource type="Resource" id="Resource_82a7m"]
script = ExtResource("6_41lep")
BaseValue = 1
[sub_resource type="Resource" id="Resource_0gdnn"]
script = ExtResource("9_bcnlx")
Name = "HitCooldown"
Modifiers = []
Components = [SubResource("Resource_gna8g")]
Executions = []
DurationType = 2
Duration = SubResource("Resource_g5uhf")
StackLimit = SubResource("Resource_82a7m")
InitialStack = SubResource("Resource_vl5ta")
Cues = []
metadata/_custom_type_script = "uid://b83hf13nj37k3"
[resource]
script = ExtResource("13_4nn3y")
Name = "Hit"
CooldownEffects = [SubResource("Resource_0gdnn")]
AbilityBehavior = SubResource("Resource_m0osh")
ActivationBlockedTags = SubResource("Resource_msmv1")
metadata/_custom_type_script = "uid://dhxfbxh54pyxp"

View File

@@ -0,0 +1,95 @@
[gd_resource type="Resource" script_class="ForgeAbilityData" format=3 uid="uid://b0ikxp5j8fn3n"]
[ext_resource type="Resource" uid="uid://cw2ytd34jsxj" path="res://forge/resources/tag_containers/immune_damage.tres" id="1_xjqwu"]
[ext_resource type="Script" uid="uid://dngf30hxy5go4" path="res://addons/forge/resources/components/ModifierTags.cs" id="2_a16tf"]
[ext_resource type="Script" uid="uid://cn3b4ya15fg7e" path="res://addons/forge/resources/magnitudes/ForgeScalableFloat.cs" id="3_1wliv"]
[ext_resource type="Script" uid="uid://2gm1hdhi8u08" path="res://addons/forge/resources/magnitudes/ForgeModifierMagnitude.cs" id="4_7dtdc"]
[ext_resource type="Script" uid="uid://1hgogislo1l6" path="res://addons/forge/resources/magnitudes/ForgeScalableInt.cs" id="5_ewbg3"]
[ext_resource type="Script" uid="uid://b83hf13nj37k3" path="res://addons/forge/resources/ForgeEffectData.cs" id="6_0akms"]
[ext_resource type="Script" uid="uid://cl5hudinl1rex" path="res://forge/abilities/ForgeEffectApplicationBehavior.cs" id="7_mhqpo"]
[ext_resource type="Script" uid="uid://dpakv7agvir6y" path="res://addons/forge/resources/ForgeTag.cs" id="8_4vjp3"]
[ext_resource type="Script" uid="uid://dhxfbxh54pyxp" path="res://addons/forge/resources/abilities/ForgeAbilityData.cs" id="9_go27d"]
[sub_resource type="Resource" id="Resource_5ht6k"]
script = ExtResource("2_a16tf")
TagsToAdd = ExtResource("1_xjqwu")
metadata/_custom_type_script = "uid://dngf30hxy5go4"
[sub_resource type="Resource" id="Resource_bn2qi"]
script = ExtResource("3_1wliv")
BaseValue = 1.0
[sub_resource type="Resource" id="Resource_pl2a2"]
script = ExtResource("3_1wliv")
[sub_resource type="Resource" id="Resource_g02pf"]
script = ExtResource("3_1wliv")
[sub_resource type="Resource" id="Resource_7ak88"]
script = ExtResource("3_1wliv")
BaseValue = 1.0
[sub_resource type="Resource" id="Resource_f12ll"]
script = ExtResource("3_1wliv")
[sub_resource type="Resource" id="Resource_xodo6"]
script = ExtResource("3_1wliv")
[sub_resource type="Resource" id="Resource_mcqfd"]
script = ExtResource("3_1wliv")
BaseValue = 2.0
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
[sub_resource type="Resource" id="Resource_w3q2i"]
script = ExtResource("4_7dtdc")
ScalableFloat = SubResource("Resource_mcqfd")
Coefficient = SubResource("Resource_7ak88")
PreMultiplyAdditiveValue = SubResource("Resource_xodo6")
PostMultiplyAdditiveValue = SubResource("Resource_f12ll")
CalculatorCoefficient = SubResource("Resource_bn2qi")
CalculatorPreMultiplyAdditiveValue = SubResource("Resource_g02pf")
CalculatorPostMultiplyAdditiveValue = SubResource("Resource_pl2a2")
metadata/_custom_type_script = "uid://2gm1hdhi8u08"
[sub_resource type="Resource" id="Resource_vgvi5"]
script = ExtResource("5_ewbg3")
BaseValue = 1
[sub_resource type="Resource" id="Resource_0ujop"]
script = ExtResource("5_ewbg3")
BaseValue = 1
[sub_resource type="Resource" id="Resource_s8mqp"]
script = ExtResource("6_0akms")
Name = "Add Invincible tag effect"
Modifiers = Array[Object]([])
Components = Array[Object]([SubResource("Resource_5ht6k")])
Executions = []
DurationType = 2
Duration = SubResource("Resource_w3q2i")
StackLimit = SubResource("Resource_0ujop")
InitialStack = SubResource("Resource_vgvi5")
Cues = []
metadata/_custom_type_script = "uid://b83hf13nj37k3"
[sub_resource type="Resource" id="Resource_tcrdt"]
script = ExtResource("7_mhqpo")
EffectData = SubResource("Resource_s8mqp")
Name = "OnHitInvincibility"
Description = "Adds the invincible tag for a given period"
metadata/_custom_type_script = "uid://cl5hudinl1rex"
[sub_resource type="Resource" id="Resource_xs7wf"]
script = ExtResource("8_4vjp3")
Tag = "events.combat.damage"
metadata/_custom_type_script = "uid://dpakv7agvir6y"
[resource]
script = ExtResource("9_go27d")
Name = "OnHitInvincibility"
InstancingPolicy = 1
CooldownEffects = []
AbilityBehavior = SubResource("Resource_tcrdt")
TriggerSource = 1
TriggerTag = SubResource("Resource_xs7wf")
metadata/_custom_type_script = "uid://dhxfbxh54pyxp"

View File

@@ -0,0 +1,158 @@
[gd_resource type="Resource" script_class="ForgeAbilityData" format=3 uid="uid://dgjsi1my7nlnk"]
[ext_resource type="Script" uid="uid://1hgogislo1l6" path="res://addons/forge/resources/magnitudes/ForgeScalableInt.cs" id="1_l0l1a"]
[ext_resource type="Script" uid="uid://n6efm5o4uxvr" path="res://forge/abilities/ForgeSimpleHitBehavior.cs" id="1_n2s8d"]
[ext_resource type="Resource" uid="uid://bpovqvlqv5bs5" path="res://forge/resources/effect_components/damageable.tres" id="1_r7waw"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_w1wo0"]
[ext_resource type="Script" uid="uid://b83hf13nj37k3" path="res://addons/forge/resources/ForgeEffectData.cs" id="2_5vjbv"]
[ext_resource type="Script" uid="uid://dngf30hxy5go4" path="res://addons/forge/resources/components/ModifierTags.cs" id="2_jwyed"]
[ext_resource type="Resource" uid="uid://4rkwr10pc6tp" path="res://forge/resources/custom_executions/physical_damage_calculator.tres" id="2_l5emy"]
[ext_resource type="Script" uid="uid://bdfcavbjyhxxa" path="res://addons/forge/resources/ForgeModifier.cs" id="3_c4wry"]
[ext_resource type="Script" uid="uid://dhxfbxh54pyxp" path="res://addons/forge/resources/abilities/ForgeAbilityData.cs" id="3_w1wo0"]
[ext_resource type="Script" uid="uid://cn3b4ya15fg7e" path="res://addons/forge/resources/magnitudes/ForgeScalableFloat.cs" id="4_c4wry"]
[ext_resource type="Script" uid="uid://2gm1hdhi8u08" path="res://addons/forge/resources/magnitudes/ForgeModifierMagnitude.cs" id="5_0cyim"]
[sub_resource type="Resource" id="Resource_0cyim"]
script = ExtResource("1_l0l1a")
BaseValue = 1
[sub_resource type="Resource" id="Resource_h8gc3"]
script = ExtResource("4_c4wry")
BaseValue = 1.0
[sub_resource type="Resource" id="Resource_ewmvj"]
script = ExtResource("4_c4wry")
[sub_resource type="Resource" id="Resource_8wvcn"]
script = ExtResource("4_c4wry")
[sub_resource type="Resource" id="Resource_no8t2"]
script = ExtResource("4_c4wry")
BaseValue = 1.0
[sub_resource type="Resource" id="Resource_vioyh"]
script = ExtResource("4_c4wry")
[sub_resource type="Resource" id="Resource_m6xnn"]
script = ExtResource("4_c4wry")
[sub_resource type="Resource" id="Resource_uinv8"]
script = ExtResource("4_c4wry")
BaseValue = 40.0
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
[sub_resource type="Resource" id="Resource_04hqa"]
script = ExtResource("3_c4wry")
Attribute = "MetaAttributeSet.IncomingDamage"
Operation = 2
ScalableFloat = SubResource("Resource_uinv8")
Coefficient = SubResource("Resource_no8t2")
PreMultiplyAdditiveValue = SubResource("Resource_m6xnn")
PostMultiplyAdditiveValue = SubResource("Resource_vioyh")
CalculatorCoefficient = SubResource("Resource_h8gc3")
CalculatorPreMultiplyAdditiveValue = SubResource("Resource_8wvcn")
CalculatorPostMultiplyAdditiveValue = SubResource("Resource_ewmvj")
metadata/_custom_type_script = "uid://bdfcavbjyhxxa"
[sub_resource type="Resource" id="Resource_8fbeq"]
script = ExtResource("1_l0l1a")
BaseValue = 1
[sub_resource type="Resource" id="Resource_ees2v"]
script = ExtResource("2_5vjbv")
Name = "Player Hit Effect"
Modifiers = Array[Object]([SubResource("Resource_04hqa")])
Components = Array[Object]([ExtResource("1_r7waw")])
Executions = Array[Object]([ExtResource("2_l5emy")])
StackLimit = SubResource("Resource_8fbeq")
InitialStack = SubResource("Resource_0cyim")
Cues = []
metadata/_custom_type_script = "uid://b83hf13nj37k3"
[sub_resource type="Resource" id="Resource_r7waw"]
script = ExtResource("1_n2s8d")
DamageEffect = SubResource("Resource_ees2v")
Name = "PlayerHitEffect"
Description = "Effect applied to target on player hit"
metadata/_custom_type_script = "uid://n6efm5o4uxvr"
[sub_resource type="Resource" id="Resource_qk2av"]
script = ExtResource("1_w1wo0")
ContainerTags = Array[String](["status.stunned"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[sub_resource type="Resource" id="Resource_w857g"]
script = ExtResource("1_w1wo0")
ContainerTags = Array[String](["cooldown.hit"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[sub_resource type="Resource" id="Resource_n2s8d"]
script = ExtResource("2_jwyed")
TagsToAdd = SubResource("Resource_w857g")
metadata/_custom_type_script = "uid://dngf30hxy5go4"
[sub_resource type="Resource" id="Resource_l5emy"]
script = ExtResource("4_c4wry")
BaseValue = 1.0
[sub_resource type="Resource" id="Resource_agfn8"]
script = ExtResource("4_c4wry")
[sub_resource type="Resource" id="Resource_tkxxk"]
script = ExtResource("4_c4wry")
[sub_resource type="Resource" id="Resource_e4qbe"]
script = ExtResource("4_c4wry")
BaseValue = 1.0
[sub_resource type="Resource" id="Resource_coxn5"]
script = ExtResource("4_c4wry")
[sub_resource type="Resource" id="Resource_wak7n"]
script = ExtResource("4_c4wry")
[sub_resource type="Resource" id="Resource_bvwi7"]
script = ExtResource("4_c4wry")
BaseValue = 0.3
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
[sub_resource type="Resource" id="Resource_3wf5l"]
script = ExtResource("5_0cyim")
ScalableFloat = SubResource("Resource_bvwi7")
Coefficient = SubResource("Resource_e4qbe")
PreMultiplyAdditiveValue = SubResource("Resource_wak7n")
PostMultiplyAdditiveValue = SubResource("Resource_coxn5")
CalculatorCoefficient = SubResource("Resource_l5emy")
CalculatorPreMultiplyAdditiveValue = SubResource("Resource_tkxxk")
CalculatorPostMultiplyAdditiveValue = SubResource("Resource_agfn8")
metadata/_custom_type_script = "uid://2gm1hdhi8u08"
[sub_resource type="Resource" id="Resource_xs7wf"]
script = ExtResource("1_l0l1a")
BaseValue = 1
[sub_resource type="Resource" id="Resource_cm4e8"]
script = ExtResource("1_l0l1a")
BaseValue = 1
[sub_resource type="Resource" id="Resource_cmmfb"]
script = ExtResource("2_5vjbv")
Name = "PlayerHitCooldown"
Modifiers = []
Components = Array[Object]([SubResource("Resource_n2s8d")])
Executions = []
DurationType = 2
Duration = SubResource("Resource_3wf5l")
StackLimit = SubResource("Resource_cm4e8")
InitialStack = SubResource("Resource_xs7wf")
Cues = []
metadata/_custom_type_script = "uid://b83hf13nj37k3"
[resource]
script = ExtResource("3_w1wo0")
Name = "PlayerHitAbility"
RetriggerInstancedAbility = true
CooldownEffects = [SubResource("Resource_cmmfb")]
AbilityBehavior = SubResource("Resource_r7waw")
ActivationBlockedTags = SubResource("Resource_qk2av")
metadata/_custom_type_script = "uid://dhxfbxh54pyxp"

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="ForgeAbilityData" format=3 uid="uid://btnnpqann3ktp"]
[ext_resource type="Resource" uid="uid://1tmxayi3nygi" path="res://scenes/player_controller/resources/forge/flying tick application ability behavior.tres" id="1_twa0w"]
[ext_resource type="Resource" uid="uid://1tmxayi3nygi" path="res://forge/resources/behaviors/flying tick application ability behavior.tres" id="1_twa0w"]
[ext_resource type="Script" uid="uid://dhxfbxh54pyxp" path="res://addons/forge/resources/abilities/ForgeAbilityData.cs" id="1_vh0wp"]
[ext_resource type="Script" uid="uid://dpakv7agvir6y" path="res://addons/forge/resources/ForgeTag.cs" id="6_napws"]

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="ForgeEffectApplicationBehavior" format=3 uid="uid://1tmxayi3nygi"]
[ext_resource type="Resource" uid="uid://bvidrwyuoos4g" path="res://scenes/player_controller/resources/forge/raise_flying_tick_event_periodically.tres" id="1_hlq5f"]
[ext_resource type="Resource" uid="uid://bvidrwyuoos4g" path="res://forge/resources/effect_datas/raise_flying_tick_event_periodically.tres" id="1_hlq5f"]
[ext_resource type="Script" uid="uid://cl5hudinl1rex" path="res://forge/abilities/ForgeEffectApplicationBehavior.cs" id="2_f5qgs"]
[resource]

View File

@@ -0,0 +1,17 @@
[gd_resource type="Resource" script_class="ForgeCue" format=3 uid="uid://bsqvfefpb7jix"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_tvgrb"]
[ext_resource type="Script" uid="uid://cmrsxccn0ei4j" path="res://addons/forge/resources/ForgeCue.cs" id="2_dyb6j"]
[sub_resource type="Resource" id="Resource_f35o6"]
script = ExtResource("1_tvgrb")
ContainerTags = Array[String](["cues.resources.health", "character.player"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[resource]
script = ExtResource("2_dyb6j")
CueKeys = SubResource("Resource_f35o6")
MaxValue = 100
MagnitudeType = 2
MagnitudeAttribute = "PlayerAttributeSet.Health"
metadata/_custom_type_script = "uid://cmrsxccn0ei4j"

View File

@@ -1,15 +1,15 @@
[gd_resource type="Resource" script_class="ForgeCue" format=3 uid="uid://dn7b8frkoxpxr"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_lbula"]
[ext_resource type="Script" uid="uid://cmrsxccn0ei4j" path="res://addons/forge/resources/ForgeCue.cs" id="2_jijlk"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_0pc1u"]
[ext_resource type="Script" uid="uid://cmrsxccn0ei4j" path="res://addons/forge/resources/ForgeCue.cs" id="2_g0vcr"]
[sub_resource type="Resource" id="Resource_4mhqs"]
script = ExtResource("1_lbula")
script = ExtResource("1_0pc1u")
ContainerTags = Array[String](["cues.resources.mana"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[resource]
script = ExtResource("2_jijlk")
script = ExtResource("2_g0vcr")
CueKeys = SubResource("Resource_4mhqs")
MaxValue = 100
MagnitudeType = 2

View File

@@ -0,0 +1,11 @@
[gd_resource type="Resource" script_class="ForgeDamageExecution" format=3 uid="uid://4rkwr10pc6tp"]
[ext_resource type="Script" uid="uid://cfx62w40nd84v" path="res://forge/calculators/ForgeDamageExecution.cs" id="1_bo86y"]
[ext_resource type="Resource" uid="uid://sn6kndc6ukic" path="res://forge/resources/tag_containers/on_damage_dealt.tres" id="1_hmxxf"]
[ext_resource type="Resource" uid="uid://5tr54q0rdpho" path="res://forge/resources/tag_containers/on_damage_taken.tres" id="2_6r7e6"]
[resource]
script = ExtResource("1_bo86y")
DamageDealerEventTags = ExtResource("1_hmxxf")
DamageReceiverEventTags = ExtResource("2_6r7e6")
metadata/_custom_type_script = "uid://cfx62w40nd84v"

View File

@@ -0,0 +1,11 @@
[gd_resource type="Resource" script_class="ForgeRaiseEventTagExecution" format=3 uid="uid://dlu7l5egpexnn"]
[ext_resource type="Resource" uid="uid://sn6kndc6ukic" path="res://forge/resources/tag_containers/on_damage_dealt.tres" id="1_cum8v"]
[ext_resource type="Resource" uid="uid://5tr54q0rdpho" path="res://forge/resources/tag_containers/on_damage_taken.tres" id="2_w48xp"]
[ext_resource type="Script" uid="uid://br7ut4lbau66w" path="res://forge/calculators/ForgeRaiseEventTagExecution.cs" id="3_ggrwn"]
[resource]
script = ExtResource("3_ggrwn")
EventTags = ExtResource("1_cum8v")
TargetEventTags = ExtResource("2_w48xp")
metadata/_custom_type_script = "uid://br7ut4lbau66w"

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="ForgeRaiseEventTagExecution" format=3 uid="uid://oe2suroa1klj"]
[ext_resource type="Resource" uid="uid://x7vtcobi7s4r" path="res://scenes/player_controller/resources/forge/weapon_flyingtick_tagcontainer.tres" id="1_ce5fv"]
[ext_resource type="Resource" uid="uid://x7vtcobi7s4r" path="res://forge/resources/tag_containers/on_weapon_flyingtick.tres" id="1_ce5fv"]
[ext_resource type="Script" uid="uid://br7ut4lbau66w" path="res://forge/calculators/ForgeRaiseEventTagExecution.cs" id="2_am2ak"]
[resource]

View File

@@ -0,0 +1,11 @@
[gd_resource type="Resource" script_class="TargetTagRequirements" format=3 uid="uid://bpovqvlqv5bs5"]
[ext_resource type="Resource" uid="uid://cw2ytd34jsxj" path="res://forge/resources/tag_containers/immune_damage.tres" id="1_8qlnl"]
[ext_resource type="Resource" uid="uid://bsogx7yhedjry" path="res://forge/resources/tag_containers/trait_damageable.tres" id="2_vxkk1"]
[ext_resource type="Script" uid="uid://b0eq12mjqfage" path="res://addons/forge/resources/components/TargetTagRequirements.cs" id="3_1mj5a"]
[resource]
script = ExtResource("3_1mj5a")
ApplicationRequiredTags = ExtResource("2_vxkk1")
ApplicationIgnoredTags = ExtResource("1_8qlnl")
metadata/_custom_type_script = "uid://b0eq12mjqfage"

View File

@@ -1,54 +1,54 @@
[gd_resource type="Resource" script_class="ForgeEffectData" format=3 uid="uid://dh437cuxgjv6b"]
[ext_resource type="Script" uid="uid://1hgogislo1l6" path="res://addons/forge/resources/magnitudes/ForgeScalableInt.cs" id="1_mlifq"]
[ext_resource type="Resource" uid="uid://dn7b8frkoxpxr" path="res://scenes/player_controller/resources/forge/player_mana_changed_cue.tres" id="1_nsr3v"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_q8tml"]
[ext_resource type="Script" uid="uid://b83hf13nj37k3" path="res://addons/forge/resources/ForgeEffectData.cs" id="2_5tp50"]
[ext_resource type="Script" uid="uid://cn3b4ya15fg7e" path="res://addons/forge/resources/magnitudes/ForgeScalableFloat.cs" id="2_pm3n3"]
[ext_resource type="Script" uid="uid://b0eq12mjqfage" path="res://addons/forge/resources/components/TargetTagRequirements.cs" id="2_xbgy2"]
[ext_resource type="Script" uid="uid://bdfcavbjyhxxa" path="res://addons/forge/resources/ForgeModifier.cs" id="3_nsr3v"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_b244r"]
[ext_resource type="Script" uid="uid://b0eq12mjqfage" path="res://addons/forge/resources/components/TargetTagRequirements.cs" id="2_h46co"]
[ext_resource type="Resource" uid="uid://dn7b8frkoxpxr" path="res://forge/resources/cues/player_mana_changed_cue.tres" id="3_kw6jm"]
[ext_resource type="Script" uid="uid://1hgogislo1l6" path="res://addons/forge/resources/magnitudes/ForgeScalableInt.cs" id="4_fgmkc"]
[ext_resource type="Script" uid="uid://cn3b4ya15fg7e" path="res://addons/forge/resources/magnitudes/ForgeScalableFloat.cs" id="5_m4art"]
[ext_resource type="Script" uid="uid://bdfcavbjyhxxa" path="res://addons/forge/resources/ForgeModifier.cs" id="6_73cww"]
[ext_resource type="Script" uid="uid://b83hf13nj37k3" path="res://addons/forge/resources/ForgeEffectData.cs" id="7_xa46f"]
[sub_resource type="Resource" id="Resource_5yygy"]
script = ExtResource("1_q8tml")
script = ExtResource("1_b244r")
ContainerTags = Array[String](["character.player.mana.regen.inhibited", "cues.resources.mana.inhibited"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[sub_resource type="Resource" id="Resource_ncjx6"]
script = ExtResource("2_xbgy2")
script = ExtResource("2_h46co")
OngoingIgnoredTags = SubResource("Resource_5yygy")
metadata/_custom_type_script = "uid://b0eq12mjqfage"
[sub_resource type="Resource" id="Resource_pm3n3"]
script = ExtResource("1_mlifq")
script = ExtResource("4_fgmkc")
BaseValue = 1
[sub_resource type="Resource" id="Resource_q8tml"]
script = ExtResource("2_pm3n3")
script = ExtResource("5_m4art")
BaseValue = 1.0
[sub_resource type="Resource" id="Resource_xbgy2"]
script = ExtResource("2_pm3n3")
script = ExtResource("5_m4art")
[sub_resource type="Resource" id="Resource_rhldn"]
script = ExtResource("2_pm3n3")
script = ExtResource("5_m4art")
[sub_resource type="Resource" id="Resource_p6h8c"]
script = ExtResource("2_pm3n3")
script = ExtResource("5_m4art")
BaseValue = 1.0
[sub_resource type="Resource" id="Resource_yqxv4"]
script = ExtResource("2_pm3n3")
script = ExtResource("5_m4art")
[sub_resource type="Resource" id="Resource_b6opn"]
script = ExtResource("2_pm3n3")
script = ExtResource("5_m4art")
[sub_resource type="Resource" id="Resource_5frso"]
script = ExtResource("2_pm3n3")
script = ExtResource("5_m4art")
BaseValue = 2.0
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
[sub_resource type="Resource" id="Resource_okenf"]
script = ExtResource("3_nsr3v")
script = ExtResource("6_73cww")
Attribute = "PlayerAttributeSet.Mana"
ScalableFloat = SubResource("Resource_5frso")
Coefficient = SubResource("Resource_p6h8c")
@@ -60,16 +60,16 @@ CalculatorPostMultiplyAdditiveValue = SubResource("Resource_xbgy2")
metadata/_custom_type_script = "uid://bdfcavbjyhxxa"
[sub_resource type="Resource" id="Resource_w35mq"]
script = ExtResource("2_pm3n3")
script = ExtResource("5_m4art")
BaseValue = 0.1
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
[sub_resource type="Resource" id="Resource_nsr3v"]
script = ExtResource("1_mlifq")
script = ExtResource("4_fgmkc")
BaseValue = 1
[resource]
script = ExtResource("2_5tp50")
script = ExtResource("7_xa46f")
Name = "Mana Regeneration"
Modifiers = Array[Object]([SubResource("Resource_okenf")])
Components = [SubResource("Resource_ncjx6")]
@@ -79,5 +79,5 @@ HasPeriodicApplication = true
Period = SubResource("Resource_w35mq")
StackLimit = SubResource("Resource_nsr3v")
InitialStack = SubResource("Resource_pm3n3")
Cues = Array[Object]([ExtResource("1_nsr3v")])
Cues = Array[Object]([ExtResource("3_kw6jm")])
metadata/_custom_type_script = "uid://b83hf13nj37k3"

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="ForgeEffectData" format=3 uid="uid://bvidrwyuoos4g"]
[ext_resource type="Resource" uid="uid://oe2suroa1klj" path="res://scenes/player_controller/resources/forge/raise_flying_tick_event.tres" id="1_cd13a"]
[ext_resource type="Resource" uid="uid://oe2suroa1klj" path="res://forge/resources/custom_executions/raise_flying_tick_event.tres" id="1_cd13a"]
[ext_resource type="Script" uid="uid://1hgogislo1l6" path="res://addons/forge/resources/magnitudes/ForgeScalableInt.cs" id="2_yyxtw"]
[ext_resource type="Script" uid="uid://cn3b4ya15fg7e" path="res://addons/forge/resources/magnitudes/ForgeScalableFloat.cs" id="3_skmyt"]
[ext_resource type="Script" uid="uid://b83hf13nj37k3" path="res://addons/forge/resources/ForgeEffectData.cs" id="4_7ma6b"]

View File

@@ -0,0 +1,8 @@
[gd_resource type="Resource" script_class="ForgeTagContainer" format=3 uid="uid://bocsykxbh8l0g"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_kdy2b"]
[resource]
script = ExtResource("1_kdy2b")
ContainerTags = Array[String](["character.enemy", "traits.damageable"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"

View File

@@ -0,0 +1,8 @@
[gd_resource type="Resource" script_class="ForgeTagContainer" format=3 uid="uid://cw2ytd34jsxj"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_vmvhu"]
[resource]
script = ExtResource("1_vmvhu")
ContainerTags = Array[String](["immunity.damage"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"

View File

@@ -0,0 +1,8 @@
[gd_resource type="Resource" script_class="ForgeTagContainer" format=3 uid="uid://sn6kndc6ukic"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_4beov"]
[resource]
script = ExtResource("1_4beov")
ContainerTags = Array[String](["events.combat.hit"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"

View File

@@ -0,0 +1,8 @@
[gd_resource type="Resource" script_class="ForgeTagContainer" format=3 uid="uid://5tr54q0rdpho"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_nvopg"]
[resource]
script = ExtResource("1_nvopg")
ContainerTags = Array[String](["events.combat.damage"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"

View File

@@ -0,0 +1,8 @@
[gd_resource type="Resource" script_class="ForgeTagContainer" format=3 uid="uid://bsogx7yhedjry"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_wyb42"]
[resource]
script = ExtResource("1_wyb42")
ContainerTags = Array[String](["traits.damageable"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"

View File

@@ -3,5 +3,5 @@ using Godot;
interface ISpawnable
{
void Initialize();
void Init();
}

View File

@@ -1,39 +1,43 @@
using System.Collections.Generic;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Gamesmiths.Forge.Godot.Resources.Abilities;
using Godot;
using Movementtests.systems;
namespace Movementtests.managers;
public partial class WeaponEventAbilityData(WeaponSystem.WeaponEvent forEvent, Resource ability)
public partial class WeaponEventAbilityData(WeaponSystem.WeaponEvent forEvent, ForgeAbilityBehavior ability)
: RefCounted
{
public WeaponSystem.WeaponEvent ForEvent { get; private set; } = forEvent;
public Resource Ability { get; private set; } = ability;
public ForgeAbilityBehavior Ability { get; private set; } = ability;
}
[GlobalClass]
public partial class InventoryManager : Node
{
[Signal]
public delegate void InventoryChangedEventHandler();
[Signal]
public delegate void WeaponEventInventoryChangedEventHandler();
#region Signals
[Signal]
public delegate void WeaponEventAbilityAddedEventHandler(WeaponEventAbilityData data);
[Signal]
public delegate void WeaponEventAbilityRemovedEventHandler(WeaponEventAbilityData data);
public Dictionary<WeaponSystem.WeaponEvent, HashSet<Resource>> WeaponEventsInventory { get; } = [];
public static InventoryManager Instance { get; private set; }
#endregion
public override void _Ready()
public Dictionary<WeaponSystem.WeaponEvent, HashSet<ForgeAbilityBehavior>> WeaponEventsInventory { get; private set; }
= new() {
{ WeaponSystem.WeaponEvent.FlyingTick, [] },
{ WeaponSystem.WeaponEvent.StartedFlying, [] },
{ WeaponSystem.WeaponEvent.StoppedFlying, [] }
};
public void InitializeFromResource(WeaponInventory inventory)
{
Instance = this;
WeaponEventsInventory[WeaponSystem.WeaponEvent.FlyingTick] = new HashSet<Resource>();
WeaponEventsInventory[WeaponSystem.WeaponEvent.StartedFlying] = new HashSet<Resource>();
WeaponEventsInventory[WeaponSystem.WeaponEvent.StoppedFlying] = new HashSet<Resource>();
WeaponEventsInventory[WeaponSystem.WeaponEvent.FlyingTick] = new HashSet<ForgeAbilityBehavior>(inventory.OnWeaponFlyingTickAbilities);
WeaponEventsInventory[WeaponSystem.WeaponEvent.StartedFlying] = new HashSet<ForgeAbilityBehavior>(inventory.OnWeaponStartedFlyingAbilities);
WeaponEventsInventory[WeaponSystem.WeaponEvent.StoppedFlying] = new HashSet<ForgeAbilityBehavior>(inventory.OnWeaponStoppedFlyingAbilities);
}
public void AddAbilityForWeaponEvent(WeaponSystem.WeaponEvent forEvent, ForgeAbilityBehavior abilityBehavior)
@@ -42,7 +46,6 @@ public partial class InventoryManager : Node
var addedAbilityToInventory = inventoryForEvent.Add(abilityBehavior);
if (!addedAbilityToInventory) return;
EmitSignalWeaponEventInventoryChanged();
EmitSignalWeaponEventAbilityAdded(new WeaponEventAbilityData(forEvent, abilityBehavior));
}
@@ -52,7 +55,6 @@ public partial class InventoryManager : Node
var removedFromInventory = inventoryForEvent.Remove(abilityBehavior);
if (!removedFromInventory) return;
EmitSignalWeaponEventInventoryChanged();
EmitSignalWeaponEventAbilityRemoved(new WeaponEventAbilityData(forEvent, abilityBehavior));
}
}

View File

@@ -0,0 +1,22 @@
using System.Collections.Generic;
using Gamesmiths.Forge.Godot.Resources.Abilities;
using Godot;
namespace Movementtests.managers;
[GlobalClass]
public partial class WeaponInventory(
ForgeAbilityBehavior[] onWeaponStartedFlyingAbilities,
ForgeAbilityBehavior[] onWeaponFlyingTickAbilities,
ForgeAbilityBehavior[] onWeaponStoppedFlyingAbilities
) : Resource
{
[Export]
public ForgeAbilityBehavior[] OnWeaponStartedFlyingAbilities { get; set; } = onWeaponStartedFlyingAbilities;
[Export]
public ForgeAbilityBehavior[] OnWeaponFlyingTickAbilities { get; set; } = onWeaponFlyingTickAbilities;
[Export]
public ForgeAbilityBehavior[] OnWeaponStoppedFlyingAbilities { get; set; } = onWeaponStoppedFlyingAbilities;
public WeaponInventory() : this([], [], []) {}
}

View File

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

View File

@@ -0,0 +1,93 @@
using Godot;
using System;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Gamesmiths.Forge.Cues;
using Gamesmiths.Forge.Godot.Core;
using Gamesmiths.Forge.Tags;
using Movementtests.interfaces;using Movementtests.managers;
using Movementtests.systems;
[Meta(
typeof(IAutoOn),
typeof(IAutoConnect),
typeof(IProvider)
)]
public partial class MainSceneTemplate : Node3D, IProvide<InventoryManager>, IProvide<TagsManager>, IProvide<CuesManager>
{
public override void _Notification(int what) => this.Notify(what);
#region Nodes
[Node("PlayerFellRespawn")] public required Marker3D PlayerRespawnMarker { get; set; }
[Node("AnimationPlayer")] public required AnimationPlayer AnimationPlayer { get; set; }
[Node("PlayerFellTP")] public required Area3D PlayerFellPlane { get; set; }
[Node("DeathPlane")] public required Area3D DeathPlane { get; set; }
#endregion
private Node3D? Respawnabble { get; set; }
#region Exports
[Export] public WeaponInventory? InitialWeaponInventory { get; set; }
#endregion
public required InventoryManager InventoryManager { get; set; }
InventoryManager IProvide<InventoryManager>.Value() => InventoryManager;
TagsManager IProvide<TagsManager>.Value() => ForgeManagers.Instance.TagsManager;
CuesManager IProvide<CuesManager>.Value() => ForgeManagers.Instance.CuesManager;
public void OnReady()
{
PlayerFellPlane.BodyEntered += StartResetPlayerAnimation;
DeathPlane.BodyEntered += KillEnemy;
InventoryManager = new InventoryManager();
if (InitialWeaponInventory != null)
InventoryManager.InitializeFromResource(InitialWeaponInventory);
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()
{
if (Respawnabble == null || PlayerRespawnMarker == null) throw new Exception("Player or respawn marker is null");
Respawnabble.GlobalPosition = PlayerRespawnMarker.GlobalPosition;
}
public void StartResetPlayerAnimation(Node3D body)
{
if (body is WeaponSystem weapon)
{
if (PlayerRespawnMarker == null) throw new Exception("Respawn marker is null");
weapon.GlobalPosition = PlayerRespawnMarker.GlobalPosition;
weapon.SetLinearVelocity(Vector3.Down);
return;
}
Respawnabble = body as PlayerController;
if (Respawnabble == null || AnimationPlayer == null) throw new Exception("Player or anim player is null");
AnimationPlayer.Play("player_fell");
}
public void KillEnemy(Node3D body)
{
if (body is not (IKillable killable and IHealthable healthable))
{
body.QueueFree();
return;
}
killable.Kill(healthable);
}
}

View File

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

View File

@@ -1,21 +0,0 @@
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

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

View File

@@ -1,6 +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="Script" uid="uid://br0f18u1iou2d" path="res://maps/_templates/MainSceneTemplate.cs" 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"]
@@ -237,7 +237,7 @@ tracks/6/keys = {
"transitions": PackedFloat32Array(1),
"values": [{
"args": [],
"method": &"reset_player_position"
"method": &"ResetPlayerPosition"
}]
}
@@ -300,6 +300,7 @@ 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
collision_mask = 65537
monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="PlayerFellTP" unique_id=1866249040]

View File

@@ -41,7 +41,7 @@ size = Vector3(6.75, 8.25, 7.25)
[node name="Main" unique_id=955321579 instance=ExtResource("1_jyq54")]
[node name="DirectionalLight3D" parent="." index="5" unique_id=1357990191]
[node name="DirectionalLight3D" parent="." index="6" unique_id=1357990191]
transform = Transform3D(-0.1772511, 0.44628847, 0.87715954, 0.49540228, -0.72966087, 0.4713508, 0.85038733, 0.51809436, -0.09175911, 0, 0, 0)
[node name="Greybox" type="CSGCombiner3D" parent="." index="7" unique_id=2082385716]
@@ -907,9 +907,9 @@ light_energy = 8.571
omni_range = 7.0
[node name="OmniLight3D29" type="OmniLight3D" parent="Lights" index="24" unique_id=2143811783]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -37, 25.5, -16.5)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -37, 16.75, -18.75)
light_energy = 4.004
omni_range = 7.0
omni_range = 9.25
[node name="OmniLight3D20" type="OmniLight3D" parent="Lights" index="25" unique_id=1665621589]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -37, 24.5, -35.25)
@@ -934,14 +934,19 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -33.5, 24.5, -47)
light_energy = 2.725
omni_range = 10.0
[node name="OmniLight3D25" type="OmniLight3D" parent="Lights" index="30" unique_id=727558952]
[node name="OmniLight3D34" type="OmniLight3D" parent="Lights" index="30" unique_id=2065211844]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -36.25, 13.75, -45.5)
light_energy = 2.725
omni_range = 10.0
[node name="OmniLight3D25" type="OmniLight3D" parent="Lights" index="31" unique_id=727558952]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -28, 24.5, -51)
[node name="OmniLight3D26" type="OmniLight3D" parent="Lights" index="31" unique_id=1646376304]
[node name="OmniLight3D26" type="OmniLight3D" parent="Lights" index="32" unique_id=1646376304]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -20, 24.5, -51.5)
omni_range = 7.0
[node name="OmniLight3D27" type="OmniLight3D" parent="Lights" index="32" unique_id=1849438050]
[node name="OmniLight3D27" type="OmniLight3D" parent="Lights" index="33" unique_id=1849438050]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -20, 24.5, -51.5)
omni_range = 4.5
@@ -1047,10 +1052,10 @@ tuto_text = "Select next level when ready"
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.875, 1.125, -4.625)
shape = SubResource("BoxShape3D_7hd1j")
[node name="Player" parent="." index="11" unique_id=1309399929]
[node name="Player" parent="." index="12" unique_id=1309399929]
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, -0.5, 0.4102497, 0.5415039)
HasSword = false
HasParry = false
[node name="PlayerFellRespawn" parent="." index="12" unique_id=479136076]
[node name="PlayerFellRespawn" parent="." index="13" unique_id=479136076]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.25, -1.25)

View File

@@ -64,7 +64,7 @@ size = Vector3(5, 2.25, 3.75)
size = Vector3(5.5, 4.5, 2)
[sub_resource type="BoxShape3D" id="BoxShape3D_prjj8"]
size = Vector3(2, 3.25, 5.25)
size = Vector3(2, 3.25, 4)
[sub_resource type="BoxShape3D" id="BoxShape3D_trte5"]
size = Vector3(6.75, 8.25, 7.25)
@@ -420,7 +420,7 @@ 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)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.625, 1.75, -0.125)
shape = SubResource("BoxShape3D_prjj8")
[node name="TutoTrigger7" parent="Tutorial/Triggers" index="5" unique_id=271532103 instance=ExtResource("10_vqwwk")]
@@ -616,15 +616,15 @@ size = Vector3(7.25, 7.75, 2)
material = ExtResource("3_4m8g1")
[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)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.5, 19.237345, 11.25)
use_collision = true
size = Vector3(3, 5, 8.5)
size = Vector3(3, 4.5, 8.5)
material = ExtResource("3_4m8g1")
[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)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.25, 19.487345, 38)
use_collision = true
size = Vector3(9.5, 5, 11.75)
size = Vector3(9.5, 5, 13)
material = ExtResource("3_4m8g1")
[node name="CSGBox3D133" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="28" unique_id=672467040]
@@ -775,5 +775,9 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 1.5, 0)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 25, 4)
[node name="OmniLight3D2" type="OmniLight3D" parent="." index="14" unique_id=2016820716]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 25, -9.5)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 25, -10)
omni_range = 12.0
[node name="OmniLight3D3" type="OmniLight3D" parent="." index="15" unique_id=845858088]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 25, -25.5)
omni_range = 12.0

View File

@@ -1,8 +1,10 @@
[gd_scene format=3 uid="uid://ndnor8g7kq07"]
[ext_resource type="PackedScene" uid="uid://55wehh6xombr" path="res://maps/_templates/main_scene_template.tscn" id="1_k7f42"]
[ext_resource type="Resource" uid="uid://ifeavnlps7hy" path="res://forge/resources/behaviors/exploding_sword.tres" id="2_ctafv"]
[ext_resource type="PackedScene" uid="uid://y77cdg7gg3y7" path="res://maps/levels/_arenas/playtest_1.tscn" id="2_kutfq"]
[ext_resource type="Material" uid="uid://31aulub2nqov" path="res://assets/materials/greybox/m_greybox.tres" id="3_1qo78"]
[ext_resource type="Script" uid="uid://cgaahnfgxcrr6" path="res://managers/WeaponInventory.cs" id="3_nix1q"]
[ext_resource type="PackedScene" uid="uid://c305mfrtumcyq" path="res://scenes/spawners/spawner.tscn" id="4_jaqjx"]
[ext_resource type="PackedScene" uid="uid://dxt0e2ugmttqq" path="res://scenes/enemies/grounded_enemy/grounded_enemy.tscn" id="5_iq67o"]
[ext_resource type="Resource" uid="uid://bqq6uukbdfysr" path="res://scenes/enemies/grounded_enemy/grounded_enemy_movement.tres" id="6_l44fp"]
@@ -15,10 +17,18 @@
[ext_resource type="PackedScene" uid="uid://qup00a7x2sji" path="res://scenes/fixed_dash_target/fixed_dashthrough_target.tscn" id="13_iq67o"]
[ext_resource type="PackedScene" uid="uid://b8aet6m4m2i83" path="res://scenes/tuto_trigger/TutoTrigger.tscn" id="14_lthgu"]
[sub_resource type="Resource" id="Resource_udq24"]
script = ExtResource("3_nix1q")
OnWeaponStartedFlyingAbilities = Array[Object]([ExtResource("2_ctafv")])
OnWeaponFlyingTickAbilities = Array[Object]([ExtResource("2_ctafv")])
OnWeaponStoppedFlyingAbilities = Array[Object]([ExtResource("2_ctafv")])
metadata/_custom_type_script = "uid://cgaahnfgxcrr6"
[sub_resource type="BoxShape3D" id="BoxShape3D_lthgu"]
size = Vector3(7.5, 3.75, 10.25)
[node name="Main" unique_id=955321579 instance=ExtResource("1_k7f42")]
InitialWeaponInventory = SubResource("Resource_udq24")
[node name="PlaytestArena" parent="." index="6" unique_id=664535670 instance=ExtResource("2_kutfq")]
@@ -35,7 +45,7 @@ MovementInputs = ExtResource("6_l44fp")
HealthInputs = ExtResource("7_ucbss")
DamageInputs = ExtResource("8_2brdd")
Target = NodePath("../Player")
SpawnInterval = 5.0
SpawnInterval = 1.808
[node name="GroundedSpawner2" parent="." index="9" unique_id=1026317919 node_paths=PackedStringArray("Target") instance=ExtResource("4_jaqjx")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 46.5, 11.5, -34.5)
@@ -45,6 +55,7 @@ HealthInputs = ExtResource("7_ucbss")
DamageInputs = ExtResource("8_2brdd")
Target = NodePath("../Player")
SpawnInterval = 5.0
IsActiveOnStart = false
[node name="GroundedSpawner3" parent="." index="10" unique_id=241829575 node_paths=PackedStringArray("Target") instance=ExtResource("4_jaqjx")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 44.5, 0, -3)
@@ -63,6 +74,7 @@ HealthInputs = ExtResource("11_5jlg7")
DamageInputs = ExtResource("12_pjgox")
Target = NodePath("../Player")
SpawnInterval = 5.0
IsActiveOnStart = false
[node name="FlyingSpawner2" parent="." index="12" unique_id=365997644 node_paths=PackedStringArray("Target") instance=ExtResource("4_jaqjx")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 45.5, 25.5, -42.5)
@@ -72,6 +84,7 @@ HealthInputs = ExtResource("11_5jlg7")
DamageInputs = ExtResource("12_pjgox")
Target = NodePath("../Player")
SpawnInterval = 5.0
IsActiveOnStart = false
[node name="Targets" type="Node3D" parent="." index="13" unique_id=1620747784]
@@ -112,5 +125,5 @@ tuto_text = "Try to survive!"
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 0.625, -1.875)
shape = SubResource("BoxShape3D_lthgu")
[node name="Player" parent="." index="15" unique_id=1309399929]
[node name="Player" parent="." index="16" unique_id=1309399929]
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, 3, 0, 0)

View File

@@ -1,82 +1,92 @@
using System;
using System.Collections.Generic;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Gamesmiths.Forge.Godot.Resources.Abilities;
using Godot;
using Movementtests.systems;
[Tool, GlobalClass]
[Tool, GlobalClass, Meta(typeof(IAutoConnect), typeof(IAutoOn))]
public partial class AbilitySelection : Control
{
public override void _Notification(int what) => this.Notify(what);
#region Signals
[Signal] public delegate void AbilityAddedEventHandler(WeaponSystem.WeaponEvent forEvent, ForgeAbilityBehavior behavior);
[Signal] public delegate void AbilityRemovedEventHandler(WeaponSystem.WeaponEvent forEvent, ForgeAbilityBehavior behavior);
#endregion
#region Exports
[Export] public WeaponSystem.WeaponEvent ForEvent { get; set; } = WeaponSystem.WeaponEvent.StartedFlying;
[Export] public string Title { get; set; } = string.Empty;
[Export] public PackedScene AbilitySelectedItem { get; set; }
[Export] public ForgeAbilityBehavior[] AbilityBehaviors { get; set; }
[Export] public PackedScene? AbilitySelectedItem { get; set; }
[Export] public ForgeAbilityBehavior[] AbilityBehaviors { get; set; } = [];
private VBoxContainer _selectedAbilities;
private MenuButton _addAbility;
private PopupMenu _addAbilityMenu;
#endregion
#region Nodes
[Node("%SelectedAbilities")] public required VBoxContainer SelectedAbilities { get; set; }
[Node("%AddAbility")] public required MenuButton AddAbility { get; set; }
public required PopupMenu AddAbilityMenu { get; set; }
#endregion
public override void _Ready()
public void OnReady()
{
// Initialize title (also in Editor as Tool)
var titleLabel = GetNode<Label>("%TitleLabel");
titleLabel.Text = Title;
_selectedAbilities = GetNode<VBoxContainer>("%SelectedAbilities");
_addAbility = GetNode<MenuButton>("%AddAbility");
_addAbilityMenu = _addAbility.GetPopup();
AddAbilityMenu = AddAbility.GetPopup();
if (Engine.IsEditorHint()) return;
if (Engine.IsEditorHint()) return; // Editor flow stops here
var i = 0;
foreach (var behavior in AbilityBehaviors)
{
_addAbilityMenu.AddIconItem(behavior.Icon, behavior.Name);
_addAbilityMenu.SetItemMetadata(i, behavior);
AddAbilityMenu.AddIconItem(behavior.Icon, behavior.Name);
AddAbilityMenu.SetItemMetadata(i, behavior);
i += 1;
}
_addAbilityMenu.IndexPressed += AddAbilityMenuOnIndexPressed;
AddAbilityMenu.IndexPressed += AddAbilityMenuOnIndexPressed;
}
public void Initialize(IEnumerable<Resource> equippedAbilities)
public void Initialize(IEnumerable<ForgeAbilityBehavior> equippedAbilities)
{
foreach (var equippedAbility in equippedAbilities)
{
if (equippedAbility is not ForgeAbilityBehavior ability) continue;
AddSelectedAbility(ability);
AddSelectedAbility(equippedAbility);
}
}
private void AddAbilityMenuOnIndexPressed(long index)
{
var indexInt = Convert.ToInt32(index);
var metadata = (ForgeAbilityBehavior) _addAbilityMenu.GetItemMetadata(indexInt);
var metadata = (ForgeAbilityBehavior) AddAbilityMenu.GetItemMetadata(indexInt);
EmitSignalAbilityAdded(ForEvent, metadata);
}
public void AddSelectedAbility(ForgeAbilityBehavior behavior)
{
var newSelectedAbilityItem = AbilitySelectedItem.Instantiate() as SelectedAbility;
if (newSelectedAbilityItem == null) return;
if (AbilitySelectedItem?.Instantiate() is not SelectedAbility newSelectedAbilityItem) return;
newSelectedAbilityItem.SetAbility(behavior);
newSelectedAbilityItem.AbilityRemoved += ability => EmitSignalAbilityRemoved(ForEvent, ability);
_selectedAbilities.AddChild(newSelectedAbilityItem);
SelectedAbilities.AddChild(newSelectedAbilityItem);
}
public void RemoveSelectedAbility(ForgeAbilityBehavior behavior)
{
foreach (var child in _selectedAbilities.GetChildren())
foreach (var child in SelectedAbilities.GetChildren())
{
if (child is not SelectedAbility selectedAbility || selectedAbility.Ability != behavior) continue;
_selectedAbilities.RemoveChild(selectedAbility);
_addAbility.GrabFocus();
SelectedAbilities.RemoveChild(selectedAbility);
AddAbility.GrabFocus();
return;
}
}

View File

@@ -1,7 +1,7 @@
[gd_scene format=3 uid="uid://dmv685sskgh3l"]
[ext_resource type="Script" uid="uid://5emed8iegtui" path="res://menus/scenes/components/AbilitySelection.cs" id="1_fcxyu"]
[ext_resource type="Resource" uid="uid://ifeavnlps7hy" path="res://scenes/player_controller/resources/forge/exploding_sword.tres" id="2_j1yif"]
[ext_resource type="Resource" uid="uid://ifeavnlps7hy" path="res://forge/resources/behaviors/exploding_sword.tres" id="2_j1yif"]
[ext_resource type="Texture2D" uid="uid://by5v33lu8v1fm" path="res://assets/ui/input-prompts/Flairs/Vector/flair_plus.svg" id="2_uf3m5"]
[ext_resource type="PackedScene" uid="uid://cjnimmo2jyvx7" path="res://menus/scenes/components/selected_ability.tscn" id="3_cndde"]

View File

@@ -1,7 +1,7 @@
[gd_scene format=3 uid="uid://cjnimmo2jyvx7"]
[ext_resource type="Script" uid="uid://duest06l5answ" path="res://menus/scenes/components/SelectedAbility.cs" id="1_dc51o"]
[ext_resource type="Resource" uid="uid://ifeavnlps7hy" path="res://scenes/player_controller/resources/forge/exploding_sword.tres" id="2_um64s"]
[ext_resource type="Resource" uid="uid://ifeavnlps7hy" path="res://forge/resources/behaviors/exploding_sword.tres" id="2_um64s"]
[ext_resource type="Texture2D" uid="uid://b3403ry3yxw1t" path="res://assets/ui/input-prompts/Flairs/Vector/flair_cross.svg" id="4_x7nho"]
[sub_resource type="AtlasTexture" id="AtlasTexture_2nvj1"]

View File

@@ -1,79 +1,88 @@
using System.Collections.Generic;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Gamesmiths.Forge.Effects;
using Gamesmiths.Forge.Godot.Resources.Abilities;
using Godot;
using Movementtests.managers;
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
{
private AbilitySelection _startedFlyingSelection;
private AbilitySelection _whileFlyingSelection;
private AbilitySelection _stoppedFlyingSelection;
public override void _Notification(int what) => this.Notify(what);
#region Dependencies
[Dependency]
public InventoryManager InventoryManager => this.DependOn<InventoryManager>();
#endregion Dependencies
public override void _Ready()
#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");
_whileFlyingSelection = GetNode<AbilitySelection>("%WhileFlying");
_stoppedFlyingSelection = GetNode<AbilitySelection>("%StoppedFlying");
_startedFlyingSelection.Initialize(InventoryManager.Instance.WeaponEventsInventory[WeaponSystem.WeaponEvent.StartedFlying]);
_whileFlyingSelection.Initialize(InventoryManager.Instance.WeaponEventsInventory[WeaponSystem.WeaponEvent.FlyingTick]);
_stoppedFlyingSelection.Initialize(InventoryManager.Instance.WeaponEventsInventory[WeaponSystem.WeaponEvent.StoppedFlying]);
StartedFlying.AbilityAdded += AddAbilityForEvent;
WhileFlying.AbilityAdded += AddAbilityForEvent;
StoppedFlying.AbilityAdded += AddAbilityForEvent;
_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;
StartedFlying.AbilityRemoved += RemoveAbilityForEvent;
WhileFlying.AbilityRemoved += RemoveAbilityForEvent;
StoppedFlying.AbilityRemoved += RemoveAbilityForEvent;
}
public override void _ExitTree()
public void OnResolved()
{
InventoryManager.Instance.WeaponEventAbilityAdded -= OnWeaponEventInventoryAdded;
InventoryManager.Instance.WeaponEventAbilityRemoved -= OnWeaponEventInventoryRemoved;
base._ExitTree();
StartedFlying.Initialize(InventoryManager.WeaponEventsInventory[WeaponSystem.WeaponEvent.StartedFlying]);
WhileFlying.Initialize(InventoryManager.WeaponEventsInventory[WeaponSystem.WeaponEvent.FlyingTick]);
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)
{
InventoryManager.Instance.AddAbilityForWeaponEvent(forEvent, abilityBehavior);
InventoryManager.AddAbilityForWeaponEvent(forEvent, abilityBehavior);
}
public void RemoveAbilityForEvent(WeaponSystem.WeaponEvent forEvent, ForgeAbilityBehavior abilityBehavior)
{
InventoryManager.Instance.RemoveAbilityForWeaponEvent(forEvent, abilityBehavior);
InventoryManager.RemoveAbilityForWeaponEvent(forEvent, abilityBehavior);
}
public void OnWeaponEventInventoryAdded(WeaponEventAbilityData data)
{
if (data.Ability is not ForgeAbilityBehavior abilityBehavior) return;
var selection = GetAbilitySelection(data.ForEvent);
selection.AddSelectedAbility(abilityBehavior);
selection.AddSelectedAbility(data.Ability);
}
public void OnWeaponEventInventoryRemoved(WeaponEventAbilityData data)
{
if (data.Ability is not ForgeAbilityBehavior abilityBehavior) return;
var selection = GetAbilitySelection(data.ForEvent);
selection.RemoveSelectedAbility(abilityBehavior);
selection.RemoveSelectedAbility(data.Ability);
}
public AbilitySelection GetAbilitySelection(WeaponSystem.WeaponEvent forEvent)
{
var abilitiesSelectionsMap = new Dictionary<WeaponSystem.WeaponEvent, AbilitySelection>
{
{ WeaponSystem.WeaponEvent.StartedFlying, _startedFlyingSelection },
{ WeaponSystem.WeaponEvent.StoppedFlying, _stoppedFlyingSelection },
{ WeaponSystem.WeaponEvent.FlyingTick, _whileFlyingSelection },
{ WeaponSystem.WeaponEvent.StartedFlying, StartedFlying },
{ WeaponSystem.WeaponEvent.StoppedFlying, StoppedFlying },
{ WeaponSystem.WeaponEvent.FlyingTick, WhileFlying },
};
return abilitiesSelectionsMap[forEvent];

View File

@@ -11,9 +11,7 @@ extends OverlaidMenu
@onready var player_damage_spin_box: SpinBox = %PlayerDamageSpinBox
func _ready() -> void:
player_invicible_toggle.button_pressed = player.IsInvincibleOverride
player_health_spin_box.value = player.RHealth.StartingHealth
player_damage_spin_box.value = player.RDamage.DamageDealt
player_invicible_toggle.button_pressed = player.IsInvincible
func _on_kill_player_button_pressed() -> void:
@@ -21,7 +19,7 @@ func _on_kill_player_button_pressed() -> void:
close()
func _on_player_invicible_toggled(toggled_on: bool) -> void:
player.IsInvincibleOverride = toggled_on
player.IsInvincible = toggled_on
func _on_restart_current_level_pressed() -> void:
@@ -38,8 +36,8 @@ func _on_level_selected() -> void:
close()
func _on_player_health_changed(value: float) -> void:
player.SetPlayerHealthOverride(value)
pass
func _on_player_damage_changed(value: float) -> void:
player.SetPlayerDamageOverride(value)
pass

View File

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

View File

@@ -1,14 +1,12 @@
using Godot;
using System;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_heart.png")]
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_heart.png"), Meta(typeof(IAutoConnect))]
public partial class CHealthbar : Sprite3D
{
private Healthbar _healthbar;
public Healthbar Healthbar => _healthbar;
public override void _Ready()
{
_healthbar = GetNode<Healthbar>("%Healthbar");
}
public override void _Notification(int what) => this.Notify(what);
[Node("%Healthbar")] public required ResourceBar ResourceBar { get; set;}
}

View File

@@ -1,23 +1,26 @@
using System;
using System.Collections.Generic;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Gamesmiths.Forge.Abilities;
using Gamesmiths.Forge.Attributes;
using Gamesmiths.Forge.Core;
using Gamesmiths.Forge.Cues;
using Gamesmiths.Forge.Effects;
using Gamesmiths.Forge.Events;
using Gamesmiths.Forge.Godot.Core;
using Gamesmiths.Forge.Godot.Nodes;
using Gamesmiths.Forge.Godot.Resources.Abilities;
using Gamesmiths.Forge.Statescript;
using Gamesmiths.Forge.Tags;
using Godot;
using Movementtests.interfaces;
using Movementtests.scenes.enemies;
using Movementtests.scenes.player_controller.scripts;
using Movementtests.systems;
using Movementtests.tools;
using Movementtests.tools.calculators;
using Node = Godot.Node;
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_beetle.png")]
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_beetle.png"), Meta(typeof(IAutoNode))]
public partial class Enemy : CharacterBody3D,
IDamageable,
IDamageDealer,
IHealthable,
IKillable,
IMoveable,
@@ -27,14 +30,32 @@ public partial class Enemy : CharacterBody3D,
IStunnable,
IForgeEntity
{
// Signals and events
public event Action<IDamageable, DamageRecord> DamageTaken = null!;
public event Action<IHealthable, HealthChangedRecord> HealthChanged = null!;
public event Action<IHealthable> HealthDepleted = null!;
public override void _Notification(int what) => this.Notify(what);
#region Dependencies
[Dependency]
public TagsManager TagsManager => this.DependOn<TagsManager>();
[Dependency]
public CuesManager CuesManager => this.DependOn<CuesManager>();
#endregion
#region Signals
// Signals and events
public event Action<IDamageable, DamageRecord> DamageTaken = null!;
public event Action<IHealthable, HealthChangedRecord> HealthChanged = null!;
public event Action<IHealthable> HealthDepleted = null!;
#endregion
#region Inspector
// Public export components
[Export]
public Node3D Target { get; set; } = null!;
public Node3D? Target { get; set; }
[Export] public required ForgeAbilityData HitAbility { get; set; }
[Export]
public float EnemyHeight { get; set; } = 1f;
@@ -48,17 +69,19 @@ public partial class Enemy : CharacterBody3D,
[ExportGroup("Damage")]
[Export]
public RDamage RDamage { get; set; } = null!;
public RDamage? RDamage { get; set; }
public IDamageable CDamageable { get; set; } = null!;
[Export]
public RKnockback RKnockback { get; set; } = null!;
public RKnockback? RKnockback { get; set; }
public IKnockbackable CKnockback { get; set; } = null!;
[ExportGroup("Movement")]
[Export]
public RMovement RMovement { get; set; } = null!;
public IMoveable CMovement { get; set; } = null!;
public required RMovement RMovement { get; set; }
public required IMoveable CMovement { get; set; }
#endregion
// Public stuff
public float CurrentHealth
@@ -66,76 +89,91 @@ public partial class Enemy : CharacterBody3D,
get => CHealth.CurrentHealth;
set => CHealth.CurrentHealth = value;
}
#region IForgeEntity
// Perfectly forward the IForgeEntity interface to the ForgeEntity component
public EntityAttributes Attributes
{
get => _forgeEntity.Attributes;
set => _forgeEntity.Attributes = value;
get => ForgeEntity.Attributes;
set => ForgeEntity.Attributes = value;
}
public EntityTags Tags
{
get => _forgeEntity.Tags;
set => _forgeEntity.Tags = value;
get => ForgeEntity.Tags;
set => ForgeEntity.Tags = value;
}
public EffectsManager EffectsManager
{
get => _forgeEntity.EffectsManager;
set => _forgeEntity.EffectsManager = value;
get => ForgeEntity.EffectsManager;
set => ForgeEntity.EffectsManager = value;
}
public EntityAbilities Abilities
{
get => _forgeEntity.Abilities;
set => _forgeEntity.Abilities = value;
get => ForgeEntity.Abilities;
set => ForgeEntity.Abilities = value;
}
public EventManager Events
{
get => _forgeEntity.Events;
set => _forgeEntity.Events = value;
get => ForgeEntity.Events;
set => ForgeEntity.Events = value;
}
public Variables SharedVariables { get; }
// Private stuff
private Area3D _damageBox = null!;
internal Node3D _target = null!;
private Healthbar _healthbar = null!;
private ForgeEntity _forgeEntity;
public override void _Ready()
public Variables SharedVariables
{
Initialize();
get => ForgeEntity.SharedVariables;
set => ForgeEntity.SharedVariables = value;
}
#endregion
[Node("DamageBox")] public required Area3D DamageBox { get; set;}
[Node("CTarget")] public required Node3D TargetComponent { get; set;}
[Node("CHealthBar")] public required CHealthbar HealthBarWrapper { get; set;}
[Node("ForgeEntityNode")] public required ForgeEntityNode ForgeEntity { get; set;}
private AbilityHandle? _hitAbilityHandle;
public void OnReady()
{
Init();
SetupSignals();
}
public void Initialize()
public void Init()
{
_damageBox = GetNode<Area3D>("DamageBox");
_target = GetNode<Node3D>("CTarget");
_forgeEntity = GetNode<ForgeEntity>("ForgeEntity");
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;
CMovement = GetNode<Node>("CMovement") as IMoveable ?? throw new Exception("Movement component not found");
CMovement.RMovement = RMovement;
CDamageable = GetNode<Node>("CDamageable") as IDamageable ?? throw new Exception("Damageable component not found");
CHealth = GetNode<Node>("CHealth") as IHealthable ?? throw new Exception("Health component not found");
CKnockback = GetNode<Node>("CKnockback") as IKnockbackable ?? throw new Exception("Knockback component not found");
CHealth.RHealth = RHealth;
CHealth.CurrentHealth = RHealth.StartingHealth;
CKnockback.RKnockback = RKnockback;
_hitAbilityHandle = Abilities.GrantAbilityPermanently(HitAbility.GetAbilityData(), 1, LevelComparison.None, this);
}
public void OnResolved()
{
var healthAttribute = Attributes["CharacterAttributeSet.Health"];
HealthBarWrapper.ResourceBar.Init(healthAttribute);
healthAttribute.OnValueChanged += OnHealthChanged;
_healthbar.Initialize(CHealth.CurrentHealth);
Events.Subscribe(Tag.RequestTag(TagsManager, "events.combat.hit"),
data => {GD.Print("Hit!");});
Events.Subscribe<DamageDone>(Tag.RequestTag(TagsManager, "events.combat.damage"), OnDamageReceived);
Events.Subscribe(Tag.RequestTag(TagsManager, "events.combat.death"), OnDeath);
}
public void SetupSignals()
{
// Anonymous function call to erase return values of ReduceHealth
CDamageable.DamageTaken += (source, record) => ReduceHealth(source, record);
CDamageable.DamageTaken += (_, record) => RegisterKnockback(new KnockbackRecord(record));
CHealth.HealthDepleted += Kill;
HealthChanged += (_, record) => _healthbar.SetHealth(record.CurrentHealth);
// CDamageable.DamageTaken += (source, record) => ReduceHealth(source, record);
// CDamageable.DamageTaken += (_, record) => RegisterKnockback(new KnockbackRecord(record));
// CHealth.HealthDepleted += Kill;
}
public override void _PhysicsProcess(double delta)
@@ -160,20 +198,56 @@ public partial class Enemy : CharacterBody3D,
public void ProcessGameplay(double delta)
{
if (IsStunned) return;
if (IsStunned || _hitAbilityHandle == null) return;
var bodies = _damageBox.GetOverlappingBodies();
var bodies = DamageBox.GetOverlappingBodies();
foreach (var body in bodies)
{
if(body is IDamageable spawnable)
spawnable.TakeDamage(new DamageRecord(GlobalPosition, RDamage));
if (body is not IForgeEntity forgeEntity) continue;
var canActivate = _hitAbilityHandle.CanActivate(out var _);
if (!canActivate) return;
_hitAbilityHandle.Activate(out var _, forgeEntity);
}
}
public Vector3 ComputeVelocity(MovementInputs inputs)
{
if (CMovement is null) return Vector3.Zero;
return CMovement.ComputeVelocity(inputs);
return CMovement is null ? Vector3.Zero : CMovement.ComputeVelocity(inputs);
}
public void OnDamageReceived(EventData<DamageDone> data)
{
var source = data.Source as Node;
var sourceName = source?.Name ?? "unknown damage dealer";
GD.Print($"Ouch! Fuck you {sourceName}!");
if (data.Payload.OverkillDamage > 0) GD.Print($"Overkill! {data.Payload.OverkillDamage} damage");
}
private void OnHealthChanged(EntityAttribute healthAttribute, int i)
{
if (healthAttribute.CurrentValue > healthAttribute.Min) return;
Events.Raise(new EventData
{
EventTags = Tag.RequestTag(TagsManager, "events.combat.death").GetSingleTagContainer()!
});
}
public void OnDeath(EventData data)
{
// Remove weapon that might be planted there
foreach (var child in GetChildren())
{
if (child is not WeaponSystem system) continue;
CallDeferred(Node.MethodName.RemoveChild, system);
GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, system);
system.CallDeferred(Node3D.MethodName.SetGlobalPosition, GlobalPosition + Vector3.Up*EnemyHeight);
system.CallDeferred(WeaponSystem.MethodName.RethrowWeapon);
}
CallDeferred(Node.MethodName.QueueFree);
}
public DamageRecord TakeDamage(DamageRecord damageRecord)
@@ -235,7 +309,7 @@ public partial class Enemy : CharacterBody3D,
public Vector3 GetTargetGlobalPosition()
{
return _target == null ? GlobalPosition : _target.GlobalPosition;
return TargetComponent == null ? GlobalPosition : TargetComponent.GlobalPosition;
}
// Stun management

View File

@@ -2,31 +2,22 @@
[ext_resource type="Script" uid="uid://bn7sc6id7n166" path="res://scenes/enemies/Enemy.cs" id="1_q8l7o"]
[ext_resource type="Script" uid="uid://b6y3ugfydvch0" path="res://scenes/components/damage/RDamageModifier.cs" id="2_1bsgx"]
[ext_resource type="Resource" uid="uid://qpdw62ubaclc" path="res://forge/resources/ability_datas/grounded_enemy_hit.tres" id="2_46wn3"]
[ext_resource type="Resource" uid="uid://dg1xbjhyhgnnk" path="res://scenes/enemies/flying_enemy/flying_enemy_health.tres" id="2_ma2bq"]
[ext_resource type="Resource" uid="uid://dgo65k2ceqfvy" path="res://scenes/enemies/flying_enemy/flying_enemy_damage.tres" id="2_on7rt"]
[ext_resource type="Resource" uid="uid://bwqjaom4k7rc3" path="res://scenes/enemies/flying_enemy/flying_enemy_movement.tres" id="4_dejyg"]
[ext_resource type="Script" uid="uid://bjwrpv3jpsc1e" path="res://scenes/components/health/CHealth.cs" id="4_ys4jv"]
[ext_resource type="Script" uid="uid://8uj04dfe8oql" path="res://addons/forge/nodes/ForgeEntity.cs" id="6_wxisp"]
[ext_resource type="Script" uid="uid://cxihb42t2mfqi" path="res://addons/forge/nodes/ForgeAttributeSet.cs" id="7_2digf"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="7_46wn3"]
[ext_resource type="Script" uid="uid://rpcbb54q4atx" path="res://forge/ForgeEntityNode.cs" id="7_46wn3"]
[ext_resource type="PackedScene" uid="uid://dmw5ibwrb483f" path="res://scenes/components/movement/CFlyingMovement.tscn" id="7_vaeds"]
[ext_resource type="PackedScene" uid="uid://bwx2um43k0ou4" path="res://scenes/components/health/CHealthbar.tscn" id="7_ykkxn"]
[ext_resource type="Script" uid="uid://ccovd5i0wr3kk" path="res://addons/forge/editor/attributes/AttributeValues.cs" id="8_46wn3"]
[ext_resource type="Resource" uid="uid://bocsykxbh8l0g" path="res://forge/resources/tag_containers/enemy_base_tags.tres" id="8_oj1ws"]
[ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://scenes/components/movement/RMovement.cs" id="8_on7rt"]
[ext_resource type="Script" uid="uid://b0u23nkpaimyc" path="res://scenes/components/damage/CDamageable.cs" id="8_uotso"]
[ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://scenes/components/knockback/CKnockback.tscn" id="10_dejyg"]
[ext_resource type="Resource" uid="uid://dt7a1io5o0b8s" path="res://scenes/enemies/flying_enemy/flying_enemy_knockback.tres" id="11_mpa2u"]
[sub_resource type="Resource" id="Resource_vfi88"]
script = ExtResource("7_46wn3")
ContainerTags = Array[String](["character.enemy"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[sub_resource type="Resource" id="Resource_oj1ws"]
script = ExtResource("8_46wn3")
Default = 50
Max = 100
[sub_resource type="Resource" id="Resource_wxisp"]
script = ExtResource("8_46wn3")
Default = 2
@@ -39,7 +30,7 @@ Default = 1
Min = 1
Max = 100
[sub_resource type="ViewportTexture" id="ViewportTexture_hf6k8"]
[sub_resource type="ViewportTexture" id="ViewportTexture_46wn3"]
viewport_path = NodePath("SubViewport")
[sub_resource type="Resource" id="Resource_jnv07"]
@@ -81,6 +72,7 @@ collision_layer = 16
collision_mask = 273
motion_mode = 1
script = ExtResource("1_q8l7o")
HitAbility = ExtResource("2_46wn3")
EnemyHeight = 0.5
RHealth = ExtResource("2_ma2bq")
DeathEffects = Array[Object]([])
@@ -88,16 +80,35 @@ RDamage = ExtResource("2_on7rt")
RKnockback = ExtResource("11_mpa2u")
RMovement = ExtResource("4_dejyg")
[node name="ForgeEntity" type="Node" parent="." unique_id=622209781]
script = ExtResource("6_wxisp")
BaseTags = SubResource("Resource_vfi88")
metadata/_custom_type_script = "uid://8uj04dfe8oql"
[node name="ForgeEntityNode" type="Node3D" parent="." unique_id=1255429192]
script = ExtResource("7_46wn3")
BaseTags = ExtResource("8_oj1ws")
metadata/_custom_type_script = "uid://rpcbb54q4atx"
[node name="ForgeAttributeSet" type="Node" parent="ForgeEntity" unique_id=1840910245]
[node name="CharacterAttributeSet" type="Node" parent="ForgeEntityNode" unique_id=418635308]
script = ExtResource("7_2digf")
AttributeSetClass = "CharacterAttributeSet"
InitialAttributeValues = Dictionary[String, ExtResource("8_46wn3")]({
"Health": Object(RefCounted,"script":ExtResource("8_46wn3"),"Default":100,"Min":0,"Max":100)
})
metadata/_custom_type_script = "uid://cxihb42t2mfqi"
[node name="MetaAttributeSet" type="Node" parent="ForgeEntityNode" unique_id=88776122]
script = ExtResource("7_2digf")
AttributeSetClass = "MetaAttributeSet"
InitialAttributeValues = Dictionary[String, ExtResource("8_46wn3")]({
"IncomingDamage": Object(RefCounted,"script":ExtResource("8_46wn3"),"Default":0,"Min":0,"Max":1000)
})
metadata/_custom_type_script = "uid://cxihb42t2mfqi"
[node name="EnemyAttributeSet" type="Node" parent="ForgeEntityNode" unique_id=1840910245]
script = ExtResource("7_2digf")
AttributeSetClass = "EnemyAttributeSet"
InitialAttributeValues = Dictionary[String, ExtResource("8_46wn3")]({
"Health": SubResource("Resource_oj1ws"),
"Health": Object(RefCounted,"script":ExtResource("8_46wn3"),"Default":50,"Min":0,"Max":50)
,
"Speed": SubResource("Resource_wxisp"),
"Strength": SubResource("Resource_yk4hc")
})
@@ -110,7 +121,7 @@ metadata/_custom_type_script = "uid://bjwrpv3jpsc1e"
[node name="CHealthBar" parent="." unique_id=1635725931 instance=ExtResource("7_ykkxn")]
transform = Transform3D(0.3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.70000005, 0)
texture = SubResource("ViewportTexture_hf6k8")
texture = SubResource("ViewportTexture_46wn3")
[node name="CDamageable" type="Node" parent="." unique_id=1785297232]
script = ExtResource("8_uotso")

View File

@@ -6,27 +6,18 @@
[ext_resource type="Script" uid="uid://b6y3ugfydvch0" path="res://scenes/components/damage/RDamageModifier.cs" id="2_r3cnf"]
[ext_resource type="Resource" uid="uid://bohbojc68j7y1" path="res://scenes/enemies/grounded_enemy/grounded_enemy_health.tres" id="2_w4lm8"]
[ext_resource type="Resource" uid="uid://bqq6uukbdfysr" path="res://scenes/enemies/grounded_enemy/grounded_enemy_movement.tres" id="4_na24f"]
[ext_resource type="Script" uid="uid://8uj04dfe8oql" path="res://addons/forge/nodes/ForgeEntity.cs" id="6_x50ya"]
[ext_resource type="Resource" uid="uid://qpdw62ubaclc" path="res://forge/resources/ability_datas/grounded_enemy_hit.tres" id="6_4jf2q"]
[ext_resource type="Script" uid="uid://cxihb42t2mfqi" path="res://addons/forge/nodes/ForgeAttributeSet.cs" id="6_yk4hc"]
[ext_resource type="Script" uid="uid://b0u23nkpaimyc" path="res://scenes/components/damage/CDamageable.cs" id="7_1tw73"]
[ext_resource type="PackedScene" uid="uid://bwx2um43k0ou4" path="res://scenes/components/health/CHealthbar.tscn" id="7_18xwy"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="7_f22p3"]
[ext_resource type="Script" uid="uid://rpcbb54q4atx" path="res://forge/ForgeEntityNode.cs" id="7_f22p3"]
[ext_resource type="PackedScene" uid="uid://dbr7ioio158ew" path="res://scenes/components/movement/CGroundedMovement.tscn" id="7_qyswd"]
[ext_resource type="Script" uid="uid://ccovd5i0wr3kk" path="res://addons/forge/editor/attributes/AttributeValues.cs" id="7_x50ya"]
[ext_resource type="Resource" uid="uid://bocsykxbh8l0g" path="res://forge/resources/tag_containers/enemy_base_tags.tres" id="8_4jf2q"]
[ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://scenes/components/movement/RMovement.cs" id="8_6d4gl"]
[ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://scenes/components/knockback/CKnockback.tscn" id="10_jqqi6"]
[ext_resource type="Resource" uid="uid://cektf6waf4s04" path="res://scenes/enemies/grounded_enemy/grounded_enemy_knockback.tres" id="11_8k3xb"]
[sub_resource type="Resource" id="Resource_4jf2q"]
script = ExtResource("7_f22p3")
ContainerTags = Array[String](["character.enemy"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[sub_resource type="Resource" id="Resource_f22p3"]
script = ExtResource("7_x50ya")
Default = 100
Max = 100
[sub_resource type="Resource" id="Resource_x50ya"]
script = ExtResource("7_x50ya")
Default = 1
@@ -39,7 +30,7 @@ Default = 1
Min = 1
Max = 100
[sub_resource type="ViewportTexture" id="ViewportTexture_ub34u"]
[sub_resource type="ViewportTexture" id="ViewportTexture_4jf2q"]
viewport_path = NodePath("SubViewport")
[sub_resource type="Resource" id="Resource_qj0ob"]
@@ -81,6 +72,7 @@ radius = 2.0
collision_layer = 16
collision_mask = 273
script = ExtResource("1_r6506")
HitAbility = ExtResource("6_4jf2q")
EnemyHeight = 2.0
RHealth = ExtResource("2_w4lm8")
DeathEffects = Array[Object]([])
@@ -88,16 +80,35 @@ RDamage = ExtResource("2_bn56u")
RKnockback = ExtResource("11_8k3xb")
RMovement = ExtResource("4_na24f")
[node name="ForgeEntity" type="Node" parent="." unique_id=432521027]
script = ExtResource("6_x50ya")
BaseTags = SubResource("Resource_4jf2q")
metadata/_custom_type_script = "uid://8uj04dfe8oql"
[node name="ForgeEntityNode" type="Node3D" parent="." unique_id=289553407]
script = ExtResource("7_f22p3")
BaseTags = ExtResource("8_4jf2q")
metadata/_custom_type_script = "uid://rpcbb54q4atx"
[node name="ForgeAttributeSet" type="Node" parent="ForgeEntity" unique_id=804252284]
[node name="CharacterAttributeSet" type="Node" parent="ForgeEntityNode" unique_id=1699781551]
script = ExtResource("6_yk4hc")
AttributeSetClass = "CharacterAttributeSet"
InitialAttributeValues = Dictionary[String, ExtResource("7_x50ya")]({
"Health": Object(RefCounted,"script":ExtResource("7_x50ya"),"Default":100,"Min":0,"Max":100)
})
metadata/_custom_type_script = "uid://cxihb42t2mfqi"
[node name="MetaAttributeSet" type="Node" parent="ForgeEntityNode" unique_id=1794036161]
script = ExtResource("6_yk4hc")
AttributeSetClass = "MetaAttributeSet"
InitialAttributeValues = Dictionary[String, ExtResource("7_x50ya")]({
"IncomingDamage": Object(RefCounted,"script":ExtResource("7_x50ya"),"Default":0,"Min":0,"Max":1000)
})
metadata/_custom_type_script = "uid://cxihb42t2mfqi"
[node name="EnnemyAttributeSet" type="Node" parent="ForgeEntityNode" unique_id=804252284]
script = ExtResource("6_yk4hc")
AttributeSetClass = "EnemyAttributeSet"
InitialAttributeValues = Dictionary[String, ExtResource("7_x50ya")]({
"Health": SubResource("Resource_f22p3"),
"Health": Object(RefCounted,"script":ExtResource("7_x50ya"),"Default":100,"Min":0,"Max":100)
,
"Speed": SubResource("Resource_x50ya"),
"Strength": SubResource("Resource_yk4hc")
})
@@ -110,7 +121,7 @@ metadata/_custom_type_script = "uid://bjwrpv3jpsc1e"
[node name="CHealthBar" parent="." unique_id=1278247727 instance=ExtResource("7_18xwy")]
transform = Transform3D(0.4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.2, 0)
texture = SubResource("ViewportTexture_ub34u")
texture = SubResource("ViewportTexture_4jf2q")
[node name="CDamageable" type="Node" parent="." unique_id=1601518000]
script = ExtResource("7_1tw73")

View File

@@ -7,18 +7,18 @@
[ext_resource type="Script" uid="uid://b44cse62qru7j" path="res://scenes/components/knockback/RKnockback.cs" id="3_cb2lu"]
[ext_resource type="Resource" uid="uid://bl5crtu1gkrtr" path="res://inputs/base_mode/base_mode.tres" id="3_cresl"]
[ext_resource type="PackedScene" uid="uid://c4ikbhojckpnc" path="res://scenes/components/health/CHealth.tscn" id="3_q7bng"]
[ext_resource type="Script" uid="uid://baiapod3csndf" path="res://scenes/components/health/RHealth.cs" id="4_abfq8"]
[ext_resource type="Resource" uid="uid://bjyd801wvverk" path="res://scenes/player_controller/resources/player_health.tres" id="4_m8gvy"]
[ext_resource type="Resource" uid="uid://cpdaw41ah5gic" path="res://inputs/base_mode/rotate_y.tres" id="4_rxwoh"]
[ext_resource type="Resource" uid="uid://dh437cuxgjv6b" path="res://scenes/player_controller/resources/forge/mana_regeneration.tres" id="5_2rkt1"]
[ext_resource type="Resource" uid="uid://dgjsi1my7nlnk" path="res://forge/resources/ability_datas/player_hit.tres" id="4_u8yay"]
[ext_resource type="Resource" uid="uid://dh437cuxgjv6b" path="res://forge/resources/effect_datas/mana_regeneration.tres" id="5_2rkt1"]
[ext_resource type="Resource" uid="uid://ccrb5xsnphc8" path="res://inputs/base_mode/rotate_floorplane.tres" id="5_4u7i3"]
[ext_resource type="PackedScene" uid="uid://hpsg4fqwrx1u" path="res://scenes/components/damage/CDamageable.tscn" id="5_jb43f"]
[ext_resource type="Resource" uid="uid://f3vs6l4m623s" path="res://inputs/base_mode/move_left.tres" id="5_q14ux"]
[ext_resource type="Resource" uid="uid://ifeavnlps7hy" path="res://scenes/player_controller/resources/forge/exploding_sword.tres" id="5_u8yay"]
[ext_resource type="Resource" uid="uid://b0ikxp5j8fn3n" path="res://forge/resources/ability_datas/on_hit_invinciblity.tres" id="5_u8yay"]
[ext_resource type="PackedScene" uid="uid://duju3atqgltkg" path="res://scenes/explosion/explosion.tscn" id="5_ue7xq"]
[ext_resource type="Resource" uid="uid://dyru7mxo121w6" path="res://scenes/player_controller/resources/player_normal_damage_mod.tres" id="6_cmijs"]
[ext_resource type="Resource" uid="uid://t612lts1wi1s" path="res://inputs/base_mode/move_right.tres" id="6_q7bng"]
[ext_resource type="Resource" uid="uid://cffil4tic3ysg" path="res://scenes/player_controller/resources/forge/inhibit_mana_regen_temporarily.tres" id="6_u8yay"]
[ext_resource type="Resource" uid="uid://cffil4tic3ysg" path="res://forge/resources/effect_datas/inhibit_mana_regen_temporarily.tres" id="6_u8yay"]
[ext_resource type="Script" uid="uid://cwbvxlfvmocc1" path="res://scenes/player_controller/scripts/StairsSystem.cs" id="7_bmt5a"]
[ext_resource type="Resource" uid="uid://brswsknpgwal2" path="res://inputs/base_mode/move_front.tres" id="7_m8gvy"]
[ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://scenes/components/knockback/CKnockback.tscn" id="7_x835q"]
@@ -29,7 +29,7 @@
[ext_resource type="PackedScene" uid="uid://wq1okogkhc5l" path="res://scenes/player_controller/components/mantle/mantle_system.tscn" id="8_qu4wy"]
[ext_resource type="AudioStream" uid="uid://clfggn87oeg1s" path="res://scenes/player_controller/audio/InteractiveSFX.tres" id="9_jb43f"]
[ext_resource type="Resource" uid="uid://bebstkm608wxx" path="res://inputs/base_mode/aim_pressed.tres" id="9_nob5r"]
[ext_resource type="Resource" uid="uid://dccuj66egxfwh" path="res://scenes/player_controller/resources/forge/empowered_action.tres" id="10_2rkt1"]
[ext_resource type="Resource" uid="uid://dccuj66egxfwh" path="res://forge/resources/ability_datas/empowered_action.tres" id="10_2rkt1"]
[ext_resource type="Resource" uid="uid://bdit2jy5gbpts" path="res://inputs/base_mode/jump.tres" id="10_4u7i3"]
[ext_resource type="Script" uid="uid://cxihb42t2mfqi" path="res://addons/forge/nodes/ForgeAttributeSet.cs" id="10_pw5r7"]
[ext_resource type="Script" uid="uid://ccovd5i0wr3kk" path="res://addons/forge/editor/attributes/AttributeValues.cs" id="11_2rkt1"]
@@ -58,11 +58,11 @@
[ext_resource type="Texture2D" uid="uid://chvt6g0xn5c2m" path="res://scenes/player_controller/components/dash/light-ring.jpg" id="32_lgpc8"]
[ext_resource type="Script" uid="uid://b4dwolbvt8our" path="res://addons/godot_state_charts/history_state.gd" id="41_ruloh"]
[ext_resource type="Texture2D" uid="uid://c40orhfdgsim" path="res://assets/ui/IconGodotNode/white/icon_circle.png" id="45_u8rdp"]
[ext_resource type="PackedScene" uid="uid://cyw8p0p6a78tl" path="res://scenes/ui/healthbar/healthbar.tscn" id="47_76kmc"]
[ext_resource type="PackedScene" uid="uid://cyw8p0p6a78tl" path="res://scenes/ui/resourcebar/healthbar.tscn" id="47_76kmc"]
[sub_resource type="Resource" id="Resource_mpigw"]
script = ExtResource("2_u8yay")
ContainerTags = Array[String](["character.player"])
ContainerTags = Array[String](["character.player", "traits.damageable"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[sub_resource type="Resource" id="Resource_5gbhg"]
@@ -70,6 +70,11 @@ script = ExtResource("11_u8yay")
Tag = "events.player.empowered_action_used"
metadata/_custom_type_script = "uid://dpakv7agvir6y"
[sub_resource type="Resource" id="Resource_2rkt1"]
script = ExtResource("11_u8yay")
Tag = "immunity.damage"
metadata/_custom_type_script = "uid://dpakv7agvir6y"
[sub_resource type="Resource" id="Resource_cb2lu"]
script = ExtResource("2_x835q")
DamageDealt = 10.0
@@ -77,14 +82,9 @@ metadata/_custom_type_script = "uid://jitubgv6judn"
[sub_resource type="Resource" id="Resource_abfq8"]
script = ExtResource("3_cb2lu")
Modifier = 20.0
Modifier = 5.0
metadata/_custom_type_script = "uid://b44cse62qru7j"
[sub_resource type="Resource" id="Resource_ue7xq"]
script = ExtResource("4_abfq8")
StartingHealth = 10.0
metadata/_custom_type_script = "uid://baiapod3csndf"
[sub_resource type="Resource" id="Resource_u8yay"]
script = ExtResource("11_2rkt1")
Default = 100
@@ -132,6 +132,9 @@ height = 1.0
[sub_resource type="SphereShape3D" id="SphereShape3D_abfq8"]
radius = 2.0
[sub_resource type="SphereShape3D" id="SphereShape3D_ue7xq"]
radius = 1.5
[sub_resource type="SphereShape3D" id="SphereShape3D_cmijs"]
radius = 1.0
@@ -142,9 +145,6 @@ height = 3.5
[sub_resource type="SphereShape3D" id="SphereShape3D_nob5r"]
radius = 0.4
[sub_resource type="SphereShape3D" id="SphereShape3D_ue7xq"]
radius = 1.5
[sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_2q0ik"]
blend_mode = 1
@@ -156,8 +156,10 @@ collision_mask = 272
script = ExtResource("1_poq2x")
BaseTags = SubResource("Resource_mpigw")
EmpoweredActionUsed = SubResource("Resource_5gbhg")
InvincibleTag = SubResource("Resource_2rkt1")
HitAbility = ExtResource("4_u8yay")
EmpoweredActionAbility = ExtResource("10_2rkt1")
WeaponExplosionBehavior = ExtResource("5_u8yay")
DefaultGrantedAbilities = [ExtResource("5_u8yay")]
DefaultPermanentEffects = [ExtResource("5_2rkt1")]
EmpoweredActionEffects = [ExtResource("6_u8yay")]
AimAssistStrength = 0.3
@@ -165,7 +167,6 @@ AimAssistReductionWhenCloseToTarget = 0.1
AimAssistReductionStartDistance = 8.0
RDamage = SubResource("Resource_cb2lu")
RKnockback = SubResource("Resource_abfq8")
RHealth = SubResource("Resource_ue7xq")
TargetingDistance = 5.0
Explosion = ExtResource("5_ue7xq")
WalkSpeed = 7.5
@@ -223,6 +224,24 @@ InitialAttributeValues = Dictionary[String, ExtResource("11_2rkt1")]({
})
metadata/_custom_type_script = "uid://cxihb42t2mfqi"
[node name="CharaAttributeSet" type="Node" parent="." unique_id=2058864775]
script = ExtResource("10_pw5r7")
AttributeSetClass = "CharacterAttributeSet"
InitialAttributeValues = Dictionary[String, ExtResource("11_2rkt1")]({
"Health": Object(RefCounted,"script":ExtResource("11_2rkt1"),"Default":100,"Min":0,"Max":100)
})
metadata/_custom_type_script = "uid://cxihb42t2mfqi"
[node name="MetaAttributeSet" type="Node" parent="." unique_id=1777903944]
script = ExtResource("10_pw5r7")
AttributeSetClass = "MetaAttributeSet"
InitialAttributeValues = Dictionary[String, ExtResource("11_2rkt1")]({
"IncomingDamage": Object(RefCounted,"script":ExtResource("11_2rkt1"),"Default":0,"Min":0,"Max":1000)
})
metadata/_custom_type_script = "uid://cxihb42t2mfqi"
[node name="CHealth" parent="." unique_id=1244478698 instance=ExtResource("3_q7bng")]
RHealth = ExtResource("4_m8gvy")
@@ -237,12 +256,6 @@ stream = ExtResource("9_jb43f")
autoplay = true
bus = &"SFX"
[node name="WallRunSnapper" type="RayCast3D" parent="." unique_id=1342764801]
unique_name_in_owner = true
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, 0, 0, 0)
target_position = Vector3(0, 0, -5)
collision_mask = 256
[node name="InputController" type="Node3D" parent="." unique_id=846069741]
script = ExtResource("16_v31n3")
base_mode = ExtResource("3_cresl")
@@ -413,6 +426,16 @@ target_position = Vector3(0, 0, 0)
max_results = 512
collision_mask = 16
[node name="SlidingEnemyDetector" type="Area3D" parent="." unique_id=42873532]
collision_layer = 0
collision_mask = 16
monitoring = false
monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="SlidingEnemyDetector" unique_id=1287455053]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
shape = SubResource("SphereShape3D_ue7xq")
[node name="CloseEnemyDetector" type="ShapeCast3D" parent="." unique_id=2109861596]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0)
@@ -426,6 +449,10 @@ target_position = Vector3(0, 0, -6)
collision_mask = 112
collide_with_areas = true
[node name="DirectGroundDetector" type="RayCast3D" parent="." unique_id=1037335553]
target_position = Vector3(0, -2, 0)
collision_mask = 256
[node name="GroundDetector" type="ShapeCast3D" parent="." unique_id=1681055424]
shape = SubResource("CapsuleShape3D_6lejt")
collision_mask = 256
@@ -437,20 +464,6 @@ shape = SubResource("SphereShape3D_nob5r")
target_position = Vector3(0, 0.4, 0)
collision_mask = 256
[node name="DirectGroundDetector" type="RayCast3D" parent="." unique_id=1037335553]
target_position = Vector3(0, -2, 0)
collision_mask = 256
[node name="SlidingEnemyDetector" type="Area3D" parent="." unique_id=42873532]
collision_layer = 0
collision_mask = 16
monitoring = false
monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="SlidingEnemyDetector" unique_id=1287455053]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
shape = SubResource("SphereShape3D_ue7xq")
[node name="InvincibilityTime" type="Timer" parent="." unique_id=1244463585]
one_shot = true

View File

@@ -1,5 +1,8 @@
using Godot;
using System;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Gamesmiths.Forge.Attributes;
using Gamesmiths.Forge.Core;
using Gamesmiths.Forge.Cues;
using Gamesmiths.Forge.Godot.Core;
@@ -7,12 +10,17 @@ using Gamesmiths.Forge.Tags;
using Movementtests.interfaces;
using Movementtests.tools;
[GlobalClass, Icon("res://assets/ui/IconGodotNode/control/icon_text_panel.png")]
public partial class PlayerUi : Control, ICueHandler
[GlobalClass, Icon("res://assets/ui/IconGodotNode/control/icon_text_panel.png"), Meta(typeof(IAutoNode))]
public partial class PlayerUi : Control
{
private TextureRect _enemyTarget = null!;
private Healthbar _healthbar = null!;
private Healthbar _manabar = null!;
public override void _Notification(int what) => this.Notify(what);
[Dependency]
public TagsManager TagsManager => this.DependOn<TagsManager>();
[Dependency]
public CuesManager CuesManager => this.DependOn<CuesManager>();
#region Utils
public enum TargetState
{
@@ -20,29 +28,40 @@ public partial class PlayerUi : Control, ICueHandler
TargetWouldNotKill,
TargetWouldKill
}
public record TargetProperties(TargetState State, Vector2 Position);
#endregion
#region Nodes
[Node] public required TextureRect EnemyTarget { get; set; }
[Node] public required ResourceBar Healthbar { get; set; }
[Node] public required ResourceBar Manabar { get; set; }
#endregion
#region Exports
[Export]
public Color WouldKillColor { get; set; } = new Color("009c8f");
[Export]
public Color WouldNotKillColor { get; set; } = new Color("fc001c");
#endregion
public override void _Ready()
private EntityAttribute? _health;
private EntityAttribute? _mana;
public void Init(EntityAttribute health, EntityAttribute mana)
{
_enemyTarget = GetNode<TextureRect>("%EnemyTarget");
_healthbar = GetNode<Healthbar>("%Healthbar");
_manabar = GetNode<Healthbar>("%Manabar");
var tagsManager = ForgeManagers.Instance.TagsManager;
var cuesManager = ForgeManagers.Instance.CuesManager;
cuesManager.RegisterCue(Tag.RequestTag(tagsManager, "cues.resources.mana"), this);
_health = health;
_mana = mana;
}
public void Initialize(float initialHealth, float initialMana)
public void OnResolved()
{
_healthbar.Initialize(initialHealth);
_manabar.Initialize(initialMana);
if (_health == null || _mana == null) throw new Exception("Health and mana attributes are not set");
Healthbar.Init(_health);
Manabar.Init(_mana);
}
public void SetEnemyTargetProperties(TargetProperties targetProperties)
@@ -57,38 +76,8 @@ public partial class PlayerUi : Control, ICueHandler
TargetState.TargetWouldKill => WouldKillColor,
_ => WouldNotKillColor
};
_enemyTarget.SetVisible(visible);
_enemyTarget.SetPosition(position - _enemyTarget.Size / 2);
_enemyTarget.SetModulate(modulation);
}
public void OnHealthChanged(IHealthable healthable, HealthChangedRecord healthChanged)
{
_healthbar.CurrentHealth = healthChanged.CurrentHealth;
}
public void OnManaChanged(float newValue)
{
_manabar.CurrentHealth = newValue;
}
public void OnExecute(IForgeEntity? target, CueParameters? parameters)
{
if (target == null || !parameters.HasValue || !IsInstanceValid(_manabar)) return;
float magnitude = parameters.Value.Magnitude;
_manabar.CurrentHealth += magnitude;
}
public void OnApply(IForgeEntity? target, CueParameters? parameters)
{
}
public void OnRemove(IForgeEntity? target, bool interrupted)
{
}
public void OnUpdate(IForgeEntity? target, CueParameters? parameters)
{
EnemyTarget.SetVisible(visible);
EnemyTarget.SetPosition(position - EnemyTarget.Size / 2);
EnemyTarget.SetModulate(modulation);
}
}

View File

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

View File

@@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Gamesmiths.Forge.Abilities;
using Gamesmiths.Forge.Attributes;
using Gamesmiths.Forge.Core;
using Gamesmiths.Forge.Cues;
using Gamesmiths.Forge.Effects;
using Gamesmiths.Forge.Effects.Calculator;
using Gamesmiths.Forge.Effects.Components;
@@ -19,68 +22,53 @@ using Gamesmiths.Forge.Tags;
using Godot;
using GodotStateCharts;
using Movementtests.addons.godot_state_charts.csharp;
using Movementtests.forge.abilities;
using Movementtests.interfaces;
using Movementtests.scenes.player_controller.components.weapon;
using Movementtests.systems.damage;
using Movementtests.tools;
using Movementtests.tools.calculators;
using Node = Godot.Node;
namespace Movementtests.systems;
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_sword.png")]
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_sword.png"), Meta(typeof(IAutoNode))]
public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
{
public override void _Notification(int what) => this.Notify(what);
#region Dependencies
[Dependency]
public TagsManager TagsManager => this.DependOn<TagsManager>();
[Dependency]
public CuesManager CuesManager => this.DependOn<CuesManager>();
#endregion
#region Enums
public enum WeaponEvent
{
StartedFlying,
StoppedFlying,
FlyingTick
}
#endregion
#region Signals
[Signal]
public delegate void WeaponThrownEventHandler();
[Signal]
public delegate void WeaponRetrievedEventHandler();
[Export]
public ForgeTagContainer BaseTags { get; set; }
[Export] public ForgeAbilityData FlyingTickAbility { get; set; }
[Export]
public RDamage RDamage { get; set; }
[Export(PropertyHint.Range, "0,2,0.01,or_greater")]
public float ThrowForce { get; set; } = 1f;
[Export(PropertyHint.Range, "0,0.2,0.01,or_greater")]
public float StraightThrowDuration { get; set; } = 0.1f;
public EntityAttributes Attributes { get; set; } = null!;
public EntityTags Tags { get; set; } = null!;
public EffectsManager EffectsManager { get; set; } = null!;
public EntityAbilities Abilities { get; set; } = null!;
public EventManager Events { get; set; } = null!;
public Variables SharedVariables { get; }
private StateChart _weaponState = null!;
public StateChartState InHandState = null!;
public StateChartState FlyingState = null!;
public StateChartState PlantedState = null!;
private Transition _handToFlying = null!;
private Transition _flyingToHand = null!;
private Transition _plantedToHand = null!;
private Transition _plantedToFlying = null!;
private Transition _toPlanted = null!;
#endregion
private ShapeCast3D _dashCast3D = null!;
public Timer WeaponFlyingTick = null!;
private Transform3D _startTransform;
private Vector3 _startMeshRotation;
#region Forge
private Vector3 _throwDirection;
public Vector3 PlantLocation { get; set; }
public Vector3 PlantNormal { get; set; }
public Node? PlantObject { get; set; }
public MeshInstance3D WeaponLocationIndicator { get; set; } = null!;
public StandardMaterial3D WeaponLocationIndicatorMaterial { get; set; } = null!;
public MeshInstance3D WeaponMesh { get; set; } = null!;
private Dictionary<ForgeAbilityBehavior, ActiveEffectHandle> _grantedWeaponStartedFlyingAbilities = new ();
private Dictionary<ForgeAbilityBehavior, ActiveEffectHandle> _grantedWeaponStoppedFlyingAbilities = new ();
private Dictionary<ForgeAbilityBehavior, ActiveEffectHandle> _grantedWeaponFlyingTickAbilities = new ();
public Tag WeaponFlyingTickEventTag;
public Tag WeaponStartedFlyingEventTag;
@@ -99,8 +87,96 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
private AbilityHandle? _weaponFlyingAbility;
public void Init()
#endregion
#region Inspector
[Export] public ForgeAbilityData? FlyingTickAbility { get; set; }
[Export]
public RDamage RDamage { get; set; }
[Export(PropertyHint.Range, "0,2,0.01,or_greater")]
public float ThrowForce { get; set; } = 1f;
[Export(PropertyHint.Range, "0,0.2,0.01,or_greater")]
public float StraightThrowDuration { get; set; } = 0.1f;
#endregion
#region IForgeEntity
// Perfectly forward the IForgeEntity interface to the ForgeEntity component
public EntityAttributes Attributes
{
get => ForgeEntity.Attributes;
set => ForgeEntity.Attributes = value;
}
public EntityTags Tags
{
get => ForgeEntity.Tags;
set => ForgeEntity.Tags = value;
}
public EffectsManager EffectsManager
{
get => ForgeEntity.EffectsManager;
set => ForgeEntity.EffectsManager = value;
}
public EntityAbilities Abilities
{
get => ForgeEntity.Abilities;
set => ForgeEntity.Abilities = value;
}
public EventManager Events
{
get => ForgeEntity.Events;
set => ForgeEntity.Events = value;
}
public Variables SharedVariables
{
get => ForgeEntity.SharedVariables;
set => ForgeEntity.SharedVariables = value;
}
#endregion
#region Publics
public StateChartState InHandState = null!;
public StateChartState FlyingState = null!;
public StateChartState PlantedState = null!;
public Vector3 PlantLocation { get; set; }
public Vector3 PlantNormal { get; set; }
public Node? PlantObject { get; set; }
public StandardMaterial3D WeaponLocationIndicatorMaterial { get; set; } = null!;
[Node("ForgeEntityNode")] public required ForgeEntityNode ForgeEntity { get; set;}
[Node("Weapon")] public required MeshInstance3D WeaponMesh { get; set; }
[Node("WeaponLocationIndicator")] public required MeshInstance3D WeaponLocationIndicator { get; set; }
#endregion
#region Privates
private StateChart _weaponState = null!;
private Transition _handToFlying = null!;
private Transition _flyingToHand = null!;
private Transition _plantedToHand = null!;
private Transition _plantedToFlying = null!;
private Transition _toPlanted = null!;
private ShapeCast3D _dashCast3D = null!;
private Transform3D _startTransform;
private Vector3 _startMeshRotation;
private Vector3 _throwDirection;
#endregion
public void OnReady()
{
#region StateManagement
_weaponState = StateChart.Of(GetNode("StateChart"));
InHandState = StateChartState.Of(GetNode("StateChart/Root/InHand"));
FlyingState = StateChartState.Of(GetNode("StateChart/Root/Flying"));
@@ -110,67 +186,46 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
_plantedToHand = Transition.Of(GetNode("StateChart/Root/Planted/ToHand"));
_plantedToFlying = Transition.Of(GetNode("StateChart/Root/Planted/ToFlying"));
_toPlanted = Transition.Of(GetNode("StateChart/Root/ToPlanted"));
WeaponLocationIndicator = GetNode<MeshInstance3D>("WeaponLocationIndicator");
WeaponLocationIndicator.Visible = false;
WeaponLocationIndicatorMaterial = (WeaponLocationIndicator.GetActiveMaterial(0) as StandardMaterial3D)!;
WeaponFlyingTick = GetNode<Timer>("WeaponFlyingTick");
WeaponMesh = GetNode<MeshInstance3D>("Weapon");
#endregion
// Initial setup
_startMeshRotation = WeaponMesh.Rotation;
_startTransform = Transform;
Freeze = true;
Visible = false;
WeaponLocationIndicator.Visible = false;
WeaponLocationIndicatorMaterial = (WeaponLocationIndicator.GetActiveMaterial(0) as StandardMaterial3D)!;
}
public void OnResolved()
{
// Forge
var tagsManager = ForgeManagers.Instance.TagsManager;
var cuesManager = ForgeManagers.Instance.CuesManager;
WeaponFlyingTickEventTag = Tag.RequestTag(TagsManager, "events.weapon.flyingTick");
WeaponStartedFlyingEventTag = Tag.RequestTag(TagsManager, "events.weapon.startedFlying");
WeaponStoppedFlyingEventTag = Tag.RequestTag(TagsManager, "events.weapon.stoppedFlying");
WeaponHandToFlyingEventTag = Tag.RequestTag(TagsManager, "events.weapon.handToFlying");
WeaponFlyingToHandEventTag = Tag.RequestTag(TagsManager, "events.weapon.flyingToHand");
WeaponPlantedToHandEventTag = Tag.RequestTag(TagsManager, "events.weapon.plantedToHand");
WeaponPlantedToFlyingEventTag = Tag.RequestTag(TagsManager, "events.weapon.plantedToFlying");
WeaponPlantedEventTag = Tag.RequestTag(TagsManager, "events.weapon.planted");
WeaponFlyingTickEventTag = Tag.RequestTag(tagsManager, "events.weapon.flyingTick");
WeaponStartedFlyingEventTag = Tag.RequestTag(tagsManager, "events.weapon.startedFlying");
WeaponStoppedFlyingEventTag = Tag.RequestTag(tagsManager, "events.weapon.stoppedFlying");
WeaponHandToFlyingEventTag = Tag.RequestTag(tagsManager, "events.weapon.handToFlying");
WeaponFlyingToHandEventTag = Tag.RequestTag(tagsManager, "events.weapon.flyingToHand");
WeaponPlantedToHandEventTag = Tag.RequestTag(tagsManager, "events.weapon.plantedToHand");
WeaponPlantedToFlyingEventTag = Tag.RequestTag(tagsManager, "events.weapon.plantedToFlying");
WeaponPlantedEventTag = Tag.RequestTag(tagsManager, "events.weapon.planted");
// WeaponInHandStatusTag = Tag.RequestTag(TagsManager, "status.weapon.inHand");
// WeaponFlyingStatusTag = Tag.RequestTag(TagsManager, "status.weapon.flying");
// WeaponPlantedStatusTag = Tag.RequestTag(TagsManager, "status.weapon.planted");
// WeaponInHandStatusTag = Tag.RequestTag(tagsManager, "status.weapon.inHand");
// WeaponFlyingStatusTag = Tag.RequestTag(tagsManager, "status.weapon.flying");
// WeaponPlantedStatusTag = Tag.RequestTag(tagsManager, "status.weapon.planted");
WeaponFlyingAbilityTag = Tag.RequestTag(tagsManager,"abilities.weapon.flying");
List<AttributeSet> attributeSetList = [];
foreach (Node node in GetChildren())
{
if (node is ForgeAttributeSet attributeSetNode)
{
AttributeSet? attributeSet = attributeSetNode.GetAttributeSet();
if (attributeSet is not null)
{
attributeSetList.Add(attributeSet);
}
}
}
Attributes = new EntityAttributes([.. attributeSetList]);
Tags = new(BaseTags.GetTagContainer());
EffectsManager = new EffectsManager(this, cuesManager);
Abilities = new(this);
Events = new();
// TODO: Waiting on bug resolve
// Manage weapon flying tick raising ability
WeaponFlyingAbilityTag = Tag.RequestTag(TagsManager,"abilities.weapon.flying");
_weaponFlyingAbility = Abilities.GrantAbilityPermanently(FlyingTickAbility.GetAbilityData(), 1, LevelComparison.None, this);
Events.Subscribe(WeaponStoppedFlyingEventTag, _ => { _weaponFlyingAbility.Cancel(); });
BodyEntered += OnThrownWeaponReachesGround;
InHandState.StateExited += WeaponLeft;
InHandState.StateEntered += WeaponBack;
#region EventRaising
_handToFlying.Taken += () =>
{
Events.Raise(new EventData
@@ -237,24 +292,12 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
});
};
Events.Subscribe(WeaponStoppedFlyingEventTag, _ => { _weaponFlyingAbility.Cancel(); });
#endregion
}
private Dictionary<ForgeAbilityBehavior, ActiveEffectHandle> _grantedWeaponStartedFlyingAbilities = new ();
private Dictionary<ForgeAbilityBehavior, ActiveEffectHandle> _grantedWeaponStoppedFlyingAbilities = new ();
private Dictionary<ForgeAbilityBehavior, ActiveEffectHandle> _grantedWeaponFlyingTickAbilities = new ();
public enum WeaponEvent
{
StartedFlying,
StoppedFlying,
FlyingTick
}
public void GrantNewAbilityForEvent(WeaponEvent forEvent, ForgeAbilityBehavior abilityBehavior)
{
var relevantMap = GetGrantedAbilities(forEvent);
GD.Print($"Granted {abilityBehavior} for {forEvent}");
if (relevantMap.ContainsKey(abilityBehavior)) return;
var eventTagsMap = new Dictionary<WeaponEvent, Tag>
@@ -296,6 +339,19 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
relevantMap.Remove(abilityBehavior);
}
public void RemoveAllEventAbilities()
{
foreach (var weaponEvent in Enum.GetValues<WeaponEvent>())
{
var abilities = GetGrantedAbilities(weaponEvent);
foreach (var ability in abilities.Values)
{
EffectsManager.RemoveEffect(ability);
}
abilities.Clear();
}
}
public Dictionary<ForgeAbilityBehavior, ActiveEffectHandle> GetGrantedAbilities(WeaponEvent forEvent)
{
var abilitiesMap = new Dictionary<WeaponEvent, Dictionary<ForgeAbilityBehavior, ActiveEffectHandle>>
@@ -421,6 +477,7 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
public override void _Process(double delta)
{
Abilities.UpdateAbilities(delta);
EffectsManager.UpdateEffects(delta);
if (!FlyingState.Active) return;

View File

@@ -6,9 +6,10 @@
[ext_resource type="Script" uid="uid://cxihb42t2mfqi" path="res://addons/forge/nodes/ForgeAttributeSet.cs" id="3_3xjpi"]
[ext_resource type="Script" uid="uid://couw105c3bde4" path="res://addons/godot_state_charts/state_chart.gd" id="3_5owyf"]
[ext_resource type="ArrayMesh" uid="uid://cho5fixitrbds" path="res://assets/meshes/swords/resources/sword23.tres" id="3_svc06"]
[ext_resource type="Resource" uid="uid://btnnpqann3ktp" path="res://scenes/player_controller/resources/forge/weapon_flying_tick_ability.tres" id="4_7bruw"]
[ext_resource type="Resource" uid="uid://btnnpqann3ktp" path="res://forge/resources/ability_datas/weapon_flying_tick_ability.tres" id="4_7bruw"]
[ext_resource type="Script" uid="uid://ccovd5i0wr3kk" path="res://addons/forge/editor/attributes/AttributeValues.cs" id="4_q6xv7"]
[ext_resource type="Script" uid="uid://jk2jm1g6q853" path="res://addons/godot_state_charts/compound_state.gd" id="4_svc06"]
[ext_resource type="Script" uid="uid://rpcbb54q4atx" path="res://forge/ForgeEntityNode.cs" id="5_7bruw"]
[ext_resource type="Script" uid="uid://cytafq8i1y8qm" path="res://addons/godot_state_charts/atomic_state.gd" id="5_m0v1h"]
[ext_resource type="Script" uid="uid://cf1nsco3w0mf6" path="res://addons/godot_state_charts/transition.gd" id="6_jpdh0"]
@@ -22,6 +23,11 @@ script = ExtResource("2_m0v1h")
DamageDealt = 2.0
metadata/_custom_type_script = "uid://jitubgv6judn"
[sub_resource type="Resource" id="Resource_7bruw"]
script = ExtResource("2_l1xlx")
ContainerTags = Array[String](["weapon"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[sub_resource type="Resource" id="Resource_pgbtr"]
script = ExtResource("4_q6xv7")
Default = 1
@@ -67,7 +73,12 @@ BaseTags = SubResource("Resource_06gln")
FlyingTickAbility = ExtResource("4_7bruw")
RDamage = SubResource("Resource_jpdh0")
[node name="WeaponAttributeSet" type="Node" parent="." unique_id=14845649]
[node name="ForgeEntityNode" type="Node3D" parent="." unique_id=1798885192]
script = ExtResource("5_7bruw")
BaseTags = SubResource("Resource_7bruw")
metadata/_custom_type_script = "uid://rpcbb54q4atx"
[node name="WeaponAttributeSet" type="Node" parent="ForgeEntityNode" unique_id=14845649]
script = ExtResource("3_3xjpi")
AttributeSetClass = "WeaponAttributeSet"
InitialAttributeValues = Dictionary[String, ExtResource("4_q6xv7")]({

View File

@@ -1,26 +0,0 @@
[gd_resource type="Resource" script_class="ForgeAbilityData" format=3 uid="uid://bl0mng4kl1xy8"]
[ext_resource type="Resource" uid="uid://ifeavnlps7hy" path="res://scenes/player_controller/resources/forge/exploding_sword.tres" id="1_postf"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="2_km5rh"]
[ext_resource type="Script" uid="uid://dpakv7agvir6y" path="res://addons/forge/resources/ForgeTag.cs" id="3_spdwn"]
[ext_resource type="Script" uid="uid://dhxfbxh54pyxp" path="res://addons/forge/resources/abilities/ForgeAbilityData.cs" id="4_cm86c"]
[sub_resource type="Resource" id="Resource_ixeut"]
script = ExtResource("2_km5rh")
ContainerTags = Array[String](["abilities.weapon.land"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[sub_resource type="Resource" id="Resource_6c3kr"]
script = ExtResource("3_spdwn")
Tag = "events.weapon.flyingtick"
metadata/_custom_type_script = "uid://dpakv7agvir6y"
[resource]
script = ExtResource("4_cm86c")
Name = "Exploding Sword on Weapon Flight"
CooldownEffects = []
AbilityBehavior = ExtResource("1_postf")
TriggerSource = 1
TriggerTag = SubResource("Resource_6c3kr")
AbilityTags = SubResource("Resource_ixeut")
metadata/_custom_type_script = "uid://dhxfbxh54pyxp"

View File

@@ -1,26 +0,0 @@
[gd_resource type="Resource" script_class="ForgeAbilityData" format=3 uid="uid://cu0685gspk2fk"]
[ext_resource type="Resource" uid="uid://ifeavnlps7hy" path="res://scenes/player_controller/resources/forge/exploding_sword.tres" id="1_6c3kr"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="2_6c3kr"]
[ext_resource type="Script" uid="uid://dpakv7agvir6y" path="res://addons/forge/resources/ForgeTag.cs" id="2_l4v7e"]
[ext_resource type="Script" uid="uid://dhxfbxh54pyxp" path="res://addons/forge/resources/abilities/ForgeAbilityData.cs" id="3_ixeut"]
[sub_resource type="Resource" id="Resource_ixeut"]
script = ExtResource("2_6c3kr")
ContainerTags = Array[String](["abilities.weapon.land"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[sub_resource type="Resource" id="Resource_6c3kr"]
script = ExtResource("2_l4v7e")
Tag = "events.weapon.stoppedflying"
metadata/_custom_type_script = "uid://dpakv7agvir6y"
[resource]
script = ExtResource("3_ixeut")
Name = "Exploding Sword on Weapon Land"
CooldownEffects = []
AbilityBehavior = ExtResource("1_6c3kr")
TriggerSource = 1
TriggerTag = SubResource("Resource_6c3kr")
AbilityTags = SubResource("Resource_ixeut")
metadata/_custom_type_script = "uid://dhxfbxh54pyxp"

View File

@@ -1,26 +0,0 @@
[gd_resource type="Resource" script_class="ForgeAbilityData" format=3 uid="uid://busdbvfi3jiic"]
[ext_resource type="Script" uid="uid://dhxfbxh54pyxp" path="res://addons/forge/resources/abilities/ForgeAbilityData.cs" id="1_85dnt"]
[ext_resource type="Resource" uid="uid://ifeavnlps7hy" path="res://scenes/player_controller/resources/forge/exploding_sword.tres" id="1_m0rkb"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="2_u5iw7"]
[ext_resource type="Script" uid="uid://dpakv7agvir6y" path="res://addons/forge/resources/ForgeTag.cs" id="3_u5iw7"]
[sub_resource type="Resource" id="Resource_cjh4j"]
script = ExtResource("2_u5iw7")
ContainerTags = Array[String](["abilities.weapon.left"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[sub_resource type="Resource" id="Resource_mtsda"]
script = ExtResource("3_u5iw7")
Tag = "events.weapon.startedflying"
metadata/_custom_type_script = "uid://dpakv7agvir6y"
[resource]
script = ExtResource("1_85dnt")
Name = "Exploding Sword on Weapon Left"
CooldownEffects = []
AbilityBehavior = ExtResource("1_m0rkb")
TriggerSource = 1
TriggerTag = SubResource("Resource_mtsda")
AbilityTags = SubResource("Resource_cjh4j")
metadata/_custom_type_script = "uid://dhxfbxh54pyxp"

File diff suppressed because it is too large Load Diff

View File

@@ -5,14 +5,14 @@ using System;
public partial class Spawner : Node3D
{
[Export(PropertyHint.NodeType)]
public PackedScene EnemyToSpawn { get; set; }
public PackedScene? EnemyToSpawn { get; set; }
[Export]
public RMovement MovementInputs { get; set; }
public RMovement? MovementInputs { get; set; }
[Export]
public RHealth HealthInputs { get; set; }
public RHealth? HealthInputs { get; set; }
[Export]
public RDamage DamageInputs { get; set; }
public RDamage? DamageInputs { get; set; }
[Export]
public Node3D Target { get; set; }
@@ -37,7 +37,7 @@ public partial class Spawner : Node3D
if (EnemyToSpawn == null || !EnemyToSpawn.CanInstantiate()) return;
if (EnemyToSpawn.Instantiate() is not Enemy spawnedInstance) return;
spawnedInstance.RequestReady();
GetTree().GetCurrentScene().AddChild(spawnedInstance);
spawnedInstance.GlobalPosition = GlobalPosition;
@@ -45,7 +45,7 @@ public partial class Spawner : Node3D
spawnedInstance.RMovement = MovementInputs;
spawnedInstance.RDamage = DamageInputs;
spawnedInstance.RHealth = HealthInputs;
spawnedInstance.Initialize();
spawnedInstance.Init();
}
public void StartSpawning()

View File

@@ -1,63 +0,0 @@
using Godot;
using System;
[GlobalClass, Icon("res://assets/ui/IconGodotNode/control/icon_heart.png")]
public partial class Healthbar : ProgressBar
{
private Timer _damageCatchUpTimer = null!;
private ProgressBar _damagedHealth = null!;
[Export] public StyleBox? BarStyle;
private float _currentHealth;
public float CurrentHealth
{
get => _currentHealth;
set => SetHealth(value);
}
public override void _Ready()
{
_damageCatchUpTimer = GetNode<Timer>("DamageCatchUp");
_damagedHealth = GetNode<ProgressBar>("Damagebar");
_damageCatchUpTimer.Timeout += OnDamageCatchUp;
Visible = false;
if (BarStyle != null)
AddThemeStyleboxOverride("fill", BarStyle);
}
public void Initialize(float initialHealth)
{
_currentHealth = initialHealth;
MaxValue = initialHealth;
Value = initialHealth;
_damagedHealth.MaxValue = initialHealth;
_damagedHealth.Value = initialHealth;
}
public void SetHealth(float newHealth)
{
var previousHealth = _currentHealth;
_currentHealth = Mathf.Min(newHealth, (float) MaxValue);
_currentHealth = newHealth;
Value = _currentHealth;
Visible = _currentHealth < MaxValue;
if (_currentHealth < previousHealth)
{
_damageCatchUpTimer.Start();
}
else
{
_damagedHealth.Value = _currentHealth;
}
}
public void OnDamageCatchUp()
{
_damagedHealth.Value = _currentHealth;
}
}

View File

@@ -0,0 +1,73 @@
using Godot;
using System;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Gamesmiths.Forge.Attributes;
using Gamesmiths.Forge.Core;
using Gamesmiths.Forge.Cues;
using Gamesmiths.Forge.Godot.Core;
using Gamesmiths.Forge.Tags;
[GlobalClass, Icon("res://assets/ui/IconGodotNode/control/icon_heart.png"), Meta(typeof(IAutoNode))]
public partial class ResourceBar : ProgressBar
{
public override void _Notification(int what) => this.Notify(what);
[Node("DamageCatchUp")] public required Timer DamageCatchUp { get; set; }
[Node("Damagebar")] public required ProgressBar DamageBar { get; set; }
[Export] public StyleBox? BarStyle;
private float _currentValue;
public float CurrentValue
{
get => _currentValue;
set => SetValue(value);
}
public void OnReady()
{
DamageCatchUp.Timeout += OnDamageCatchUp;
Visible = false;
if (BarStyle != null)
AddThemeStyleboxOverride("fill", BarStyle);
}
public void Init(EntityAttribute attribute)
{
_currentValue = attribute.BaseValue;
// Should be Max but it's bugged
// Therefore we just assume that the base value is the max value, i.e. entities spawn at full health
MaxValue = attribute.BaseValue; // MaxValue = attribute.Max;
Value = attribute.BaseValue;
DamageBar.MaxValue = attribute.Max;
DamageBar.Value = attribute.BaseValue;
attribute.OnValueChanged += (entityAttribute, i) => CurrentValue = entityAttribute.CurrentValue;
}
public void SetValue(float newValue)
{
var previousValue = _currentValue;
_currentValue = Mathf.Min(newValue, (float) MaxValue);
_currentValue = newValue;
Value = _currentValue;
Visible = _currentValue < MaxValue;
if (_currentValue < previousValue)
{
DamageCatchUp.Start();
}
else
{
DamageBar.Value = _currentValue;
}
}
public void OnDamageCatchUp()
{
DamageBar.Value = _currentValue;
}
}

View File

@@ -1,30 +0,0 @@
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 ComputeDamageNoComponent()
{
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 Unstun()
{
var enemy = new Enemy();
enemy.IsStunned = true;
enemy.Unstun();
AssertBool(enemy.IsStunned).IsFalse();
}
}

View File

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

View File

@@ -1,133 +0,0 @@
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 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

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

View File

@@ -1,51 +0,0 @@
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

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

22
tools/ForgeUtils.cs Normal file
View File

@@ -0,0 +1,22 @@
using System.Collections.Generic;
using Gamesmiths.Forge.Attributes;
using Gamesmiths.Forge.Godot.Nodes;
using Godot;
namespace Movementtests.tools;
public static class ForgeUtils
{
public static List<AttributeSet> CollectAttributeList(Node node)
{
List<AttributeSet> attributeSetList = [];
foreach (var child in node.GetChildren())
{
if (child is not ForgeAttributeSet attributeSetNode) continue;
var attributeSet = attributeSetNode.GetAttributeSet();
if (attributeSet is not null)
attributeSetList.Add(attributeSet);
}
return attributeSetList;
}
}

1
tools/ForgeUtils.cs.uid Normal file
View File

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