134 lines
4.0 KiB
C#
134 lines
4.0 KiB
C#
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);
|
|
}
|
|
} |