using System; using System.Collections.Generic; using System.Linq; using RPGCore.Core; using RPGCore.Core.Objects; using RPGCore.ObjectModules.EventObjectModule; using RPGCore.StatusEffect.ObjectModules.StatusObjectModule.Effects; using RPGCore.StatusEffect.ObjectModules.StatusObjectModule.Events; using UnityEngine; namespace RPGCore.StatusEffect.ObjectModules.StatusObjectModule { [Serializable] [RequireComponent(typeof(BaseObject))] public class StatusModule : ObjectModule { internal List statuses { get; private set; } = new(); [SerializeField] internal StatusUpdateType updateType; /// Checks if any has . public virtual bool IsControllable() { return !statuses.Any(status => status.definition.effects.Any(effect => effect is NotControllableEffect)); } /// Checks if any active that uses is present. public bool Check(StatusDefinitionSO definition) { return statuses.Any(status => status.definition == definition); } /// Adds new . public Status Apply(StatusDefinitionSO definition) { var status = new Status(definition, this); statuses.Add(status); status.OnApply_Internal(); parent.events.Invoke(new StatusStartEvent { status = status, target = parent }); return status; } /// Removes given forcefully. public void Remove(Status status) { if (status == null) return; if (!statuses.Contains(status)) return; status.OnRemove_Internal(); statuses.Remove(status); parent.events.Invoke(new StatusRemoveEvent { status = status, target = parent }); } /// Removes all es forcefully that uses . public void Remove(StatusDefinitionSO definition) { GetStatuses(definition).ForEach(Remove); } /// Executed internally when status ending itself (by timer or effect). internal void End(Status status) { if (status == null) return; if (!statuses.Contains(status)) return; status.OnEnd_Internal(); statuses.Remove(status); parent.events.Invoke(new StatusEndEvent { status = status, target = parent }); } /// Returns all active es. public List GetStatuses() { return statuses.ToList(); } /// Returns all active es that uses . public List GetStatuses(StatusDefinitionSO definition) { return statuses.Where(status => status.definition == definition).ToList(); } private void FixedUpdate() { if (updateType is StatusUpdateType.Automatically) statuses.ToList().ForEach(status => status.UpdateTime_Internal(Time.fixedDeltaTime)); } /// Update each status timer, decreases them by given seconds. public void UpdateTime(float deltaTime) { if (updateType is not StatusUpdateType.Manually) { Debug.LogError($"Updating status time available only when: {nameof(StatusUpdateType)} = {nameof(StatusUpdateType.Manually)}"); return; } statuses.ForEach(status => status.UpdateTime_Internal(deltaTime)); } } }