using UnityEngine; namespace BaseGames.Combat.StatusEffects { /// /// 状态效果抽象基类(架构 06_CombatModule §11)。 /// ⚠️ 类名为 StatusEffect(非 StatusEffectBase)。 /// /// 生命周期: /// OnApply(owner) → Update(delta) × N [内部调用 OnTick()] → OnExpire() /// /// 叠加规则:同类型再次施加时调用 OnStack();Manager 保证每种类型只有一个实例。 /// public abstract class StatusEffect { /// 效果类型标识(用作 Dictionary key)。 public abstract StatusEffectType EffectType { get; } /// 最大叠加层数(1 = 不可叠加,重复施加只刷新持续时间)。 public abstract int MaxStacks { get; } /// 当前叠加层数。 public int StackCount { get; protected set; } = 1; /// 当前剩余持续时间(秒)。 public float Duration { get; protected set; } /// 每次 Tick 的间隔(秒)。 public float TickInterval { get; protected set; } /// 是否已过期(由 Manager 每帧检查)。 public virtual bool IsExpired => Duration <= 0f; /// /// 施加此效果时将被净化的互斥效果类型列表。 /// 例:FireEffect 返回 [Freeze],表示施加燃烧时会同时移除冻结。 /// public virtual StatusEffectType[] MutualExclusions => System.Array.Empty(); /// /// 阻止此效果施加的效果类型列表。 /// 宿主当前存在列表中任意效果时,本效果将被拒绝施加。 /// 例:StaggerEffect 返回 [Stun],表示眩晕状态下无法再施加硬直。 /// public virtual StatusEffectType[] BlockedBy => System.Array.Empty(); private float _tickTimer; /// 宿主 Manager(OnApply 时注入,OnTick/OnExpire 中可访问)。 public StatusEffectManager Owner { get; protected set; } // ── 生命周期回调(可重写)───────────────────────────────────────── /// /// 效果施加时调用(Owner 在此注入)。 /// ⚠️ 参数为 StatusEffectManager(非 IDamageable),架构 06 §11。 /// public virtual void OnApply(StatusEffectManager owner) { Owner = owner; Duration = GetBaseDuration(); } /// /// 同类型效果再次施加时调用(叠层 / 刷新持续时间)。 /// 默认行为:刷新持续时间并叠加层数(若未达上限)。 /// public virtual void OnStack() { Duration = GetBaseDuration(); StackCount = Mathf.Min(StackCount + 1, MaxStacks); } /// 每个 TickInterval 秒调用一次(DoT 等周期效果)。 public virtual void OnTick() { } /// 效果到期 / 被净化时调用。⚠️ 名称 OnExpire(非 OnRemove)。 public virtual void OnExpire() { } // ── 框架驱动(由 Manager.Update 调用,每帧执行)────────────────── /// 递减持续时间并在到达 Tick 间隔时触发 OnTick。 public void Update(float delta) { Duration -= delta; if (TickInterval <= 0f) return; _tickTimer += delta; if (_tickTimer >= TickInterval) { _tickTimer -= TickInterval; OnTick(); } } // ── 子类必须实现 ────────────────────────────────────────────────── /// 返回本类型效果的基础持续时间(秒)。 protected abstract float GetBaseDuration(); /// 返回本效果的本地化显示名称。 public abstract string GetDisplayName(); } }