Files
zeling_v2/Assets/Scripts/Combat/DamageInfo.cs
2026-05-08 11:04:00 +08:00

83 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;
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 同步初始化 AmountAmount 始终以 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> { }
}