From c04d0bdba6067f6f162bb6467150502706defc3e Mon Sep 17 00:00:00 2001 From: "ProjectKoi-Kalo\\Kalo" Date: Thu, 12 Feb 2026 17:31:10 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=A4=BA=E8=88=8D?= =?UTF-8?q?=E8=83=BD=E5=8A=9B=E5=9C=A8=E8=B7=B3=E8=B7=83=E5=89=8D=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E5=AF=BC=E8=87=B4=E7=A9=BA=E6=8C=87=E9=92=88=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复 GestaltNode 相关逻辑的空指针异常 修复 Overlord 死亡或销毁时 HiveNode 的状态更新问题 增加 Pawn 不在当前地图时的检查 --- .../CompAbilityEffect_Possess.cs | 15 ++++--------- .../ARA_GestaltNode/HediffComp_GestaltNode.cs | 6 +++++ .../PawnRelationWorker_GestaltOverseer.cs | 22 +++++++++---------- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/Source/ArachnaeSwarm/Abilities/ARA_HuggingFace/CompAbilityEffect_Possess.cs b/Source/ArachnaeSwarm/Abilities/ARA_HuggingFace/CompAbilityEffect_Possess.cs index 054f289..854b7b6 100644 --- a/Source/ArachnaeSwarm/Abilities/ARA_HuggingFace/CompAbilityEffect_Possess.cs +++ b/Source/ArachnaeSwarm/Abilities/ARA_HuggingFace/CompAbilityEffect_Possess.cs @@ -41,17 +41,10 @@ namespace ArachnaeSwarm { base.Apply(target, dest); - // 新增:检查目标是否无法行动(倒地) - if (target.Pawn != null && IsTargetImmobilized(target.Pawn)) - { - ArachnaeLog.Debug($"[夺舍] 目标 {target.Pawn.LabelShort} 无法行动,直接执行夺舍"); - DoPossession(this.parent.pawn, target.Pawn); - } - else - { - ArachnaeLog.Debug($"[夺舍] 目标可以行动,执行标准夺舍流程"); - DoPossession(this.parent.pawn, target.Pawn); - } + // 修复:不再在 Apply 中直接执行 DoPossession。 + // 因为该能力使用 Verb_JumpAndCastOnLanding,会在落地时通过 OnJumpCompleted 触发夺舍。 + // 在此处执行会导致施法者在跳跃开始前或期间被销毁,导致 PawnFlyer 抛出空指针异常。 + ArachnaeLog.Debug($"[夺舍] Apply 触发,目标: {target.Pawn?.LabelShort ?? "无"}。等待跳跃落地后执行夺舍逻辑。"); } // 新增:检查目标是否无法行动 diff --git a/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/HediffComp_GestaltNode.cs b/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/HediffComp_GestaltNode.cs index 7dcb654..e6e3f2f 100644 --- a/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/HediffComp_GestaltNode.cs +++ b/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/HediffComp_GestaltNode.cs @@ -124,6 +124,12 @@ namespace ArachnaeSwarm return; } + // 如果Pawn当前不在地图上,无法寻找Overlord + if (Pawn.Map == null) + { + return; + } + // 在殖民地寻找可用的OverlordNode Pawn bestOverlord = null; float bestScore = -1f; diff --git a/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/PawnRelationWorker_GestaltOverseer.cs b/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/PawnRelationWorker_GestaltOverseer.cs index daf361b..fbd22e0 100644 --- a/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/PawnRelationWorker_GestaltOverseer.cs +++ b/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/PawnRelationWorker_GestaltOverseer.cs @@ -65,27 +65,25 @@ namespace ArachnaeSwarm { base.Notify_PostRemovedByDeath(firstPawn, secondPawn); + if (firstPawn == null || secondPawn == null) + return; + // 处理死亡事件 Pawn overlord = (firstPawn.IsGestaltNode(GestaltNodeType.OverlordNode) ? firstPawn : secondPawn); Pawn hiveNode = (firstPawn == overlord) ? secondPawn : firstPawn; - if (!hiveNode.Dead && hiveNode.IsGestaltNode(GestaltNodeType.HiveNode)) + if (hiveNode != null && !hiveNode.Dead && hiveNode.IsGestaltNode(GestaltNodeType.HiveNode)) { - // 断开连接并寻找新的Overlord - if (overlord != null && !overlord.Dead) + // 当关系断开时(无论是Overlord死亡还是被销毁),HiveNode 需要更新状态并寻找新主 + HediffComp_GestaltNode hiveNodeComp = hiveNode.GetGestaltNodeComp(); + if (hiveNodeComp != null) { - HediffComp_GestaltNode hiveNodeComp = hiveNode.GetGestaltNodeComp(); - if (hiveNodeComp != null) - { - hiveNodeComp.UpdateSeverityBasedOnConnection(); - } - - // HiveNode会自动尝试寻找新的Overlord - hiveNodeComp?.TryFindOverlord(); + hiveNodeComp.UpdateSeverityBasedOnConnection(); + hiveNodeComp.TryFindOverlord(); } } - if (overlord != null && !overlord.Dead) + if (overlord != null && hiveNode != null && (!overlord.Dead || overlord.Destroyed)) { Messages.Message("MessageGestaltLostControl".Translate(overlord, hiveNode) + ": " + hiveNode.LabelShortCap, new LookTargets(new Thing[] { overlord, hiveNode }), MessageTypeDefOf.NeutralEvent);