89 lines
2.0 KiB
C#
89 lines
2.0 KiB
C#
using Chickensoft.Collections;
|
|
using Godot;
|
|
using System;
|
|
using Zennysoft.Ma.Adapter;
|
|
|
|
namespace Zennysoft.Game.Ma;
|
|
|
|
public class HealthComponent : IHealthComponent
|
|
{
|
|
public IAutoProp<int> CurrentHP => _currentHP;
|
|
|
|
public IAutoProp<int> MaximumHP => _maximumHP;
|
|
|
|
private readonly AutoProp<int> _currentHP;
|
|
|
|
private readonly AutoProp<int> _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<int>(initialHP);
|
|
_currentHP = new AutoProp<int>(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);
|
|
}
|
|
}
|