using System.Collections.Generic;
using Data;
using UnityEngine;
namespace Entity
{
///
/// 表示一个具有生命周期、属性和可受健康状态(Hediff)影响的实体。
///
public class LivingEntity : CombatantEntity
{
///
/// 当健康状态(Hediff)被添加到实体时触发的事件。
///
/// 触发事件的实体。
/// 被添加的Hediff实例。
public delegate void HediffAppliedEventHandler(LivingEntity entity, Hediff hediff);
///
/// 当健康状态(Hediff)从实体移除时触发的事件。
///
/// 触发事件的实体。
/// 被移除的Hediff实例。
public delegate void HediffRemovedEventHandler(LivingEntity entity, Hediff hediff);
public bool getBaseHediff;
private Attributes _cachedBaseAttributes;
// 标记实体属性是否需要重新计算。当Hediff发生变化时,此标记会被设置为true。
private bool _needUpdateAttributes = true;
// 存储应用于此实体的所有健康状态(Hediff)列表。
protected List hediffs = new();
public EntityPathManager pathManager;
// 指示当前是否正在使用路径寻路模式。
private bool _isUsingPathfinding;
// 路径寻路的距离阈值。
private const float PATHFINDING_DISTANCE_THRESHOLD = 10f;
public LivingEntity()
{
pathManager = new EntityPathManager(this);
}
///
/// 获取实体的基础属性。来源于实体的定义(Def)+健康状态。
///
public override Attributes BaseAttributes
{
get
{
if (_cachedBaseAttributes == null || _needUpdateAttributes)
{
var defAttributes = DefAttributes;
var hediffOffset = new AttributesOffsetDef();
foreach (var hediff in Hediffs)
{
if (hediff.CurrentStage == null)
continue;
var attributes = hediff.CurrentStage?.attributesOffset;
if (attributes != null) hediffOffset += attributes;
}
_cachedBaseAttributes = defAttributes.GetModifiedAttributes(hediffOffset);
_needUpdateAttributes = false;
AttributesNow = Attributes.Min(AttributesNow, _cachedBaseAttributes);
}
return _cachedBaseAttributes;
}
}
public override bool OnTargetPoint => pathManager.IsPathComplete;
public virtual IReadOnlyList Hediffs => hediffs.AsReadOnly();
///
/// Hediff被成功添加到此实体时触发。
///
public event HediffAppliedEventHandler OnHediffAdded;
///
/// Hediff被从此实体移除时触发。
///
public event HediffRemovedEventHandler OnHediffRemoved;
///
/// 供内部使用的属性标记方法。当 Hediff 自身状态改变并影响属性时,通过此方法通知 LivingEntity。
///
public void SetAttribsDirty()
{
_needUpdateAttributes = true;
}
///
/// 每帧调用的更新函数,传入时间增量。
///
public override void Tick()
{
base.Tick();
for (var i = hediffs.Count - 1; i >= 0; i--)
{
var hediff = hediffs[i];
hediff.Tick(Time.deltaTime);
if (hediff.ShouldRemove) RemoveHediff(hediff);
}
}
///
/// 添加一个新的健康状态到实体上。
///
/// 要添加的 Hediff 实例。
public void AddHediff(Hediff hediff)
{
if (hediff == null)
{
Debug.LogWarning("警告: 尝试向活体实体添加一个空的健康状态(Hediff)。");
return;
}
hediffs.Add(hediff);
hediff.OnAdded(this);
SetAttribsDirty();
OnHediffAdded?.Invoke(this, hediff);
}
///
/// 移除一个特定的健康状态。
///
/// 要移除的 Hediff 实例。
public void RemoveHediff(Hediff hediff)
{
if (hediff == null)
{
Debug.LogWarning("警告: 尝试从活体实体移除一个空的健康状态(Hediff)。");
return;
}
if (hediffs.Remove(hediff))
{
hediff.OnRemoved(this);
SetAttribsDirty();
OnHediffRemoved?.Invoke(this, hediff);
}
}
///
/// 设置实体的目标位置。
///
/// 目标位置。
/// 如果目标设置成功则返回 true,否则返回 false。
public override bool SetTarget(Vector3 pos)
{
bool baseSetResult = base.SetTarget(pos);
if (!baseSetResult)
{
_isUsingPathfinding = false;
return false;
}
float distance = (transform.position - pos).sqrMagnitude;
if (distance < PATHFINDING_DISTANCE_THRESHOLD * PATHFINDING_DISTANCE_THRESHOLD)
{
bool pathGenerated = pathManager.GeneratePath(pos);
if (pathGenerated)
{
_isUsingPathfinding = true;
return true;
}
else
{
_isUsingPathfinding = false;
return true;
}
}
else
{
_isUsingPathfinding = false;
return true;
}
}
///
/// 尝试移动实体。
///
public override void TryMove()
{
if (_isUsingPathfinding)
{
if (pathManager.IsPathComplete)
{
_isUsingPathfinding = false;
return;
}
_walkingTimer = 2;
var targetWorldPos = pathManager.GetNextPosition(transform.position, AttributesNow.moveSpeed);
Direction = targetWorldPos - transform.position;
SetBodyTexture(EntityState.Walking, CurrentOrientation);
transform.position = targetWorldPos;
}
else
{
base.TryMove();
}
}
}
}