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(); } } }