Files
zeling_v2/Assets/Scripts/Combat/StatusEffects/StatusEffect.cs
2026-05-13 09:19:54 +08:00

105 lines
4.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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>宿主 ManagerOnApply 时注入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();
}
}