Files
Gen_Hack-and-Slash-Roguelit…/Client/Assets/Scripts/Entity/LivingEntity.cs
2025-09-02 11:08:15 +08:00

163 lines
6.7 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 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需要更新属性缓存
}
}
}
}