WIP: integrating forge systems into the game, now trying periodic abilities

This commit is contained in:
2026-03-28 11:43:34 +01:00
parent 7bf19868e7
commit cc70fb361b
12 changed files with 242 additions and 43 deletions

View File

@@ -18,10 +18,14 @@ public partial class ForgeManager : Node
// Abilities // Abilities
"abilities.weapon.land", "abilities.weapon.land",
"abilities.weapon.flying",
"abilities.weapon.left",
// Events // Events
"events.combat.damage", "events.combat.damage",
"events.combat.hit", "events.combat.hit",
"events.weapon.left",
"events.weapon.flyingTick",
"events.weapon.land", "events.weapon.land",
// Cooldowns // Cooldowns

View File

@@ -24,7 +24,7 @@ public partial class RAbilityBase(float cost, float cooldown) : Resource, IAbili
{ {
} }
public virtual AbilityData Ability(TagsManager tagsManager, Node3D owner) public virtual AbilityData Ability(TagsManager tagsManager, TagContainer? tags, Node3D owner)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View File

@@ -1,3 +1,4 @@
using System;
using Gamesmiths.Forge.Abilities; using Gamesmiths.Forge.Abilities;
using Gamesmiths.Forge.Cues; using Gamesmiths.Forge.Cues;
using Gamesmiths.Forge.Effects; using Gamesmiths.Forge.Effects;
@@ -7,27 +8,28 @@ using Gamesmiths.Forge.Effects.Magnitudes;
using Gamesmiths.Forge.Effects.Modifiers; using Gamesmiths.Forge.Effects.Modifiers;
using Gamesmiths.Forge.Tags; using Gamesmiths.Forge.Tags;
using Godot; using Godot;
using Movementtests.systems;
namespace Movementtests.forge.abilities; namespace Movementtests.forge.abilities;
[GlobalClass, Icon("res://assets/ui/IconGodotNode/white/icon_projectile.png")] [GlobalClass, Icon("res://assets/ui/IconGodotNode/white/icon_projectile.png")]
public partial class RExplodingSwordThrow(PackedScene? explosion, float cost, float cooldown) : RAbilityBase(cost, cooldown) public partial class RExplodingSword(PackedScene? explosion, float cost, float cooldown) : RAbilityBase(cost, cooldown)
{ {
[Export] public PackedScene? Explosion { get; set; } = explosion; [Export] public PackedScene? Explosion { get; set; } = explosion;
public RExplodingSwordThrow() : this(null, 20.0f, 0.0f) public RExplodingSword() : this(null, 20.0f, 0.0f)
{ {
} }
public override AbilityData Ability(TagsManager tagsManager, Node3D owner) public override AbilityData Ability(TagsManager tagsManager, TagContainer? tags, Node3D owner)
{ {
return new AbilityData( return new AbilityData(
name: "Exploding Sword Throw", name: "Exploding Sword Throw",
costEffect: CostEffect(tagsManager), costEffect: CostEffect(tagsManager),
cooldownEffects: [CooldownEffect(tagsManager)], cooldownEffects: [CooldownEffect(tagsManager)],
abilityTags: Tag.RequestTag(tagsManager, "abilities.weapon.land").GetSingleTagContainer(), abilityTags: tags,
instancingPolicy: AbilityInstancingPolicy.PerEntity, instancingPolicy: AbilityInstancingPolicy.PerEntity,
behaviorFactory: () => new ExplodingSwordThrowBehavior(owner, Explosion)); behaviorFactory: () => new ExplodingSwordThrowBehavior<WeaponLeftPayload>(owner, Explosion));
} }
public override EffectData CostEffect(TagsManager tagsManager) public override EffectData CostEffect(TagsManager tagsManager)
@@ -77,21 +79,28 @@ public partial class RExplodingSwordThrow(PackedScene? explosion, float cost, fl
} }
} }
public class ExplodingSwordThrowBehavior(Node3D owner, PackedScene? explosion) : IAbilityBehavior public class ExplodingSwordThrowBehavior<TPayload>(Node3D owner, PackedScene? explosion) : IAbilityBehavior<TPayload>
{ {
private Node3D _owner = owner; private Node3D _owner = owner;
private PackedScene? _explosion = explosion; private PackedScene? _explosion = explosion;
public void OnStarted(AbilityBehaviorContext context) public void OnStarted(AbilityBehaviorContext context, TPayload payload)
{ {
GD.Print(payload);
if (_explosion?.Instantiate() is not Explosion explosion) if (_explosion?.Instantiate() is not Explosion explosion)
{ {
context.InstanceHandle.End(); context.InstanceHandle.End();
return; return;
} }
if (!_owner.IsInsideTree())
{
context.InstanceHandle.End();
return;
}
explosion.Radius = 10f; explosion.Radius = 6f;
_owner.GetTree().GetRoot().AddChild(explosion);
explosion.GlobalPosition = _owner.GlobalPosition; _owner.GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, explosion);
explosion.CallDeferred(Node3D.MethodName.SetGlobalPosition, _owner.GlobalPosition);
context.AbilityHandle.CommitAbility(); context.AbilityHandle.CommitAbility();
context.InstanceHandle.End(); context.InstanceHandle.End();
@@ -99,6 +108,17 @@ public class ExplodingSwordThrowBehavior(Node3D owner, PackedScene? explosion) :
public void OnEnded(AbilityBehaviorContext context) public void OnEnded(AbilityBehaviorContext context)
{ {
} }
} }
public class TestBehavior<TPayload>(
Action<AbilityBehaviorContext, TPayload> callback) : IAbilityBehavior<TPayload>
{
public void OnStarted(AbilityBehaviorContext context, TPayload data)
{
callback(context, data);
context.InstanceHandle.End();
}
public void OnEnded(AbilityBehaviorContext context){}
}

View File

@@ -0,0 +1,67 @@
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 Godot;
namespace Movementtests.tools.calculators;
public class FlyingWeaponExecution : CustomExecution
{
private readonly Node3D _comboSystem;
public AttributeCaptureDefinition TargetHealth { get; }
public AttributeCaptureDefinition AttackerStrength { get; }
public FlyingWeaponExecution()
{
TargetHealth = new AttributeCaptureDefinition(
"CombatAttributeSet.CurrentHealth",
AttributeCaptureSource.Target,
Snapshot: false);
AttackerStrength = new AttributeCaptureDefinition(
"StatAttributeSet.Strength",
AttributeCaptureSource.Source,
Snapshot: true);
AttributesToCapture.Add(TargetHealth);
AttributesToCapture.Add(AttackerStrength);
CustomCueParameters.Add("cues.combat.combo_count", 0);
CustomCueParameters.Add("cues.combat.combo_damage", 0f);
}
public override ModifierEvaluatedData[] EvaluateExecution(Effect effect, IForgeEntity target, EffectEvaluatedData? effectEvaluatedData)
{
var results = new List<ModifierEvaluatedData>();
int strength = CaptureAttributeMagnitude(AttackerStrength, effect, target, effectEvaluatedData);
int comboCount = 0;
// Calculate combo damage
float baseDamage = strength * 0.8f;
float comboDamage = baseDamage * (1 + comboCount * 0.2f);
// Apply health damage
if (TargetHealth.TryGetAttribute(target, out EntityAttribute? healthAttribute))
{
results.Add(new ModifierEvaluatedData(
healthAttribute,
ModifierOperation.FlatBonus,
-comboDamage, // Negative for damage
channel: 0
));
}
// Add combo to cue parameters
CustomCueParameters["cues.combat.combo_count"] = comboCount;
CustomCueParameters["cues.combat.combo_damage"] = comboDamage;
return results.ToArray();
}
}

View File

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

View File

@@ -7,7 +7,7 @@ namespace Movementtests.interfaces;
public interface IAbilityBase public interface IAbilityBase
{ {
AbilityData Ability(TagsManager tagsManager, Node3D owner); AbilityData Ability(TagsManager tagsManager, TagContainer? tags, Node3D owner);
EffectData CostEffect(TagsManager tagsManager); EffectData CostEffect(TagsManager tagsManager);
EffectData CooldownEffect(TagsManager tagsManager); EffectData CooldownEffect(TagsManager tagsManager);
} }

View File

@@ -7,7 +7,7 @@
[ext_resource type="Resource" uid="uid://bl5crtu1gkrtr" path="res://inputs/base_mode/base_mode.tres" id="3_cresl"] [ext_resource type="Resource" uid="uid://bl5crtu1gkrtr" path="res://inputs/base_mode/base_mode.tres" id="3_cresl"]
[ext_resource type="Resource" uid="uid://dtmhtlix2amme" path="res://scenes/player_controller/resources/player_mana_regen.tres" id="3_n24vh"] [ext_resource type="Resource" uid="uid://dtmhtlix2amme" path="res://scenes/player_controller/resources/player_mana_regen.tres" id="3_n24vh"]
[ext_resource type="PackedScene" uid="uid://c4ikbhojckpnc" path="res://scenes/components/health/CHealth.tscn" id="3_q7bng"] [ext_resource type="PackedScene" uid="uid://c4ikbhojckpnc" path="res://scenes/components/health/CHealth.tscn" id="3_q7bng"]
[ext_resource type="Script" uid="uid://rux15j7q78e8" path="res://forge/abilities/RExplodingSwordThrow.cs" id="4_11013"] [ext_resource type="Resource" uid="uid://cdxbwirfiaipi" path="res://scenes/player_controller/resources/forge/exploding_sword_throw.tres" id="4_11013"]
[ext_resource type="Script" uid="uid://baiapod3csndf" path="res://scenes/components/health/RHealth.cs" id="4_abfq8"] [ext_resource type="Script" uid="uid://baiapod3csndf" path="res://scenes/components/health/RHealth.cs" id="4_abfq8"]
[ext_resource type="Resource" uid="uid://bjyd801wvverk" path="res://scenes/player_controller/resources/player_health.tres" id="4_m8gvy"] [ext_resource type="Resource" uid="uid://bjyd801wvverk" path="res://scenes/player_controller/resources/player_health.tres" id="4_m8gvy"]
[ext_resource type="Resource" uid="uid://cpdaw41ah5gic" path="res://inputs/base_mode/rotate_y.tres" id="4_rxwoh"] [ext_resource type="Resource" uid="uid://cpdaw41ah5gic" path="res://inputs/base_mode/rotate_y.tres" id="4_rxwoh"]
@@ -56,12 +56,6 @@
[ext_resource type="Texture2D" uid="uid://c40orhfdgsim" path="res://assets/ui/IconGodotNode/white/icon_circle.png" id="45_u8rdp"] [ext_resource type="Texture2D" uid="uid://c40orhfdgsim" path="res://assets/ui/IconGodotNode/white/icon_circle.png" id="45_u8rdp"]
[ext_resource type="PackedScene" uid="uid://cyw8p0p6a78tl" path="res://scenes/ui/healthbar/healthbar.tscn" id="47_76kmc"] [ext_resource type="PackedScene" uid="uid://cyw8p0p6a78tl" path="res://scenes/ui/healthbar/healthbar.tscn" id="47_76kmc"]
[sub_resource type="Resource" id="Resource_5b7hb"]
script = ExtResource("4_11013")
Explosion = ExtResource("5_ue7xq")
Cost = 10.0
metadata/_custom_type_script = "uid://rux15j7q78e8"
[sub_resource type="Resource" id="Resource_cb2lu"] [sub_resource type="Resource" id="Resource_cb2lu"]
script = ExtResource("2_x835q") script = ExtResource("2_x835q")
DamageDealt = 10.0 DamageDealt = 10.0
@@ -126,7 +120,7 @@ collision_mask = 272
script = ExtResource("1_poq2x") script = ExtResource("1_poq2x")
EmpoweredAction = ExtResource("7_qheee") EmpoweredAction = ExtResource("7_qheee")
ManaRegen = ExtResource("3_n24vh") ManaRegen = ExtResource("3_n24vh")
AbilityLoadout = [SubResource("Resource_5b7hb")] AbilityLoadout = [ExtResource("4_11013")]
AimAssistStrength = 0.3 AimAssistStrength = 0.3
AimAssistReductionWhenCloseToTarget = 0.1 AimAssistReductionWhenCloseToTarget = 0.1
AimAssistReductionStartDistance = 8.0 AimAssistReductionStartDistance = 8.0

View File

@@ -12,7 +12,9 @@ using Movementtests.tools;
namespace Movementtests.systems; namespace Movementtests.systems;
public record struct WeaponLandPayload(int Damage, bool IsCritical); public record struct WeaponLandPayload();
public record struct WeaponFlyingPayload(string Message);
public record struct WeaponLeftPayload();
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_sword.png")] [GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_sword.png")]
public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
@@ -41,6 +43,7 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
public StateChartState FlyingState = null!; public StateChartState FlyingState = null!;
public StateChartState PlantedState = null!; public StateChartState PlantedState = null!;
private ShapeCast3D _dashCast3D = null!; private ShapeCast3D _dashCast3D = null!;
public Timer WeaponFlyingTick = null!;
private Transform3D _startTransform; private Transform3D _startTransform;
private Vector3 _startMeshRotation; private Vector3 _startMeshRotation;
@@ -54,6 +57,8 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
public StandardMaterial3D WeaponLocationIndicatorMaterial { get; set; } = null!; public StandardMaterial3D WeaponLocationIndicatorMaterial { get; set; } = null!;
public MeshInstance3D WeaponMesh { get; set; } = null!; public MeshInstance3D WeaponMesh { get; set; } = null!;
public Tag WeaponLeftTag;
public Tag WeaponFlyingTickTag;
public Tag WeaponLandTag; public Tag WeaponLandTag;
public void Init() public void Init()
@@ -67,6 +72,8 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
WeaponLocationIndicator.Visible = false; WeaponLocationIndicator.Visible = false;
WeaponLocationIndicatorMaterial = (WeaponLocationIndicator.GetActiveMaterial(0) as StandardMaterial3D)!; WeaponLocationIndicatorMaterial = (WeaponLocationIndicator.GetActiveMaterial(0) as StandardMaterial3D)!;
WeaponFlyingTick = GetNode<Timer>("WeaponFlyingTick");
WeaponMesh = GetNode<MeshInstance3D>("Weapon"); WeaponMesh = GetNode<MeshInstance3D>("Weapon");
_startMeshRotation = WeaponMesh.Rotation; _startMeshRotation = WeaponMesh.Rotation;
@@ -88,12 +95,29 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
Abilities = new(this); Abilities = new(this);
Events = new(); Events = new();
WeaponLeftTag = Tag.RequestTag(tagsManager, "events.weapon.left");
WeaponFlyingTickTag = Tag.RequestTag(tagsManager, "events.weapon.flyingTick");
WeaponLandTag = Tag.RequestTag(tagsManager, "events.weapon.land"); WeaponLandTag = Tag.RequestTag(tagsManager, "events.weapon.land");
BodyEntered += OnThrownWeaponReachesGround; BodyEntered += OnThrownWeaponReachesGround;
InHandState.StateExited += WeaponLeft; InHandState.StateExited += WeaponLeft;
InHandState.StateEntered += WeaponBack; InHandState.StateEntered += WeaponBack;
FlyingState.StateEntered += FlyingStarted;
FlyingState.StateExited += FlyingEnded;
WeaponFlyingTick.Timeout += RaiseWeaponFlyingTickEvent;
}
public void FlyingStarted()
{
RaiseWeaponFlyingTickEvent();
WeaponFlyingTick.Start();
}
public void FlyingEnded()
{
WeaponFlyingTick.Stop();
} }
public void WeaponLeft() public void WeaponLeft()
@@ -121,6 +145,7 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
public void ThrowWeapon(Vector3 end, bool hasHit, Vector3 collisionLocation, Vector3 collisionNormal, Node collidedObject) public void ThrowWeapon(Vector3 end, bool hasHit, Vector3 collisionLocation, Vector3 collisionNormal, Node collidedObject)
{ {
_weaponState.SendEvent("throw"); _weaponState.SendEvent("throw");
RaiseWeaponLeftEvent();
// WeaponLocationIndicatorMaterial.StencilColor = new Color(1f, 1f, 1f); // WeaponLocationIndicatorMaterial.StencilColor = new Color(1f, 1f, 1f);
@@ -129,7 +154,6 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
PlantNormal = collisionNormal; PlantNormal = collisionNormal;
LookAt(end); LookAt(end);
var tween = GetTree().CreateTween(); var tween = GetTree().CreateTween();
tween.TweenProperty(this, "global_position", end, StraightThrowDuration); tween.TweenProperty(this, "global_position", end, StraightThrowDuration);
if (hasHit) if (hasHit)
@@ -149,7 +173,30 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
Source = this, Source = this,
Target = victim, Target = victim,
EventMagnitude = 25f, EventMagnitude = 25f,
Payload = new WeaponLandPayload(Damage: 25, IsCritical: true) Payload = new WeaponLandPayload()
});
}
public void RaiseWeaponLeftEvent()
{
Events.Raise(new EventData<WeaponLeftPayload>
{
EventTags = WeaponLeftTag.GetSingleTagContainer(),
Source = this,
EventMagnitude = 25f,
Payload = new WeaponLeftPayload()
});
}
public void RaiseWeaponFlyingTickEvent()
{
Events.Raise(new EventData<WeaponFlyingPayload>
{
EventTags = WeaponFlyingTickTag.GetSingleTagContainer(),
Source = this,
EventMagnitude = 12f,
Payload = new WeaponFlyingPayload(Message: "flying")
}); });
} }
@@ -170,6 +217,8 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
public void RethrowWeapon() public void RethrowWeapon()
{ {
_weaponState.SendEvent("throw"); _weaponState.SendEvent("throw");
RaiseWeaponLeftEvent();
_throwDirection = Vector3.Up; _throwDirection = Vector3.Up;
ThrowWeaponOnCurve(); ThrowWeaponOnCurve();
} }

