using Chickensoft.Collections; using Godot; using System; using Zennysoft.Ma.Adapter; namespace Zennysoft.Game.Ma; public class HealthComponent : IHealthComponent { public IAutoProp CurrentHP => _currentHP; public IAutoProp MaximumHP => _maximumHP; private readonly AutoProp _currentHP; private readonly AutoProp _maximumHP; public event Action? HealthReachedZero; public event Action? DamageTaken; public bool AtFullHealth => CurrentHP.Value == MaximumHP.Value; private readonly int _initialValue; public HealthComponent(int initialHP) { _maximumHP = new AutoProp(initialHP); _currentHP = new AutoProp(initialHP); _initialValue = initialHP; } public void Reset() { _maximumHP.OnNext(_initialValue); _currentHP.OnNext(_initialValue); } public void Heal(int healAmount) { if (CurrentHP.Value <= 0) return; var cappedAmount = Math.Min(healAmount + _currentHP.Value, _maximumHP.Value); _currentHP.OnNext(cappedAmount); } public void Damage(int damageAmount) { if (CurrentHP.Value <= 0) return; var cappedAmount = Math.Max(_currentHP.Value - damageAmount, 0); _currentHP.OnNext(cappedAmount); if (cappedAmount == 0) HealthReachedZero?.Invoke(); else DamageTaken?.Invoke(); } public void SetCurrentHealth(int health) { var cappedAmount = Math.Min(health, _maximumHP.Value); _currentHP.OnNext(cappedAmount); } public void SetMaximumHealth(int health) { _maximumHP.OnNext(health); if (_currentHP.Value > _maximumHP.Value) _currentHP.OnNext(_maximumHP.Value); } public void RaiseMaximumHP(int raiseAmount, bool restoreHP = true) { _maximumHP.OnNext(_maximumHP.Value + raiseAmount); if (restoreHP) Heal(raiseAmount); } public void LowerMaximumHP(int lowerAmount) { _maximumHP.OnNext(Mathf.Max(_maximumHP.Value - lowerAmount, 1)); if (_currentHP.Value > _maximumHP.Value) _currentHP.OnNext(_maximumHP.Value); } }