Compare commits

..

23 Commits

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

View File

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

1
.gitignore vendored
View File

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

View File

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

View File

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

View File

@@ -10,5 +10,9 @@ namespace Gamesmiths.Forge.Godot.Resources.Abilities;
[Icon("uid://bcx7anhepqfmd")]
public abstract partial class ForgeAbilityBehavior : Resource
{
[Export] public string? Name { get; set; }
[Export] public string? Description { get; set; }
[Export] public Texture2D? Icon { get; set; }
public abstract IAbilityBehavior GetBehavior();
}

View File

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

72
forge/ForgeEntityNode.cs Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,7 +2,11 @@
[ext_resource type="PackedScene" uid="uid://duju3atqgltkg" path="res://scenes/explosion/explosion.tscn" id="1_mnals"]
[ext_resource type="Script" uid="uid://bnee6amtc2bhj" path="res://forge/abilities/ForgeExplodingSwordBehavior.cs" id="1_ot53g"]
[ext_resource type="Texture2D" uid="uid://c2akxlg7tdb67" path="res://assets/ui/IconGodotNode/node/icon_projectile.png" id="2_l3coe"]
[resource]
script = ExtResource("1_ot53g")
Explosion = ExtResource("1_mnals")
Name = "Exploding Sword"
Description = "Make the sword explode"
Icon = ExtResource("2_l3coe")

View File

@@ -1,9 +1,10 @@
[gd_resource type="Resource" script_class="ForgeEffectApplicationBehavior" format=3 uid="uid://1tmxayi3nygi"]
[ext_resource type="Resource" uid="uid://bvidrwyuoos4g" path="res://scenes/player_controller/resources/forge/raise_flying_tick_event_periodically.tres" id="1_hlq5f"]
[ext_resource type="Resource" uid="uid://bvidrwyuoos4g" path="res://forge/resources/effect_datas/raise_flying_tick_event_periodically.tres" id="1_hlq5f"]
[ext_resource type="Script" uid="uid://cl5hudinl1rex" path="res://forge/abilities/ForgeEffectApplicationBehavior.cs" id="2_f5qgs"]
[resource]
script = ExtResource("2_f5qgs")
EffectData = ExtResource("1_hlq5f")
Name = "Flying tick application"
metadata/_custom_type_script = "uid://cl5hudinl1rex"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
[gd_scene format=3 uid="uid://55wehh6xombr"]
[ext_resource type="Script" uid="uid://beof168aw2acj" path="res://maps/_templates/main_scene_template.gd" id="1_5g5a0"]
[ext_resource type="Script" uid="uid://br0f18u1iou2d" path="res://maps/_templates/MainSceneTemplate.cs" id="1_5g5a0"]
[ext_resource type="PackedScene" uid="uid://bkcsjsk2ciff" path="res://addons/maaacks_game_template/base/scenes/music_players/background_music_player.tscn" id="2_roiv2"]
[ext_resource type="AudioStream" uid="uid://f8cvr5s041ej" path="res://assets/audio/ambiance/637083__nox_sound__ambiance_nature_night_cricket_calm_loop_stereo.wav" id="3_boadi"]
[ext_resource type="Script" uid="uid://cupqhe3qv7ero" path="res://tools/general_manager.gd" id="3_k6got"]
@@ -237,7 +237,7 @@ tracks/6/keys = {
"transitions": PackedFloat32Array(1),
"values": [{
"args": [],
"method": &"reset_player_position"
"method": &"ResetPlayerPosition"
}]
}
@@ -300,6 +300,7 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 300, 0)
[node name="PlayerFellTP" type="Area3D" parent="." unique_id=1277888169]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -200, 0)
collision_layer = 0
collision_mask = 65537
monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="PlayerFellTP" unique_id=1866249040]

View File

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

View File

