Files

163 lines
6.7 KiB
C#
Raw Permalink Normal View History

2025-09-02 11:08:15 +08:00
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 */ }
// }
/// <summary>
/// 表示一个具有生命周期、属性和可受健康状态Hediff影响的实体。
/// </summary>
public class LivingEntity : Entity
{
// 存储应用于此实体的所有健康状态Hediff列表。
protected List<Hediff> hediffs = new List<Hediff>();
// 标记实体属性是否需要重新计算。当Hediff发生变化时此标记会被设置为true。
private bool _needUpdateAttributes = true;
// 缓存实体的基础属性这些属性不受动态Hediff影响但可能受基类或Def影响。
private Attributes _cachedBaseAttributes;
/// <summary>
/// 获取实体的基础属性。这些属性通常来源于实体的定义Def并可能受到常驻的基础健康状态Base Hediffs影响。
/// </summary>
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;
/// <summary>
/// 获取实体当前的最终属性包括所有健康状态Hediff的修正。
/// </summary>
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;
}
/// <summary>
/// 供内部使用的属性标记方法。当 Hediff 自身状态改变并影响属性时,通过此方法通知 LivingEntity。
/// </summary>
internal void SetAttribsDirty()
{
_needUpdateAttributes = true;
}
/// <summary>
/// 每帧调用的更新函数,传入时间增量。
/// </summary>
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
}
}
}
/// <summary>
/// 添加一个新的健康状态到实体上。
/// </summary>
/// <param name="hediff">要添加的 Hediff 实例。</param>
public void AddHediff(Hediff hediff)
{
if (hediff == null)
{
Debug.LogWarning("尝试向活体实体添加一个空的健康状态Hediff。");
return;
}
hediffs.Add(hediff);
// 通知Hediff它被添加到一个实体上进行初始化等操作并传入自身引用
hediff.OnAdded(this);
_needUpdateAttributes = true; // 添加新Hediff需要更新属性缓存
}
/// <summary>
/// 移除一个特定的健康状态。
/// </summary>
/// <param name="hediff">要移除的 Hediff 实例。</param>
public void RemoveHediff(Hediff hediff)
{
if (hediff == null)
{
Debug.LogWarning("尝试从活体实体移除一个空的健康状态Hediff。");
return;
}
// 尝试从列表中移除Hediff
if (hediffs.Remove(hediff))
{
// 通知Hediff它被从实体上移除进行清理等操作并传入自身引用
hediff.OnRemoved(this);
_needUpdateAttributes = true; // 移除Hediff需要更新属性缓存
}
}
}
}