View File

@@ -50,6 +50,9 @@ max_contacts_reported = 1
script = ExtResource("1_csqwk") script = ExtResource("1_csqwk")
RDamage = SubResource("Resource_jpdh0") RDamage = SubResource("Resource_jpdh0")
[node name="WeaponFlyingTick" type="Timer" parent="." unique_id=656309486]
wait_time = 0.2
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=884463982] [node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=884463982]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0)
shape = SubResource("CylinderShape3D_avini") shape = SubResource("CylinderShape3D_avini")

View File

@@ -1,8 +1,10 @@
[gd_resource type="Resource" script_class="RExplodingSwordThrow" format=3 uid="uid://cdxbwirfiaipi"] [gd_resource type="Resource" script_class="RExplodingSword" format=3 uid="uid://cdxbwirfiaipi"]
[ext_resource type="Script" uid="uid://rux15j7q78e8" path="res://forge/abilities/RExplodingSwordThrow.cs" id="1_5iq8v"] [ext_resource type="PackedScene" uid="uid://duju3atqgltkg" path="res://scenes/explosion/explosion.tscn" id="1_aru71"]
[ext_resource type="Script" path="res://forge/abilities/RExplodingSword.cs" id="2_syk3q"]
[resource] [resource]
script = ExtResource("1_5iq8v") script = ExtResource("2_syk3q")
Cost = 20.0 Explosion = ExtResource("1_aru71")
Cost = 10.0
metadata/_custom_type_script = "uid://rux15j7q78e8" metadata/_custom_type_script = "uid://rux15j7q78e8"