@@ -64,7 +64,7 @@ size = Vector3(5, 2.25, 3.75)
size = Vector3(5.5, 4.5, 2)
[sub_resource type="BoxShape3D" id="BoxShape3D_prjj8"]
size = Vector3(2, 3.25, 5.25)
size = Vector3(2, 3.25, 4)
[sub_resource type="BoxShape3D" id="BoxShape3D_trte5"]
size = Vector3(6.75, 8.25, 7.25)
@@ -343,7 +343,7 @@ transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, -7.25, 20.5, -27.5)
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 1.3647223, 23.75, -13.75)
[node name="Enemy28" parent="Tutorial" index="2" unique_id=1765389924 node_paths=PackedStringArray("Target") instance=ExtResource("7_egib5")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -5, 22, 16.5)
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -5, 22, 15.5)
Target = NodePath("../../Player")
RHealth = SubResource("Resource_invhv")
RDamage = SubResource("Resource_cgfmf")
@@ -420,7 +420,7 @@ input_related_text = "at enemy"
tuto_text = "dash through"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Tutorial/Triggers/TutoTrigger6" index="1" unique_id=1214410006]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.625, 1.75, -0.75)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.625, 1.75, -0.125)
shape = SubResource("BoxShape3D_prjj8")
[node name="TutoTrigger7" parent="Tutorial/Triggers" index="5" unique_id=271532103 instance=ExtResource("10_vqwwk")]
@@ -520,15 +520,15 @@ size = Vector3(1, 1, 4.75)
material = ExtResource("3_4m8g1")
[node name="CSGBox3D137" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="10" unique_id=1930091014]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 22.5, 58)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 22.5, 57.5)
use_collision = true
size = Vector3(1, 1, 11)
size = Vector3(1, 1, 12)
material = ExtResource("3_4m8g1")
[node name="CSGBox3D138" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="11" unique_id=1299444131]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 22.5, 58)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 22.5, 57.5)
use_collision = true
size = Vector3(1, 1, 11)
size = Vector3(1, 1, 12)
material = ExtResource("3_4m8g1")
[node name="CSGBox3D139" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="12" unique_id=1708119368]
@@ -616,21 +616,21 @@ size = Vector3(7.25, 7.75, 2)
material = ExtResource("3_4m8g1")
[node name="CSGBox3D124" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="26" unique_id=1068505352]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.5, 19.487345, 11.25)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.5, 19.237345, 11.25)
use_collision = true
size = Vector3(3, 5, 8.5)
size = Vector3(3, 4.5, 8.5)
material = ExtResource("3_4m8g1")
[node name="CSGBox3D129" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="27" unique_id=302301078]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.25, 19.487345, 38.625)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.25, 19.487345, 38)
use_collision = true
size = Vector3(9.5, 5, 11.75)
size = Vector3(9.5, 5, 13)
material = ExtResource("3_4m8g1")
[node name="CSGBox3D133" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="28" unique_id=672467040]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 21.487345, 58)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 21.487345, 57.5)
use_collision = true
size = Vector3(5, 1, 11)
size = Vector3(5, 1, 12)
material = ExtResource("3_4m8g1")
[node name="CSGBox3D141" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="29" unique_id=1207463075]
@@ -765,15 +765,19 @@ use_collision = true
size = Vector3(2, 3.25, 1)
material = ExtResource("3_4m8g1")
[node name="Player" parent="." index="9" unique_id=1309399929]
[node name="Player" parent="." index="10" unique_id=1309399929]
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, -0.5, 0, 0)
[node name="PlayerFellRespawn" parent="." index="10" unique_id=479136076]
[node name="PlayerFellRespawn" parent="." index="11" unique_id=479136076]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 1.5, 0)
[node name="OmniLight3D" type="OmniLight3D" parent="." index="13" unique_id=702421172]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 25, 4)
[node name="OmniLight3D2" type="OmniLight3D" parent="." index="14" unique_id=2016820716]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 25, -9.5)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 25, -10)
omni_range = 12.0
[node name="OmniLight3D3" type="OmniLight3D" parent="." index="15" unique_id=845858088]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 25, -25.5)
omni_range = 12.0

View File

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

View File

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

View File

@@ -0,0 +1,56 @@
using Godot;
using System;
using Gamesmiths.Forge.Godot.Resources.Abilities;
[Tool, GlobalClass]
public partial class SelectedAbility : Control
{
[Signal] public delegate void AbilityRemovedEventHandler(ForgeAbilityBehavior ability);
private ForgeAbilityBehavior? _ability;
[Export]
public ForgeAbilityBehavior? Ability
{
get => _ability;
set
{
_ability = value;
if (_ability == null || !Engine.IsEditorHint()) return;
AbilityUpdated();
}
}
private TextureRect? _icon;
private Label? _title;
private Button? _remove;
public override void _Ready()
{
_icon = GetNode<TextureRect>("%Icon");
_title = GetNode<Label>("%Title");
_remove = GetNode<Button>("%Remove");
_remove.Pressed += () => EmitSignalAbilityRemoved(Ability);
}
public void SetAbility(ForgeAbilityBehavior ability)
{
_ability = ability;
AbilityUpdated();
}
public void AbilityUpdated()
{
var icon = _icon ?? GetNode<TextureRect>("%Icon");
var title = _title ?? GetNode<Label>("%Title");
if (icon == null || title == null) return;
if (_ability == null)
{
icon.Texture = null;
title.Text = "";
return;
}
icon.Texture = _ability.Icon;
title.Text = _ability.Name;
}
}

