using Godot; namespace Newlon.Components.Zombies; public partial class RuntimeZombieData : Entity { [Export] private Armor _armor; [Signal] public delegate void HasBeenKilledEventHandler(RuntimeZombieData who); [Signal] public delegate void HPChangedMixedEventHandler(EntitySignalContext context); public bool AbleToEat = true; public override void _Ready() { base._Ready(); OnHPChanged += HPChangedMixedInvokerSource; LocalTimescale -= (float)GD.Randf() / 100.0f; } public override void Heal(float amount, Node origin) { var context = new EntitySignalContext() { source = (Entity)origin, target = this, actionAmount = amount, deltaHP = Mathf.Clamp(HP+amount,0,MaxHP-amount) }; if (_armor != null) { HP += _armor.Heal(amount); } else HP += amount; EmitSignal(SignalName.OnHPChanged, amount, origin); if (HP > MaxHP) { HP = MaxHP; } } public override void TakeDamage(float amount, Node origin) { var damage = amount; if (_armor != null) { damage = _armor.RecieveDamage(amount); } EmitSignal(SignalName.OnDamaged); var context = new EntitySignalContext() { source = origin, target = this, actionAmount = amount }; if (HP - damage <= 0) { var delta = -HP; HP = 0; EmitSignal(SignalName.OnHPChanged, context); context.deltaHP = delta; KillByDamage(); } else { HP -= damage; context.deltaHP = -damage; EmitSignal(SignalName.OnHPChanged, context); } } public void HPChangedMixedInvokerSource(EntitySignalContext context) { EmitSignal(SignalName.HPChangedMixed, context); } public void HPChangedMixedInvoker(float delta) { EmitSignal(SignalName.HPChangedMixed, new EntitySignalContext() { deltaHP = -delta, source = null, target = this, actionAmount = delta }); } public float GetMaxHPMixed() { if (_armor != null) return MaxHP + _armor.MaxHP; return MaxHP; } public float GetHPMixed() { if (_armor != null) return HP + _armor._hp; return HP; } #region Death sequence private bool _killed = false; public override void KillByDamage() { if (_killed) return; _killed = true; AbleToEat = false; EmitSignal(SignalName.HasBeenKilled,this); } #endregion }