yow it's working or wat
Some checks failed
Create tag and build when new code gets to main / BumpTag (push) Successful in 24s
Create tag and build when new code gets to main / Export (push) Failing after 4m23s

This commit is contained in:
2026-03-29 17:30:14 +02:00
parent dafb0c96cc
commit 42ff38f39b
7 changed files with 276 additions and 236 deletions

View File

@@ -17,6 +17,10 @@ public partial class ForgeManager : Node
// Statuses // Statuses
"status.stunned", "status.stunned",
"status.weapon.inHand",
"status.weapon.flying",
"status.weapon.planted",
// Abilities // Abilities
"abilities.weapon.land", "abilities.weapon.land",
"abilities.weapon.flying", "abilities.weapon.flying",
@@ -25,9 +29,15 @@ public partial class ForgeManager : Node
// Events // Events
"events.combat.damage", "events.combat.damage",
"events.combat.hit", "events.combat.hit",
"events.weapon.left",
"events.weapon.flyingTick", "events.weapon.flyingTick",
"events.weapon.land", "events.weapon.startedFlying",
"events.weapon.stoppedFlying",
"events.weapon.handToFlying",
"events.weapon.flyingToHand",
"events.weapon.plantedToHand",
"events.weapon.plantedToFlying",
"events.weapon.planted",
// Cooldowns // Cooldowns
"cooldown.empoweredAction", "cooldown.empoweredAction",

View File

