暂存
This commit is contained in:
Binary file not shown.
35
1.6/1.6/Defs/AbilityDefs/ARA_Abilities_HiveMind.xml
Normal file
35
1.6/1.6/Defs/AbilityDefs/ARA_Abilities_HiveMind.xml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<Defs>
|
||||||
|
|
||||||
|
<AbilityDef ParentName="AbilityTouchBase">
|
||||||
|
<defName>ARA_BindDrone</defName>
|
||||||
|
<label>虫群联结</label>
|
||||||
|
<description>Allows the hive mind master to bind with an unlinked drone, bringing it under direct psychic control.</description>
|
||||||
|
<iconPath>UI/Commands/EggSpew</iconPath> <!-- Placeholder: You'll need to create this icon -->
|
||||||
|
|
||||||
|
<jobDef>CastAbilityOnThing</jobDef>
|
||||||
|
<targetRequired>true</targetRequired>
|
||||||
|
<cooldownTicksRange>60</cooldownTicksRange> <!-- 1 second cooldown -->
|
||||||
|
|
||||||
|
<verbProperties>
|
||||||
|
<verbClass>Verb_CastAbility</verbClass>
|
||||||
|
<warmupTime>0.5</warmupTime>
|
||||||
|
<range>99</range> <!-- Short range, like touch -->
|
||||||
|
<targetParams>
|
||||||
|
<canTargetPawns>true</canTargetPawns>
|
||||||
|
<canTargetBuildings>false</canTargetBuildings>
|
||||||
|
<canTargetAnimals>true</canTargetAnimals>
|
||||||
|
<canTargetMechs>false</canTargetMechs>
|
||||||
|
<canTargetCorpses>false</canTargetCorpses>
|
||||||
|
<canTargetSelf>false</canTargetSelf>
|
||||||
|
</targetParams>
|
||||||
|
</verbProperties>
|
||||||
|
|
||||||
|
<comps>
|
||||||
|
<li Class="ArachnaeSwarm.CompProperties_AbilityBindDrone">
|
||||||
|
<!-- No custom properties needed for now -->
|
||||||
|
</li>
|
||||||
|
</comps>
|
||||||
|
</AbilityDef>
|
||||||
|
|
||||||
|
</Defs>
|
||||||
@@ -15,6 +15,9 @@
|
|||||||
<Shooting>2</Shooting>
|
<Shooting>2</Shooting>
|
||||||
<Melee>2</Melee>
|
<Melee>2</Melee>
|
||||||
</skillGains>
|
</skillGains>
|
||||||
|
<forcedHediffs>
|
||||||
|
<li>ARA_HiveMindMaster</li>
|
||||||
|
</forcedHediffs>
|
||||||
|
|
||||||
<spawnCategories>
|
<spawnCategories>
|
||||||
<li>ArachnaeQueen_spawnCategoriesA</li>
|
<li>ArachnaeQueen_spawnCategoriesA</li>
|
||||||
@@ -53,6 +56,10 @@
|
|||||||
<li>ArachnaeNode_spawnCategoriesA</li>
|
<li>ArachnaeNode_spawnCategoriesA</li>
|
||||||
</spawnCategories>
|
</spawnCategories>
|
||||||
|
|
||||||
|
<forcedHediffs>
|
||||||
|
<li>ARA_HiveMindDrone</li>
|
||||||
|
</forcedHediffs>
|
||||||
|
|
||||||
<requiresSpawnCategory>true</requiresSpawnCategory>
|
<requiresSpawnCategory>true</requiresSpawnCategory>
|
||||||
</AlienRace.AlienBackstoryDef>
|
</AlienRace.AlienBackstoryDef>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<HediffDef>
|
<HediffDef>
|
||||||
<defName>ARA_HiveMindMaster</defName>
|
<defName>ARA_HiveMindMaster</defName>
|
||||||
<label>hive mind master</label>
|
<label>阿拉克涅主巢</label>
|
||||||
<description>The central node of a hive mind, connected to multiple drone beings.</description>
|
<description>The central node of a hive mind, connected to multiple drone beings.</description>
|
||||||
<hediffClass>ArachnaeSwarm.Hediff_HiveMindMaster</hediffClass>
|
<hediffClass>ArachnaeSwarm.Hediff_HiveMindMaster</hediffClass>
|
||||||
<defaultLabelColor>(0.8, 0.3, 0.8)</defaultLabelColor>
|
<defaultLabelColor>(0.8, 0.3, 0.8)</defaultLabelColor>
|
||||||
@@ -19,18 +19,20 @@
|
|||||||
</stages>
|
</stages>
|
||||||
</HediffDef>
|
</HediffDef>
|
||||||
|
|
||||||
<HediffDef ParentName="HediffWithTargetBase">
|
<HediffDef>
|
||||||
<defName>ARA_HiveMindDrone</defName>
|
<defName>ARA_HiveMindDrone</defName>
|
||||||
<label>hive mind drone</label>
|
<label>阿拉克涅工蜂</label>
|
||||||
<description>A drone being, psychically linked to a master node. If the master dies, this unit will cease to function.</description>
|
<description>A drone being, psychically linked to a master node. If the master dies, this unit will cease to function.</description>
|
||||||
<hediffClass>ArachnaeSwarm.Hediff_HiveMindDrone</hediffClass>
|
<hediffClass>ArachnaeSwarm.Hediff_HiveMindDrone</hediffClass>
|
||||||
<defaultLabelColor>(0.6, 0.4, 0.8)</defaultLabelColor>
|
<defaultLabelColor>(0.6, 0.4, 0.8)</defaultLabelColor>
|
||||||
<isBad>false</isBad>
|
<isBad>false</isBad>
|
||||||
<scenarioCanAdd>true</scenarioCanAdd>
|
<scenarioCanAdd>true</scenarioCanAdd>
|
||||||
<stages>
|
<comps>
|
||||||
<li>
|
<li Class="ArachnaeSwarm.HediffCompProperties_HiveMindDrone">
|
||||||
<label>linked</label>
|
<unlinkedDieDelayTicks>6400</unlinkedDieDelayTicks> <!-- Default to 30 seconds -->
|
||||||
</li>
|
</li>
|
||||||
|
</comps>
|
||||||
|
<stages>
|
||||||
</stages>
|
</stages>
|
||||||
</HediffDef>
|
</HediffDef>
|
||||||
|
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
<abilities>
|
<abilities>
|
||||||
<li>ARA_EggSpew</li>
|
<li>ARA_EggSpew</li>
|
||||||
<li>ARA_AcidSprayBurst</li>
|
<li>ARA_AcidSprayBurst</li>
|
||||||
|
<li>ARA_BindDrone</li>
|
||||||
</abilities>
|
</abilities>
|
||||||
<xenotypeSet>
|
<xenotypeSet>
|
||||||
<xenotypeChances>
|
<xenotypeChances>
|
||||||
|
|||||||
@@ -77,6 +77,12 @@
|
|||||||
<Compile Include="Hediffs\Hediff_CurseFlame.cs" />
|
<Compile Include="Hediffs\Hediff_CurseFlame.cs" />
|
||||||
<Compile Include="CompAbilityEffect_NeedCost.cs" />
|
<Compile Include="CompAbilityEffect_NeedCost.cs" />
|
||||||
<Compile Include="CompAbilityEffect_BodyPartCheck.cs" />
|
<Compile Include="CompAbilityEffect_BodyPartCheck.cs" />
|
||||||
|
<Compile Include="Hediff_HiveMindMaster.cs" />
|
||||||
|
<Compile Include="Hediff_HiveMindDrone.cs" />
|
||||||
|
<Compile Include="HediffCompProperties_HiveMindDrone.cs" />
|
||||||
|
<Compile Include="HediffComp_HiveMindDrone.cs" />
|
||||||
|
<Compile Include="CompAbilityEffect_BindDrone.cs" />
|
||||||
|
<Compile Include="CompProperties_AbilityBindDrone.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
|||||||
108
Source/ArachnaeSwarm/CompAbilityEffect_BindDrone.cs
Normal file
108
Source/ArachnaeSwarm/CompAbilityEffect_BindDrone.cs
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
using RimWorld;
|
||||||
|
using Verse;
|
||||||
|
using System.Linq; // For LINQ operations
|
||||||
|
|
||||||
|
namespace ArachnaeSwarm
|
||||||
|
{
|
||||||
|
public class CompAbilityEffect_BindDrone : CompAbilityEffect
|
||||||
|
{
|
||||||
|
public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
|
||||||
|
{
|
||||||
|
base.Apply(target, dest);
|
||||||
|
|
||||||
|
Pawn dronePawn = target.Pawn;
|
||||||
|
Pawn masterPawn = parent.pawn; // The pawn casting the ability
|
||||||
|
|
||||||
|
if (masterPawn != null && dronePawn != null)
|
||||||
|
{
|
||||||
|
Hediff_HiveMindMaster masterHediff = masterPawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("ARA_HiveMindMaster")) as Hediff_HiveMindMaster;
|
||||||
|
if (masterHediff != null)
|
||||||
|
{
|
||||||
|
if (masterHediff.TryBindDrone(dronePawn))
|
||||||
|
{
|
||||||
|
Messages.Message($"Successfully bound {dronePawn.LabelShort} to {masterPawn.LabelShort}'s hive mind.", MessageTypeDefOf.PositiveEvent, historical: false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Messages.Message($"Failed to bind {dronePawn.LabelShort} to {masterPawn.LabelShort}'s hive mind. Check logs for details.", MessageTypeDefOf.NegativeEvent, historical: false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Error($"[ArachnaeSwarm] Master {masterPawn.LabelShort} tried to bind a drone but does not have Hediff_HiveMindMaster.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Valid(LocalTargetInfo target, bool throwMessages = false)
|
||||||
|
{
|
||||||
|
if (!base.Valid(target, throwMessages))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pawn dronePawn = target.Pawn;
|
||||||
|
Pawn masterPawn = parent.pawn;
|
||||||
|
|
||||||
|
// Target must be a pawn
|
||||||
|
if (dronePawn == null)
|
||||||
|
{
|
||||||
|
if (throwMessages)
|
||||||
|
{
|
||||||
|
Messages.Message("MustTargetPawn".Translate(parent.def.label), MessageTypeDefOf.RejectInput, historical: false);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Target must be on the same map as the caster
|
||||||
|
if (dronePawn.Map != masterPawn.Map)
|
||||||
|
{
|
||||||
|
if (throwMessages)
|
||||||
|
{
|
||||||
|
Messages.Message("CannotTargetDifferentMap".Translate(), MessageTypeDefOf.RejectInput, historical: false);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Target must have ARA_HiveMindDrone hediff
|
||||||
|
Hediff_HiveMindDrone droneHediff = dronePawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("ARA_HiveMindDrone")) as Hediff_HiveMindDrone;
|
||||||
|
if (droneHediff == null)
|
||||||
|
{
|
||||||
|
if (throwMessages)
|
||||||
|
{
|
||||||
|
Messages.Message($"Target {dronePawn.LabelShort} does not have the 'ARA_HiveMindDrone' hediff.", MessageTypeDefOf.RejectInput, historical: false);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Target must not be already bound to another master
|
||||||
|
if (droneHediff.target != null && droneHediff.target != masterPawn)
|
||||||
|
{
|
||||||
|
if (throwMessages)
|
||||||
|
{
|
||||||
|
Messages.Message($"Target {dronePawn.LabelShort} is already bound to {droneHediff.target.LabelShort}.", MessageTypeDefOf.RejectInput, historical: false);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Caster must have ARA_HiveMindMaster hediff
|
||||||
|
Hediff_HiveMindMaster masterHediff = masterPawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("ARA_HiveMindMaster")) as Hediff_HiveMindMaster;
|
||||||
|
if (masterHediff == null)
|
||||||
|
{
|
||||||
|
if (throwMessages)
|
||||||
|
{
|
||||||
|
Messages.Message($"Caster {masterPawn.LabelShort} does not have the 'ARA_HiveMindMaster' hediff.", MessageTypeDefOf.RejectInput, historical: false);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All checks passed
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanApplyOn(LocalTargetInfo target, LocalTargetInfo dest)
|
||||||
|
{
|
||||||
|
return Valid(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
Source/ArachnaeSwarm/CompProperties_AbilityBindDrone.cs
Normal file
13
Source/ArachnaeSwarm/CompProperties_AbilityBindDrone.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using Verse;
|
||||||
|
using RimWorld;
|
||||||
|
|
||||||
|
namespace ArachnaeSwarm
|
||||||
|
{
|
||||||
|
public class CompProperties_AbilityBindDrone : CompProperties_AbilityEffect
|
||||||
|
{
|
||||||
|
public CompProperties_AbilityBindDrone()
|
||||||
|
{
|
||||||
|
this.compClass = typeof(CompAbilityEffect_BindDrone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
Source/ArachnaeSwarm/HediffCompProperties_HiveMindDrone.cs
Normal file
14
Source/ArachnaeSwarm/HediffCompProperties_HiveMindDrone.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using Verse;
|
||||||
|
|
||||||
|
namespace ArachnaeSwarm
|
||||||
|
{
|
||||||
|
public class HediffCompProperties_HiveMindDrone : HediffCompProperties
|
||||||
|
{
|
||||||
|
public int unlinkedDieDelayTicks = 1800; // Default to 30 seconds
|
||||||
|
|
||||||
|
public HediffCompProperties_HiveMindDrone()
|
||||||
|
{
|
||||||
|
this.compClass = typeof(HediffComp_HiveMindDrone); // Reference the Comp class
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
57
Source/ArachnaeSwarm/HediffComp_HiveMindDrone.cs
Normal file
57
Source/ArachnaeSwarm/HediffComp_HiveMindDrone.cs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
using Verse;
|
||||||
|
using RimWorld;
|
||||||
|
|
||||||
|
namespace ArachnaeSwarm
|
||||||
|
{
|
||||||
|
public class HediffComp_HiveMindDrone : HediffComp
|
||||||
|
{
|
||||||
|
public HediffCompProperties_HiveMindDrone Props => (HediffCompProperties_HiveMindDrone)this.props;
|
||||||
|
|
||||||
|
public int TicksUnlinked => ticksUnlinked; // Expose as public property
|
||||||
|
private int ticksUnlinked = 0;
|
||||||
|
|
||||||
|
public override void CompExposeData()
|
||||||
|
{
|
||||||
|
base.CompExposeData();
|
||||||
|
Scribe_Values.Look(ref ticksUnlinked, "ticksUnlinked", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void CompPostTick(ref float severityAdjustment)
|
||||||
|
{
|
||||||
|
base.CompPostTick(ref severityAdjustment);
|
||||||
|
|
||||||
|
// Only check if pawn is spawned and on a map
|
||||||
|
if (parent.pawn.Spawned && parent.pawn.Map != null)
|
||||||
|
{
|
||||||
|
// We use parent.pawn.IsHashIntervalTick(60) for performance
|
||||||
|
if (!parent.pawn.IsHashIntervalTick(60))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Hediff_HiveMindDrone droneHediff = parent as Hediff_HiveMindDrone;
|
||||||
|
if (droneHediff == null) return; // Should not happen
|
||||||
|
|
||||||
|
Pawn masterPawn = droneHediff.target as Pawn;
|
||||||
|
|
||||||
|
if (masterPawn == null || masterPawn.Destroyed || masterPawn.Dead || !masterPawn.health.hediffSet.HasHediff(HediffDef.Named("ARA_HiveMindMaster")))
|
||||||
|
{
|
||||||
|
// Master is invalid or unlinked, start/continue unlinked timer
|
||||||
|
ticksUnlinked += 60; // Increment by 60 because we check every 60 ticks
|
||||||
|
if (ticksUnlinked >= Props.unlinkedDieDelayTicks)
|
||||||
|
{
|
||||||
|
Log.Message($"[ArachnaeSwarm] Drone {parent.pawn.LabelShort} was unlinked from master for too long and will die. Forcing death.");
|
||||||
|
// Ensure the pawn is killed only once and prevent further ticks
|
||||||
|
if (!parent.pawn.Dead && !parent.pawn.Destroyed)
|
||||||
|
{
|
||||||
|
parent.pawn.Kill(null, parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Master is valid, reset unlinked timer
|
||||||
|
ticksUnlinked = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
73
Source/ArachnaeSwarm/Hediff_HiveMindDrone.cs
Normal file
73
Source/ArachnaeSwarm/Hediff_HiveMindDrone.cs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using RimWorld;
|
||||||
|
using Verse;
|
||||||
|
|
||||||
|
namespace ArachnaeSwarm
|
||||||
|
{
|
||||||
|
public class Hediff_HiveMindDrone : HediffWithTarget
|
||||||
|
{
|
||||||
|
public override string LabelBase
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string baseLabel = base.LabelBase + " (" + (target != null ? target.LabelShortCap : "未连接") + ")";
|
||||||
|
|
||||||
|
// Get the HediffComp_HiveMindDrone to access ticksUnlinked
|
||||||
|
HediffComp_HiveMindDrone comp = this.TryGetComp<HediffComp_HiveMindDrone>();
|
||||||
|
if (comp != null)
|
||||||
|
{
|
||||||
|
// Safely cast target to Pawn for Dead and health checks
|
||||||
|
Pawn masterPawn = target as Pawn;
|
||||||
|
|
||||||
|
if (masterPawn == null || masterPawn.Destroyed || masterPawn.Dead || !masterPawn.health.hediffSet.HasHediff(HediffDef.Named("ARA_HiveMindMaster")))
|
||||||
|
{
|
||||||
|
float timeLeftSecs = (comp.Props.unlinkedDieDelayTicks - comp.TicksUnlinked) / 60f;
|
||||||
|
if (timeLeftSecs > 0)
|
||||||
|
{
|
||||||
|
return baseLabel + " (死亡倒计时: " + timeLeftSecs.ToString("F1") + "s)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return baseLabel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PostAdd(DamageInfo? dinfo)
|
||||||
|
{
|
||||||
|
base.PostAdd(dinfo);
|
||||||
|
// No direct linking in PostAdd, master will link manually
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool ShouldRemove
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// Only remove if base ShouldRemove is true, OR if pawn is dead
|
||||||
|
// We do NOT want to remove it just because target is invalid, as the Comp will handle delayed death
|
||||||
|
if (base.ShouldRemove && pawn.Dead)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Also remove if pawn is no longer spawned or on a map
|
||||||
|
if (!pawn.Spawned || pawn.Map == null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false; // Let the Comp handle the unlinked death
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PostRemoved()
|
||||||
|
{
|
||||||
|
base.PostRemoved();
|
||||||
|
// Deregister from the master when this hediff is removed
|
||||||
|
// Ensure target is a Pawn and not dead before attempting to deregister
|
||||||
|
if (this.target is Pawn master && master != null && !master.Destroyed && !master.Dead)
|
||||||
|
{
|
||||||
|
var masterHediff = master.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("ARA_HiveMindMaster")) as Hediff_HiveMindMaster;
|
||||||
|
masterHediff?.DeregisterDrone(this.pawn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// PostTick logic moved to HediffComp_HiveMindDrone
|
||||||
|
}
|
||||||
|
}
|
||||||
86
Source/ArachnaeSwarm/Hediff_HiveMindMaster.cs
Normal file
86
Source/ArachnaeSwarm/Hediff_HiveMindMaster.cs
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using RimWorld;
|
||||||
|
using Verse;
|
||||||
|
|
||||||
|
namespace ArachnaeSwarm
|
||||||
|
{
|
||||||
|
public class Hediff_HiveMindMaster : Hediff
|
||||||
|
{
|
||||||
|
private List<Pawn> drones = new List<Pawn>();
|
||||||
|
|
||||||
|
public override string LabelInBrackets => drones.Count.ToString();
|
||||||
|
|
||||||
|
public override void ExposeData()
|
||||||
|
{
|
||||||
|
base.ExposeData();
|
||||||
|
Scribe_Collections.Look(ref drones, "drones", LookMode.Reference);
|
||||||
|
if (drones == null)
|
||||||
|
{
|
||||||
|
drones = new List<Pawn>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryBindDrone(Pawn drone)
|
||||||
|
{
|
||||||
|
if (drone == null || drone.Dead || !drone.Spawned || drone.Map != this.pawn.Map)
|
||||||
|
{
|
||||||
|
Log.Message($"[ArachnaeSwarm] Cannot bind drone {drone?.LabelShort ?? "null"}: Invalid pawn state.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Hediff_HiveMindDrone droneHediff = drone.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("ARA_HiveMindDrone")) as Hediff_HiveMindDrone;
|
||||||
|
if (droneHediff == null)
|
||||||
|
{
|
||||||
|
Log.Message($"[ArachnaeSwarm] Cannot bind drone {drone.LabelShort}: Does not have ARA_HiveMindDrone hediff.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (droneHediff.target != null && droneHediff.target != this.pawn)
|
||||||
|
{
|
||||||
|
Log.Message($"[ArachnaeSwarm] Cannot bind drone {drone.LabelShort}: Already bound to another master ({droneHediff.target.LabelShort}).");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drones.Contains(drone))
|
||||||
|
{
|
||||||
|
Log.Message($"[ArachnaeSwarm] Drone {drone.LabelShort} is already bound to this master.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
droneHediff.target = this.pawn; // Set the drone's target to this master
|
||||||
|
drones.Add(drone);
|
||||||
|
UpdateSeverity();
|
||||||
|
Log.Message($"[ArachnaeSwarm] Master {this.pawn.LabelShort} successfully bound drone {drone.LabelShort}.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeregisterDrone(Pawn drone)
|
||||||
|
{
|
||||||
|
if (drones.Contains(drone))
|
||||||
|
{
|
||||||
|
drones.Remove(drone);
|
||||||
|
UpdateSeverity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateSeverity()
|
||||||
|
{
|
||||||
|
this.Severity = drones.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PostRemoved()
|
||||||
|
{
|
||||||
|
base.PostRemoved();
|
||||||
|
// Kill all drones when the master hediff is removed (e.g., master dies)
|
||||||
|
foreach (var drone in drones.ToList()) // ToList() to avoid collection modification issues
|
||||||
|
{
|
||||||
|
if (drone != null && !drone.Dead)
|
||||||
|
{
|
||||||
|
Log.Message($"[ArachnaeSwarm] Master {pawn.LabelShort} died, killing drone {drone.LabelShort}.");
|
||||||
|
drone.Kill(null, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user