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();
}
}