using System; using System.Collections.Generic; using Data; using Managers; using UnityEngine; namespace Entity { // 假设 Entity 基类如下结构 // public abstract class Entity // { // public virtual Attributes baseAttributes { get; protected set; } = new Attributes(); // public virtual Attributes attributes { get; protected set; } = new Attributes(); // public virtual void Tick(float deltaTime) { /* Base entity update logic */ } // } /// /// 表示一个具有生命周期、属性和可受健康状态(Hediff)影响的实体。 /// public class LivingEntity : Entity { // 存储应用于此实体的所有健康状态(Hediff)列表。 protected List hediffs = new List(); // 标记实体属性是否需要重新计算。当Hediff发生变化时,此标记会被设置为true。 private bool _needUpdateAttributes = true; // 缓存实体的基础属性,这些属性不受动态Hediff影响,但可能受基类或Def影响。 private Attributes _cachedBaseAttributes; /// /// 获取实体的基础属性。这些属性通常来源于实体的定义(Def),并可能受到常驻的基础健康状态(Base Hediffs)影响。 /// public override Attributes baseAttributes { get { // 仅在 _cachedBaseAttributes 为 null 时计算一次 if(_cachedBaseAttributes == null) { var defAttributes = base.baseAttributes; var hediffOffset = new AttributesOffsetDef(); // 这里假设 SaveManager.Instance.baseHediffs 指的是“所有实体共通的基础Hediff” // 并且这些基础 Hediff 也会影响 baseAttributes foreach (var hediff in SaveManager.Instance.baseHediffs) { hediffOffset += hediff.CurrentTotalAttributesOffset; } _cachedBaseAttributes = defAttributes.GetModifiedAttributes(hediffOffset); } return _cachedBaseAttributes; } } // 缓存实体当前的最终属性,该属性是基础属性加上所有健康状态(Hediff)修正后的结果。 private Attributes _cachedAttributes; /// /// 获取实体当前的最终属性,包括所有健康状态(Hediff)的修正。 /// public override Attributes attributes { get { if (_needUpdateAttributes || _cachedAttributes == null) { // 1. 获取旧的属性值(在重新计算之前,也就是当前的缓存值) // 仅用于需要与“当前值”进行比较或钳制的情况,例如最大生命值Buff移除时 var oldCachedAttributes = _cachedAttributes; if (oldCachedAttributes == null) // 如果是第一次计算,初始化一个默认值或者使用baseAttributes { oldCachedAttributes = baseAttributes; } // 2. 计算完全修正后的“理论”最大属性值(基于 baseAttributes 和所有 Hediff 偏移) var totalModifiedAttributes = baseAttributes; var hediffOffset = new AttributesOffsetDef(); foreach (var hediff in hediffs) { hediffOffset += hediff.CurrentTotalAttributesOffset; } // 应用所有 hediff 的偏移到 totalModifiedAttributes totalModifiedAttributes = totalModifiedAttributes.GetModifiedAttributes(hediffOffset); _cachedAttributes = Attributes.Min(oldCachedAttributes, totalModifiedAttributes); // 标记为已更新 _needUpdateAttributes = false; } return _cachedAttributes; } protected set => _cachedAttributes = value; } /// /// 供内部使用的属性标记方法。当 Hediff 自身状态改变并影响属性时,通过此方法通知 LivingEntity。 /// internal void SetAttribsDirty() { _needUpdateAttributes = true; } /// /// 每帧调用的更新函数,传入时间增量。 /// public override void Tick() { base.Tick(); // 调用基类的Tick方法 // 遍历并更新所有健康状态,从后向前循环以安全地移除已完成的Hediff for (var i = hediffs.Count - 1; i >= 0; i--) { var hediff = hediffs[i]; hediff.Tick(Time.deltaTime); // 调用单个Hediff的Tick方法 // 检查Hediff是否已达到移除条件 if (hediff.ShouldRemove) { RemoveHediff(hediff); // 使用RemoveHediff方法确保OnRemoved被调用并设置_needUpdateAttributes } } } /// /// 添加一个新的健康状态到实体上。 /// /// 要添加的 Hediff 实例。 public void AddHediff(Hediff hediff) { if (hediff == null) { Debug.LogWarning("尝试向活体实体添加一个空的健康状态(Hediff)。"); return; } hediffs.Add(hediff); // 通知Hediff它被添加到一个实体上,进行初始化等操作,并传入自身引用 hediff.OnAdded(this); _needUpdateAttributes = true; // 添加新Hediff,需要更新属性缓存 } /// /// 移除一个特定的健康状态。 /// /// 要移除的 Hediff 实例。 public void RemoveHediff(Hediff hediff) { if (hediff == null) { Debug.LogWarning("尝试从活体实体移除一个空的健康状态(Hediff)。"); return; } // 尝试从列表中移除Hediff if (hediffs.Remove(hediff)) { // 通知Hediff它被从实体上移除,进行清理等操作,并传入自身引用 hediff.OnRemoved(this); _needUpdateAttributes = true; // 移除Hediff,需要更新属性缓存 } } } }