Files
ArachnaeSwarm/Source/ArachnaeSwarm/HediffComp_SpawnPawnOnRemoved.cs
2025-09-09 17:51:20 +08:00

104 lines
3.8 KiB
C#

using RimWorld;
using Verse;
using System.Collections.Generic;
using System.Linq;
namespace ArachnaeSwarm
{
/// <summary>
/// Defines the properties for HediffComp_SpawnPawnOnRemoved.
/// You must specify the pawnKindDef to spawn.
/// </summary>
public class HediffCompProperties_SpawnPawnOnRemoved : HediffCompProperties
{
public List<PawnKindDef> pawnKindDefs; // 更改为列表
public int spawnCount = 1; // 新增生成数量
public float? fixedBiologicalAge; // 新增用于XML配置的固定生物年龄
public FloatRange? biologicalAgeRange; // 新增用于XML配置的生物年龄范围
public HediffCompProperties_SpawnPawnOnRemoved()
{
this.compClass = typeof(HediffComp_SpawnPawnOnRemoved);
}
}
/// <summary>
/// Spawns a specified pawn when the parent hediff is removed.
/// The pawn's faction is determined by the hediff's instigator.
/// </summary>
public class HediffComp_SpawnPawnOnRemoved : HediffComp
{
// This field will store the faction of the original attacker.
private Faction casterFaction;
public HediffCompProperties_SpawnPawnOnRemoved Props => (HediffCompProperties_SpawnPawnOnRemoved)this.props;
/// <summary>
/// Called after the hediff is added. We use this to capture the instigator's faction.
/// </summary>
public override void CompPostPostAdd(DamageInfo? dinfo)
{
base.CompPostPostAdd(dinfo);
if (dinfo.HasValue && dinfo.Value.Instigator != null)
{
this.casterFaction = dinfo.Value.Instigator.Faction;
}
}
/// <summary>
/// Called when the hediff is removed. This is where we spawn the pawn.
/// </summary>
public override void CompPostPostRemoved()
{
base.CompPostPostRemoved();
if (this.Pawn == null || this.Pawn.Map == null || Props.pawnKindDefs.NullOrEmpty())
{
Log.Warning("ArachnaeSwarm: HediffComp_SpawnPawnOnRemoved tried to spawn a pawn but required data was missing (Pawn, Map, or pawnKindDefs).");
return;
}
Map map = this.Pawn.Map;
IntVec3 loc = this.Pawn.Position;
// If casterFaction is null, default to the player's faction
if (this.casterFaction == null)
{
this.casterFaction = Faction.OfPlayer;
}
for (int i = 0; i < Props.spawnCount; i++)
{
PawnKindDef selectedPawnKindDef = Props.pawnKindDefs.RandomElement();
Pawn newPawn = PawnGenerator.GeneratePawn(new PawnGenerationRequest(
kind: selectedPawnKindDef,
faction: this.casterFaction, // Use the stored faction
context: PawnGenerationContext.NonPlayer,
tile: -1,
forceGenerateNewPawn: true,
fixedBiologicalAge: Props.fixedBiologicalAge, // 使用XML配置的固定生物年龄
biologicalAgeRange: Props.biologicalAgeRange // 使用XML配置的生物年龄范围
));
if (newPawn != null)
{
GenSpawn.Spawn(newPawn, loc, map, WipeMode.Vanish);
}
else
{
Log.Error($"ArachnaeSwarm: Failed to generate pawn of kind {selectedPawnKindDef.defName}.");
}
}
}
/// <summary>
/// Ensures the casterFaction is saved and loaded with the game.
/// </summary>
public override void CompExposeData()
{
base.CompExposeData();
Scribe_References.Look(ref this.casterFaction, "casterFaction");
}
}
}