186 lines
4.3 KiB
C#

using Kryz.CharacterStats.Examples;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class Health : Resource
{
protected CharacterStats character;
protected EntityEventBroker broker;
protected AbsorbEffectInstance absorbEffectInstance;
public UnityEvent<float> onMaxHealthChanged = new UnityEvent<float>();
public UnityEvent onDeath = new UnityEvent();
private bool noCost = false;
public bool NoCost => noCost;
protected bool invulnerable = false;
public bool Invulnerable => invulnerable;
float incomingValue;
float percentStatMitigation;
float reducedDamage;
private bool isDead;
public UnityEvent<bool> OnInvulnerabilityStateChanged = new UnityEvent<bool>();
public UnityEvent OnDodgedSuccessfully = new UnityEvent();
public void SetIsDeadState(bool isDead)
{
this.isDead = isDead;
canRegen = !isDead;
}
protected virtual void Awake()
{
broker = GetComponent<EntityEventBroker>();
character = GetComponent<CharacterStats>();
absorbEffectInstance = GetComponent<AbsorbEffectInstance>();
character.onAllStatsUpdated.AddListener(CalculateMaxValueBasedOnStat);
}
protected override void Start()
{
baseRegenValue = character.GetStat("healthregen").BaseValue;
baseMaxValue = character.GetStat("maxhealth").BaseValue;
base.Start();
}
public bool EnoughHealth(float cost)
{
if (noCost || invulnerable) return true;
return cost <= currentValue;
}
public void SetInvulnerabilityState(bool isInvulnerable)
{
invulnerable = isInvulnerable;
OnInvulnerabilityStateChanged.Invoke(invulnerable);
}
public void ApplyDamage(DamageArgs args)
{
if (isDead) return;
broker.OnIncomingDamage.Invoke(args);
UpdateValue(args.currentValue);
CheckForDeath(args);
broker.OnIncomingDamageProcessed.Invoke(args);
}
public void ApplyHeal(HealArgs args)
{
if (isDead) return;
broker.OnIncomingHeal.Invoke(args);
UpdateValue(args.currentValue);
broker.OnIncomingHealProcessed.Invoke(args);
}
private void UpdateValue(float incomingValue)
{
currentValue += incomingValue;
currentValue = Mathf.Clamp(currentValue, 0, maxValue);
//Debug.Log("CurrentHealth: " + currentValue);
onResourceChanged.Invoke(currentValue);
}
private void CheckForDeath(DamageArgs args)
{
if (currentValue == 0)
{
//dead;
isDead = true;
args.targetDead = true;
onDeath.Invoke();
}
}
public override void ChangeValue(float value)
{
//Debug.Log("Value to change: " + value);
if (isDead) return;
incomingValue = value;
if (invulnerable && incomingValue < 0) return;
currentValue += incomingValue;
currentValue = Mathf.Clamp(currentValue, 0, maxValue);
if (currentValue == 0)
{
//dead;
onDeath.Invoke();
}
//Debug.Log("CurrentHealth: " + currentValue);
onResourceChanged.Invoke(currentValue);
}
public void ChangeValueDirect(float value)
{
//Debug.Log("Value to change: " + value);
if (isDead) return;
incomingValue = value;
if (invulnerable && incomingValue < 0) return;
currentValue += incomingValue;
currentValue = Mathf.Clamp(currentValue, 0, maxValue);
if (currentValue == 0)
{
//dead;
onDeath.Invoke();
}
//Debug.Log("CurrentHealth: " + currentValue);
onResourceChanged.Invoke(currentValue);
}
public override float GetMaxValue()
{
return base.GetMaxValue();
}
public virtual void CalculateMaxValueBasedOnStat()
{
maxValue = character.GetStat("maxhealth").Value;
CalculateRegenValueBasedOnStat();
onMaxHealthChanged.Invoke(maxValue);
}
public void CalculateRegenValueBasedOnStat()
{
flatRegen = character.GetStat("healthregen").Value;
}
public override void SetMaxValue(float value)
{
base.SetMaxValue(value);
onMaxHealthChanged.Invoke(maxValue);
}
}