Compare commits

...

13 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
82 changed files with 2030 additions and 1102 deletions

View File

@@ -100,7 +100,7 @@ jobs:
# - uses: actions/setup-dotnet@v5 # - uses: actions/setup-dotnet@v5
# name: 💽 Setup .NET SDK # name: 💽 Setup .NET SDK
# with: # with:
# dotnet-version: ${DOTNET_VERSION} # dotnet-version: '9.0.x'
# #
# - name: 📦 Restore Dependencies # - name: 📦 Restore Dependencies
# run: | # run: |
@@ -114,7 +114,7 @@ jobs:
# with: # with:
# # Version must include major, minor, and patch, and be >= 4.0.0 # # Version must include major, minor, and patch, and be >= 4.0.0
# # Pre-release label is optional. # # Pre-release label is optional.
# version: ${GODOT_VERSION} # version: '4.6.2'
# # Use .NET-enabled version of Godot (the default is also true). # # Use .NET-enabled version of Godot (the default is also true).
# use-dotnet: true # use-dotnet: true
# # Include the Godot Export Templates (the default is false). # # Include the Godot Export Templates (the default is false).
@@ -126,20 +126,21 @@ jobs:
# godot --version # godot --version
# #
# - name: 🧑‍🔬 Generate .NET Bindings # - name: 🧑‍🔬 Generate .NET Bindings
# run: godot --headless --build-solutions --quit || exit 0 # run: godot --headless --build-solutions --import --quit || exit 0
# #
# - name: 🦺 Build Projects # - name: 🦺 Build Projects
# run: dotnet build --configuration Release # run: dotnet build --configuration ExportRelease
# #
# - name: Run C# Tests # - name: Run C# Tests
# env: # env:
# GODOT_BIN: godot # GODOT_BIN: /root/bin/godot
# shell: bash # shell: bash
# run: | # run: |
# dotnet test --no-build --settings .runsettings --results-directory ./reports --logger "console;verbosity=normal" --logger "trx;LogFileName=results.xml" -- GdUnit4.Parameters="--verbose --headless --import" # 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 # - name: Upload test report
# uses: actions/upload-artifact@v3-node20 # uses: actions/upload-artifact@v3-node20
# if: always()
# with: # with:
# name: Test Report # name: Test Report
# path: ${{ github.workspace }}/reports/test-result.html # path: ${{ github.workspace }}/reports/test-result.html

1
.gitignore vendored
View File

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

View File

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

View File

