Effects handling rework

This commit is contained in:
Rendo 2025-07-07 17:29:10 +05:00
commit 63930450a3
21 changed files with 100 additions and 228 deletions

View file

@ -7,8 +7,8 @@ namespace Newlon.Components;
public partial class Entity : Node2D
{
#region Health points
[Export] public float MaxHP { get; private set; }
public float HP { get; private set; }
[Export] public float MaxHP;
public float HP;
[Signal] public delegate void OnHPChangedEventHandler(int deltaHP, Node origin);
[Signal] public delegate void OnDamagedEventHandler();
@ -55,9 +55,14 @@ public partial class Entity : Node2D
}
#endregion
#region Effects
[Export] private Array<Effect> _effectImmunities;
private readonly Effect[] _activeEffectSlots = new Effect[Utility.EffectSlotCount];
private readonly Timer[] _effectSlotTimers = new Timer[Utility.EffectSlotCount];
[Export] private Array<Effect> _effectImmunities = new();
private readonly Dictionary<string,Effect> _activeEffectSlots = new();
private readonly Dictionary<string,Timer> _effectSlotTimers = new();
[Signal] public delegate void EffectStartedEventHandler(Effect what);
[Signal] public delegate void EffectEndedEventHandler(Effect what);
[Signal] public delegate void EffectContinuedEventHandler(Effect what);
public virtual void GiveEffect(Effect what)
{
@ -65,7 +70,22 @@ public partial class Entity : Node2D
{
return;
}
int slot = (int)what.Slot;
string slot = what.Slot;
if (_activeEffectSlots.ContainsKey(slot) == false)
{
InitSlot(slot);
}
if (what == _activeEffectSlots[slot])
{
EmitSignal(SignalName.EffectContinued, what);
}
else
{
EmitSignal(SignalName.EffectStarted, what);
}
if (_activeEffectSlots[slot] != null)
{
_effectSlotTimers[slot].Stop();
@ -76,24 +96,39 @@ public partial class Entity : Node2D
what.Enter(this);
_activeEffectSlots[slot] = what;
}
private void InitSlot(string key)
{
_activeEffectSlots.Add(key, null);
var timer = new Timer() { Autostart = false, OneShot = true };
AddChild(timer);
timer.Timeout += () => { EndEffectAtSlot(key); };
_effectSlotTimers.Add(key, timer);
}
public void EndEffect(Effect what)
{
what.Exit(this);
_activeEffectSlots[(int)what.Slot] = null;
EndEffectAtSlot(what.Slot);
}
public void ProcessEffects()
{
for (int i = 0; i < Utility.EffectSlotCount; i++)
_activeEffectSlots[i]?.Process(this);
foreach(string key in _activeEffectSlots.Keys)
_activeEffectSlots[key]?.Process(this);
}
private void EndEffectAtSlot(int slot)
private void EndEffectAtSlot(string slot)
{
_activeEffectSlots[slot].Exit(this);
_activeEffectSlots[slot] = null;
EmitSignal(SignalName.EffectEnded, _activeEffectSlots[slot]);
}
#endregion
#region LocalTimescale
@ -113,16 +148,6 @@ public partial class Entity : Node2D
public override void _Ready()
{
HP = MaxHP;
// Effect timers setup
for(int i = 0; i < Utility.EffectSlotCount; i++)
{
var timer = new Timer() {Autostart = false, OneShot = true};
_effectSlotTimers[i] = timer;
AddChild(timer);
int current_index = i;
timer.Timeout += () => {EndEffectAtSlot(current_index);};
}
}
#endregion
}