@@ -13,28 +13,13 @@ using Movementtests.interfaces;
namespace Movementtests.forge.abilities; namespace Movementtests.forge.abilities;
[GlobalClass] [GlobalClass]
public partial class RAbilityBase(float cost, float cooldown) : Resource, IAbilityBase public partial class RAbilityBase : Resource
{ {
[Export(PropertyHint.Range, "0,100,1,or_greater")] public RAbilityBase()
public float Cost { get; set; } = cost;
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
public float Cooldown { get; set; } = cooldown;
public RAbilityBase() : this(20.0f, 0.0f)
{ {
} }
public virtual AbilityData Ability(TagsManager tagsManager, TagContainer? tags, Node3D owner) public virtual AbilityData Ability(TagContainer? tags, Node3D owner)
{
throw new NotImplementedException();
}
public virtual EffectData CostEffect(TagsManager tagsManager)
{
throw new NotImplementedException();
}
public virtual EffectData CooldownEffect(TagsManager tagsManager)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View File

@@ -8,74 +8,32 @@ 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.interfaces;
using Movementtests.systems; using Movementtests.systems;
namespace Movementtests.forge.abilities; namespace Movementtests.forge.abilities;
public record struct ExplodingSwordCreation(Node3D Owner);
[GlobalClass, Icon("res://assets/ui/IconGodotNode/white/icon_projectile.png")] [GlobalClass, Icon("res://assets/ui/IconGodotNode/white/icon_projectile.png")]
public partial class RExplodingSword(PackedScene? explosion, float cost, float cooldown) : RAbilityBase(cost, cooldown) public partial class RExplodingSword(PackedScene? explosion) : Resource, IAbilityBase<ExplodingSwordCreation, WeaponEventPayload>
{ {
[Export] public PackedScene? Explosion { get; set; } = explosion; [Export] public PackedScene? Explosion { get; set; } = explosion;
public RExplodingSword() : this(null, 20.0f, 0.0f) public RExplodingSword() : this(null) {}
{
}
public override AbilityData Ability(TagsManager tagsManager, TagContainer? tags, Node3D owner) public AbilityData Ability(ExplodingSwordCreation creationData, TagContainer? tags)
{ {
return new AbilityData( return new AbilityData(
name: "Exploding Sword Throw", name: "Exploding Sword Throw",
costEffect: CostEffect(tagsManager),
cooldownEffects: [CooldownEffect(tagsManager)],
abilityTags: tags, abilityTags: tags,
instancingPolicy: AbilityInstancingPolicy.PerEntity, instancingPolicy: AbilityInstancingPolicy.PerEntity,
behaviorFactory: () => new ExplodingSwordThrowBehavior<WeaponLeftPayload>(owner, Explosion)); behaviorFactory: () => new ExplodingSwordThrowBehavior<WeaponEventPayload>(creationData.Owner, Explosion));
} }
public override EffectData CostEffect(TagsManager tagsManager) public IAbilityBehavior<WeaponEventPayload> Behavior(ExplodingSwordCreation creationData)
{ {
return new( return new ExplodingSwordThrowBehavior<WeaponEventPayload>(creationData.Owner, Explosion);
"Exploding Sword Throw Mana Cost",
new DurationData(DurationType.Instant),
new[]
{
new Modifier(
"PlayerAttributeSet.Mana",
ModifierOperation.FlatBonus,
new ModifierMagnitude(
MagnitudeCalculationType.ScalableFloat,
new ScalableFloat(-Cost)
)
)
},
cues: new []
{
new CueData(
CueTags: Tag.RequestTag(tagsManager, "cues.resources.mana").GetSingleTagContainer(),
MinValue: 0,
MaxValue: 100,
MagnitudeType: CueMagnitudeType.AttributeValueChange,
MagnitudeAttribute: "PlayerAttributeSet.Mana"
)
});
}
public override EffectData CooldownEffect(TagsManager tagsManager)
{
return new(
"Exploding Sword Throw Cooldown",
new DurationData(
DurationType.HasDuration,
new ModifierMagnitude(
MagnitudeCalculationType.ScalableFloat,
new ScalableFloat(Cooldown))),
effectComponents: new[]
{
new ModifierTagsEffectComponent(
tagsManager.RequestTagContainer(new[] { "cooldown.empoweredSwordThrow" })
)
});
} }
} }
@@ -85,18 +43,21 @@ public class ExplodingSwordThrowBehavior<TPayload>(Node3D owner, PackedScene? ex
private PackedScene? _explosion = explosion; private PackedScene? _explosion = explosion;
public void OnStarted(AbilityBehaviorContext context, TPayload payload) public void OnStarted(AbilityBehaviorContext context, TPayload payload)
{ {
GD.Print(payload);
if (_explosion?.Instantiate() is not Explosion explosion) if (_explosion?.Instantiate() is not Explosion explosion)
{ {
GD.Print("Cannot instantiate");
context.InstanceHandle.End(); context.InstanceHandle.End();
return; return;
} }
if (!_owner.IsInsideTree()) if (!_owner.IsInsideTree())
{ {
GD.Print("Not inside tree");
context.InstanceHandle.End(); context.InstanceHandle.End();
return; return;
} }
GD.Print("EXPLOSION");
explosion.Radius = 6f; explosion.Radius = 6f;
_owner.GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, explosion); _owner.GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, explosion);
@@ -110,15 +71,3 @@ public class ExplodingSwordThrowBehavior<TPayload>(Node3D owner, PackedScene? ex
{ {
} }
} }
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

@@ -11,17 +11,18 @@ using Movementtests.systems;
namespace Movementtests.tools.calculators; namespace Movementtests.tools.calculators;
public class FlyingWeaponExecution(WeaponSystem weaponSystem) : CustomExecution public class FlyingWeaponExecution(WeaponSystem weaponSystem) : CustomExecution
{ {
public override ModifierEvaluatedData[] EvaluateExecution(Effect effect, IForgeEntity target, EffectEvaluatedData? effectEvaluatedData) public override ModifierEvaluatedData[] EvaluateExecution(Effect effect, IForgeEntity target, EffectEvaluatedData? effectEvaluatedData)
{ {
GD.Print("Custom execution executed"); GD.Print("Custom execution executed");
weaponSystem.Events.Raise(new EventData<WeaponFlyingPayload> weaponSystem.Events.Raise(new EventData<WeaponEventPayload>
{ {
EventTags = weaponSystem.WeaponFlyingTickTag.GetSingleTagContainer()!, EventTags = weaponSystem.WeaponFlyingTickEventTag.GetSingleTagContainer()!,
Source = weaponSystem, Source = weaponSystem,
EventMagnitude = 12f, EventMagnitude = 12f,
Payload = new WeaponFlyingPayload(Message: "flying") Payload = new WeaponEventPayload(Message: "flying")
}); });
return []; return [];

View File

@@ -5,9 +5,8 @@ using Godot;
namespace Movementtests.interfaces; namespace Movementtests.interfaces;
public interface IAbilityBase public interface IAbilityBase<TCreation, TPayload>
{ {
AbilityData Ability(TagsManager tagsManager, TagContainer? tags, Node3D owner); AbilityData Ability(TCreation creationData, TagContainer? tags);
EffectData CostEffect(TagsManager tagsManager); IAbilityBehavior<TPayload> Behavior(TCreation creationData);
EffectData CooldownEffect(TagsManager tagsManager);
} }

View File

@@ -1,20 +1,41 @@
using System; using System;
using System.Collections.Generic;
using Gamesmiths.Forge.Abilities;
using Gamesmiths.Forge.Core; using Gamesmiths.Forge.Core;
using Gamesmiths.Forge.Effects; using Gamesmiths.Forge.Effects;
using Gamesmiths.Forge.Effects.Calculator;
using Gamesmiths.Forge.Effects.Components;
using Gamesmiths.Forge.Effects.Duration;
using Gamesmiths.Forge.Effects.Magnitudes;
using Gamesmiths.Forge.Effects.Periodic;
using Gamesmiths.Forge.Events; using Gamesmiths.Forge.Events;
using Gamesmiths.Forge.Tags; using Gamesmiths.Forge.Tags;
using Godot; using Godot;
using GodotStateCharts; using GodotStateCharts;
using Movementtests.addons.godot_state_charts.csharp;
using Movementtests.forge.abilities;
using Movementtests.interfaces; using Movementtests.interfaces;
using Movementtests.scenes.player_controller.components.weapon; using Movementtests.scenes.player_controller.components.weapon;
using Movementtests.systems.damage; using Movementtests.systems.damage;
using Movementtests.tools; using Movementtests.tools;
using Movementtests.tools.calculators;
namespace Movementtests.systems; namespace Movementtests.systems;
public record struct WeaponLandPayload(); public record struct WeaponEventPayload(String Message);
public record struct WeaponFlyingPayload(string Message);
public record struct WeaponLeftPayload();
public class ClosureBehavior<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){}
}
[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
@@ -42,6 +63,12 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
public StateChartState InHandState = null!; public StateChartState InHandState = null!;
public StateChartState FlyingState = null!; public StateChartState FlyingState = null!;
public StateChartState PlantedState = 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!; private ShapeCast3D _dashCast3D = null!;
public Timer WeaponFlyingTick = null!; public Timer WeaponFlyingTick = null!;
@@ -57,9 +84,23 @@ 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 WeaponFlyingTickEventTag;
public Tag WeaponFlyingTickTag; public Tag WeaponStartedFlyingEventTag;
public Tag WeaponLandTag; public Tag WeaponStoppedFlyingEventTag;
public Tag WeaponHandToFlyingEventTag;
public Tag WeaponFlyingToHandEventTag;
public Tag WeaponPlantedToHandEventTag;
public Tag WeaponPlantedToFlyingEventTag;
public Tag WeaponPlantedEventTag;
public Tag WeaponInHandStatusTag;
public Tag WeaponFlyingStatusTag;
public Tag WeaponPlantedStatusTag;
public Tag WeaponFlyingAbilityTag;
private RAbilityBase? _flyingAbility;
public List<RAbilityBase> AbilityLoadout { get; } = [];
public void Init() public void Init()
{ {
@@ -67,6 +108,11 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
InHandState = StateChartState.Of(GetNode("StateChart/Root/InHand")); InHandState = StateChartState.Of(GetNode("StateChart/Root/InHand"));
FlyingState = StateChartState.Of(GetNode("StateChart/Root/Flying")); FlyingState = StateChartState.Of(GetNode("StateChart/Root/Flying"));
PlantedState = StateChartState.Of(GetNode("StateChart/Root/Planted")); PlantedState = StateChartState.Of(GetNode("StateChart/Root/Planted"));
_handToFlying = Transition.Of(GetNode("StateChart/Root/InHand/ToFlying"));
_flyingToHand = Transition.Of(GetNode("StateChart/Root/Flying/ToHand"));
_plantedToHand = Transition.Of(GetNode("StateChart/Root/Planted/ToHand"));
_plantedToFlying = Transition.Of(GetNode("StateChart/Root/Planted/ToFlying"));
_toPlanted = Transition.Of(GetNode("StateChart/Root/ToPlanted"));
WeaponLocationIndicator = GetNode<MeshInstance3D>("WeaponLocationIndicator"); WeaponLocationIndicator = GetNode<MeshInstance3D>("WeaponLocationIndicator");
WeaponLocationIndicator.Visible = false; WeaponLocationIndicator.Visible = false;
@@ -81,12 +127,29 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
Freeze = true; Freeze = true;
Visible = false; Visible = false;
// Forge
var tagsManager = ForgeManager.GetTagsManager(this); var tagsManager = ForgeManager.GetTagsManager(this);
var cuesManager = ForgeManager.GetCuesManager(this); var cuesManager = ForgeManager.GetCuesManager(this);
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");
WeaponFlyingAbilityTag = Tag.RequestTag(tagsManager,"abilities.weapon.flying");
var baseTags = new TagContainer( var baseTags = new TagContainer(
tagsManager, tagsManager,
[ [
Tag.RequestTag(tagsManager, "weapon") Tag.RequestTag(tagsManager, "weapon"),
]); ]);
Attributes = new EntityAttributes(new WeaponAttributeSet()); Attributes = new EntityAttributes(new WeaponAttributeSet());
@@ -95,29 +158,149 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
Abilities = new(this); Abilities = new(this);
Events = new(); Events = new();
WeaponLeftTag = Tag.RequestTag(tagsManager, "events.weapon.left"); CreateFlyingAbility();
WeaponFlyingTickTag = Tag.RequestTag(tagsManager, "events.weapon.flyingTick");
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; _handToFlying.Taken += () =>
{
Events.Raise(new EventData<WeaponEventPayload>
{
EventTags = WeaponHandToFlyingEventTag.GetSingleTagContainer()!,
Source = this,
Payload = new WeaponEventPayload(Message: "handToFlying")
});
Events.Raise(new EventData<WeaponEventPayload>
{
EventTags = WeaponStartedFlyingEventTag.GetSingleTagContainer()!,
Source = this,
Payload = new WeaponEventPayload(Message: "startedFlying")
});
};
_flyingToHand.Taken += () =>
{
Events.Raise(new EventData<WeaponEventPayload>
{
EventTags = WeaponFlyingToHandEventTag.GetSingleTagContainer()!,
Source = this,
Payload = new WeaponEventPayload(Message: "flyingToHand")
});
Events.Raise(new EventData<WeaponEventPayload>
{
EventTags = WeaponStoppedFlyingEventTag.GetSingleTagContainer()!,
Source = this,
Payload = new WeaponEventPayload(Message: "stoppedFlying")
});
};
_plantedToHand.Taken += () =>
{
Events.Raise(new EventData<WeaponEventPayload>
{
EventTags = WeaponPlantedToHandEventTag.GetSingleTagContainer()!,
Source = this,
Payload = new WeaponEventPayload(Message: "plantedToHand")
});
};
_plantedToFlying.Taken += () =>
{
Events.Raise(new EventData<WeaponEventPayload>
{
EventTags = WeaponPlantedToFlyingEventTag.GetSingleTagContainer()!,
Source = this,
Payload = new WeaponEventPayload(Message: "plantedToFlying")
});
Events.Raise(new EventData<WeaponEventPayload>
{
EventTags = WeaponStartedFlyingEventTag.GetSingleTagContainer()!,
Source = this,
Payload = new WeaponEventPayload(Message: "startedFlying")
});
};
_toPlanted.Taken += () =>
{
Events.Raise(new EventData<WeaponEventPayload>
{
EventTags = WeaponPlantedEventTag.GetSingleTagContainer()!,
Source = this,
Target = _plantedEntity,
Payload = new WeaponEventPayload(Message: "planted")
});
Events.Raise(new EventData<WeaponEventPayload>
{
EventTags = WeaponStoppedFlyingEventTag.GetSingleTagContainer()!,
Source = this,
Payload = new WeaponEventPayload(Message: "stoppedFlying")
});
};
Events.Subscribe<WeaponEventPayload>(WeaponStoppedFlyingEventTag, data =>
{
GD.Print("This is removing the periodic effect to the flying weapon");
GD.Print(data.Payload.Message);
if (_flyingWeaponEffectHandle is { IsValid: true }) EffectsManager.RemoveEffect(_flyingWeaponEffectHandle);
});
}
private ActiveEffectHandle? _flyingWeaponEffectHandle;
public void CreateFlyingAbility()
{
var flyingWeaponEffectData = new EffectData(
"Flying Weapon Effect Data",
new DurationData(DurationType.Infinite),
customExecutions:
[
new FlyingWeaponExecution(this)
],
periodicData: new PeriodicData(new ScalableFloat(0.2f), false, PeriodInhibitionRemovedPolicy.ResetPeriod)
);
var weaponHandToFlyingAbilityData = new AbilityData(
name: "WeaponHandToFlyingSword",
abilityTags: WeaponFlyingAbilityTag.GetSingleTagContainer(),
instancingPolicy: AbilityInstancingPolicy.PerEntity,
abilityTriggerData: AbilityTriggerData.ForEvent<WeaponEventPayload>(WeaponStartedFlyingEventTag),
behaviorFactory: () => new ClosureBehavior<WeaponEventPayload>((ctx, payload) =>
{
GD.Print("This is applying the periodic effect to the flying weapon");
GD.Print(payload.Message);
_flyingWeaponEffectHandle = EffectsManager.ApplyEffect(new Effect(flyingWeaponEffectData, new EffectOwnership(this, this)));
}));
Abilities.GrantAbilityPermanently(weaponHandToFlyingAbilityData, 1, LevelComparison.None, this);
} }
public void FlyingStarted() public void GrantNewAbilityForWeaponFly(RExplodingSword ability)
{ {
RaiseWeaponFlyingTickEvent(); var weaponFlyingAbilityData = new AbilityData(
WeaponFlyingTick.Start(); name: "WeaponFlyingSwordAbility",
} abilityTags: WeaponFlyingAbilityTag.GetSingleTagContainer(),
instancingPolicy: AbilityInstancingPolicy.PerEntity,
abilityTriggerData: AbilityTriggerData.ForEvent<WeaponEventPayload>(WeaponFlyingTickEventTag),
behaviorFactory: () => ability.Behavior(new ExplodingSwordCreation(this)));
public void FlyingEnded() var weaponFlyGrantAbilityConfig = new GrantAbilityConfig(
{ weaponFlyingAbilityData,
WeaponFlyingTick.Stop(); ScalableLevel: new ScalableInt(1),
RemovalPolicy: AbilityDeactivationPolicy.CancelImmediately,
InhibitionPolicy: AbilityDeactivationPolicy.CancelImmediately,
TryActivateOnGrant: false,
TryActivateOnEnable: false,
LevelOverridePolicy: LevelComparison.Higher);
var weaponFlyGrantComponent = new GrantAbilityEffectComponent([weaponFlyGrantAbilityConfig]);
var weaponFlyGrantEffect = new EffectData(
"Grant Weapon Fly Ability",
new DurationData(DurationType.Infinite),
effectComponents: [weaponFlyGrantComponent]);
EffectsManager.ApplyEffect(new Effect(weaponFlyGrantEffect, new EffectOwnership(this, this)));
GD.Print("New weapon flight ability granted");
} }
public void WeaponLeft() public void WeaponLeft()
@@ -145,9 +328,6 @@ 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);
_throwDirection = (end - GlobalPosition).Normalized(); _throwDirection = (end - GlobalPosition).Normalized();
PlantLocation = collisionLocation; PlantLocation = collisionLocation;
@@ -165,48 +345,14 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
tween.Finished += ThrowWeaponOnCurve; tween.Finished += ThrowWeaponOnCurve;
} }
public void RaiseWeaponLandEvent(IForgeEntity? victim = null) private IForgeEntity? _plantedEntity;
{
Events.Raise(new EventData<WeaponLandPayload>
{
EventTags = WeaponLandTag.GetSingleTagContainer(),
Source = this,
Target = victim,
EventMagnitude = 25f,
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")
});
}
public void PlantInEnemy(Node3D enemy) public void PlantInEnemy(Node3D enemy)
{ {
GetTree().GetRoot().CallDeferred(Node.MethodName.RemoveChild, this); GetTree().GetRoot().CallDeferred(Node.MethodName.RemoveChild, this);
enemy.CallDeferred(Node.MethodName.AddChild, this); enemy.CallDeferred(Node.MethodName.AddChild, this);
if (enemy is IForgeEntity victim) RaiseWeaponLandEvent(victim); if (enemy is IForgeEntity victim) _plantedEntity = victim;
else RaiseWeaponLandEvent(); else _plantedEntity = null;
if (enemy is IDamageable damageable) if (enemy is IDamageable damageable)
{ {
@@ -217,7 +363,6 @@ 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();
@@ -231,17 +376,14 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
public void PlantWeaponInWall() public void PlantWeaponInWall()
{ {
_weaponState.SendEvent("plant");
Freeze = true; Freeze = true;
WeaponMesh.Rotation = _startMeshRotation; WeaponMesh.Rotation = _startMeshRotation;
// WeaponLocationIndicatorMaterial.StencilColor = new Color(1f, 0.2f, 0.2f); // WeaponLocationIndicatorMaterial.StencilColor = new Color(1f, 0.2f, 0.2f);
if (PlantObject is Node3D node) if (PlantObject is Node3D node)
{
PlantInEnemy(node); PlantInEnemy(node);
}
else RaiseWeaponLandEvent(); _weaponState.SendEvent("plant");
CallDeferred(Node3D.MethodName.SetGlobalPosition, PlantLocation); CallDeferred(Node3D.MethodName.SetGlobalPosition, PlantLocation);
CallDeferred(Node3D.MethodName.LookAt, GlobalTransform.Origin + PlantNormal, Vector3.Up, true); CallDeferred(Node3D.MethodName.LookAt, GlobalTransform.Origin + PlantNormal, Vector3.Up, true);

View File

@@ -113,7 +113,7 @@ public partial class PlayerController : CharacterBody3D,
[ExportGroup("Abilities")] [ExportGroup("Abilities")]
[ExportSubgroup("WeaponThrow")] [ExportSubgroup("WeaponThrow")]
[Export] public RAbilityBase[] AbilityLoadout = []; [Export] public RExplodingSword[] AbilityLoadout = [];
// Combat stuff // Combat stuff
[ExportCategory("Combat")] [ExportCategory("Combat")]
@@ -712,93 +712,49 @@ public partial class PlayerController : CharacterBody3D,
foreach (var weaponLandAbility in AbilityLoadout) foreach (var weaponLandAbility in AbilityLoadout)
{ {
// var weaponLeftTag = Tag.RequestTag(tagsManager,"abilities.weapon.left").GetSingleTagContainer(); var weaponLeftTag = Tag.RequestTag(tagsManager,"abilities.weapon.left").GetSingleTagContainer();
// var leftGrantAbilityConfig = new GrantAbilityConfig( var leftGrantAbilityConfig = new GrantAbilityConfig(
// weaponLandAbility.Ability(tagsManager, weaponLeftTag, WeaponSystem), weaponLandAbility.Ability(new ExplodingSwordCreation(WeaponSystem), weaponLeftTag),
// 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: true, TryActivateOnEnable: false,
LevelOverridePolicy: LevelComparison.Higher); LevelOverridePolicy: LevelComparison.Higher);
var flyingGrantComponent = new GrantAbilityEffectComponent([flyingGrantAbilityConfig]); var leftGrantComponent = new GrantAbilityEffectComponent([leftGrantAbilityConfig]);
var flyingGrantEffect = new EffectData( var leftGrantEffect = new EffectData(
"Grant Weapon Flying Ability", "Grant Weapon Left Ability",
new DurationData(DurationType.Infinite), new DurationData(DurationType.Infinite),
effectComponents: [flyingGrantComponent] effectComponents: [leftGrantComponent]);
); EffectsManager.ApplyEffect(new Effect(leftGrantEffect, new EffectOwnership(this, this)));
EffectsManager.ApplyEffect(new Effect(flyingGrantEffect, new EffectOwnership(this, this))); var weaponLandedTag = Tag.RequestTag(tagsManager, "abilities.weapon.land").GetSingleTagContainer();
var landGrantAbilityConfig = new GrantAbilityConfig(
weaponLandAbility.Ability(new ExplodingSwordCreation(WeaponSystem), weaponLandedTag),
ScalableLevel: new ScalableInt(1),
RemovalPolicy: AbilityDeactivationPolicy.CancelImmediately,
InhibitionPolicy: AbilityDeactivationPolicy.CancelImmediately,
TryActivateOnGrant: false,
TryActivateOnEnable: false,
LevelOverridePolicy: LevelComparison.Higher);
flyingWeaponEffect = new EffectData( var landGrantComponent = new GrantAbilityEffectComponent([landGrantAbilityConfig]);
"Flying Weapon", var landGrantEffect = new EffectData(
"Grant Weapon Land Ability",
new DurationData(DurationType.Infinite), new DurationData(DurationType.Infinite),
customExecutions: effectComponents: [landGrantComponent]);
[ EffectsManager.ApplyEffect(new Effect(landGrantEffect, new EffectOwnership(this, this)));
new FlyingWeaponExecution(WeaponSystem)
], GetTree().CreateTimer(5).Timeout += () => WeaponSystem.GrantNewAbilityForWeaponFly(weaponLandAbility);
periodicData: new PeriodicData(new ScalableFloat(1f), false, PeriodInhibitionRemovedPolicy.ResetPeriod)
);
flyingWeaponEffectHandle = EffectsManager.ApplyEffect(new Effect(flyingWeaponEffect, new EffectOwnership(this, this)));
flyingWeaponEffectHandle?.SetInhibit(true);
} }
// Forge events // Forge events
var weaponLeftToken = WeaponSystem.Events.Subscribe<WeaponLeftPayload>(WeaponSystem.WeaponLeftTag, OnWeaponLeft); var weaponLeftToken = WeaponSystem.Events.Subscribe<WeaponEventPayload>(WeaponSystem.WeaponStartedFlyingEventTag, OnWeaponLeft);
var weaponFlyingToken = WeaponSystem.Events.Subscribe<WeaponFlyingPayload>(WeaponSystem.WeaponFlyingTickTag, data => Events.Raise(data)); var weaponLandedToken = WeaponSystem.Events.Subscribe<WeaponEventPayload>(WeaponSystem.WeaponStoppedFlyingEventTag, OnWeaponLanded);
var weaponLandedToken = WeaponSystem.Events.Subscribe<WeaponLandPayload>(WeaponSystem.WeaponLandTag, OnWeaponLanded);
} }
private EffectData flyingWeaponEffect; public void OnWeaponLeft(EventData<WeaponEventPayload> data)
private ActiveEffectHandle? flyingWeaponEffectHandle;
public void OnWeaponLeft(EventData<WeaponLeftPayload> data)
{ {
//flyingWeaponEffectHandle?.SetInhibit(false);
var target = data.Target; var target = data.Target;
var tagsManager = ForgeManager.GetTagsManager(this); var tagsManager = ForgeManager.GetTagsManager(this);
@@ -807,10 +763,8 @@ public partial class PlayerController : CharacterBody3D,
Abilities.TryActivateAbilitiesByTag(weaponLeftTag, target, out var landedFailures); Abilities.TryActivateAbilitiesByTag(weaponLeftTag, target, out var landedFailures);
} }
public void OnWeaponLanded(EventData<WeaponLandPayload> data) public void OnWeaponLanded(EventData<WeaponEventPayload> data)
{ {
flyingWeaponEffectHandle?.SetInhibit(true);
var source = data.Source; var source = data.Source;
var target = data.Target; var target = data.Target;
var magnitude = data.EventMagnitude; var magnitude = data.EventMagnitude;