Damage dealing through meta attribute and custom exec
This commit is contained in:
134
forge/calculators/ForgeDamageExecution.cs
Normal file
134
forge/calculators/ForgeDamageExecution.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user