using UnityEngine; using BaseGames.Core.Events; namespace BaseGames.Combat { /// /// 单次伤害信息。流水线:RawDamage → Amount(护盾修改)→ FinalDamage(防御减免后)。 /// ⚠️ 非 readonly struct — Builder 就地写入字段。 /// [System.Serializable] public struct DamageInfo { public int RawDamage; // HitBox 设定的原始值(Builder.SetRaw 写入一次) public int Amount; // 流水线中被护盾/防御修改 public int FinalDamage; // HurtBox 写入,最终 HP 扣除量 public Vector2 KnockbackDirection; public float KnockbackForce; public float HitStunDuration; public DamageType Type; public DamageCategory Category; public DamageFlags Flags; public DamageTags Tags; public Vector2 SourcePosition; public int SourceLayer; public HitFxType FxType; public BreakLevel Break; public string SourceId; public string SkillId; // ── Builder ────────────────────────────────────────────────────────── public class Builder { private DamageInfo _d; public Builder() { } // SetRaw 同步初始化 Amount(Amount 始终以 RawDamage 为起点) public Builder SetRaw(int v) { _d.RawDamage = v; _d.Amount = v; return this; } public Builder SetType(DamageType v) { _d.Type = v; return this; } public Builder SetCategory(DamageCategory v){ _d.Category = v; return this; } public Builder SetFlags(DamageFlags v) { _d.Flags = v; return this; } public Builder SetTags(DamageTags v) { _d.Tags = v; return this; } public Builder SetSkillId(string v) { _d.SkillId = v; return this; } public Builder SetSourceId(string v) { _d.SourceId = v; return this; } public Builder SetKnockback(Vector2 dir, float force) { _d.KnockbackDirection = dir; _d.KnockbackForce = force; return this; } public Builder SetStun(float dur) { _d.HitStunDuration = dur; return this; } public Builder SetFx(HitFxType v) { _d.FxType = v; return this; } public Builder SetBreak(BreakLevel v) { _d.Break = v; return this; } public Builder SetSourcePos(Vector2 v) { _d.SourcePosition = v; return this; } public Builder SetLayer(int v) { _d.SourceLayer = v; return this; } public DamageInfo Build() => _d; } /// /// ⚡ 零堆分配工厂(热路径首选)。直接从 DamageSourceSO 填入基础字段。 /// KnockbackDirection / SourcePosition / SourceLayer 等运行时字段由调用方就地赋值。 /// public static DamageInfo From(DamageSourceSO so) { int baseAmt = Mathf.RoundToInt(so.BaseDamage * so.DamageMultiplier); return new DamageInfo { RawDamage = baseAmt, Amount = baseAmt, Type = so.Type, Category = so.Category, Flags = so.Flags, Tags = so.Tags, HitStunDuration = so.HitStunDuration, FxType = so.FxType, Break = so.BreakLevel, SourceId = so.sourceId, SkillId = so.skillId, }; } } /// 伤害事件频道(EVT_DamageDealt)。 [UnityEngine.CreateAssetMenu(menuName = "Events/DamageDealt")] public class DamageInfoEventChannelSO : BaseEventChannelSO { } }