83 lines
4.3 KiB
C#
83 lines
4.3 KiB
C#
using UnityEngine;
|
||
using BaseGames.Core.Events;
|
||
|
||
namespace BaseGames.Combat
|
||
{
|
||
/// <summary>
|
||
/// 单次伤害信息。流水线:RawDamage → Amount(护盾修改)→ FinalDamage(防御减免后)。
|
||
/// ⚠️ 非 readonly struct — Builder 就地写入字段。
|
||
/// </summary>
|
||
[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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// ⚡ 零堆分配工厂(热路径首选)。直接从 DamageSourceSO 填入基础字段。
|
||
/// KnockbackDirection / SourcePosition / SourceLayer 等运行时字段由调用方就地赋值。
|
||
/// </summary>
|
||
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,
|
||
};
|
||
}
|
||
}
|
||
|
||
/// <summary>伤害事件频道(EVT_DamageDealt)。</summary>
|
||
[UnityEngine.CreateAssetMenu(menuName = "Events/DamageDealt")]
|
||
public class DamageInfoEventChannelSO : BaseEventChannelSO<DamageInfo> { }
|
||
}
|