741 lines
25 KiB
C#
741 lines
25 KiB
C#
using ArachnaeSwarm;
|
||
using RimWorld;
|
||
using System.Collections.Generic;
|
||
using Verse;
|
||
using UnityEngine;
|
||
|
||
namespace ArachnaeSwarm
|
||
{
|
||
public enum GestaltNodeType
|
||
{
|
||
HiveNode,
|
||
OverlordNode
|
||
}
|
||
|
||
public class HediffComp_GestaltNode : HediffComp
|
||
{
|
||
private GestaltNodeType? cachedNodeType;
|
||
private Pawn_GestaltTracker tracker;
|
||
private bool wasConnected = false; // 缓存连接状态,避免每帧都调整严重性
|
||
|
||
// === 延迟初始化字段 ===
|
||
/// <summary>
|
||
/// 生成时间戳(ticks),用于延迟计算
|
||
/// </summary>
|
||
private int spawnTimestamp = -1;
|
||
|
||
/// <summary>
|
||
/// 是否已经初始化完成(延迟后)
|
||
/// </summary>
|
||
private bool isInitialized = false;
|
||
|
||
/// <summary>
|
||
/// 延迟时间(ticks),默认1秒
|
||
/// </summary>
|
||
private const int DELAY_TICKS = 60;
|
||
|
||
// === 动态过渡系统字段 ===
|
||
/// <summary>
|
||
/// 过渡开始时间(ticks)
|
||
/// </summary>
|
||
private int transitionStartTick = -1;
|
||
|
||
/// <summary>
|
||
/// 过渡期持续时间(ticks),5秒
|
||
/// </summary>
|
||
private const int TRANSITION_DURATION = 300; // 5秒
|
||
|
||
/// <summary>
|
||
/// 过渡开始时的严重性
|
||
/// </summary>
|
||
private float transitionStartSeverity = 0.5f;
|
||
|
||
/// <summary>
|
||
/// 过渡结束时的目标严重性
|
||
/// </summary>
|
||
private float targetSeverityAfterTransition = 1.0f;
|
||
|
||
/// <summary>
|
||
/// 是否正在过渡中
|
||
/// </summary>
|
||
private bool isTransitioning = false;
|
||
|
||
/// <summary>
|
||
/// 上一次更新严重性的时间(ticks)
|
||
/// </summary>
|
||
private int lastSeverityUpdateTick = -1;
|
||
|
||
// === 属性 ===
|
||
|
||
/// <summary>
|
||
/// 获取节点类型
|
||
/// </summary>
|
||
public GestaltNodeType NodeType
|
||
{
|
||
get
|
||
{
|
||
if (!cachedNodeType.HasValue)
|
||
{
|
||
HediffCompProperties_GestaltNode props = this.props as HediffCompProperties_GestaltNode;
|
||
cachedNodeType = props?.nodeType ?? GestaltNodeType.HiveNode;
|
||
}
|
||
return cachedNodeType.Value;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 是否已经过了生成延迟期
|
||
/// </summary>
|
||
public bool IsPastSpawnDelay
|
||
{
|
||
get
|
||
{
|
||
// OverlordNode 不需要延迟
|
||
if (NodeType == GestaltNodeType.OverlordNode)
|
||
return true;
|
||
|
||
// 如果已经初始化完成,直接返回true
|
||
if (isInitialized)
|
||
return true;
|
||
|
||
// 如果还没有记录生成时间,记录当前时间
|
||
if (spawnTimestamp < 0)
|
||
return false;
|
||
|
||
// 检查是否已经过了延迟期
|
||
return Find.TickManager.TicksGame >= spawnTimestamp + DELAY_TICKS;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 是否在过渡期中
|
||
/// </summary>
|
||
public bool IsInTransition
|
||
{
|
||
get
|
||
{
|
||
if (transitionStartTick < 0)
|
||
return false;
|
||
|
||
return Find.TickManager.TicksGame - transitionStartTick < TRANSITION_DURATION;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取当前过渡进度(0-1)
|
||
/// </summary>
|
||
public float TransitionProgress
|
||
{
|
||
get
|
||
{
|
||
if (!IsInTransition || transitionStartTick < 0)
|
||
return 1.0f;
|
||
|
||
int elapsed = Find.TickManager.TicksGame - transitionStartTick;
|
||
return Mathf.Clamp01((float)elapsed / TRANSITION_DURATION);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取每秒变化速率
|
||
/// </summary>
|
||
public float SeverityChangePerSecond
|
||
{
|
||
get
|
||
{
|
||
// 根据过渡类型计算不同的变化速率
|
||
if (targetSeverityAfterTransition > transitionStartSeverity)
|
||
{
|
||
// 连接状态,从0.5到1.5,总共1.0的变化量,5秒内完成
|
||
return 0.2f; // 1.0 / 5.0 = 0.2
|
||
}
|
||
else
|
||
{
|
||
// 断开状态,从1.5到0.5,总共-1.0的变化量,5秒内完成
|
||
return -0.2f; // -1.0 / 5.0 = -0.2
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取 GestaltTracker
|
||
/// </summary>
|
||
public Pawn_GestaltTracker GestaltTracker
|
||
{
|
||
get
|
||
{
|
||
var pawn = Pawn;
|
||
if (pawn == null)
|
||
{
|
||
return tracker;
|
||
}
|
||
|
||
CompGestalt comp = pawn.TryGetComp<CompGestalt>();
|
||
if (comp != null)
|
||
{
|
||
return comp.GestaltTracker;
|
||
}
|
||
|
||
if (tracker == null && NodeType == GestaltNodeType.OverlordNode && pawn != null)
|
||
{
|
||
tracker = new Pawn_GestaltTracker(pawn);
|
||
}
|
||
return tracker;
|
||
}
|
||
}
|
||
|
||
// === 生命周期方法 ===
|
||
|
||
public override void CompPostMake()
|
||
{
|
||
base.CompPostMake();
|
||
|
||
// 记录生成时间戳
|
||
spawnTimestamp = Find.TickManager.TicksGame;
|
||
|
||
if (NodeType == GestaltNodeType.HiveNode)
|
||
{
|
||
if (parent != null)
|
||
{
|
||
parent.Severity = 1.5f;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// OverlordNode 立即初始化
|
||
isInitialized = true;
|
||
}
|
||
}
|
||
|
||
public override void CompPostTick(ref float severityAdjustment)
|
||
{
|
||
base.CompPostTick(ref severityAdjustment);
|
||
|
||
var pawn = Pawn;
|
||
if (pawn == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// 检查是否已经过了生成延迟期
|
||
if (!IsPastSpawnDelay)
|
||
{
|
||
// 还在延迟期内,不执行任何计算
|
||
return;
|
||
}
|
||
|
||
// 延迟期过后,执行初始化
|
||
if (!isInitialized)
|
||
{
|
||
InitializeAfterDelay();
|
||
}
|
||
|
||
// 检查过渡状态,并更新严重性变化
|
||
UpdateTransitionStateWithRate();
|
||
|
||
// 正常的Tick逻辑
|
||
if (NodeType == GestaltNodeType.HiveNode)
|
||
{
|
||
// 定期检查连接状态(如果不在过渡中)
|
||
if (!IsInTransition && Find.TickManager.TicksGame % 60 == 0) // 每60tick检查一次
|
||
{
|
||
UpdateSeverityBasedOnConnection();
|
||
}
|
||
|
||
// 定期寻找 OverlordNode
|
||
if (pawn.Spawned &&
|
||
!pawn.Dead &&
|
||
Find.TickManager.TicksGame % 250 == 0)
|
||
{
|
||
TryFindOverlord();
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 延迟期过后初始化
|
||
/// </summary>
|
||
private void InitializeAfterDelay()
|
||
{
|
||
var pawn = Pawn;
|
||
if (pawn == null)
|
||
return;
|
||
|
||
// 标记为已初始化
|
||
isInitialized = true;
|
||
|
||
// 如果是HiveNode,检查当前连接状态
|
||
if (NodeType == GestaltNodeType.HiveNode)
|
||
{
|
||
// 延迟后第一次更新严重性
|
||
UpdateSeverityBasedOnConnection();
|
||
|
||
// 延迟后第一次尝试寻找Overlord
|
||
if (pawn.IsColonist && pawn.Spawned && !pawn.Dead)
|
||
{
|
||
TryFindOverlord();
|
||
}
|
||
|
||
ArachnaeLog.Debug($"[GestaltNode] {pawn.LabelShort} (HiveNode) 延迟初始化完成,当前连接状态: {IsConnectedToOverlord()}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 带速率变化的过渡状态更新
|
||
/// </summary>
|
||
private void UpdateTransitionStateWithRate()
|
||
{
|
||
// 检查Pawn是否死亡或无效
|
||
var pawn = Pawn;
|
||
if (pawn == null || pawn.Dead)
|
||
{
|
||
isTransitioning = false;
|
||
transitionStartTick = -1;
|
||
lastSeverityUpdateTick = -1;
|
||
return;
|
||
}
|
||
|
||
// 如果不在过渡中,重置并返回
|
||
if (!isTransitioning || transitionStartTick < 0)
|
||
{
|
||
lastSeverityUpdateTick = -1;
|
||
return;
|
||
}
|
||
|
||
// 检查过渡是否已经完成
|
||
if (!IsInTransition)
|
||
{
|
||
// 过渡完成,确保设置到目标严重性
|
||
CompleteTransition();
|
||
return;
|
||
}
|
||
|
||
// 检查是否应该更新严重性(每秒更新一次)
|
||
int currentTick = Find.TickManager.TicksGame;
|
||
if (lastSeverityUpdateTick < 0 || currentTick - lastSeverityUpdateTick >= 60) // 60ticks = 1秒
|
||
{
|
||
UpdateSeverityWithRate(currentTick);
|
||
lastSeverityUpdateTick = currentTick;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 使用速率更新严重性
|
||
/// </summary>
|
||
private void UpdateSeverityWithRate(int currentTick)
|
||
{
|
||
var pawn = Pawn;
|
||
if (pawn == null || parent == null)
|
||
return;
|
||
|
||
// 计算经过的时间(秒)
|
||
float elapsedSeconds = (currentTick - transitionStartTick) / 60f;
|
||
|
||
// 计算新的严重性
|
||
float newSeverity;
|
||
|
||
// 方法1:线性插值
|
||
// newSeverity = Mathf.Lerp(transitionStartSeverity, targetSeverityAfterTransition,
|
||
// Mathf.Clamp01(elapsedSeconds / (TRANSITION_DURATION / 60f)));
|
||
|
||
// 方法2:使用速率计算(更符合要求)
|
||
float changeAmount = SeverityChangePerSecond * (currentTick - transitionStartTick) / 60f;
|
||
newSeverity = transitionStartSeverity + changeAmount;
|
||
|
||
// 确保严重性在合理范围内
|
||
if (targetSeverityAfterTransition > transitionStartSeverity)
|
||
{
|
||
// 连接过程,严重性增加
|
||
newSeverity = Mathf.Clamp(newSeverity, transitionStartSeverity, targetSeverityAfterTransition);
|
||
}
|
||
else
|
||
{
|
||
// 断开过程,严重性减少
|
||
newSeverity = Mathf.Clamp(newSeverity, targetSeverityAfterTransition, transitionStartSeverity);
|
||
}
|
||
|
||
// 应用新的严重性
|
||
if (Mathf.Abs(parent.Severity - newSeverity) > 0.001f)
|
||
{
|
||
parent.Severity = newSeverity;
|
||
|
||
// 通知Pawn状态改变
|
||
if (pawn?.health != null)
|
||
{
|
||
pawn.health.Notify_HediffChanged(parent);
|
||
}
|
||
|
||
// 调试信息
|
||
if (Find.TickManager.TicksGame % 120 == 0) // 每2秒记录一次
|
||
{
|
||
ArachnaeLog.Debug($"[GestaltNode] {pawn.LabelShort} 过渡中: {parent.Severity:F2} -> {targetSeverityAfterTransition:F2} " +
|
||
$"(进度: {TransitionProgress:P0}, 速率: {SeverityChangePerSecond:F2}/秒)");
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 完成过渡
|
||
/// </summary>
|
||
private void CompleteTransition()
|
||
{
|
||
var pawn = Pawn;
|
||
if (pawn == null || parent == null)
|
||
{
|
||
ResetTransition();
|
||
return;
|
||
}
|
||
|
||
// 确保最终严重性准确
|
||
if (Mathf.Abs(parent.Severity - targetSeverityAfterTransition) > 0.01f)
|
||
{
|
||
parent.Severity = targetSeverityAfterTransition;
|
||
|
||
if (pawn?.health != null)
|
||
{
|
||
pawn.health.Notify_HediffChanged(parent);
|
||
}
|
||
}
|
||
|
||
ArachnaeLog.Debug($"[GestaltNode] {pawn.LabelShort} 过渡完成: {targetSeverityAfterTransition:F2}");
|
||
|
||
// 重置过渡状态
|
||
ResetTransition();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 重置过渡状态
|
||
/// </summary>
|
||
private void ResetTransition()
|
||
{
|
||
transitionStartTick = -1;
|
||
isTransitioning = false;
|
||
lastSeverityUpdateTick = -1;
|
||
transitionStartSeverity = 0.5f;
|
||
targetSeverityAfterTransition = 1.0f;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开始带速率变化的过渡
|
||
/// </summary>
|
||
private void StartRateBasedTransition(bool isConnecting)
|
||
{
|
||
var pawn = Pawn;
|
||
if (pawn == null || parent == null)
|
||
return;
|
||
|
||
// 设置目标严重性
|
||
targetSeverityAfterTransition = isConnecting ? 1.5f : 0.5f;
|
||
|
||
// 记录过渡开始时的严重性
|
||
transitionStartSeverity = parent.Severity;
|
||
|
||
// 记录过渡开始时间
|
||
transitionStartTick = Find.TickManager.TicksGame;
|
||
isTransitioning = true;
|
||
lastSeverityUpdateTick = transitionStartTick;
|
||
|
||
ArachnaeLog.Debug($"[GestaltNode] {pawn.LabelShort} 开始速率过渡: {transitionStartSeverity:F2} -> {targetSeverityAfterTransition:F2} " +
|
||
$"({(isConnecting ? "连接" : "断开")}, 速率: {SeverityChangePerSecond:F2}/秒)");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据连接状态更新 Hediff 严重性
|
||
/// </summary>
|
||
public void UpdateSeverityBasedOnConnection()
|
||
{
|
||
if (NodeType != GestaltNodeType.HiveNode || parent == null)
|
||
return;
|
||
|
||
var pawn = Pawn;
|
||
if (pawn?.health == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
bool isConnected = IsConnectedToOverlord();
|
||
|
||
// 检查连接状态是否改变
|
||
if (isConnected != wasConnected)
|
||
{
|
||
// 连接状态改变,开始带速率变化的过渡
|
||
StartRateBasedTransition(isConnected);
|
||
|
||
wasConnected = isConnected;
|
||
}
|
||
else
|
||
{
|
||
// 连接状态没有改变,但可能不在过渡中,需要确保严重性正确
|
||
// 如果不在过渡中,直接设置到目标严重性
|
||
if (!IsInTransition)
|
||
{
|
||
float currentTargetSeverity = isConnected ? 1.5f : 0.5f;
|
||
|
||
if (Mathf.Abs(parent.Severity - currentTargetSeverity) > 0.01f)
|
||
{
|
||
parent.Severity = currentTargetSeverity;
|
||
|
||
// 如果严重性改变,需要重新计算Pawn的能力
|
||
pawn.health.Notify_HediffChanged(parent);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查是否连接到 Overlord
|
||
/// </summary>
|
||
public bool IsConnectedToOverlord()
|
||
{
|
||
return Pawn.GetOverlord() != null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 尝试寻找 Overlord
|
||
/// </summary>
|
||
public void TryFindOverlord()
|
||
{
|
||
// 如果还没有过延迟期,不执行
|
||
if (!IsPastSpawnDelay)
|
||
return;
|
||
|
||
// 如果已经有Overlord,更新连接状态并返回
|
||
var pawn = Pawn;
|
||
if (pawn == null || pawn.Dead || pawn.Destroyed)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (IsConnectedToOverlord())
|
||
{
|
||
UpdateSeverityBasedOnConnection();
|
||
return;
|
||
}
|
||
|
||
// 如果Pawn当前不在地图上,无法寻找Overlord
|
||
if (pawn.Map == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// 在殖民地寻找可用的OverlordNode
|
||
Pawn bestOverlord = null;
|
||
float bestScore = -1f;
|
||
|
||
foreach (Pawn candidate in pawn.Map.mapPawns.FreeColonists)
|
||
{
|
||
HediffComp_GestaltNode nodeComp = candidate.GetGestaltNodeComp();
|
||
if (nodeComp?.NodeType == GestaltNodeType.OverlordNode &&
|
||
candidate != pawn &&
|
||
!candidate.Dead &&
|
||
!candidate.Downed &&
|
||
!candidate.Destroyed)
|
||
{
|
||
Pawn_GestaltTracker tracker = candidate.GestaltTracker();
|
||
if (tracker != null && tracker.CanControlPawn(pawn))
|
||
{
|
||
float score = CalculateOverlordScore(candidate, tracker);
|
||
if (score > bestScore)
|
||
{
|
||
bestScore = score;
|
||
bestOverlord = candidate;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 找到合适的Overlord,建立关系并更新严重性
|
||
if (bestOverlord != null)
|
||
{
|
||
// Pawns being destroyed/vanished can temporarily have no relations tracker.
|
||
if (pawn.relations != null && ARA_PawnRelationDefOf.ARA_GestaltOverseer != null)
|
||
{
|
||
pawn.relations.AddDirectRelation(ARA_PawnRelationDefOf.ARA_GestaltOverseer, bestOverlord);
|
||
}
|
||
UpdateSeverityBasedOnConnection();
|
||
|
||
ArachnaeLog.Debug($"[GestaltNode] {pawn.LabelShort} 连接到 Overlord: {bestOverlord.LabelShort}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 计算 Overlord 得分
|
||
/// </summary>
|
||
private float CalculateOverlordScore(Pawn overlord, Pawn_GestaltTracker tracker)
|
||
{
|
||
float score = 0f;
|
||
|
||
if (overlord.Spawned && Pawn.Spawned && overlord.Map == Pawn.Map)
|
||
{
|
||
float distance = overlord.Position.DistanceTo(Pawn.Position);
|
||
score += 100f / (distance + 1f);
|
||
}
|
||
|
||
float availableBandwidth = tracker.TotalBandwidth - tracker.UsedBandwidth;
|
||
score += availableBandwidth * 10f;
|
||
|
||
score += (10 - tracker.ControlGroups.Count) * 5f;
|
||
|
||
return score;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Hediff 被移除时的清理
|
||
/// </summary>
|
||
public override void CompPostPostRemoved()
|
||
{
|
||
base.CompPostPostRemoved();
|
||
|
||
// 清理过渡状态
|
||
ResetTransition();
|
||
|
||
// 当Hediff被移除时,如果连接到Overlord,需要断开连接
|
||
if (NodeType == GestaltNodeType.HiveNode && IsConnectedToOverlord())
|
||
{
|
||
var pawn = Pawn;
|
||
if (pawn?.relations == null || ARA_PawnRelationDefOf.ARA_GestaltOverseer == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
Pawn overlord = pawn.GetOverlord();
|
||
if (overlord != null)
|
||
{
|
||
pawn.relations.RemoveDirectRelation(ARA_PawnRelationDefOf.ARA_GestaltOverseer, overlord);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Pawn 死亡时的处理
|
||
/// </summary>
|
||
public override void Notify_PawnDied(DamageInfo? dinfo, Hediff culprit = null)
|
||
{
|
||
base.Notify_PawnDied(dinfo, culprit);
|
||
|
||
// 清理过渡状态
|
||
ResetTransition();
|
||
|
||
ArachnaeLog.Debug($"[GestaltNode] {Pawn?.LabelShort} 死亡,清理过渡状态");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 序列化
|
||
/// </summary>
|
||
public override void CompExposeData()
|
||
{
|
||
base.CompExposeData();
|
||
Scribe_Values.Look(ref wasConnected, "wasConnected", false);
|
||
Scribe_Values.Look(ref spawnTimestamp, "spawnTimestamp", -1);
|
||
Scribe_Values.Look(ref isInitialized, "isInitialized", false);
|
||
Scribe_Values.Look(ref transitionStartTick, "transitionStartTick", -1);
|
||
Scribe_Values.Look(ref transitionStartSeverity, "transitionStartSeverity", 0.5f);
|
||
Scribe_Values.Look(ref targetSeverityAfterTransition, "targetSeverityAfterTransition", 1.0f);
|
||
Scribe_Values.Look(ref isTransitioning, "isTransitioning", false);
|
||
Scribe_Values.Look(ref lastSeverityUpdateTick, "lastSeverityUpdateTick", -1);
|
||
|
||
// 加载后,如果已经过了延迟期,标记为已初始化
|
||
if (Scribe.mode == LoadSaveMode.PostLoadInit && spawnTimestamp >= 0)
|
||
{
|
||
// 检查当前时间是否已经过了延迟期
|
||
if (Find.TickManager.TicksGame >= spawnTimestamp + DELAY_TICKS)
|
||
{
|
||
isInitialized = true;
|
||
}
|
||
|
||
// 如果正在过渡中,恢复过渡状态
|
||
if (transitionStartTick >= 0 && isTransitioning)
|
||
{
|
||
// 检查过渡是否已经完成
|
||
if (!IsInTransition)
|
||
{
|
||
// 过渡已完成,设置最终严重性
|
||
if (parent != null)
|
||
{
|
||
parent.Severity = targetSeverityAfterTransition;
|
||
}
|
||
ResetTransition();
|
||
}
|
||
else
|
||
{
|
||
// 过渡未完成,恢复过渡
|
||
ArachnaeLog.Debug($"[GestaltNode] 恢复未完成的过渡: {transitionStartSeverity:F2} -> {targetSeverityAfterTransition:F2}");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 调试信息
|
||
/// </summary>
|
||
public string GetDebugInfo()
|
||
{
|
||
var pawn = Pawn;
|
||
if (pawn == null)
|
||
return "Pawn is null";
|
||
|
||
string transitionInfo = "无";
|
||
if (IsInTransition)
|
||
{
|
||
float rate = SeverityChangePerSecond;
|
||
string direction = rate > 0 ? "增加" : "减少";
|
||
transitionInfo = $"过渡中,进度: {TransitionProgress:P0}\n" +
|
||
$"从: {transitionStartSeverity:F2} 到: {targetSeverityAfterTransition:F2}\n" +
|
||
$"速率: {Mathf.Abs(rate):F2}/秒 ({direction})\n" +
|
||
$"当前: {parent?.Severity:F2}";
|
||
}
|
||
else if (isTransitioning)
|
||
{
|
||
transitionInfo = $"过渡完成,目标: {targetSeverityAfterTransition:F2}";
|
||
}
|
||
|
||
return $"NodeType: {NodeType}\n" +
|
||
$"SpawnTimestamp: {spawnTimestamp}\n" +
|
||
$"IsPastSpawnDelay: {IsPastSpawnDelay}\n" +
|
||
$"IsInitialized: {isInitialized}\n" +
|
||
$"WasConnected: {wasConnected}\n" +
|
||
$"IsConnected: {IsConnectedToOverlord()}\n" +
|
||
$"Transition: {transitionInfo}\n" +
|
||
$"CurrentSeverity: {parent?.Severity ?? 0f:F2}";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Pawn 扩展方法
|
||
/// </summary>
|
||
public static class HediffExtensions
|
||
{
|
||
public static HediffComp_GestaltNode GetGestaltNodeComp(this Pawn pawn)
|
||
{
|
||
if (pawn?.health?.hediffSet?.hediffs == null)
|
||
return null;
|
||
|
||
foreach (Hediff hediff in pawn.health.hediffSet.hediffs)
|
||
{
|
||
HediffComp_GestaltNode comp = hediff.TryGetComp<HediffComp_GestaltNode>();
|
||
if (comp != null)
|
||
return comp;
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public static bool IsGestaltNode(this Pawn pawn, GestaltNodeType nodeType)
|
||
{
|
||
HediffComp_GestaltNode comp = pawn.GetGestaltNodeComp();
|
||
return comp?.NodeType == nodeType;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取延迟信息(调试用)
|
||
/// </summary>
|
||
public static string GetGestaltNodeDelayInfo(this Pawn pawn)
|
||
{
|
||
HediffComp_GestaltNode comp = pawn.GetGestaltNodeComp();
|
||
if (comp == null)
|
||
return "No GestaltNode";
|
||
|
||
return comp.GetDebugInfo();
|
||
}
|
||
}
|
||
}
|