@@ -128,7 +128,6 @@
<ItemGroup> <ItemGroup>
<Folder Include="addons\" /> <Folder Include="addons\" />
<Folder Include="tests\" /> <Folder Include="tests\" />
<Folder Include="tools\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="RustyOptions" Version="0.10.1" /> <PackageReference Include="RustyOptions" Version="0.10.1" />

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; return;
} }
explo.Radius = radius; explo.Radius = radius;
GD.Print("explosion");
owner.GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, explo); owner.GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, explo);
explo.CallDeferred(Node3D.MethodName.SetGlobalPosition, owner.GlobalPosition); 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; using Gamesmiths.Forge.Attributes;
namespace Movementtests.scenes.enemies; namespace Movementtests.scenes.enemies;
public class EnemyAttributeSet : AttributeSet public class EnemyAttributeSet : AttributeSet
{ {
public EntityAttribute Health { get; }
public EntityAttribute Strength { get; } public EntityAttribute Strength { get; }
public EntityAttribute Speed { get; } public EntityAttribute Speed { get; }
public EnemyAttributeSet() public EnemyAttributeSet()
{ {
Health = InitializeAttribute(nameof(Health), 100, 0, 150);
Strength = InitializeAttribute(nameof(Strength), 10, 0, 99); Strength = InitializeAttribute(nameof(Strength), 10, 0, 99);
Speed = InitializeAttribute(nameof(Speed), 5, 0, 10); 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 class PlayerAttributeSet : AttributeSet
{ {
public EntityAttribute Health { get; }
public EntityAttribute Mana { get; } public EntityAttribute Mana { get; }
public EntityAttribute Strength { get; }
public EntityAttribute Speed { get; }
public PlayerAttributeSet() public PlayerAttributeSet()
{ {
Health = InitializeAttribute(nameof(Health), 100, 0, 150);
Mana = InitializeAttribute(nameof(Mana), 100, 0, 100); 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; 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) public override ModifierEvaluatedData[] EvaluateExecution(Effect effect, IForgeEntity target, EffectEvaluatedData? effectEvaluatedData)
{ {
var owner = effect.Ownership.Owner; var owner = effect.Ownership.Owner;
if (owner == null) return []; var magnitude = effectEvaluatedData is { ModifiersEvaluatedData.Length: > 0 }
? effectEvaluatedData.ModifiersEvaluatedData[0].Magnitude
owner.Events.Raise(new EventData : 0f;
if (owner != null && ownerEventTags != null)
{ {
EventTags = eventTags, owner.Events.Raise(new EventData
Source = owner, {
EventMagnitude = 12f EventTags = ownerEventTags,
}); Source = owner,
EventMagnitude = magnitude
});
}
if (targetEventTags != null)
{
target.Events.Raise(new EventData
{
EventTags = targetEventTags,
Source = owner,
EventMagnitude = magnitude
});
}
return []; return [];
} }
@@ -39,10 +53,11 @@ public class RaiseEventTagExecution(TagContainer eventTags) : CustomExecution
[GlobalClass] [GlobalClass]
public partial class ForgeRaiseEventTagExecution : ForgeCustomExecution public partial class ForgeRaiseEventTagExecution : ForgeCustomExecution
{ {
[Export] ForgeTagContainer EventTags { get; set; } [Export] ForgeTagContainer? EventTags { get; set; }
[Export] ForgeTagContainer? TargetEventTags { get; set; }
public override CustomExecution GetExecutionClass() public override CustomExecution GetExecutionClass()
{ {
return new RaiseEventTagExecution(EventTags.GetTagContainer()); return new RaiseEventTagExecution(EventTags?.GetTagContainer(), TargetEventTags?.GetTagContainer());
} }
} }

View File

@@ -4,4 +4,4 @@
[resource] [resource]
script = ExtResource("1_l686n") 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"] [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://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://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://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://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://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="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://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"] [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"] [sub_resource type="Resource" id="Resource_h116a"]
script = ExtResource("2_prg0a") script = ExtResource("2_prg0a")
ContainerTags = Array[String](["cooldown.empoweredaction"]) ContainerTags = Array[String](["cooldown.empoweredaction"])
@@ -78,6 +147,42 @@ InitialStack = SubResource("Resource_lmnuh")
Cues = [] Cues = []
metadata/_custom_type_script = "uid://b83hf13nj37k3" 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"] [sub_resource type="Resource" id="Resource_8dsdw"]
script = ExtResource("6_yi0bg") script = ExtResource("6_yi0bg")
BaseValue = 1 BaseValue = 1
@@ -129,6 +234,7 @@ Name = "Empowered Action Cost"
Modifiers = Array[Object]([SubResource("Resource_dhni4")]) Modifiers = Array[Object]([SubResource("Resource_dhni4")])
Components = [] Components = []
Executions = [] Executions = []
Duration = SubResource("Resource_rwc4g")
StackLimit = SubResource("Resource_w5rmc") StackLimit = SubResource("Resource_w5rmc")
InitialStack = SubResource("Resource_8dsdw") InitialStack = SubResource("Resource_8dsdw")
Cues = Array[Object]([ExtResource("8_0olwd")]) Cues = Array[Object]([ExtResource("8_0olwd")])
@@ -139,5 +245,5 @@ script = ExtResource("10_2sq4o")
Name = "Empowered Action" Name = "Empowered Action"
CooldownEffects = [SubResource("Resource_egh2b")] CooldownEffects = [SubResource("Resource_egh2b")]
CostEffect = SubResource("Resource_mtef8") CostEffect = SubResource("Resource_mtef8")
AbilityBehavior = ExtResource("1_x7d0c") AbilityBehavior = SubResource("Resource_xh53a")
metadata/_custom_type_script = "uid://dhxfbxh54pyxp" 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"] [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://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"] [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"] [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"] [ext_resource type="Script" uid="uid://cl5hudinl1rex" path="res://forge/abilities/ForgeEffectApplicationBehavior.cs" id="2_f5qgs"]
[resource] [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"] [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://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_jijlk"] [ext_resource type="Script" uid="uid://cmrsxccn0ei4j" path="res://addons/forge/resources/ForgeCue.cs" id="2_g0vcr"]
[sub_resource type="Resource" id="Resource_4mhqs"] [sub_resource type="Resource" id="Resource_4mhqs"]
script = ExtResource("1_lbula") script = ExtResource("1_0pc1u")
ContainerTags = Array[String](["cues.resources.mana"]) ContainerTags = Array[String](["cues.resources.mana"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0" metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[resource] [resource]
script = ExtResource("2_jijlk") script = ExtResource("2_g0vcr")
CueKeys = SubResource("Resource_4mhqs") CueKeys = SubResource("Resource_4mhqs")
MaxValue = 100 MaxValue = 100
MagnitudeType = 2 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"] [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"] [ext_resource type="Script" uid="uid://br7ut4lbau66w" path="res://forge/calculators/ForgeRaiseEventTagExecution.cs" id="2_am2ak"]
[resource] [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"] [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="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_b244r"]
[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://b0eq12mjqfage" path="res://addons/forge/resources/components/TargetTagRequirements.cs" id="2_h46co"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_q8tml"] [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://b83hf13nj37k3" path="res://addons/forge/resources/ForgeEffectData.cs" id="2_5tp50"] [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="2_pm3n3"] [ext_resource type="Script" uid="uid://cn3b4ya15fg7e" path="res://addons/forge/resources/magnitudes/ForgeScalableFloat.cs" id="5_m4art"]
[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="6_73cww"]
[ext_resource type="Script" uid="uid://bdfcavbjyhxxa" path="res://addons/forge/resources/ForgeModifier.cs" id="3_nsr3v"] [ext_resource type="Script" uid="uid://b83hf13nj37k3" path="res://addons/forge/resources/ForgeEffectData.cs" id="7_xa46f"]
[sub_resource type="Resource" id="Resource_5yygy"] [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"]) ContainerTags = Array[String](["character.player.mana.regen.inhibited", "cues.resources.mana.inhibited"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0" metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[sub_resource type="Resource" id="Resource_ncjx6"] [sub_resource type="Resource" id="Resource_ncjx6"]
script = ExtResource("2_xbgy2") script = ExtResource("2_h46co")
OngoingIgnoredTags = SubResource("Resource_5yygy") OngoingIgnoredTags = SubResource("Resource_5yygy")
metadata/_custom_type_script = "uid://b0eq12mjqfage" metadata/_custom_type_script = "uid://b0eq12mjqfage"
[sub_resource type="Resource" id="Resource_pm3n3"] [sub_resource type="Resource" id="Resource_pm3n3"]
script = ExtResource("1_mlifq") script = ExtResource("4_fgmkc")
BaseValue = 1 BaseValue = 1
[sub_resource type="Resource" id="Resource_q8tml"] [sub_resource type="Resource" id="Resource_q8tml"]
script = ExtResource("2_pm3n3") script = ExtResource("5_m4art")
BaseValue = 1.0 BaseValue = 1.0
[sub_resource type="Resource" id="Resource_xbgy2"] [sub_resource type="Resource" id="Resource_xbgy2"]
script = ExtResource("2_pm3n3") script = ExtResource("5_m4art")
[sub_resource type="Resource" id="Resource_rhldn"] [sub_resource type="Resource" id="Resource_rhldn"]
script = ExtResource("2_pm3n3") script = ExtResource("5_m4art")
[sub_resource type="Resource" id="Resource_p6h8c"] [sub_resource type="Resource" id="Resource_p6h8c"]
script = ExtResource("2_pm3n3") script = ExtResource("5_m4art")
BaseValue = 1.0 BaseValue = 1.0
[sub_resource type="Resource" id="Resource_yqxv4"] [sub_resource type="Resource" id="Resource_yqxv4"]
script = ExtResource("2_pm3n3") script = ExtResource("5_m4art")
[sub_resource type="Resource" id="Resource_b6opn"] [sub_resource type="Resource" id="Resource_b6opn"]
script = ExtResource("2_pm3n3") script = ExtResource("5_m4art")
[sub_resource type="Resource" id="Resource_5frso"] [sub_resource type="Resource" id="Resource_5frso"]
script = ExtResource("2_pm3n3") script = ExtResource("5_m4art")
BaseValue = 2.0 BaseValue = 2.0
metadata/_custom_type_script = "uid://cn3b4ya15fg7e" metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
[sub_resource type="Resource" id="Resource_okenf"] [sub_resource type="Resource" id="Resource_okenf"]
script = ExtResource("3_nsr3v") script = ExtResource("6_73cww")
Attribute = "PlayerAttributeSet.Mana" Attribute = "PlayerAttributeSet.Mana"
ScalableFloat = SubResource("Resource_5frso") ScalableFloat = SubResource("Resource_5frso")
Coefficient = SubResource("Resource_p6h8c") Coefficient = SubResource("Resource_p6h8c")
@@ -60,16 +60,16 @@ CalculatorPostMultiplyAdditiveValue = SubResource("Resource_xbgy2")
metadata/_custom_type_script = "uid://bdfcavbjyhxxa" metadata/_custom_type_script = "uid://bdfcavbjyhxxa"
[sub_resource type="Resource" id="Resource_w35mq"] [sub_resource type="Resource" id="Resource_w35mq"]
script = ExtResource("2_pm3n3") script = ExtResource("5_m4art")
BaseValue = 0.1 BaseValue = 0.1
metadata/_custom_type_script = "uid://cn3b4ya15fg7e" metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
[sub_resource type="Resource" id="Resource_nsr3v"] [sub_resource type="Resource" id="Resource_nsr3v"]
script = ExtResource("1_mlifq") script = ExtResource("4_fgmkc")
BaseValue = 1 BaseValue = 1
[resource] [resource]
script = ExtResource("2_5tp50") script = ExtResource("7_xa46f")
Name = "Mana Regeneration" Name = "Mana Regeneration"
Modifiers = Array[Object]([SubResource("Resource_okenf")]) Modifiers = Array[Object]([SubResource("Resource_okenf")])
Components = [SubResource("Resource_ncjx6")] Components = [SubResource("Resource_ncjx6")]
@@ -79,5 +79,5 @@ HasPeriodicApplication = true
Period = SubResource("Resource_w35mq") Period = SubResource("Resource_w35mq")
StackLimit = SubResource("Resource_nsr3v") StackLimit = SubResource("Resource_nsr3v")
InitialStack = SubResource("Resource_pm3n3") InitialStack = SubResource("Resource_pm3n3")
Cues = Array[Object]([ExtResource("1_nsr3v")]) Cues = Array[Object]([ExtResource("3_kw6jm")])
metadata/_custom_type_script = "uid://b83hf13nj37k3" metadata/_custom_type_script = "uid://b83hf13nj37k3"

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="ForgeEffectData" format=3 uid="uid://bvidrwyuoos4g"] [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://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://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"] [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 interface ISpawnable
{ {
void Initialize(); void Init();
} }

View File

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

@@ -2,6 +2,9 @@ using Godot;
using System; using System;
using Chickensoft.AutoInject; using Chickensoft.AutoInject;
using Chickensoft.Introspection; using Chickensoft.Introspection;
using Gamesmiths.Forge.Cues;
using Gamesmiths.Forge.Godot.Core;
using Gamesmiths.Forge.Tags;
using Movementtests.interfaces;using Movementtests.managers; using Movementtests.interfaces;using Movementtests.managers;
using Movementtests.systems; using Movementtests.systems;
@@ -10,37 +13,43 @@ using Movementtests.systems;
typeof(IAutoConnect), typeof(IAutoConnect),
typeof(IProvider) typeof(IProvider)
)] )]
public partial class MainSceneTemplate : Node3D, IProvide<InventoryManager> public partial class MainSceneTemplate : Node3D, IProvide<InventoryManager>, IProvide<TagsManager>, IProvide<CuesManager>
{ {
public override void _Notification(int what) => this.Notify(what); public override void _Notification(int what) => this.Notify(what);
[Node("PlayerFellRespawn")] private Marker3D? PlayerRespawnMarker { get; set; }
private AnimationPlayer? _animationPlayer;
private Node3D? _respawnabble;
private Area3D? _playerFellPlane; #region Nodes
private Area3D? _deathPlane;
[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; } public required InventoryManager InventoryManager { get; set; }
InventoryManager IProvide<InventoryManager>.Value() => InventoryManager; InventoryManager IProvide<InventoryManager>.Value() => InventoryManager;
TagsManager IProvide<TagsManager>.Value() => ForgeManagers.Instance.TagsManager;
CuesManager IProvide<CuesManager>.Value() => ForgeManagers.Instance.CuesManager;
public void OnReady() public void OnReady()
{ {
_animationPlayer = GetNode<AnimationPlayer>("AnimationPlayer"); PlayerFellPlane.BodyEntered += StartResetPlayerAnimation;
DeathPlane.BodyEntered += KillEnemy;
_playerFellPlane = GetNode<Area3D>("PlayerFellTP");
_deathPlane = GetNode<Area3D>("DeathPlane");
if (PlayerRespawnMarker == null) throw new Exception("Player respawn marker is null");
if (_animationPlayer == null) throw new Exception("Animation player is null");
if (_playerFellPlane == null) throw new Exception("Player reset plane is null");
if (_deathPlane == null) throw new Exception("Enemy death plane is null");
_playerFellPlane.BodyEntered += StartResetPlayerAnimation;
_deathPlane.BodyEntered += KillEnemy;
InventoryManager = new InventoryManager(); InventoryManager = new InventoryManager();
if (InitialWeaponInventory != null)
InventoryManager.InitializeFromResource(InitialWeaponInventory);
AddChild(InventoryManager); AddChild(InventoryManager);
this.Provide(); this.Provide();
} }
@@ -53,8 +62,8 @@ public partial class MainSceneTemplate : Node3D, IProvide<InventoryManager>
public void ResetPlayerPosition() public void ResetPlayerPosition()
{ {
if (_respawnabble == null || PlayerRespawnMarker == null) throw new Exception("Player or respawn marker is null"); if (Respawnabble == null || PlayerRespawnMarker == null) throw new Exception("Player or respawn marker is null");
_respawnabble.GlobalPosition = PlayerRespawnMarker.GlobalPosition; Respawnabble.GlobalPosition = PlayerRespawnMarker.GlobalPosition;
} }
public void StartResetPlayerAnimation(Node3D body) public void StartResetPlayerAnimation(Node3D body)
@@ -66,23 +75,19 @@ public partial class MainSceneTemplate : Node3D, IProvide<InventoryManager>
weapon.SetLinearVelocity(Vector3.Down); weapon.SetLinearVelocity(Vector3.Down);
return; return;
} }
_respawnabble = body as PlayerController; Respawnabble = body as PlayerController;
if (_respawnabble == null || _animationPlayer == null) throw new Exception("Player or anim player is null"); if (Respawnabble == null || AnimationPlayer == null) throw new Exception("Player or anim player is null");
_animationPlayer.Play("player_fell"); AnimationPlayer.Play("player_fell");
} }
public void KillEnemy(Node3D body) public void KillEnemy(Node3D body)
{ {
if (body is not IKillable killable) if (body is not (IKillable killable and IHealthable healthable))
{
body.QueueFree();
return;
}
if (killable is not IHealthable healthable)
{ {
body.QueueFree(); body.QueueFree();
return; return;
} }
killable.Kill(healthable); killable.Kill(healthable);
} }
} }

View File

@@ -64,7 +64,7 @@ size = Vector3(5, 2.25, 3.75)
size = Vector3(5.5, 4.5, 2) size = Vector3(5.5, 4.5, 2)
[sub_resource type="BoxShape3D" id="BoxShape3D_prjj8"] [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"] [sub_resource type="BoxShape3D" id="BoxShape3D_trte5"]
size = Vector3(6.75, 8.25, 7.25) size = Vector3(6.75, 8.25, 7.25)
@@ -420,7 +420,7 @@ input_related_text = "at enemy"
tuto_text = "dash through" tuto_text = "dash through"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Tutorial/Triggers/TutoTrigger6" index="1" unique_id=1214410006] [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") shape = SubResource("BoxShape3D_prjj8")
[node name="TutoTrigger7" parent="Tutorial/Triggers" index="5" unique_id=271532103 instance=ExtResource("10_vqwwk")] [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") material = ExtResource("3_4m8g1")
[node name="CSGBox3D124" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="26" unique_id=1068505352] [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 use_collision = true
size = Vector3(3, 5, 8.5) size = Vector3(3, 4.5, 8.5)
material = ExtResource("3_4m8g1") material = ExtResource("3_4m8g1")
[node name="CSGBox3D129" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="27" unique_id=302301078] [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 use_collision = true
size = Vector3(9.5, 5, 11.75) size = Vector3(9.5, 5, 13)
material = ExtResource("3_4m8g1") material = ExtResource("3_4m8g1")
[node name="CSGBox3D133" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="28" unique_id=672467040] [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) 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] [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 omni_range = 12.0

View File

@@ -1,8 +1,10 @@
[gd_scene format=3 uid="uid://ndnor8g7kq07"] [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="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="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="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://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="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"] [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://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"] [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"] [sub_resource type="BoxShape3D" id="BoxShape3D_lthgu"]
size = Vector3(7.5, 3.75, 10.25) size = Vector3(7.5, 3.75, 10.25)
[node name="Main" unique_id=955321579 instance=ExtResource("1_k7f42")] [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")] [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") HealthInputs = ExtResource("7_ucbss")
DamageInputs = ExtResource("8_2brdd") DamageInputs = ExtResource("8_2brdd")
Target = NodePath("../Player") 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")] [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) 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") DamageInputs = ExtResource("8_2brdd")
Target = NodePath("../Player") Target = NodePath("../Player")
SpawnInterval = 5.0 SpawnInterval = 5.0
IsActiveOnStart = false
[node name="GroundedSpawner3" parent="." index="10" unique_id=241829575 node_paths=PackedStringArray("Target") instance=ExtResource("4_jaqjx")] [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) 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") DamageInputs = ExtResource("12_pjgox")
Target = NodePath("../Player") Target = NodePath("../Player")
SpawnInterval = 5.0 SpawnInterval = 5.0
IsActiveOnStart = false
[node name="FlyingSpawner2" parent="." index="12" unique_id=365997644 node_paths=PackedStringArray("Target") instance=ExtResource("4_jaqjx")] [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) 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") DamageInputs = ExtResource("12_pjgox")
Target = NodePath("../Player") Target = NodePath("../Player")
SpawnInterval = 5.0 SpawnInterval = 5.0
IsActiveOnStart = false
[node name="Targets" type="Node3D" parent="." index="13" unique_id=1620747784] [node name="Targets" type="Node3D" parent="." index="13" unique_id=1620747784]

View File

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

View File

@@ -1,7 +1,7 @@
[gd_scene format=3 uid="uid://dmv685sskgh3l"] [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="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="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"] [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"] [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="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"] [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"] [sub_resource type="AtlasTexture" id="AtlasTexture_2nvj1"]

View File

@@ -66,18 +66,14 @@ public partial class InventoryUi : Control
public void OnWeaponEventInventoryAdded(WeaponEventAbilityData data) public void OnWeaponEventInventoryAdded(WeaponEventAbilityData data)
{ {
if (data.Ability is not ForgeAbilityBehavior abilityBehavior) return;
var selection = GetAbilitySelection(data.ForEvent); var selection = GetAbilitySelection(data.ForEvent);
selection.AddSelectedAbility(abilityBehavior); selection.AddSelectedAbility(data.Ability);
} }
public void OnWeaponEventInventoryRemoved(WeaponEventAbilityData data) public void OnWeaponEventInventoryRemoved(WeaponEventAbilityData data)
{ {
if (data.Ability is not ForgeAbilityBehavior abilityBehavior) return;
var selection = GetAbilitySelection(data.ForEvent); var selection = GetAbilitySelection(data.ForEvent);
selection.RemoveSelectedAbility(abilityBehavior); selection.RemoveSelectedAbility(data.Ability);
} }
public AbilitySelection GetAbilitySelection(WeaponSystem.WeaponEvent forEvent) public AbilitySelection GetAbilitySelection(WeaponSystem.WeaponEvent forEvent)

View File

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

View File

@@ -1,14 +1,12 @@
using Godot; using Godot;
using System; 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 public partial class CHealthbar : Sprite3D
{ {
private Healthbar _healthbar; public override void _Notification(int what) => this.Notify(what);
public Healthbar Healthbar => _healthbar;
[Node("%Healthbar")] public required ResourceBar ResourceBar { get; set;}
public override void _Ready()
{
_healthbar = GetNode<Healthbar>("%Healthbar");
}
} }

View File

@@ -1,23 +1,26 @@
using System; 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.Core;
using Gamesmiths.Forge.Cues;
using Gamesmiths.Forge.Effects; using Gamesmiths.Forge.Effects;
using Gamesmiths.Forge.Events; using Gamesmiths.Forge.Events;
using Gamesmiths.Forge.Godot.Core; using Gamesmiths.Forge.Godot.Resources.Abilities;
using Gamesmiths.Forge.Godot.Nodes;
using Gamesmiths.Forge.Statescript; using Gamesmiths.Forge.Statescript;
using Gamesmiths.Forge.Tags; using Gamesmiths.Forge.Tags;
using Godot; using Godot;
using Movementtests.interfaces; using Movementtests.interfaces;
using Movementtests.scenes.enemies;
using Movementtests.scenes.player_controller.scripts;
using Movementtests.systems; using Movementtests.systems;
using Movementtests.tools; using Movementtests.tools;
using Movementtests.tools.calculators;
using Node = Godot.Node; 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, public partial class Enemy : CharacterBody3D,
IDamageable, IDamageable,
IDamageDealer,
IHealthable, IHealthable,
IKillable, IKillable,
IMoveable, IMoveable,
@@ -27,14 +30,32 @@ public partial class Enemy : CharacterBody3D,
IStunnable, IStunnable,
IForgeEntity IForgeEntity
{ {
// Signals and events public override void _Notification(int what) => this.Notify(what);
public event Action<IDamageable, DamageRecord> DamageTaken = null!;
public event Action<IHealthable, HealthChangedRecord> HealthChanged = null!; #region Dependencies
public event Action<IHealthable> HealthDepleted = null!;
[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 // Public export components
[Export] [Export]
public Node3D Target { get; set; } = null!; public Node3D? Target { get; set; }
[Export] public required ForgeAbilityData HitAbility { get; set; }
[Export] [Export]
public float EnemyHeight { get; set; } = 1f; public float EnemyHeight { get; set; } = 1f;
@@ -48,17 +69,19 @@ public partial class Enemy : CharacterBody3D,
[ExportGroup("Damage")] [ExportGroup("Damage")]
[Export] [Export]
public RDamage RDamage { get; set; } = null!; public RDamage? RDamage { get; set; }
public IDamageable CDamageable { get; set; } = null!; public IDamageable CDamageable { get; set; } = null!;
[Export] [Export]
public RKnockback RKnockback { get; set; } = null!; public RKnockback? RKnockback { get; set; }
public IKnockbackable CKnockback { get; set; } = null!; public IKnockbackable CKnockback { get; set; } = null!;
[ExportGroup("Movement")] [ExportGroup("Movement")]
[Export] [Export]
public RMovement RMovement { get; set; } = null!; public required RMovement RMovement { get; set; }
public IMoveable CMovement { get; set; } = null!; public required IMoveable CMovement { get; set; }
#endregion
// Public stuff // Public stuff
public float CurrentHealth public float CurrentHealth
@@ -66,76 +89,91 @@ public partial class Enemy : CharacterBody3D,
get => CHealth.CurrentHealth; get => CHealth.CurrentHealth;
set => CHealth.CurrentHealth = value; set => CHealth.CurrentHealth = value;
} }
#region IForgeEntity
// Perfectly forward the IForgeEntity interface to the ForgeEntity component // Perfectly forward the IForgeEntity interface to the ForgeEntity component
public EntityAttributes Attributes public EntityAttributes Attributes
{ {
get => _forgeEntity.Attributes; get => ForgeEntity.Attributes;
set => _forgeEntity.Attributes = value; set => ForgeEntity.Attributes = value;
} }
public EntityTags Tags public EntityTags Tags
{ {
get => _forgeEntity.Tags; get => ForgeEntity.Tags;
set => _forgeEntity.Tags = value; set => ForgeEntity.Tags = value;
} }
public EffectsManager EffectsManager public EffectsManager EffectsManager
{ {
get => _forgeEntity.EffectsManager; get => ForgeEntity.EffectsManager;
set => _forgeEntity.EffectsManager = value; set => ForgeEntity.EffectsManager = value;
} }
public EntityAbilities Abilities public EntityAbilities Abilities
{ {
get => _forgeEntity.Abilities; get => ForgeEntity.Abilities;
set => _forgeEntity.Abilities = value; set => ForgeEntity.Abilities = value;
} }
public EventManager Events public EventManager Events
{ {
get => _forgeEntity.Events; get => ForgeEntity.Events;
set => _forgeEntity.Events = value; set => ForgeEntity.Events = value;
} }
public Variables SharedVariables { get; } public Variables SharedVariables
// Private stuff
private Area3D _damageBox = null!;
internal Node3D _target = null!;
private Healthbar _healthbar = null!;
private ForgeEntity _forgeEntity;
public override void _Ready()
{ {
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(); SetupSignals();
} }
public void Initialize() public void Init()
{ {
_damageBox = GetNode<Area3D>("DamageBox"); CMovement = GetNode<Node>("CMovement") as IMoveable ?? throw new Exception("Movement component not found");
_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.RMovement = RMovement; 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.RHealth = RHealth;
CHealth.CurrentHealth = RHealth.StartingHealth; CHealth.CurrentHealth = RHealth.StartingHealth;
CKnockback.RKnockback = RKnockback; 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() public void SetupSignals()
{ {
// Anonymous function call to erase return values of ReduceHealth // Anonymous function call to erase return values of ReduceHealth
CDamageable.DamageTaken += (source, record) => ReduceHealth(source, record); // CDamageable.DamageTaken += (source, record) => ReduceHealth(source, record);
CDamageable.DamageTaken += (_, record) => RegisterKnockback(new KnockbackRecord(record)); // CDamageable.DamageTaken += (_, record) => RegisterKnockback(new KnockbackRecord(record));
CHealth.HealthDepleted += Kill; // CHealth.HealthDepleted += Kill;
HealthChanged += (_, record) => _healthbar.SetHealth(record.CurrentHealth);
} }
public override void _PhysicsProcess(double delta) public override void _PhysicsProcess(double delta)
@@ -160,20 +198,56 @@ public partial class Enemy : CharacterBody3D,
public void ProcessGameplay(double delta) 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) foreach (var body in bodies)
{ {
if(body is IDamageable spawnable) if (body is not IForgeEntity forgeEntity) continue;
spawnable.TakeDamage(new DamageRecord(GlobalPosition, RDamage)); var canActivate = _hitAbilityHandle.CanActivate(out var _);
if (!canActivate) return;
_hitAbilityHandle.Activate(out var _, forgeEntity);
} }
} }
public Vector3 ComputeVelocity(MovementInputs inputs) public Vector3 ComputeVelocity(MovementInputs inputs)
{ {
if (CMovement is null) return Vector3.Zero; return CMovement is null ? Vector3.Zero : CMovement.ComputeVelocity(inputs);
return 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) public DamageRecord TakeDamage(DamageRecord damageRecord)
@@ -235,7 +309,7 @@ public partial class Enemy : CharacterBody3D,
public Vector3 GetTargetGlobalPosition() public Vector3 GetTargetGlobalPosition()
{ {
return _target == null ? GlobalPosition : _target.GlobalPosition; return TargetComponent == null ? GlobalPosition : TargetComponent.GlobalPosition;
} }
// Stun management // 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://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="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://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://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="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://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://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://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="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="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://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="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="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"] [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"] [sub_resource type="Resource" id="Resource_wxisp"]
script = ExtResource("8_46wn3") script = ExtResource("8_46wn3")
Default = 2 Default = 2
@@ -39,7 +30,7 @@ Default = 1
Min = 1 Min = 1
Max = 100 Max = 100
[sub_resource type="ViewportTexture" id="ViewportTexture_hf6k8"] [sub_resource type="ViewportTexture" id="ViewportTexture_46wn3"]
viewport_path = NodePath("SubViewport") viewport_path = NodePath("SubViewport")
[sub_resource type="Resource" id="Resource_jnv07"] [sub_resource type="Resource" id="Resource_jnv07"]
@@ -81,6 +72,7 @@ collision_layer = 16
collision_mask = 273 collision_mask = 273
motion_mode = 1 motion_mode = 1
script = ExtResource("1_q8l7o") script = ExtResource("1_q8l7o")
HitAbility = ExtResource("2_46wn3")
EnemyHeight = 0.5 EnemyHeight = 0.5
RHealth = ExtResource("2_ma2bq") RHealth = ExtResource("2_ma2bq")
DeathEffects = Array[Object]([]) DeathEffects = Array[Object]([])
@@ -88,16 +80,35 @@ RDamage = ExtResource("2_on7rt")
RKnockback = ExtResource("11_mpa2u") RKnockback = ExtResource("11_mpa2u")
RMovement = ExtResource("4_dejyg") RMovement = ExtResource("4_dejyg")
[node name="ForgeEntity" type="Node" parent="." unique_id=622209781] [node name="ForgeEntityNode" type="Node3D" parent="." unique_id=1255429192]
script = ExtResource("6_wxisp") script = ExtResource("7_46wn3")
BaseTags = SubResource("Resource_vfi88") BaseTags = ExtResource("8_oj1ws")
metadata/_custom_type_script = "uid://8uj04dfe8oql" 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") script = ExtResource("7_2digf")
AttributeSetClass = "EnemyAttributeSet" AttributeSetClass = "EnemyAttributeSet"
InitialAttributeValues = Dictionary[String, ExtResource("8_46wn3")]({ 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"), "Speed": SubResource("Resource_wxisp"),
"Strength": SubResource("Resource_yk4hc") "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")] [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) 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] [node name="CDamageable" type="Node" parent="." unique_id=1785297232]
script = ExtResource("8_uotso") 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="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://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="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://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="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="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="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="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="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="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"] [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"] [sub_resource type="Resource" id="Resource_x50ya"]
script = ExtResource("7_x50ya") script = ExtResource("7_x50ya")
Default = 1 Default = 1
@@ -39,7 +30,7 @@ Default = 1
Min = 1 Min = 1
Max = 100 Max = 100
[sub_resource type="ViewportTexture" id="ViewportTexture_ub34u"] [sub_resource type="ViewportTexture" id="ViewportTexture_4jf2q"]
viewport_path = NodePath("SubViewport") viewport_path = NodePath("SubViewport")
[sub_resource type="Resource" id="Resource_qj0ob"] [sub_resource type="Resource" id="Resource_qj0ob"]
@@ -81,6 +72,7 @@ radius = 2.0
collision_layer = 16 collision_layer = 16
collision_mask = 273 collision_mask = 273
script = ExtResource("1_r6506") script = ExtResource("1_r6506")
HitAbility = ExtResource("6_4jf2q")
EnemyHeight = 2.0 EnemyHeight = 2.0
RHealth = ExtResource("2_w4lm8") RHealth = ExtResource("2_w4lm8")
DeathEffects = Array[Object]([]) DeathEffects = Array[Object]([])
@@ -88,16 +80,35 @@ RDamage = ExtResource("2_bn56u")
RKnockback = ExtResource("11_8k3xb") RKnockback = ExtResource("11_8k3xb")
RMovement = ExtResource("4_na24f") RMovement = ExtResource("4_na24f")
[node name="ForgeEntity" type="Node" parent="." unique_id=432521027] [node name="ForgeEntityNode" type="Node3D" parent="." unique_id=289553407]
script = ExtResource("6_x50ya") script = ExtResource("7_f22p3")
BaseTags = SubResource("Resource_4jf2q") BaseTags = ExtResource("8_4jf2q")
metadata/_custom_type_script = "uid://8uj04dfe8oql" 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") script = ExtResource("6_yk4hc")
AttributeSetClass = "EnemyAttributeSet" AttributeSetClass = "EnemyAttributeSet"
InitialAttributeValues = Dictionary[String, ExtResource("7_x50ya")]({ 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"), "Speed": SubResource("Resource_x50ya"),
"Strength": SubResource("Resource_yk4hc") "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")] [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) 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] [node name="CDamageable" type="Node" parent="." unique_id=1601518000]
script = ExtResource("7_1tw73") 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="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="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="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://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://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="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="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://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="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://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://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="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="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"] [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="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="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://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="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://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"] [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="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="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="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"] [sub_resource type="Resource" id="Resource_mpigw"]
script = ExtResource("2_u8yay") script = ExtResource("2_u8yay")
ContainerTags = Array[String](["character.player"]) ContainerTags = Array[String](["character.player", "traits.damageable"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0" metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[sub_resource type="Resource" id="Resource_5gbhg"] [sub_resource type="Resource" id="Resource_5gbhg"]
@@ -70,6 +70,11 @@ script = ExtResource("11_u8yay")
Tag = "events.player.empowered_action_used" Tag = "events.player.empowered_action_used"
metadata/_custom_type_script = "uid://dpakv7agvir6y" 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"] [sub_resource type="Resource" id="Resource_cb2lu"]
script = ExtResource("2_x835q") script = ExtResource("2_x835q")
DamageDealt = 10.0 DamageDealt = 10.0
@@ -80,11 +85,6 @@ script = ExtResource("3_cb2lu")
Modifier = 5.0 Modifier = 5.0
metadata/_custom_type_script = "uid://b44cse62qru7j" 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"] [sub_resource type="Resource" id="Resource_u8yay"]
script = ExtResource("11_2rkt1") script = ExtResource("11_2rkt1")
Default = 100 Default = 100
@@ -132,6 +132,9 @@ height = 1.0
[sub_resource type="SphereShape3D" id="SphereShape3D_abfq8"] [sub_resource type="SphereShape3D" id="SphereShape3D_abfq8"]
radius = 2.0 radius = 2.0
[sub_resource type="SphereShape3D" id="SphereShape3D_ue7xq"]
radius = 1.5
[sub_resource type="SphereShape3D" id="SphereShape3D_cmijs"] [sub_resource type="SphereShape3D" id="SphereShape3D_cmijs"]
radius = 1.0 radius = 1.0
@@ -142,9 +145,6 @@ height = 3.5
[sub_resource type="SphereShape3D" id="SphereShape3D_nob5r"] [sub_resource type="SphereShape3D" id="SphereShape3D_nob5r"]
radius = 0.4 radius = 0.4
[sub_resource type="SphereShape3D" id="SphereShape3D_ue7xq"]
radius = 1.5
[sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_2q0ik"] [sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_2q0ik"]
blend_mode = 1 blend_mode = 1
@@ -156,8 +156,10 @@ collision_mask = 272
script = ExtResource("1_poq2x") script = ExtResource("1_poq2x")
BaseTags = SubResource("Resource_mpigw") BaseTags = SubResource("Resource_mpigw")
EmpoweredActionUsed = SubResource("Resource_5gbhg") EmpoweredActionUsed = SubResource("Resource_5gbhg")
InvincibleTag = SubResource("Resource_2rkt1")
HitAbility = ExtResource("4_u8yay")
EmpoweredActionAbility = ExtResource("10_2rkt1") EmpoweredActionAbility = ExtResource("10_2rkt1")
WeaponExplosionBehavior = ExtResource("5_u8yay") DefaultGrantedAbilities = [ExtResource("5_u8yay")]
DefaultPermanentEffects = [ExtResource("5_2rkt1")] DefaultPermanentEffects = [ExtResource("5_2rkt1")]
EmpoweredActionEffects = [ExtResource("6_u8yay")] EmpoweredActionEffects = [ExtResource("6_u8yay")]
AimAssistStrength = 0.3 AimAssistStrength = 0.3
@@ -165,7 +167,6 @@ AimAssistReductionWhenCloseToTarget = 0.1
AimAssistReductionStartDistance = 8.0 AimAssistReductionStartDistance = 8.0
RDamage = SubResource("Resource_cb2lu") RDamage = SubResource("Resource_cb2lu")
RKnockback = SubResource("Resource_abfq8") RKnockback = SubResource("Resource_abfq8")
RHealth = SubResource("Resource_ue7xq")
TargetingDistance = 5.0 TargetingDistance = 5.0
Explosion = ExtResource("5_ue7xq") Explosion = ExtResource("5_ue7xq")
WalkSpeed = 7.5 WalkSpeed = 7.5
@@ -223,6 +224,24 @@ InitialAttributeValues = Dictionary[String, ExtResource("11_2rkt1")]({
}) })
metadata/_custom_type_script = "uid://cxihb42t2mfqi" 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")] [node name="CHealth" parent="." unique_id=1244478698 instance=ExtResource("3_q7bng")]
RHealth = ExtResource("4_m8gvy") RHealth = ExtResource("4_m8gvy")
@@ -237,12 +256,6 @@ stream = ExtResource("9_jb43f")
autoplay = true autoplay = true
bus = &"SFX" 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] [node name="InputController" type="Node3D" parent="." unique_id=846069741]
script = ExtResource("16_v31n3") script = ExtResource("16_v31n3")
base_mode = ExtResource("3_cresl") base_mode = ExtResource("3_cresl")
@@ -413,6 +426,16 @@ target_position = Vector3(0, 0, 0)
max_results = 512 max_results = 512
collision_mask = 16 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] [node name="CloseEnemyDetector" type="ShapeCast3D" parent="." unique_id=2109861596]
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0) 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 collision_mask = 112
collide_with_areas = true 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] [node name="GroundDetector" type="ShapeCast3D" parent="." unique_id=1681055424]
shape = SubResource("CapsuleShape3D_6lejt") shape = SubResource("CapsuleShape3D_6lejt")
collision_mask = 256 collision_mask = 256
@@ -437,20 +464,6 @@ shape = SubResource("SphereShape3D_nob5r")
target_position = Vector3(0, 0.4, 0) target_position = Vector3(0, 0.4, 0)
collision_mask = 256 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] [node name="InvincibilityTime" type="Timer" parent="." unique_id=1244463585]
one_shot = true one_shot = true

