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; // 缓存连接状态,避免每帧都调整严重性
// === 新增字段 ===
///
/// 生成时间戳(ticks),用于延迟计算
///
private int spawnTimestamp = -1;
///
/// 是否已经初始化完成(延迟后)
///
private bool isInitialized = false;
///
/// 延迟时间(ticks),默认1秒
///
private const int DELAY_TICKS = 60;
// === 属性 ===
///
/// 获取节点类型
///
public GestaltNodeType NodeType
{
get
{
if (!cachedNodeType.HasValue)
{
HediffCompProperties_GestaltNode props = this.props as HediffCompProperties_GestaltNode;
cachedNodeType = props?.nodeType ?? GestaltNodeType.HiveNode;
}
return cachedNodeType.Value;
}
}
///
/// 是否已经过了生成延迟期
///
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;
}
}
///
/// 获取 GestaltTracker
///
public Pawn_GestaltTracker GestaltTracker
{
get
{
var pawn = Pawn;
if (pawn == null)
{
return tracker;
}
CompGestalt comp = pawn.TryGetComp();
if (comp != null)
{
return comp.GestaltTracker;
}
if (tracker == null && NodeType == GestaltNodeType.OverlordNode)
{
tracker = new Pawn_GestaltTracker(pawn);
}
return tracker;
}
}
// === 生命周期方法 ===
public override void CompPostMake()
{
base.CompPostMake();
// 记录生成时间戳
spawnTimestamp = Find.TickManager.TicksGame;
// 如果是HiveNode,初始化时设置较低的严重性,延迟后再计算
if (NodeType == GestaltNodeType.HiveNode)
{
// 设置初始严重性为0.5(未连接状态)
if (parent != null)
{
parent.Severity = 0.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();
}
// 正常的Tick逻辑
if (NodeType == GestaltNodeType.HiveNode)
{
// 定期更新严重性
if (Find.TickManager.TicksGame % 60 == 0) // 每60tick检查一次
{
UpdateSeverityBasedOnConnection();
}
// 定期寻找 OverlordNode
if (pawn.IsColonist &&
pawn.Spawned &&
!pawn.Dead &&
Find.TickManager.TicksGame % 250 == 0)
{
TryFindOverlord();
}
}
}
///
/// 延迟期过后初始化
///
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();
}
Log.Message($"[GestaltNode] {pawn.LabelShort} (HiveNode) 延迟初始化完成,当前连接状态: {IsConnectedToOverlord()}");
}
}
///
/// 根据连接状态更新 Hediff 严重性
///
public void UpdateSeverityBasedOnConnection()
{
if (NodeType != GestaltNodeType.HiveNode || parent == null)
return;
var pawn = Pawn;
if (pawn?.health == null)
{
return;
}
bool isConnected = IsConnectedToOverlord();
// 只有连接状态改变时才更新,避免每帧都设置
if (isConnected != wasConnected)
{
float targetSeverity = isConnected ? 1.5f : 0.5f;
// 平滑过渡到目标严重性
if (Mathf.Abs(parent.Severity - targetSeverity) > 0.01f)
{
parent.Severity = targetSeverity;
}
wasConnected = isConnected;
// 如果严重性改变,需要重新计算Pawn的能力
pawn.health.Notify_HediffChanged(parent);
}
}
///
/// 检查是否连接到 Overlord
///
public bool IsConnectedToOverlord()
{
return Pawn.GetOverlord() != null;
}
///
/// 尝试寻找 Overlord
///
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();
Log.Message($"[GestaltNode] {pawn.LabelShort} 连接到 Overlord: {bestOverlord.LabelShort}");
}
}
///
/// 计算 Overlord 得分
///
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;
}
///
/// Hediff 被移除时的清理
///
public override void CompPostPostRemoved()
{
base.CompPostPostRemoved();
// 当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);
}
}
}
///
/// 序列化
///
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);
// 加载后,如果已经过了延迟期,标记为已初始化
if (Scribe.mode == LoadSaveMode.PostLoadInit && spawnTimestamp >= 0)
{
// 检查当前时间是否已经过了延迟期
if (Find.TickManager.TicksGame >= spawnTimestamp + DELAY_TICKS)
{
isInitialized = true;
}
}
}
///
/// 调试信息
///
public string GetDebugInfo()
{
var pawn = Pawn;
if (pawn == null)
return "Pawn is null";
return $"NodeType: {NodeType}\n" +
$"SpawnTimestamp: {spawnTimestamp}\n" +
$"IsPastSpawnDelay: {IsPastSpawnDelay}\n" +
$"IsInitialized: {isInitialized}\n" +
$"WasConnected: {wasConnected}\n" +
$"IsConnected: {IsConnectedToOverlord()}\n" +
$"CurrentSeverity: {parent?.Severity ?? 0f}";
}
}
///
/// Pawn 扩展方法
///
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();
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;
}
///
/// 获取延迟信息(调试用)
///
public static string GetGestaltNodeDelayInfo(this Pawn pawn)
{
HediffComp_GestaltNode comp = pawn.GetGestaltNodeComp();
if (comp == null)
return "No GestaltNode";
return comp.GetDebugInfo();
}
}
}