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 onMaxHealthChanged = new UnityEvent(); 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 OnInvulnerabilityStateChanged = new UnityEvent(); public UnityEvent OnDodgedSuccessfully = new UnityEvent(); public void SetIsDeadState(bool isDead) { this.isDead = isDead; canRegen = !isDead; } protected virtual void Awake() { broker = GetComponent(); character = GetComponent(); absorbEffectInstance = GetComponent(); 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); } }