View File

@@ -6,7 +6,10 @@ using Gamesmiths.Forge.Effects;
using Gamesmiths.Forge.Effects.Components; using Gamesmiths.Forge.Effects.Components;
using Gamesmiths.Forge.Effects.Duration; using Gamesmiths.Forge.Effects.Duration;
using Gamesmiths.Forge.Effects.Magnitudes; using Gamesmiths.Forge.Effects.Magnitudes;
using Gamesmiths.Forge.Effects.Modifiers;
using Gamesmiths.Forge.Effects.Periodic;
using Gamesmiths.Forge.Events; using Gamesmiths.Forge.Events;
using Gamesmiths.Forge.Godot.Resources.Abilities;
using Gamesmiths.Forge.Tags; using Gamesmiths.Forge.Tags;
using Godot; using Godot;
@@ -707,25 +710,83 @@ public partial class PlayerController : CharacterBody3D,
foreach (var weaponLandAbility in AbilityLoadout) foreach (var weaponLandAbility in AbilityLoadout)
{ {
var grantAbilityConfig = new GrantAbilityConfig( // var weaponLeftTag = Tag.RequestTag(tagsManager,"abilities.weapon.left").GetSingleTagContainer();
weaponLandAbility.Ability(tagsManager, WeaponSystem), // var leftGrantAbilityConfig = new GrantAbilityConfig(
// weaponLandAbility.Ability(tagsManager, weaponLeftTag, WeaponSystem),
// ScalableLevel: new ScalableInt(1),
// RemovalPolicy: AbilityDeactivationPolicy.CancelImmediately,
// InhibitionPolicy: AbilityDeactivationPolicy.CancelImmediately,
// TryActivateOnGrant: false,
// TryActivateOnEnable: false,
// LevelOverridePolicy: LevelComparison.Higher);
//
// var leftGrantComponent = new GrantAbilityEffectComponent([leftGrantAbilityConfig]);
// var leftGrantEffect = new EffectData(
// "Grant Weapon Left Ability",
// new DurationData(DurationType.Infinite),
// effectComponents: [leftGrantComponent]);
// EffectsManager.ApplyEffect(new Effect(leftGrantEffect, new EffectOwnership(this, this)));
//
// var weaponLandedTag = Tag.RequestTag(tagsManager, "abilities.weapon.land").GetSingleTagContainer();
// var landGrantAbilityConfig = new GrantAbilityConfig(
// weaponLandAbility.Ability(tagsManager, weaponLandedTag, WeaponSystem),
// ScalableLevel: new ScalableInt(1),
// RemovalPolicy: AbilityDeactivationPolicy.CancelImmediately,
// InhibitionPolicy: AbilityDeactivationPolicy.CancelImmediately,
// TryActivateOnGrant: false,
// TryActivateOnEnable: false,
// LevelOverridePolicy: LevelComparison.Higher);
//
// var landGrantComponent = new GrantAbilityEffectComponent([landGrantAbilityConfig]);
// var landGrantEffect = new EffectData(
// "Grant Weapon Land Ability",
// new DurationData(DurationType.Infinite),
// effectComponents: [landGrantComponent]);
// EffectsManager.ApplyEffect(new Effect(landGrantEffect, new EffectOwnership(this, this)));
//
//////////////////////////////////////////////
var weaponFlyingTag = Tag.RequestTag(tagsManager,"abilities.weapon.flying").GetSingleTagContainer();
var weaponFlyingAbilityData = new AbilityData(
name: "Exploding Flying Sword",
abilityTags: weaponFlyingTag,
instancingPolicy: AbilityInstancingPolicy.PerEntity,
abilityTriggerData: AbilityTriggerData.ForEvent<WeaponFlyingPayload>(WeaponSystem.WeaponFlyingTickTag),
behaviorFactory: () => new ExplodingSwordThrowBehavior<WeaponFlyingPayload>(WeaponSystem, Explosion));
var flyingGrantAbilityConfig = new GrantAbilityConfig(
weaponFlyingAbilityData,
ScalableLevel: new ScalableInt(1), ScalableLevel: new ScalableInt(1),
RemovalPolicy: AbilityDeactivationPolicy.CancelImmediately, RemovalPolicy: AbilityDeactivationPolicy.CancelImmediately,
InhibitionPolicy: AbilityDeactivationPolicy.CancelImmediately, InhibitionPolicy: AbilityDeactivationPolicy.CancelImmediately,
TryActivateOnGrant: false, TryActivateOnGrant: false,
TryActivateOnEnable: false, TryActivateOnEnable: true,
LevelOverridePolicy: LevelComparison.Higher); LevelOverridePolicy: LevelComparison.Higher);
var grantComponent = new GrantAbilityEffectComponent([grantAbilityConfig]); var flyingGrantComponent = new GrantAbilityEffectComponent([flyingGrantAbilityConfig]);
var grantEffect = new EffectData( var flyingGrantEffect = new EffectData(
"Grant Weapon Land Ability", "Grant Weapon Flying Ability",
new DurationData(DurationType.Infinite), new DurationData(DurationType.Infinite),
effectComponents: [grantComponent]); effectComponents: [flyingGrantComponent]
EffectsManager.ApplyEffect(new Effect(grantEffect, new EffectOwnership(this, this))); );
}
EffectsManager.ApplyEffect(new Effect(flyingGrantEffect, new EffectOwnership(this, this)));
}
// Forge events // Forge events
EventSubscriptionToken token = WeaponSystem.Events.Subscribe<WeaponLandPayload>(WeaponSystem.WeaponLandTag, OnWeaponLanded); var weaponLeftToken = WeaponSystem.Events.Subscribe<WeaponLeftPayload>(WeaponSystem.WeaponLeftTag, OnWeaponLeft);
var weaponFlyingToken = WeaponSystem.Events.Subscribe<WeaponFlyingPayload>(WeaponSystem.WeaponFlyingTickTag, data => Events.Raise(data));
var weaponLandedToken = WeaponSystem.Events.Subscribe<WeaponLandPayload>(WeaponSystem.WeaponLandTag, OnWeaponLanded);
}
public void OnWeaponLeft(EventData<WeaponLeftPayload> data)
{
var target = data.Target;
var tagsManager = ForgeManager.GetTagsManager(this);
var weaponLeftTag = Tag.RequestTag(tagsManager, "abilities.weapon.left").GetSingleTagContainer();
if (weaponLeftTag == null) return;
Abilities.TryActivateAbilitiesByTag(weaponLeftTag, target, out var landedFailures);
} }
public void OnWeaponLanded(EventData<WeaponLandPayload> data) public void OnWeaponLanded(EventData<WeaponLandPayload> data)
@@ -736,15 +797,13 @@ public partial class PlayerController : CharacterBody3D,
var weaponLandPayload = data.Payload; var weaponLandPayload = data.Payload;
var tagsManager = ForgeManager.GetTagsManager(this); var tagsManager = ForgeManager.GetTagsManager(this);
var weaponLandTag = Tag.RequestTag(tagsManager, "abilities.weapon.land").GetSingleTagContainer(); var weaponLandTag = Tag.RequestTag(tagsManager, "abilities.weapon.land").GetSingleTagContainer();
if (weaponLandTag == null) return; if (weaponLandTag == null) return;
var anyActivated = Abilities.TryActivateAbilitiesByTag( var anyActivated = Abilities.TryActivateAbilitiesByTag(
weaponLandTag, weaponLandTag,
target, target,
out var failures); out var failures);
if (anyActivated)
{
}
} }
/////////////////////////// ///////////////////////////