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