using Photon.Pun; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; public class StatusEffectInstance : MonoBehaviour { public bool canStack; public bool canRefresh; [Header("Set by code:")] public PhotonView owner; public bool IsActive => effectStateCoroutine != null; public float endEffectTime; public List activeStacks = new List(); public UnityEvent OnEffectStackAddedEvent = new UnityEvent(); public UnityEvent OnEffectEnded = new UnityEvent(); protected Coroutine effectStateCoroutine; protected virtual void Awake() { owner = GetComponentInParent(); } public virtual void ApplyEffect(StatusEffect effect) { if (CanAddStack()) { AddStack(effect); } else if(CanRefresh()) { RefreshEffect(effect); } } protected virtual void AddStack(StatusEffect addedEffect) { activeStacks.Add(addedEffect); OnEffectStackAdded(); } protected virtual bool CanAddStack() { return canStack || (!canStack && activeStacks.Count <= 0); } protected virtual bool CanRefresh() { return canRefresh; } protected virtual float GetHighestDuration() { float highestDuration = 0; for (int i = activeStacks.Count - 1; i >= 0; i--) { if (activeStacks[i].duration > highestDuration) highestDuration = activeStacks[i].duration; } return highestDuration; } protected virtual void RefreshEffect(StatusEffect effect) { } protected virtual void OnEffectStackAdded() { UpdateEndEffectTime(); if (!IsActive) effectStateCoroutine = StartCoroutine(EffectStateCoroutine()); OnEffectStackAddedEvent.Invoke(); } protected virtual void UpdateEndEffectTime() { endEffectTime = Time.time + GetHighestDuration(); } protected virtual IEnumerator EffectStateCoroutine() { EffectStateStarted(); while (Time.time < endEffectTime) { yield return null; } EffectStateEnded(); } protected virtual void EffectStateStarted() { } protected virtual void EffectStateEnded() { effectStateCoroutine = null; activeStacks.Clear(); OnEffectEnded.Invoke(); } }