99 lines
3.4 KiB
C#
99 lines
3.4 KiB
C#
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<Thing>(this, false, LookMode.Deep);
|
||
}
|
||
|
||
public Pawn StoredCasterPawn => casterContainer.Count > 0 ? casterContainer[0] as Pawn : null;
|
||
|
||
public IThingHolder ParentHolder => this.pawn;
|
||
|
||
public void GetChildHolders(List<IThingHolder> 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");
|
||
}
|
||
}
|
||
} |