fix(possess): don't destroy caster in Apply; defer possession to OnJumpCompleted to prevent PawnFlyer NRE
- CompAbilityEffect_Possess.Apply now only logs; DoPossession runs after landing - Harden HediffComp_GestaltNode against null/destroyed pawn (tick/severity/overlord search/relations) - Fix GestaltOverseer Notify_PostRemovedByDeath message condition (only when overlord died/destroyed and hive node alive)
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -35,15 +35,21 @@ namespace ArachnaeSwarm
|
||||
{
|
||||
get
|
||||
{
|
||||
CompGestalt comp = Pawn.TryGetComp<CompGestalt>();
|
||||
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)
|
||||
{
|
||||
tracker = new Pawn_GestaltTracker(Pawn);
|
||||
tracker = new Pawn_GestaltTracker(pawn);
|
||||
}
|
||||
return tracker;
|
||||
}
|
||||
@@ -59,6 +65,12 @@ namespace ArachnaeSwarm
|
||||
public override void CompPostTick(ref float severityAdjustment)
|
||||
{
|
||||
base.CompPostTick(ref severityAdjustment);
|
||||
|
||||
var pawn = Pawn;
|
||||
if (pawn == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (NodeType == GestaltNodeType.HiveNode)
|
||||
{
|
||||
@@ -69,9 +81,9 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
|
||||
// 定期寻找 OverlordNode
|
||||
if (Pawn.IsColonist &&
|
||||
Pawn.Spawned &&
|
||||
!Pawn.Dead &&
|
||||
if (pawn.IsColonist &&
|
||||
pawn.Spawned &&
|
||||
!pawn.Dead &&
|
||||
Find.TickManager.TicksGame % 250 == 0)
|
||||
{
|
||||
TryFindOverlord();
|
||||
@@ -86,6 +98,12 @@ namespace ArachnaeSwarm
|
||||
{
|
||||
if (NodeType != GestaltNodeType.HiveNode || parent == null)
|
||||
return;
|
||||
|
||||
var pawn = Pawn;
|
||||
if (pawn?.health == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool isConnected = IsConnectedToOverlord();
|
||||
|
||||
@@ -103,7 +121,7 @@ namespace ArachnaeSwarm
|
||||
wasConnected = isConnected;
|
||||
|
||||
// 如果严重性改变,需要重新计算Pawn的能力
|
||||
Pawn.health.Notify_HediffChanged(parent);
|
||||
pawn.health.Notify_HediffChanged(parent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,6 +136,12 @@ namespace ArachnaeSwarm
|
||||
public void TryFindOverlord()
|
||||
{
|
||||
// 如果已经有Overlord,更新连接状态并返回
|
||||
var pawn = Pawn;
|
||||
if (pawn == null || pawn.Dead || pawn.Destroyed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsConnectedToOverlord())
|
||||
{
|
||||
UpdateSeverityBasedOnConnection();
|
||||
@@ -125,7 +149,7 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
|
||||
// 如果Pawn当前不在地图上,无法寻找Overlord
|
||||
if (Pawn.Map == null)
|
||||
if (pawn.Map == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -134,22 +158,23 @@ namespace ArachnaeSwarm
|
||||
Pawn bestOverlord = null;
|
||||
float bestScore = -1f;
|
||||
|
||||
foreach (Pawn pawn in Pawn.Map.mapPawns.FreeColonists)
|
||||
foreach (Pawn candidate in pawn.Map.mapPawns.FreeColonists)
|
||||
{
|
||||
HediffComp_GestaltNode nodeComp = pawn.GetGestaltNodeComp();
|
||||
HediffComp_GestaltNode nodeComp = candidate.GetGestaltNodeComp();
|
||||
if (nodeComp?.NodeType == GestaltNodeType.OverlordNode &&
|
||||
pawn != Pawn &&
|
||||
!pawn.Dead &&
|
||||
!pawn.Downed)
|
||||
candidate != pawn &&
|
||||
!candidate.Dead &&
|
||||
!candidate.Downed &&
|
||||
!candidate.Destroyed)
|
||||
{
|
||||
Pawn_GestaltTracker tracker = pawn.GestaltTracker();
|
||||
if (tracker != null && tracker.CanControlPawn(Pawn))
|
||||
Pawn_GestaltTracker tracker = candidate.GestaltTracker();
|
||||
if (tracker != null && tracker.CanControlPawn(pawn))
|
||||
{
|
||||
float score = CalculateOverlordScore(pawn, tracker);
|
||||
float score = CalculateOverlordScore(candidate, tracker);
|
||||
if (score > bestScore)
|
||||
{
|
||||
bestScore = score;
|
||||
bestOverlord = pawn;
|
||||
bestOverlord = candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -158,7 +183,11 @@ namespace ArachnaeSwarm
|
||||
// 找到合适的Overlord,建立关系并更新严重性
|
||||
if (bestOverlord != null)
|
||||
{
|
||||
Pawn.relations.AddDirectRelation(ARA_PawnRelationDefOf.ARA_GestaltOverseer, bestOverlord);
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
@@ -188,10 +217,16 @@ namespace ArachnaeSwarm
|
||||
// 当Hediff被移除时,如果连接到Overlord,需要断开连接
|
||||
if (NodeType == GestaltNodeType.HiveNode && IsConnectedToOverlord())
|
||||
{
|
||||
Pawn overlord = Pawn.GetOverlord();
|
||||
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);
|
||||
pawn.relations.RemoveDirectRelation(ARA_PawnRelationDefOf.ARA_GestaltOverseer, overlord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
}
|
||||
|
||||
if (overlord != null && hiveNode != null && (!overlord.Dead || overlord.Destroyed))
|
||||
if (overlord != null && hiveNode != null && !hiveNode.Dead && (overlord.Dead || overlord.Destroyed))
|
||||
{
|
||||
Messages.Message("MessageGestaltLostControl".Translate(overlord, hiveNode) + ": " + hiveNode.LabelShortCap,
|
||||
new LookTargets(new Thing[] { overlord, hiveNode }), MessageTypeDefOf.NeutralEvent);
|
||||
|
||||
Reference in New Issue
Block a user