using System.Collections.Generic; using RimWorld; using Verse; namespace ArachnaeSwarm { public class Hediff_Possession : HediffWithComps, IThingHolder { public ThingOwner casterContainer; public OriginalPawnData originalHostData; public Hediff_Possession() { this.casterContainer = new ThingOwner(this, false, LookMode.Deep); } public Pawn StoredCasterPawn => casterContainer.Count > 0 ? casterContainer[0] as Pawn : null; public IThingHolder ParentHolder => this.pawn; public void GetChildHolders(List outChildren) { ThingOwnerUtility.AppendThingHoldersFromThings(outChildren, this.GetDirectlyHeldThings()); } public ThingOwner GetDirectlyHeldThings() { return casterContainer; } // PostAdd现在只在游戏加载时起作用,我们不需要在这里做任何特殊操作。 // 所有的夺舍逻辑都在CompAbilityEffect_Possess中处理了。 public override void Notify_PawnDied(DamageInfo? dinfo, Hediff culprit = null) { base.Notify_PawnDied(dinfo, culprit); Pawn deadBody = this.pawn; Pawn storedCaster = this.StoredCasterPawn; if (originalHostData != null) { Log.Message($"[夺舍结束] 正在将 {deadBody.LabelShort}'s 的灵魂恢复为原始宿主数据。"); originalHostData.RestoreData(deadBody); // 恢复数据后,移除可能存在的无人机Hediff Hediff droneHediff = deadBody.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("ARA_HiveMindDrone")); if (droneHediff != null) { deadBody.health.RemoveHediff(droneHediff); Log.Message($"[夺舍结束] 已从 {deadBody.LabelShort} 的尸体上移除 ARA_HiveMindDrone Hediff。"); } } else { Log.Error("Possessed pawn died, but no original host data was found to restore."); } if (storedCaster != null) { EjectCaster(); } else { Log.Error("Possessed pawn died, but no caster soul was found inside."); } } public void EjectCaster() { if (StoredCasterPawn == null) return; // 采用更稳健的方式获取地图和位置,防止因宿主死亡导致Map为null Map map = this.pawn.MapHeld ?? Find.AnyPlayerHomeMap; if (map == null) { Log.Error("[夺舍] 无法找到一个有效的地图来重生抱脸虫。"); return; } IntVec3 cell = this.pawn.PositionHeld; if (!cell.IsValid) { cell = map.Center; } Log.Message($"[夺舍] 准备在地图 {map.ToString()} 的位置 {cell.ToString()} 处重生 {StoredCasterPawn.LabelShort}。"); this.casterContainer.TryDropAll(cell, map, ThingPlaceMode.Near); } public override void ExposeData() { base.ExposeData(); Scribe_Deep.Look(ref casterContainer, "casterContainer", this); Scribe_Deep.Look(ref originalHostData, "originalHostData"); } } }