View File

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

View File

@@ -1,8 +1,9 @@
[gd_scene format=3 uid="uid://dmv685sskgh3l"]
[ext_resource type="Script" uid="uid://5emed8iegtui" path="res://menus/scenes/components/AbilitySelection.cs" id="1_fcxyu"]
[ext_resource type="Resource" uid="uid://ifeavnlps7hy" path="res://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://c2akxlg7tdb67" path="res://assets/ui/IconGodotNode/node/icon_projectile.png" id="3_41pdy"]
[ext_resource type="PackedScene" uid="uid://cjnimmo2jyvx7" path="res://menus/scenes/components/selected_ability.tscn" id="3_cndde"]
[node name="AbilitySelection" type="MarginContainer" unique_id=1373426933]
size_flags_horizontal = 3
@@ -11,6 +12,9 @@ theme_override_constants/margin_top = 4
theme_override_constants/margin_right = 4
theme_override_constants/margin_bottom = 4
script = ExtResource("1_fcxyu")
Title = "Test"
AbilitySelectedItem = ExtResource("3_cndde")
AbilityBehaviors = [ExtResource("2_j1yif")]
[node name="HBoxContainer" type="VBoxContainer" parent="." unique_id=364343452]
layout_mode = 2
@@ -18,6 +22,7 @@ layout_mode = 2
[node name="TitleLabel" type="Label" parent="HBoxContainer" unique_id=8350369]
unique_name_in_owner = true
layout_mode = 2
text = "Test"
[node name="SelectedAbilities" type="VBoxContainer" parent="HBoxContainer" unique_id=1173689490]
unique_name_in_owner = true
@@ -39,7 +44,3 @@ layout_mode = 2
focus_mode = 2
text = "Add ability"
icon = ExtResource("2_uf3m5")
item_count = 1
popup/item_0/text = "Weapon explosion"
popup/item_0/icon = ExtResource("3_41pdy")
popup/item_0/id = 0

View File

@@ -0,0 +1,30 @@
[gd_scene format=3 uid="uid://cjnimmo2jyvx7"]
[ext_resource type="Script" uid="uid://duest06l5answ" path="res://menus/scenes/components/SelectedAbility.cs" id="1_dc51o"]
[ext_resource type="Resource" uid="uid://ifeavnlps7hy" path="res://forge/resources/behaviors/exploding_sword.tres" id="2_um64s"]
[ext_resource type="Texture2D" uid="uid://b3403ry3yxw1t" path="res://assets/ui/input-prompts/Flairs/Vector/flair_cross.svg" id="4_x7nho"]
[sub_resource type="AtlasTexture" id="AtlasTexture_2nvj1"]
atlas = ExtResource("4_x7nho")
region = Rect2(20, 20, 24, 24)
[node name="SelectedAbility" type="PanelContainer" unique_id=931414010]
script = ExtResource("1_dc51o")
Ability = ExtResource("2_um64s")
[node name="HBoxContainer" type="HBoxContainer" parent="." unique_id=489712453]
layout_mode = 2
[node name="Icon" type="TextureRect" parent="HBoxContainer" unique_id=1615158957]
unique_name_in_owner = true
layout_mode = 2
stretch_mode = 3
[node name="Title" type="Label" parent="HBoxContainer" unique_id=809638027]
unique_name_in_owner = true
layout_mode = 2
[node name="Remove" type="Button" parent="HBoxContainer" unique_id=1761723956]
unique_name_in_owner = true
layout_mode = 2
icon = SubResource("AtlasTexture_2nvj1")

View File

@@ -37,6 +37,7 @@ option_name = "Joystick Sensitivity"
option_section = 1
key = "LookSensitivity"
section = "InputSettings"
default_value = 1.1
[node name="OptionLabel" parent="VBoxContainer/MarginContainer/VBoxContainer/LookSensitivityControl" index="0" unique_id=1789907427]
text = "Joystick Sensitivity :"
@@ -44,8 +45,8 @@ text = "Joystick Sensitivity :"
[node name="HSlider" parent="VBoxContainer/MarginContainer/VBoxContainer/LookSensitivityControl" index="1" unique_id=494926010]
min_value = 0.2
max_value = 2.0
step = 0.2
value = 0.6000000000000001
step = 0.1
value = 1.1
tick_count = 10
[node name="MouseSensitivityControl" parent="VBoxContainer/MarginContainer/VBoxContainer" unique_id=1444662884 instance=ExtResource("2_iyvrj")]
@@ -54,16 +55,17 @@ option_name = "Mouse Sensitivity"
option_section = 1
key = "MouseSensitivity"
section = "InputSettings"
default_value = 25.0
[node name="OptionLabel" parent="VBoxContainer/MarginContainer/VBoxContainer/MouseSensitivityControl" index="0" unique_id=1789907427]
text = "Mouse Sensitivity :"
[node name="HSlider" parent="VBoxContainer/MarginContainer/VBoxContainer/MouseSensitivityControl" index="1" unique_id=494926010]
min_value = 1.0
max_value = 20.0
max_value = 50.0
step = 1.0
value = 8.0
tick_count = 20
value = 25.0
tick_count = 10
[node name="HeadBobbingControl" parent="VBoxContainer/MarginContainer/VBoxContainer" unique_id=1905029466 instance=ExtResource("2_iyvrj")]
layout_mode = 2

