fix: 修复夺舍能力在跳跃前执行导致空指针的问题

修复 GestaltNode 相关逻辑的空指针异常
修复 Overlord 死亡或销毁时 HiveNode 的状态更新问题
增加 Pawn 不在当前地图时的检查
This commit is contained in:
2026-02-12 17:31:10 +08:00
parent c1639e6f9a
commit c04d0bdba6
3 changed files with 20 additions and 23 deletions

View File

@@ -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 ?? ""}。等待跳跃落地后执行夺舍逻辑。");
}
// 新增:检查目标是否无法行动

View File

@@ -124,6 +124,12 @@ namespace ArachnaeSwarm
return;
}
// 如果Pawn当前不在地图上无法寻找Overlord
if (Pawn.Map == null)
{
return;
}
// 在殖民地寻找可用的OverlordNode
Pawn bestOverlord = null;
float bestScore = -1f;

View File

@@ -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);