using System.Collections; using System.Collections.Generic; using UnityEngine; using Sirenix.OdinInspector; using KairoEngine.Core.GameActions; using KairoEngine.Stats.GameActions; namespace KairoEngine.Stats { [System.Serializable] public class StatusEffect { [SerializeField, HideInInspector] private string name = ""; [FoldoutGroup("@name")] public StatusEffectTemplate template; [FoldoutGroup("@name")] public Transform target; [FoldoutGroup("@name")] public Transform source; [FoldoutGroup("@name")] public int stack = 1; [SerializeField, HideInInspector] private List actionsControllerList; [SerializeField, HideInInspector] private GameActionContext context; [SerializeField, HideInInspector] private List time; public StatusEffect(StatusEffectTemplate template, Transform target = null, Transform source = null, StatsController statsController = null) { this.stack = 1; this.name = $"{template.title} ({stack})"; this.time = new List(); this.time.Add(0); this.target = target; this.source = source; this.template = template; this.actionsControllerList = new List(); this.actionsControllerList.Add(template.onAddController.Duplicate()); this.actionsControllerList.Add(template.onStackController.Duplicate()); this.actionsControllerList.Add(template.onWhileController.Duplicate()); this.actionsControllerList.Add(template.onDestackController.Duplicate()); this.actionsControllerList.Add(template.onRemoveController.Duplicate()); this.context = template.context.Duplicate(); foreach (var ctrl in actionsControllerList) ctrl.context = this.context; // Set Game Action Variables var targetVar = context.GetVariable("Target GameObject"); if(targetVar != null) ((GameActionContextGameObject)targetVar).value = this.target.gameObject; var statsVar = context.GetVariable("Stats"); if(statsVar != null) ((GameActionContextStatsController)statsVar).value = statsController; actionsControllerList[0].Start(); // Run the OnAdd actions } public void AddToStack() { if(template.maxStack <= stack) return; this.stack += 1; this.name = $"{template.title} ({stack})"; this.time.Add(0); this.actionsControllerList[1].Restart(); this.actionsControllerList[1].Start(); // Run the OnStack actions } public void OnRemove() { this.actionsControllerList[4].Start(); // Run OnRemove actions } /// Update times for each unit in the stack. If a unit has reached the template duration, /// it is removed from the stack and the OnDestack actions are run. /// How much time has passed since the last update. Just pass Time.deltaTime. public void Update(float elapsed) { if(this.template.hasDuration == false) return; for (int i = 0; i < this.time.Count; i++) this.time[i] += elapsed; for (int i = 0; i < this.time.Count; i++) { if(this.time[i] > template.duration) { this.time.RemoveAt(i); this.stack -= 1; this.name = $"{template.title} ({stack})"; if(stack > 0) { this.actionsControllerList[3].Restart(); this.actionsControllerList[3].Start(); // Tun OnDestack actions; } else OnRemove(); } } if(this.actionsControllerList[2].isDone || !this.actionsControllerList[2].started) { this.actionsControllerList[2].Restart(); this.actionsControllerList[2].Start(); // Run OnWhile actions } } } }