102 lines
3.9 KiB
C#
102 lines
3.9 KiB
C#
using System.Collections.Generic;
|
|
using Gamesmiths.Forge.Core;
|
|
using Gamesmiths.Forge.Effects;
|
|
using Gamesmiths.Forge.Effects.Calculator;
|
|
using Gamesmiths.Forge.Effects.Magnitudes;
|
|
using Gamesmiths.Forge.Events;
|
|
using Gamesmiths.Forge.Godot.Resources;
|
|
using Gamesmiths.Forge.Godot.Resources.Calculators;
|
|
using Godot;
|
|
using Movementtests.forge.abilities;
|
|
using Movementtests.scenes.components.knockback;
|
|
|
|
namespace Movementtests.tools.calculators;
|
|
|
|
|
|
public record KnockbackDone(float KnockbackValue, Vector3 knockbackDirection);
|
|
|
|
public class KnockbackExecution : CustomExecution
|
|
{
|
|
private readonly RKnockback _knockback;
|
|
private readonly ForgeTag _knockbackTag;
|
|
private readonly ForgeTagContainer? _knockbackReceiverEventTags;
|
|
private readonly ForgeTagContainer? _knockbackDealerEventTags;
|
|
|
|
public AttributeCaptureDefinition TargetIncomingDamage { get; }
|
|
|
|
public KnockbackExecution(ForgeTag knockbackTag, RKnockback knockback, ForgeTagContainer? knockbackDealerEventTags, ForgeTagContainer? knockbackReceiverEventTags)
|
|
{
|
|
_knockback = knockback;
|
|
_knockbackTag = knockbackTag;
|
|
_knockbackDealerEventTags = knockbackDealerEventTags;
|
|
_knockbackReceiverEventTags = knockbackReceiverEventTags;
|
|
|
|
TargetIncomingDamage = new AttributeCaptureDefinition(
|
|
"MetaAttributeSet.IncomingDamage",
|
|
AttributeCaptureSource.Target);
|
|
AttributesToCapture.Add(TargetIncomingDamage);
|
|
}
|
|
|
|
public override ModifierEvaluatedData[] EvaluateExecution(Effect effect, IForgeEntity target, EffectEvaluatedData? effectEvaluatedData)
|
|
{
|
|
var results = new List<ModifierEvaluatedData>();
|
|
if (!target.Tags.CombinedTags.HasTag(_knockbackTag.GetTag()))
|
|
return [.. results];
|
|
|
|
float targetIncomingDamage = CaptureAttributeMagnitude(
|
|
TargetIncomingDamage,
|
|
effect,
|
|
target,
|
|
effectEvaluatedData);
|
|
|
|
if (targetIncomingDamage <= 0)
|
|
return [.. results];
|
|
|
|
var knockbackValue = _knockback.Modifier * targetIncomingDamage / 100.0f;
|
|
|
|
if (_knockbackReceiverEventTags is null)
|
|
return [.. results];
|
|
|
|
var knockbackDirection = Vector3.Zero;
|
|
if (effectEvaluatedData?.TryGetContextData(out SimpleHitEffectData? hitEffectData) == true)
|
|
{
|
|
knockbackDirection = hitEffectData.SourceLocation.DirectionTo(hitEffectData.TargetLocation);
|
|
}
|
|
target.Events.Raise(new EventData<KnockbackDone>
|
|
{
|
|
EventTags = _knockbackReceiverEventTags.GetTagContainer(),
|
|
Source = effect.Ownership.Owner,
|
|
Target = target,
|
|
EventMagnitude = knockbackValue,
|
|
Payload = new KnockbackDone(knockbackValue, knockbackDirection)
|
|
});
|
|
|
|
if (effect.Ownership.Source is null || _knockbackDealerEventTags is null)
|
|
return [.. results];
|
|
|
|
effect.Ownership.Source.Events.Raise(new EventData<KnockbackDone>
|
|
{
|
|
EventTags = _knockbackDealerEventTags.GetTagContainer(),
|
|
Source = effect.Ownership.Owner,
|
|
Target = target,
|
|
EventMagnitude = knockbackValue,
|
|
Payload = new KnockbackDone(knockbackValue, knockbackDirection)
|
|
});
|
|
|
|
return [.. results];
|
|
}
|
|
}
|
|
|
|
[GlobalClass]
|
|
public partial class ForgeKnockbackExecution : ForgeCustomExecution
|
|
{
|
|
[Export] public ForgeTag? KnockbackableTag { get; set; }
|
|
[Export] public RKnockback? Knockback { get; set; }
|
|
[Export] public ForgeTagContainer? KnockbackDealerEventTags { get; set; }
|
|
[Export] public ForgeTagContainer? KnockbackReceiverEventTags { get; set; }
|
|
public override CustomExecution GetExecutionClass()
|
|
{
|
|
if (Knockback == null || KnockbackableTag == null) throw new System.ArgumentException("Knockback or KnockbackableTag is null");
|
|
return new KnockbackExecution(KnockbackableTag, Knockback, KnockbackDealerEventTags, KnockbackReceiverEventTags);
|
|
}
|
|
} |