View File

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

View File

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

View File

@@ -1,8 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Gamesmiths.Forge.Abilities; using Gamesmiths.Forge.Abilities;
using Gamesmiths.Forge.Attributes; using Gamesmiths.Forge.Attributes;
using Gamesmiths.Forge.Core; using Gamesmiths.Forge.Core;
using Gamesmiths.Forge.Cues;
using Gamesmiths.Forge.Effects; using Gamesmiths.Forge.Effects;
using Gamesmiths.Forge.Effects.Calculator; using Gamesmiths.Forge.Effects.Calculator;
using Gamesmiths.Forge.Effects.Components; using Gamesmiths.Forge.Effects.Components;
@@ -19,68 +22,53 @@ using Gamesmiths.Forge.Tags;
using Godot; using Godot;
using GodotStateCharts; using GodotStateCharts;
using Movementtests.addons.godot_state_charts.csharp; using Movementtests.addons.godot_state_charts.csharp;
using Movementtests.forge.abilities;
using Movementtests.interfaces; using Movementtests.interfaces;
using Movementtests.scenes.player_controller.components.weapon;
using Movementtests.systems.damage;
using Movementtests.tools; using Movementtests.tools;
using Movementtests.tools.calculators;
using Node = Godot.Node; using Node = Godot.Node;
namespace Movementtests.systems; 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 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] [Signal]
public delegate void WeaponThrownEventHandler(); public delegate void WeaponThrownEventHandler();
[Signal] [Signal]
public delegate void WeaponRetrievedEventHandler(); 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!; #endregion
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!;
private ShapeCast3D _dashCast3D = null!; #region Forge
public Timer WeaponFlyingTick = null!;
private Transform3D _startTransform;
private Vector3 _startMeshRotation;
private Vector3 _throwDirection; private Dictionary<ForgeAbilityBehavior, ActiveEffectHandle> _grantedWeaponStartedFlyingAbilities = new ();
public Vector3 PlantLocation { get; set; } private Dictionary<ForgeAbilityBehavior, ActiveEffectHandle> _grantedWeaponStoppedFlyingAbilities = new ();
public Vector3 PlantNormal { get; set; } private Dictionary<ForgeAbilityBehavior, ActiveEffectHandle> _grantedWeaponFlyingTickAbilities = new ();
public Node? PlantObject { get; set; }
public MeshInstance3D WeaponLocationIndicator { get; set; } = null!;
public StandardMaterial3D WeaponLocationIndicatorMaterial { get; set; } = null!;
public MeshInstance3D WeaponMesh { get; set; } = null!;
public Tag WeaponFlyingTickEventTag; public Tag WeaponFlyingTickEventTag;
public Tag WeaponStartedFlyingEventTag; public Tag WeaponStartedFlyingEventTag;
@@ -99,8 +87,96 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
private AbilityHandle? _weaponFlyingAbility; 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")); _weaponState = StateChart.Of(GetNode("StateChart"));
InHandState = StateChartState.Of(GetNode("StateChart/Root/InHand")); InHandState = StateChartState.Of(GetNode("StateChart/Root/InHand"));
FlyingState = StateChartState.Of(GetNode("StateChart/Root/Flying")); 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")); _plantedToHand = Transition.Of(GetNode("StateChart/Root/Planted/ToHand"));
_plantedToFlying = Transition.Of(GetNode("StateChart/Root/Planted/ToFlying")); _plantedToFlying = Transition.Of(GetNode("StateChart/Root/Planted/ToFlying"));
_toPlanted = Transition.Of(GetNode("StateChart/Root/ToPlanted")); _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; _startMeshRotation = WeaponMesh.Rotation;
_startTransform = Transform; _startTransform = Transform;
Freeze = true; Freeze = true;
Visible = false; Visible = false;
WeaponLocationIndicator.Visible = false;
WeaponLocationIndicatorMaterial = (WeaponLocationIndicator.GetActiveMaterial(0) as StandardMaterial3D)!;
}
public void OnResolved()
{
// Forge // Forge
var tagsManager = ForgeManagers.Instance.TagsManager; WeaponFlyingTickEventTag = Tag.RequestTag(TagsManager, "events.weapon.flyingTick");
var cuesManager = ForgeManagers.Instance.CuesManager; 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"); // WeaponInHandStatusTag = Tag.RequestTag(TagsManager, "status.weapon.inHand");
WeaponStartedFlyingEventTag = Tag.RequestTag(tagsManager, "events.weapon.startedFlying"); // WeaponFlyingStatusTag = Tag.RequestTag(TagsManager, "status.weapon.flying");
WeaponStoppedFlyingEventTag = Tag.RequestTag(tagsManager, "events.weapon.stoppedFlying"); // WeaponPlantedStatusTag = Tag.RequestTag(TagsManager, "status.weapon.planted");
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"); // Manage weapon flying tick raising ability
// WeaponFlyingStatusTag = Tag.RequestTag(tagsManager, "status.weapon.flying"); WeaponFlyingAbilityTag = Tag.RequestTag(TagsManager,"abilities.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
_weaponFlyingAbility = Abilities.GrantAbilityPermanently(FlyingTickAbility.GetAbilityData(), 1, LevelComparison.None, this); _weaponFlyingAbility = Abilities.GrantAbilityPermanently(FlyingTickAbility.GetAbilityData(), 1, LevelComparison.None, this);
Events.Subscribe(WeaponStoppedFlyingEventTag, _ => { _weaponFlyingAbility.Cancel(); });
BodyEntered += OnThrownWeaponReachesGround; BodyEntered += OnThrownWeaponReachesGround;
InHandState.StateExited += WeaponLeft; InHandState.StateExited += WeaponLeft;
InHandState.StateEntered += WeaponBack; InHandState.StateEntered += WeaponBack;
#region EventRaising
_handToFlying.Taken += () => _handToFlying.Taken += () =>
{ {
Events.Raise(new EventData 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) public void GrantNewAbilityForEvent(WeaponEvent forEvent, ForgeAbilityBehavior abilityBehavior)
{ {
var relevantMap = GetGrantedAbilities(forEvent); var relevantMap = GetGrantedAbilities(forEvent);
GD.Print($"Granted {abilityBehavior} for {forEvent}");
if (relevantMap.ContainsKey(abilityBehavior)) return; if (relevantMap.ContainsKey(abilityBehavior)) return;
var eventTagsMap = new Dictionary<WeaponEvent, Tag> var eventTagsMap = new Dictionary<WeaponEvent, Tag>
@@ -296,6 +339,19 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
relevantMap.Remove(abilityBehavior); 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) public Dictionary<ForgeAbilityBehavior, ActiveEffectHandle> GetGrantedAbilities(WeaponEvent forEvent)
{ {
var abilitiesMap = new Dictionary<WeaponEvent, Dictionary<ForgeAbilityBehavior, ActiveEffectHandle>> 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) public override void _Process(double delta)
{ {
Abilities.UpdateAbilities(delta);
EffectsManager.UpdateEffects(delta); EffectsManager.UpdateEffects(delta);
if (!FlyingState.Active) return; 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://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="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="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://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://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://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"] [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 DamageDealt = 2.0
metadata/_custom_type_script = "uid://jitubgv6judn" 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"] [sub_resource type="Resource" id="Resource_pgbtr"]
script = ExtResource("4_q6xv7") script = ExtResource("4_q6xv7")
Default = 1 Default = 1
@@ -67,7 +73,12 @@ BaseTags = SubResource("Resource_06gln")
FlyingTickAbility = ExtResource("4_7bruw") FlyingTickAbility = ExtResource("4_7bruw")
RDamage = SubResource("Resource_jpdh0") 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") script = ExtResource("3_3xjpi")
AttributeSetClass = "WeaponAttributeSet" AttributeSetClass = "WeaponAttributeSet"
InitialAttributeValues = Dictionary[String, ExtResource("4_q6xv7")]({ 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"

View File

@@ -5,13 +5,10 @@ using Chickensoft.Introspection;
using Gamesmiths.Forge.Abilities; using Gamesmiths.Forge.Abilities;
using Gamesmiths.Forge.Attributes; using Gamesmiths.Forge.Attributes;
using Gamesmiths.Forge.Core; using Gamesmiths.Forge.Core;
using Gamesmiths.Forge.Cues;
using Gamesmiths.Forge.Effects; using Gamesmiths.Forge.Effects;
using Gamesmiths.Forge.Effects.Calculator;
using Gamesmiths.Forge.Effects.Components; using Gamesmiths.Forge.Effects.Components;
using Gamesmiths.Forge.Effects.Duration; using Gamesmiths.Forge.Effects.Duration;
using Gamesmiths.Forge.Effects.Magnitudes;
using Gamesmiths.Forge.Effects.Modifiers;
using Gamesmiths.Forge.Effects.Periodic;
using Gamesmiths.Forge.Events; using Gamesmiths.Forge.Events;
using Gamesmiths.Forge.Godot.Core; using Gamesmiths.Forge.Godot.Core;
using Gamesmiths.Forge.Godot.Nodes; using Gamesmiths.Forge.Godot.Nodes;
@@ -27,10 +24,8 @@ using Movementtests.addons.godot_state_charts.csharp;
using Movementtests.interfaces; using Movementtests.interfaces;
using Movementtests.systems; using Movementtests.systems;
using Movementtests.player_controller.Scripts; using Movementtests.player_controller.Scripts;
using Movementtests.scenes.player_controller.scripts;
using Movementtests.tools;
using Movementtests.forge.abilities;
using Movementtests.managers; using Movementtests.managers;
using Movementtests.tools;
using Movementtests.tools.calculators; using Movementtests.tools.calculators;
using RustyOptions; using RustyOptions;
using Node = Godot.Node; using Node = Godot.Node;
@@ -39,28 +34,21 @@ public record struct EmpoweredActionPayload;
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_character.png"), Meta(typeof(IAutoNode))] [GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_character.png"), Meta(typeof(IAutoNode))]
public partial class PlayerController : CharacterBody3D, public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandler
IDamageable,
IDamageDealer,
IHealthable,
IKnockbackable,
IForgeEntity
{ {
public override void _Notification(int what) => this.Notify(what); public override void _Notification(int what) => this.Notify(what);
#region Dependencies
[Dependency] [Dependency]
public InventoryManager InventoryManager => this.DependOn<InventoryManager>(); public InventoryManager InventoryManager => this.DependOn<InventoryManager>();
[Dependency]
// Enums public TagsManager TagsManager => this.DependOn<TagsManager>();
public enum AllowedInputs [Dependency]
{ public CuesManager CuesManager => this.DependOn<CuesManager>();
All, #endregion
MoveCamera,
None, #region Utils
}
private bool _isUsingGamepad;
public AllowedInputs CurrentlyAllowedInputs { get; set; } = AllowedInputs.All;
public enum BufferedActions public enum BufferedActions
{ {
None, None,
@@ -69,69 +57,80 @@ public partial class PlayerController : CharacterBody3D,
Dash, Dash,
MantleDash MantleDash
} }
private BufferedActions _bufferedAction = BufferedActions.None;
#endregion
///////////////////////////
// Signals and events // #region Forge
///////////////////////////
private AbilityHandle? _empoweredActionHandle;
private AbilityHandle? _hitAbilityHandle;
public required EntityAttribute HealthAttribute { get; set; }
public required EntityAttribute ManaAttribute { get; set; }
#endregion
#region Signals
[Signal] [Signal]
public delegate void PlayerDiedEventHandler(); public delegate void PlayerDiedEventHandler();
public event Action<IDamageable, DamageRecord> DamageTaken = null!; public event Action<IDamageable, DamageRecord> DamageTaken = null!;
public event Action<IHealthable, HealthChangedRecord> HealthChanged = null!; public event Action<IHealthable, HealthChangedRecord> HealthChanged = null!;
public event Action<IHealthable> HealthDepleted = null!; public event Action<IHealthable> HealthDepleted = null!;
///////////////////////////
// Public stuff //
///////////////////////////
public HeadSystem HeadSystem = null!;
public StairsSystem StairsSystem = null!;
public MantleSystem MantleSystem = null!;
public DashSystem DashSystem = null!;
public CollisionShape3D StandingCollider = null!;
public CollisionShape3D SlideCollider = null!;
public WeaponSystem WeaponSystem = null!;
public WallHugSystem WallHugSystem = null!;
public PlayerUi PlayerUi = null!;
public Node3D DashIndicatorNode = null!;
public MeshInstance3D DashIndicatorMesh = null!;
public CylinderMesh DashIndicatorMeshCylinder = null!;
public RayCast3D WallRunSnapper = null!;
public ShapeCast3D GroundDetector = null!;
public ShapeCast3D CeilingDetector = null!;
public RayCast3D DirectGroundDetector = null!;
public Area3D WeaponHitbox = null!;
public AudioStreamPlayer3D SfxPlayer = null!;
public ShapeCast3D DashDamageDetector = null!;
public Area3D SlidingEnemyDetector = null!;
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; }
// Inspector stuff #endregion
#region Nodes
[Node("HeadSystem")] public required HeadSystem HeadSystem { get; set; }
[Node("StairsSystem")] public required StairsSystem StairsSystem { get; set; }
[Node("HeadSystem/MantleSystem")] public required MantleSystem MantleSystem { get; set; }
[Node("DashSystem")] public required DashSystem DashSystem { get; set; }
[Node("StandingCollider")] public required CollisionShape3D StandingCollider { get; set; }
[Node("SlideCollider")] public required CollisionShape3D SlideCollider { get; set; }
[Node("WeaponSystem")] public required WeaponSystem WeaponSystem { get; set; }
[Node("WallHugSystem")] public required WallHugSystem WallHugSystem { get; set; }
[Node("UI")] public required PlayerUi PlayerUi { get; set; }
[Node("GroundDetector")] public required ShapeCast3D GroundDetector { get; set; }
[Node("CeilingDetector")] public required ShapeCast3D CeilingDetector { get; set; }
[Node("DirectGroundDetector")] public required RayCast3D DirectGroundDetector { get; set; }
[Node("%WeaponHitbox")] public required Area3D WeaponHitbox { get; set; }
[Node("SFXPlayer")] public required AudioStreamPlayer3D SfxPlayer { get; set; }
[Node("DashDamage")] public required ShapeCast3D DashDamageDetector { get; set; }
[Node("SlidingEnemyDetector")] public required Area3D SlidingEnemyDetector { get; set; }
[Node("%CloseEnemyDetector")] public required ShapeCast3D CloseEnemyDetector { get; set; }
[Node("AimAssistRayCast")] public required RayCast3D AimAssistRayCast { get; set; }
[Node("HeadSystem/CameraSmooth/Camera3D")] public required Camera3D Camera { get; set; }
#endregion
#region Publics
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; }
#endregion
#region Inspector
[Export] public bool HasSword { get; set; } = true; [Export] public bool HasSword { get; set; } = true;
[Export] public bool HasParry { get; set; } = true; [Export] public bool HasParry { get; set; } = true;
// Forge stuff // Forge stuff
[ExportCategory("Forge")] [ExportCategory("Forge")]
[ExportGroup("General")] [ExportGroup("General")]
[Export] [Export] public required ForgeTagContainer BaseTags { get; set; }
public ForgeTagContainer BaseTags { get; set; } [Export] public required ForgeTag EmpoweredActionUsed { get; set; }
[Export] public ForgeTag EmpoweredActionUsed; [Export] public required ForgeTag InvincibleTag { get; set; }
[ExportGroup("Abilities")] [ExportGroup("Abilities")]
[ExportSubgroup("Common and defaults")] [ExportSubgroup("Common and defaults")]
[Export] public ForgeAbilityData EmpoweredActionAbility = null!; [Export] public required ForgeAbilityData HitAbility { get; set; }
[Export] public ForgeAbilityData[] DefaultPermanentAbilities = []; [Export] public required ForgeAbilityData EmpoweredActionAbility { get; set; }
[Export] public ForgeAbilityData[] DefaultGrantedAbilities = [];
[ExportSubgroup("WeaponThrow")] [Export]
public ForgeAbilityBehavior WeaponExplosionBehavior;
[ExportGroup("Effects")] [ExportGroup("Effects")]
[ExportSubgroup("Common and defaults")] [ExportSubgroup("Common and defaults")]
@@ -151,7 +150,6 @@ public partial class PlayerController : CharacterBody3D,
[ExportGroup("Damage")] [Export] public RDamage RDamage { get; set; } = null!; [ExportGroup("Damage")] [Export] public RDamage RDamage { get; set; } = null!;
[Export] public RKnockback? RKnockback { get; set; } = null!; [Export] public RKnockback? RKnockback { get; set; } = null!;
[Export] public RHealth? RHealth { get; set; } = null!;
[ExportGroup("Targeting")] [ExportGroup("Targeting")]
[Export(PropertyHint.Range, "0,20,0.1,or_greater")] [Export(PropertyHint.Range, "0,20,0.1,or_greater")]
@@ -306,10 +304,10 @@ public partial class PlayerController : CharacterBody3D,
public float WallRunAltitudeLossSpeed { get; set; } = 10f; public float WallRunAltitudeLossSpeed { get; set; } = 10f;
[Export(PropertyHint.Range, "0,20,0.1,or_greater")] [Export(PropertyHint.Range, "0,20,0.1,or_greater")]
public float WallRunSpeedThreshold { get; set; } = 8f; public float WallRunSpeedThreshold { get; set; } = 8f;
#endregion
#region Privates
///////////////////////////
// Private stuff //
///////////////////////////
// Stairs and shit // Stairs and shit
private float _lastFrameWasOnFloor = -Mathf.Inf; private float _lastFrameWasOnFloor = -Mathf.Inf;
private const int NumOfHeadCollisionDetectors = 4; private const int NumOfHeadCollisionDetectors = 4;
@@ -317,7 +315,8 @@ public partial class PlayerController : CharacterBody3D,
private AudioStreamPlaybackInteractive _audioStream = null!; private AudioStreamPlaybackInteractive _audioStream = null!;
// Basic movement // Basic movement
private bool _movementEnabled = true; private bool _isUsingGamepad;
private BufferedActions _bufferedAction = BufferedActions.None;
private Vector3 _inputMove = Vector3.Zero; private Vector3 _inputMove = Vector3.Zero;
private Vector3 _inputMoveKeyboard = Vector3.Zero; private Vector3 _inputMoveKeyboard = Vector3.Zero;
private float _inputRotateY; private float _inputRotateY;
@@ -412,124 +411,74 @@ public partial class PlayerController : CharacterBody3D,
private Transition _onGroundSlideJump = null!; private Transition _onGroundSlideJump = null!;
private Transition _onAirGlideDoubleJump = null!; private Transition _onAirGlideDoubleJump = null!;
// Damage #endregion
public CDamageable? CDamageable { get; set; }
public CHealth? CHealth { get; set; }
public CKnockback? CKnockback { get; set; }
public float CurrentHealth { get; set; }
private bool _isInvincible; #region DamageManagement
public bool IsInvincibleOverride { get; set; }
// Invincibility
private ActiveEffectHandle? _invincibleEffect;
public bool IsInvincible public bool IsInvincible
{ {
get => _isInvincible || IsInvincibleOverride; get => Tags.CombinedTags.HasTag(InvincibleTag.GetTag());
set => _isInvincible = value; set => SetInvincible(value);
} }
public void SetInvincible(bool invincible)
private readonly List<IDamageable> _hitEnemies = new List<IDamageable>(); {
if (invincible && !IsInvincible)
{
var invincibility = new EffectData(
"Invincibility",
new DurationData(DurationType.Infinite),
effectComponents:
[
new ModifierTagsEffectComponent(
InvincibleTag.GetTag().GetSingleTagContainer()!
)
]);
_invincibleEffect = EffectsManager.ApplyEffect(new Effect(invincibility,
new EffectOwnership(this, this)));
return;
}
if (_invincibleEffect == null) return;
EffectsManager.RemoveEffect(_invincibleEffect);
_invincibleEffect = null;
}
// Damage dealing
private readonly List<IForgeEntity> _hitEnemies = [];
#endregion
private ShapeCast3D _closeEnemyDetector = null!;
private RayCast3D _aimAssisRayCast = null!;
private Camera3D _camera = null!;
private AbilityHandle? _empoweredActionHandle;
public void OnReady() public void OnReady()
{ {
LoadSettings(); LoadSettings();
///////////////////////////
// Getting components /////
///////////////////////////
// General use stuff // General use stuff
PlayerUi = GetNode<PlayerUi>("UI"); Attributes = new EntityAttributes([.. ForgeUtils.CollectAttributeList(this)]);
_closeEnemyDetector = GetNode<ShapeCast3D>("%CloseEnemyDetector"); HealthAttribute = Attributes["CharacterAttributeSet.Health"];
_closeEnemyDetector.TargetPosition = _closeEnemyDetector.TargetPosition.Normalized() * TargetingDistance; ManaAttribute = Attributes["PlayerAttributeSet.Mana"];
_aimAssisRayCast = GetNode<RayCast3D>("AimAssistRayCast");
_aimAssisRayCast.TargetPosition = _aimAssisRayCast.TargetPosition.Normalized() * (TargetingDistance*1.5f);
// Forge stuff
var tagsManager = ForgeManagers.Instance.TagsManager;
var cuesManager = ForgeManagers.Instance.CuesManager;
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()); Tags = new(BaseTags.GetTagContainer());
EffectsManager = new EffectsManager(this, cuesManager);
Abilities = new(this); Abilities = new(this);
Events = new(); Events = new();
PlayerUi.Init(HealthAttribute, ManaAttribute);
CloseEnemyDetector.TargetPosition = CloseEnemyDetector.TargetPosition.Normalized() * TargetingDistance;
AimAssistRayCast.TargetPosition = AimAssistRayCast.TargetPosition.Normalized() * (TargetingDistance*1.5f);
_empoweredActionHandle = Abilities.GrantAbilityPermanently(
EmpoweredActionAbility.GetAbilityData(),
abilityLevel: 1,
levelOverridePolicy: LevelComparison.None,
sourceEntity: this);
foreach (var ability in DefaultPermanentAbilities)
{
Abilities.GrantAbilityPermanently(
ability.GetAbilityData(),
abilityLevel: 1,
levelOverridePolicy: LevelComparison.None,
sourceEntity: this);
}
// Apply all default effects
foreach (var effect in DefaultPermanentEffects)
{
EffectsManager.ApplyEffect(new Effect(effect.GetEffectData(), new EffectOwnership(this, this)));
}
// Subscribe default empowered actions effects to the Empowered Action Used event
foreach (var effect in EmpoweredActionEffects)
{
Events.Subscribe<EmpoweredActionPayload>(EmpoweredActionUsed.GetTag(), data =>
{
EffectsManager.ApplyEffect(new Effect(effect.GetEffectData(), new EffectOwnership(this, this)));
});
}
// DashIndicator = GetNode<TextureRect>("%DashIndicator"); // DashIndicator = GetNode<TextureRect>("%DashIndicator");
TargetSpeed = WalkSpeed; TargetSpeed = WalkSpeed;
DashIndicatorNode = GetNode<Node3D>("DashIndicator");
DashIndicatorMesh = GetNode<MeshInstance3D>("DashIndicator/DashIndicatorMesh");
DashIndicatorMeshCylinder = (DashIndicatorMesh.Mesh as CylinderMesh)!;
DashIndicatorMesh.Visible = false;
SfxPlayer = GetNode<AudioStreamPlayer3D>("SFXPlayer");
_audioStream = (SfxPlayer.GetStreamPlayback() as AudioStreamPlaybackInteractive)!; _audioStream = (SfxPlayer.GetStreamPlayback() as AudioStreamPlaybackInteractive)!;
// Camera stuff // Camera stuff
HeadSystem = GetNode<HeadSystem>("HeadSystem");
_camera = GetNode<Camera3D>("HeadSystem/CameraSmooth/Camera3D");
Node3D cameraSmooth = GetNode<Node3D>("HeadSystem/CameraSmooth"); Node3D cameraSmooth = GetNode<Node3D>("HeadSystem/CameraSmooth");
// Movement stuff // Movement stuff
WeaponSystem = GetNode<WeaponSystem>("WeaponSystem");
MantleSystem = GetNode<MantleSystem>("HeadSystem/MantleSystem");
StandingCollider = GetNode<CollisionShape3D>("StandingCollider");
SlideCollider = GetNode<CollisionShape3D>("SlideCollider");
DashSystem = GetNode<DashSystem>("DashSystem");
StairsSystem = GetNode<StairsSystem>("StairsSystem");
WallHugSystem = GetNode<WallHugSystem>("WallHugSystem");
WallRunSnapper = GetNode<RayCast3D>("%WallRunSnapper");
GroundDetector = GetNode<ShapeCast3D>("GroundDetector");
CeilingDetector = GetNode<ShapeCast3D>("CeilingDetector");
DirectGroundDetector = GetNode<RayCast3D>("DirectGroundDetector");
DashDamageDetector = GetNode<ShapeCast3D>("DashDamage");
SlidingEnemyDetector = GetNode<Area3D>("SlidingEnemyDetector");
RayCast3D stairsBelowRayCast3D = GetNode<RayCast3D>("StairsBelowRayCast3D"); RayCast3D stairsBelowRayCast3D = GetNode<RayCast3D>("StairsBelowRayCast3D");
RayCast3D stairsAheadRayCast3D = GetNode<RayCast3D>("StairsAheadRayCast3D"); RayCast3D stairsAheadRayCast3D = GetNode<RayCast3D>("StairsAheadRayCast3D");
_headCollisionDetectors = new RayCast3D[NumOfHeadCollisionDetectors]; _headCollisionDetectors = new RayCast3D[NumOfHeadCollisionDetectors];
@@ -544,31 +493,23 @@ public partial class PlayerController : CharacterBody3D,
_playerRadius = playerShape.Radius; _playerRadius = playerShape.Radius;
// Combat stuff // Combat stuff
WeaponHitbox = GetNode<Area3D>("%WeaponHitbox");
WeaponHitbox.Monitoring = false; WeaponHitbox.Monitoring = false;
WeaponHitbox.BodyEntered += RegisterHitEnnemy; WeaponHitbox.BodyEntered += RegisterHitEnnemy;
CHealth = GetNode<Node>("CHealth") as CHealth; // if (RHealth != null)
CKnockback = GetNode<Node>("CKnockback") as CKnockback; // {
CDamageable = GetNode<Node>("CDamageable") as CDamageable; // CHealth.RHealth = RHealth;
if (CHealth == null) throw new Exception("CHealth not found!"); // CHealth.CurrentHealth = RHealth.StartingHealth;
if (CKnockback == null) throw new Exception("CKnockback not found!"); // }
if (CDamageable == null) throw new Exception("CDamageable not found!"); // if (RKnockback != null) CKnockback!.RKnockback = RKnockback;
//
// CDamageable.DamageTaken += (damageable, record) => ReduceHealth(damageable, record);
// CDamageable.DamageTaken += (_, record) => RegisterKnockback(new KnockbackRecord(record));
// CHealth.HealthChanged += PlayerUi.OnHealthChanged;
// CHealth.HealthDepleted += (_) => Kill();
if (RHealth != null) #region StateManagement
{
CHealth.RHealth = RHealth;
CHealth.CurrentHealth = RHealth.StartingHealth;
}
if (RKnockback != null) CKnockback!.RKnockback = RKnockback;
PlayerUi.Initialize(CHealth.CurrentHealth, Attributes["PlayerAttributeSet.Mana"].BaseValue);
CDamageable.DamageTaken += (damageable, record) => ReduceHealth(damageable, record);
CDamageable.DamageTaken += (_, record) => RegisterKnockback(new KnockbackRecord(record));
CHealth.HealthChanged += PlayerUi.OnHealthChanged;
CHealth.HealthDepleted += (_) => Kill();
// State management
_playerState = StateChart.Of(GetNode("StateChart")); _playerState = StateChart.Of(GetNode("StateChart"));
_aiming = StateChartState.Of(GetNode("StateChart/Root/Aim/On")); _aiming = StateChartState.Of(GetNode("StateChart/Root/Aim/On"));
@@ -617,6 +558,7 @@ public partial class PlayerController : CharacterBody3D,
_airborneDashCooldownTimer = GetNode<Timer>("AirborneDashCooldown"); _airborneDashCooldownTimer = GetNode<Timer>("AirborneDashCooldown");
_invincibilityTimer = GetNode<Timer>("InvincibilityTime"); _invincibilityTimer = GetNode<Timer>("InvincibilityTime");
_attackCooldown = GetNode<Timer>("AttackCooldown"); _attackCooldown = GetNode<Timer>("AttackCooldown");
#endregion
/////////////////////////// ///////////////////////////
// Initialize components // // Initialize components //
@@ -634,18 +576,16 @@ public partial class PlayerController : CharacterBody3D,
Gravity = (float)ProjectSettings.GetSetting("physics/3d/default_gravity"); Gravity = (float)ProjectSettings.GetSetting("physics/3d/default_gravity");
MantleSystem.Init(); MantleSystem.Init();
StairsSystem.Init(stairsBelowRayCast3D, stairsAheadRayCast3D, cameraSmooth); StairsSystem.Init(stairsBelowRayCast3D, stairsAheadRayCast3D, cameraSmooth);
DashSystem.Init(HeadSystem, _camera); DashSystem.Init(HeadSystem, Camera);
WeaponSystem.Init();
WallHugSystem.Init(); WallHugSystem.Init();
// if (!TutorialDone) // if (!TutorialDone)
// PlaceWeaponForTutorial(); // PlaceWeaponForTutorial();
HeadSystem.SetWeaponsVisible(HasSword, HasParry); HeadSystem.SetWeaponsVisible(HasSword, HasParry);
#region SignalBinding
///////////////////////////
// Signal setup ///////////
///////////////////////////
_invincibilityTimer.Timeout += ResetInvincibility; _invincibilityTimer.Timeout += ResetInvincibility;
_attackCooldown.Timeout += ResetAttackCooldown; _attackCooldown.Timeout += ResetAttackCooldown;
@@ -723,27 +663,105 @@ public partial class PlayerController : CharacterBody3D,
_attackDash.StateEntered += OnDashAttackStarted; _attackDash.StateEntered += OnDashAttackStarted;
_parryStandard.StateEntered += OnStandardParryStarted; _parryStandard.StateEntered += OnStandardParryStarted;
_parryDash.StateEntered += OnDashParryStarted; _parryDash.StateEntered += OnDashParryStarted;
#endregion
// Forge events // Forge events
HealthAttribute.OnValueChanged += OnHealthChanged;
var weaponLeftToken = WeaponSystem.Events.Subscribe(WeaponSystem.WeaponStartedFlyingEventTag, OnWeaponLeft); var weaponLeftToken = WeaponSystem.Events.Subscribe(WeaponSystem.WeaponStartedFlyingEventTag, OnWeaponLeft);
var weaponLandedToken = WeaponSystem.Events.Subscribe(WeaponSystem.WeaponStoppedFlyingEventTag, OnWeaponLanded); var weaponLandedToken = WeaponSystem.Events.Subscribe(WeaponSystem.WeaponStoppedFlyingEventTag, OnWeaponLanded);
} }
#region LifecycleManagement
public override void _ExitTree()
{
base._ExitTree();
ForgeManagers.Instance.CuesManager.UnregisterCue(Tag.RequestTag(TagsManager, "cues.resources.health"), this);
}
public void OnResolved() public void OnResolved()
{ {
// All of my dependencies are now available! Do whatever you want with #region Forge
// them here. EffectsManager = new EffectsManager(this, CuesManager);
CuesManager.RegisterCue(Tag.RequestTag(TagsManager, "cues.resources.health"), this);
// Inventory Management _hitAbilityHandle = Abilities.GrantAbilityPermanently(
HitAbility.GetAbilityData(),
abilityLevel: 1,
levelOverridePolicy: LevelComparison.None,
sourceEntity: this);
_empoweredActionHandle = Abilities.GrantAbilityPermanently(
EmpoweredActionAbility.GetAbilityData(),
abilityLevel: 1,
levelOverridePolicy: LevelComparison.None,
sourceEntity: this);
foreach (var defaultGrantedAbility in DefaultGrantedAbilities)
{
Abilities.GrantAbilityPermanently(
defaultGrantedAbility.GetAbilityData(),
abilityLevel: 1,
levelOverridePolicy: LevelComparison.None,
sourceEntity: this);
}
// Apply all default effects
foreach (var effect in DefaultPermanentEffects)
{
EffectsManager.ApplyEffect(new Effect(effect.GetEffectData(), new EffectOwnership(this, this)));
}
// Apply children node effects
// var effectApplier = new EffectApplier(this);
// effectApplier.ApplyEffects(this, this, this);
// Subscribe default empowered actions effects to the Empowered Action Used event
foreach (var effect in EmpoweredActionEffects)
{
Events.Subscribe<EmpoweredActionPayload>(EmpoweredActionUsed.GetTag(), data =>
{
EffectsManager.ApplyEffect(new Effect(effect.GetEffectData(), new EffectOwnership(this, this)));
});
}
Events.Subscribe<DamageDone>(Tag.RequestTag(TagsManager, "events.combat.damage"), OnDamageReceived);
Events.Subscribe(Tag.RequestTag(TagsManager, "events.combat.death"), OnDeath);
#endregion
// Initialize weapon with inventory abilities
WeaponSystem.RemoveAllEventAbilities();
foreach (var (weaponEvent, abilities) in InventoryManager.WeaponEventsInventory)
{
foreach (var ability in abilities)
{
WeaponSystem.GrantNewAbilityForEvent(weaponEvent, ability);
}
}
// Inventory changes signal binding
InventoryManager.WeaponEventAbilityAdded += OnWeaponEventAbilityAdded; InventoryManager.WeaponEventAbilityAdded += OnWeaponEventAbilityAdded;
InventoryManager.WeaponEventAbilityRemoved += OnWeaponEventAbilityRemoved; InventoryManager.WeaponEventAbilityRemoved += OnWeaponEventAbilityRemoved;
} }
public void OnExitTree()
{
InventoryManager.WeaponEventAbilityAdded -= OnWeaponEventAbilityAdded;
InventoryManager.WeaponEventAbilityRemoved -= OnWeaponEventAbilityRemoved;
}
#endregion
#region WeaponEvents
public void OnWeaponLeft(EventData data) public void OnWeaponLeft(EventData data)
{ {
var target = data.Target; var target = data.Target;
var tagsManager = ForgeManagers.Instance.TagsManager; var tagsManager = TagsManager;
var weaponLeftTag = Tag.RequestTag(tagsManager, "abilities.weapon.left").GetSingleTagContainer(); var weaponLeftTag = Tag.RequestTag(tagsManager, "abilities.weapon.left").GetSingleTagContainer();
if (weaponLeftTag == null) return; if (weaponLeftTag == null) return;
Abilities.TryActivateAbilitiesByTag(weaponLeftTag, target, out var landedFailures); Abilities.TryActivateAbilitiesByTag(weaponLeftTag, target, out var landedFailures);
@@ -756,7 +774,7 @@ public partial class PlayerController : CharacterBody3D,
var magnitude = data.EventMagnitude; var magnitude = data.EventMagnitude;
var weaponLandPayload = data.Payload; var weaponLandPayload = data.Payload;
var tagsManager = ForgeManagers.Instance.TagsManager; var tagsManager = TagsManager;
var weaponLandTag = Tag.RequestTag(tagsManager, "abilities.weapon.land").GetSingleTagContainer(); var weaponLandTag = Tag.RequestTag(tagsManager, "abilities.weapon.land").GetSingleTagContainer();
if (weaponLandTag == null) return; if (weaponLandTag == null) return;
@@ -768,33 +786,18 @@ public partial class PlayerController : CharacterBody3D,
public void OnWeaponEventAbilityAdded(WeaponEventAbilityData data) public void OnWeaponEventAbilityAdded(WeaponEventAbilityData data)
{ {
if (data.Ability is not ForgeAbilityBehavior abilityBehavior) return; WeaponSystem.GrantNewAbilityForEvent(data.ForEvent, data.Ability);
WeaponSystem.GrantNewAbilityForEvent(data.ForEvent, abilityBehavior);
} }
public void OnWeaponEventAbilityRemoved(WeaponEventAbilityData data) public void OnWeaponEventAbilityRemoved(WeaponEventAbilityData data)
{ {
if (data.Ability is not ForgeAbilityBehavior abilityBehavior) return; WeaponSystem.RemoveAbilityForEvent(data.ForEvent, data.Ability);
WeaponSystem.RemoveAbilityForEvent(data.ForEvent, abilityBehavior);
} }
#endregion
/////////////////////////// #region Settings
// Settings & tutorial //
///////////////////////////
public void SetAllowedInputsAll()
{
CurrentlyAllowedInputs = AllowedInputs.All;
}
public void SetAllowedInputsMoveCamera()
{
CurrentlyAllowedInputs = AllowedInputs.MoveCamera;
}
public void SetAllowedInputsNone()
{
CurrentlyAllowedInputs = AllowedInputs.None;
}
public void LoadSettings() public void LoadSettings()
{ {
var config = new ConfigFile(); var config = new ConfigFile();
@@ -814,25 +817,26 @@ public partial class PlayerController : CharacterBody3D,
_fovChangeMultiplier = (float) config.GetValue("InputSettings", "FovChangeWithSpeed", 1.0f); _fovChangeMultiplier = (float) config.GetValue("InputSettings", "FovChangeWithSpeed", 1.0f);
_aimAssistMultiplier = (float) config.GetValue("InputSettings", "AimAssist", 1.0f); _aimAssistMultiplier = (float) config.GetValue("InputSettings", "AimAssist", 1.0f);
} }
#endregion
/////////////////////////// #region Toolbox
// Toolbox Utils //
///////////////////////////
public void SetPlayerHealthOverride(float newHealthValue) public void SetPlayerHealthOverride(float newHealthValue)
{ {
RHealth.StartingHealth = newHealthValue; // RHealth.StartingHealth = newHealthValue;
CHealth!.CurrentHealth = newHealthValue; // CHealth!.CurrentHealth = newHealthValue;
PlayerUi.Initialize(CHealth.CurrentHealth, Attributes["PlayerAttributeSet.Mana"].BaseValue); // PlayerUi.Initialize(CHealth.CurrentHealth, Attributes["PlayerAttributeSet.Mana"].BaseValue);
} }
public void SetPlayerDamageOverride(float newDamageValue) public void SetPlayerDamageOverride(float newDamageValue)
{ {
RDamage.DamageDealt = newDamageValue; RDamage.DamageDealt = newDamageValue;
} }
#endregion
/////////////////////////// #region GroundManagement
// Grounded management //
///////////////////////////
public void OnGrounded() public void OnGrounded()
{ {
_isWallJumpAvailable = true; _isWallJumpAvailable = true;
@@ -884,10 +888,7 @@ public partial class PlayerController : CharacterBody3D,
_audioStream.SwitchToClipByName("land"); _audioStream.SwitchToClipByName("land");
} }
public bool IsGroundLike() public bool IsGroundLike() => GroundDetector.GetCollisionResult().Count > 0;
{
return GroundDetector.GetCollisionResult().Count > 0;
}
public void HandleGrounded(float delta) public void HandleGrounded(float delta)
{ {
@@ -974,11 +975,10 @@ public partial class PlayerController : CharacterBody3D,
{ {
return IsOnFloor() || StairsSystem.WasSnappedToStairsLastFrame(); return IsOnFloor() || StairsSystem.WasSnappedToStairsLastFrame();
} }
///////////////////////////
// Airborne management //
///////////////////////////
#endregion
#region AirborneManagement
public void OnAirborne() public void OnAirborne()
{ {
if (_aiming.Active) if (_aiming.Active)
@@ -1028,6 +1028,8 @@ public partial class PlayerController : CharacterBody3D,
var verticalVelocity = ComputeVerticalSpeedGravity((float) delta); var verticalVelocity = ComputeVerticalSpeedGravity((float) delta);
Velocity = new Vector3(horizontalVelocity.X, verticalVelocity, horizontalVelocity.Z); Velocity = new Vector3(horizontalVelocity.X, verticalVelocity, horizontalVelocity.Z);
} }
#endregion
/////////////////////////// ///////////////////////////
// Movement input // // Movement input //
@@ -1093,17 +1095,17 @@ public partial class PlayerController : CharacterBody3D,
// Camera stuff // Camera stuff
private Vector2 ComputeAimAssist() private Vector2 ComputeAimAssist()
{ {
_aimAssisRayCast.SetRotation(HeadSystem.GetGlobalLookRotation()); AimAssistRayCast.SetRotation(HeadSystem.GetGlobalLookRotation());
if (!_aimAssisRayCast.IsColliding()) return Vector2.Zero; if (!AimAssistRayCast.IsColliding()) return Vector2.Zero;
// Hard dependency on the aim assist to be an Area3D and having a parent // Hard dependency on the aim assist to be an Area3D and having a parent
var collidedObject = _aimAssisRayCast.GetCollider() as Area3D; var collidedObject = AimAssistRayCast.GetCollider() as Area3D;
if (collidedObject is null) return Vector2.Zero; if (collidedObject is null) return Vector2.Zero;
if (collidedObject.GetParent() is not ITargetable targetable) return Vector2.Zero; if (collidedObject.GetParent() is not ITargetable targetable) return Vector2.Zero;
var targetPosition = targetable.GetTargetGlobalPosition(); var targetPosition = targetable.GetTargetGlobalPosition();
var targetPositionOnCamera = _camera.UnprojectPosition(targetPosition); var targetPositionOnCamera = Camera.UnprojectPosition(targetPosition);
var centerOfScreen = _camera.GetViewport().GetVisibleRect().Size / 2f; var centerOfScreen = Camera.GetViewport().GetVisibleRect().Size / 2f;
var aimAssistDirection = centerOfScreen - targetPositionOnCamera; var aimAssistDirection = centerOfScreen - targetPositionOnCamera;
var aimAssist = aimAssistDirection * AimAssistStrength / 1000f; var aimAssist = aimAssistDirection * AimAssistStrength / 1000f;
@@ -1928,9 +1930,9 @@ public partial class PlayerController : CharacterBody3D,
public void EnemyHitWhileSliding(Node enemy) public void EnemyHitWhileSliding(Node enemy)
{ {
if(enemy is not IDamageable damageable) if(enemy is not IForgeEntity entity)
return; return;
_hitEnemies.Add(damageable); _hitEnemies.Add(entity);
TriggerDamage(); TriggerDamage();
} }
@@ -2063,7 +2065,7 @@ public partial class PlayerController : CharacterBody3D,
if (!isOnFloorCustom()) if (!isOnFloorCustom())
ReduceTimeScaleWhileAiming(); ReduceTimeScaleWhileAiming();
_aimAssisRayCast.TargetPosition = _aimAssisRayCast.TargetPosition.Normalized() * AimAssistRayCast.TargetPosition = AimAssistRayCast.TargetPosition.Normalized() *
(DashSystem.DashCast3D.TargetPosition.Length() + DashSystem.DashCastRadius); (DashSystem.DashCast3D.TargetPosition.Length() + DashSystem.DashCastRadius);
} }
public void HandleAiming(float delta) public void HandleAiming(float delta)
@@ -2078,7 +2080,7 @@ public partial class PlayerController : CharacterBody3D,
{ {
DashSystem.StopPreparingDash(); DashSystem.StopPreparingDash();
_aimAssisRayCast.TargetPosition = _aimAssisRayCast.TargetPosition.Normalized() * (TargetingDistance*1.5f); AimAssistRayCast.TargetPosition = AimAssistRayCast.TargetPosition.Normalized() * (TargetingDistance*1.5f);
// DashIndicatorMesh.Visible = false; // DashIndicatorMesh.Visible = false;
} }
@@ -2149,8 +2151,8 @@ public partial class PlayerController : CharacterBody3D,
for (var i = 0; i < DashDamageDetector.GetCollisionCount(); i++) for (var i = 0; i < DashDamageDetector.GetCollisionCount(); i++)
{ {
var collidedObject = DashDamageDetector.GetCollider(i); var collidedObject = DashDamageDetector.GetCollider(i);
if (collidedObject is not IDamageable damageable) continue; if (collidedObject is not IForgeEntity entity) continue;
_hitEnemies.Add(damageable); _hitEnemies.Add(entity);
} }
TriggerDamage(); TriggerDamage();
@@ -2300,9 +2302,9 @@ public partial class PlayerController : CharacterBody3D,
public void ManageAttackedEnemyPostDash(Node? enemy) public void ManageAttackedEnemyPostDash(Node? enemy)
{ {
if (enemy is IDamageable damageable) if (enemy is IForgeEntity entity)
{ {
_hitEnemies.Add(damageable); _hitEnemies.Add(entity);
TriggerDamage(); TriggerDamage();
} }
if (enemy is IStunnable stunnable) if (enemy is IStunnable stunnable)
@@ -2336,9 +2338,9 @@ public partial class PlayerController : CharacterBody3D,
LookAround(delta); LookAround(delta);
} }
// private float _oldMana = 100;
public override void _Process(double delta) public override void _Process(double delta)
{ {
Abilities.UpdateAbilities(delta);
EffectsManager.UpdateEffects(delta); EffectsManager.UpdateEffects(delta);
} }
@@ -2353,7 +2355,7 @@ public partial class PlayerController : CharacterBody3D,
public void HandleEnemyTargeting() public void HandleEnemyTargeting()
{ {
_isEnemyInDashAttackRange = false; _isEnemyInDashAttackRange = false;
_closeEnemyDetector.SetRotation(HeadSystem.GetGlobalLookRotation()); CloseEnemyDetector.SetRotation(HeadSystem.GetGlobalLookRotation());
var enemyTargetState = PlayerUi.TargetState.NoTarget; var enemyTargetState = PlayerUi.TargetState.NoTarget;
var positionOnScreen = Vector2.Zero; var positionOnScreen = Vector2.Zero;
@@ -2361,20 +2363,20 @@ public partial class PlayerController : CharacterBody3D,
{ {
enemyTargetState = PlayerUi.TargetState.TargetWouldKill; enemyTargetState = PlayerUi.TargetState.TargetWouldKill;
_targetLocation = dashTarget.GetTargetGlobalPosition(); _targetLocation = dashTarget.GetTargetGlobalPosition();
positionOnScreen = _camera.UnprojectPosition(_targetLocation); positionOnScreen = Camera.UnprojectPosition(_targetLocation);
PlayerUi.SetEnemyTargetProperties(new PlayerUi.TargetProperties(enemyTargetState, positionOnScreen)); PlayerUi.SetEnemyTargetProperties(new PlayerUi.TargetProperties(enemyTargetState, positionOnScreen));
return; return;
} }
if (!_closeEnemyDetector.IsColliding()) if (!CloseEnemyDetector.IsColliding())
{ {
PlayerUi.SetEnemyTargetProperties(new PlayerUi.TargetProperties(enemyTargetState, positionOnScreen)); PlayerUi.SetEnemyTargetProperties(new PlayerUi.TargetProperties(enemyTargetState, positionOnScreen));
return; return;
} }
_targetHitLocation = _closeEnemyDetector.GetCollisionPoint(0); _targetHitLocation = CloseEnemyDetector.GetCollisionPoint(0);
_targetObject = _closeEnemyDetector.GetCollider(0); _targetObject = CloseEnemyDetector.GetCollider(0);
if (_targetObject is not ITargetable target) if (_targetObject is not ITargetable target)
{ {
PlayerUi.SetEnemyTargetProperties(new PlayerUi.TargetProperties(enemyTargetState, positionOnScreen)); PlayerUi.SetEnemyTargetProperties(new PlayerUi.TargetProperties(enemyTargetState, positionOnScreen));
@@ -2383,7 +2385,7 @@ public partial class PlayerController : CharacterBody3D,
_targetLocation = target.GetTargetGlobalPosition(); _targetLocation = target.GetTargetGlobalPosition();
// var targetDistance = _targetLocation.DistanceTo(GlobalPosition); // var targetDistance = _targetLocation.DistanceTo(GlobalPosition);
positionOnScreen = _camera.UnprojectPosition(_targetLocation); positionOnScreen = Camera.UnprojectPosition(_targetLocation);
var wouldKill = false; var wouldKill = false;
if (_targetObject is IHealthable h and IDamageable d) if (_targetObject is IHealthable h and IDamageable d)
@@ -2401,20 +2403,21 @@ public partial class PlayerController : CharacterBody3D,
if (IsInvincible) if (IsInvincible)
return damageRecord with { Damage = new RDamage(0, damageRecord.Damage.DamageType) }; return damageRecord with { Damage = new RDamage(0, damageRecord.Damage.DamageType) };
var finalDamage = CDamageable!.TakeDamage(damageRecord); // var finalDamage = CDamageable!.TakeDamage(damageRecord);
DamageTaken?.Invoke(this, finalDamage); // DamageTaken?.Invoke(this, finalDamage);
HeadSystem.OnGetHit(); HeadSystem.OnGetHit();
_audioStream.SwitchToClipByName("damage_taken"); _audioStream.SwitchToClipByName("damage_taken");
TriggerHitstop(); TriggerHitstop();
OnHitInvincibility(); OnHitInvincibility();
return finalDamage; return damageRecord;
} }
public DamageRecord ComputeDamage(DamageRecord damageRecord) public DamageRecord ComputeDamage(DamageRecord damageRecord)
{ {
return CDamageable!.ComputeDamage(damageRecord); // return CDamageable!.ComputeDamage(damageRecord);
return damageRecord;
} }
public void OnHitInvincibility() public void OnHitInvincibility()
@@ -2481,9 +2484,9 @@ public partial class PlayerController : CharacterBody3D,
public void StopDashAction() public void StopDashAction()
{ {
if (_targetObject is IDamageable damageable) if (_targetObject is IForgeEntity entity)
{ {
_hitEnemies.Add(damageable); _hitEnemies.Add(entity);
TriggerDamage(); TriggerDamage();
} }
if (_targetObject is IStunnable stunnable) if (_targetObject is IStunnable stunnable)
@@ -2539,9 +2542,12 @@ public partial class PlayerController : CharacterBody3D,
return; return;
} }
if (!WeaponSystem.InHandState.Active) return; if (!WeaponSystem.InHandState.Active) return;
if (_hitAbilityHandle is null) return;
if (!_hitAbilityHandle.CanActivate(out _)) return;
var attackToDo = _isEnemyInDashAttackRange ? "dash_attack" : "standard_attack"; var attackToDo = _isEnemyInDashAttackRange ? "dash_attack" : "standard_attack";
_playerState.SendEvent(attackToDo); _playerState.SendEvent("standard_attack");
} }
public void ResetAttackCooldown() public void ResetAttackCooldown()
@@ -2562,16 +2568,27 @@ public partial class PlayerController : CharacterBody3D,
public void RegisterHitEnnemy(Node3D body) public void RegisterHitEnnemy(Node3D body)
{ {
if (body is not IDamageable damageable) return; if (body is not IForgeEntity entity) return;
_hitEnemies.Add(damageable); _hitEnemies.Add(entity);
// return;
// if (body is not IDamageable damageable) return;
// _hitEnemies.Add(damageable);
} }
public void TriggerDamage() public void TriggerDamage()
{ {
if (_hitEnemies.Count == 0) return; if (_hitEnemies.Count == 0) return;
foreach (var damageable in _hitEnemies) if (_hitAbilityHandle is null) return;
damageable.TakeDamage(new DamageRecord(GlobalPosition, RDamage));
if (!_hitAbilityHandle.CanActivate(out _)) return;
foreach (var entity in _hitEnemies)
{
// TODO: WTF why doesn't health move
// GD.Print(entity.Attributes["EnemyAttributeSet.Health"].CurrentValue);
_hitAbilityHandle.Activate(out _, entity);
}
_hitEnemies.Clear(); _hitEnemies.Clear();
HeadSystem.OnHitTarget(); HeadSystem.OnHitTarget();
@@ -2590,23 +2607,22 @@ public partial class PlayerController : CharacterBody3D,
{ {
ResetTimeScale(); ResetTimeScale();
} }
public HealthChangedRecord ReduceHealth(IDamageable source, DamageRecord damageRecord)
{
var record = CHealth!.ReduceHealth(source, damageRecord);
HealthChanged?.Invoke(this, record);
return record;
}
public void RegisterKnockback(KnockbackRecord knockbackRecord) public void RegisterKnockback(KnockbackRecord knockbackRecord)
{ {
CKnockback!.RegisterKnockback(knockbackRecord); // CKnockback!.RegisterKnockback(knockbackRecord);
} }
public Vector3 ComputeKnockback() public Vector3 ComputeKnockback()
{ {
var kb = CKnockback!.ComputeKnockback(); // var kb = CKnockback!.ComputeKnockback();
return kb; // return kb;
return Vector3.Zero;
} }
public void OnDeath(EventData data)
{
Kill();
}
public void Kill() public void Kill()
{ {
HeadSystem.OnStartDeathAnimation(); HeadSystem.OnStartDeathAnimation();
@@ -2627,4 +2643,56 @@ public partial class PlayerController : CharacterBody3D,
{ {
_audioStream.SwitchToClipByName("footsteps"); _audioStream.SwitchToClipByName("footsteps");
} }
// Forge Damage handling
private void OnHealthChanged(EntityAttribute healthAttribute, int i)
{
if (healthAttribute.CurrentValue > HealthAttribute.Min) return;
var tagsManager = TagsManager;
Events.Raise(new EventData
{
EventTags = Tag.RequestTag(tagsManager, "events.combat.death").GetSingleTagContainer()!,
});
}
public void OnDamageReceived(EventData<DamageDone> data)
{
CuesManager.ExecuteCue(
Tag.RequestTag(TagsManager, "cues.resources.health"),
this,
new CueParameters(
(int) data.EventMagnitude,
data.EventMagnitude / HealthAttribute.Max,
data.Source,
new Dictionary<StringKey, object>
{
{"test", "hello"}
})
);
}
public void OnExecute(IForgeEntity? target, CueParameters? parameters)
{
if (target == null || !parameters.HasValue) return;
float magnitude = parameters.Value.Magnitude;
if (magnitude <= 0) return;
HeadSystem.OnGetHit();
_audioStream.SwitchToClipByName("damage_taken");
TriggerHitstop();
}
public void OnApply(IForgeEntity? target, CueParameters? parameters)
{
}
public void OnRemove(IForgeEntity? target, bool interrupted)
{
}
public void OnUpdate(IForgeEntity? target, CueParameters? parameters)
{
}
} }

View File

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