View File

@@ -1,28 +0,0 @@
using Godot;
using Movementtests.systems;
[Tool, GlobalClass, Icon("res://assets/ui/IconGodotNode/control/icon_crate.png")]
public partial class Inventory : Control
{
public PlayerController? Player { get; set; }
private AbilitySelection _startedFlyingSelection;
private AbilitySelection _whileFlyingSelection;
private AbilitySelection _stoppedFlyingSelection;
public override void _Ready()
{
_startedFlyingSelection = GetNode<AbilitySelection>("%StartedFlying");
_whileFlyingSelection = GetNode<AbilitySelection>("%WhileFlying");
_stoppedFlyingSelection = GetNode<AbilitySelection>("%StoppedFlying");
_startedFlyingSelection.AbilityAdded += AddAbilityForEvent;
_whileFlyingSelection.AbilityAdded += AddAbilityForEvent;
_stoppedFlyingSelection.AbilityAdded += AddAbilityForEvent;
}
public void AddAbilityForEvent(WeaponSystem.WeaponEvent forEvent, string abilityName)
{
if (Player is null) return;
Player.GrantWeaponExplosionAbilityForEvent(forEvent, abilityName);
}
}

View File

@@ -1 +0,0 @@
uid://7yil0fiftvaf

View File

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

View File

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

View File

@@ -2,7 +2,7 @@
[ext_resource type="Script" uid="uid://vu5kh5amnta" path="res://menus/scenes/overlaid_menus/inventory_wrapper.gd" id="1_yst23"]
[ext_resource type="Script" uid="uid://1nf36h0gms3q" path="res://addons/maaacks_game_template/base/scripts/capture_focus.gd" id="2_ijoei"]
[ext_resource type="Script" uid="uid://7yil0fiftvaf" path="res://menus/scenes/overlaid_menus/Inventory.cs" id="2_sb1gh"]
[ext_resource type="Script" uid="uid://cvwiftuay8jep" path="res://menus/scenes/overlaid_menus/InventoryUi.cs" id="2_sb1gh"]
[ext_resource type="PackedScene" uid="uid://dmv685sskgh3l" path="res://menus/scenes/components/ability_selection.tscn" id="3_ijoei"]
[node name="InventoryWrapper" type="Control" unique_id=1853168495]

View File

@@ -3,13 +3,10 @@
class_name InventoryWrapper
extends OverlaidMenu
@export var player: PlayerController
@onready var inventory: Control = %Inventory
func _ready() -> void:
if Engine.is_editor_hint(): return
inventory.Player = player
func _on_close_button_pressed() -> void:
close()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

@@ -1,30 +0,0 @@
using Godot;
using GdUnit4;
using static GdUnit4.Assertions;
using Movementtests.interfaces;
using Movementtests.systems.damage;
namespace Movementtests.tests;
[TestSuite, RequireGodotRuntime]
public class EnemyUnitTest
{
[TestCase]
public void ComputeDamageNoComponent()
{
var enemy = new Enemy();
var input = new DamageRecord(Vector3.Zero, new RDamage(10.0f, EDamageTypes.Normal));
var result = enemy.ComputeDamage(input);
AssertFloat(result.Damage.DamageDealt).IsEqual(0.0f);
}
[TestCase]
public void Unstun()
{
var enemy = new Enemy();
enemy.IsStunned = true;
enemy.Unstun();
AssertBool(enemy.IsStunned).IsFalse();
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

22
tools/ForgeUtils.cs Normal file
View File

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

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

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

View File

@@ -38,7 +38,7 @@ func open_toolbox() -> void:
func open_inventory() -> void:
var inventory: Control = open_overlaid_menu(inventory_scene)
inventory.player = player
# inventory.player = player
inventory_layer.call_deferred("add_child", inventory)
func on_player_died() -> void: