This commit is contained in:
2025-10-21 17:34:41 +08:00
parent a3ca5040e0
commit ef79645c19
19 changed files with 1319 additions and 92 deletions

Binary file not shown.

View File

@@ -1469,8 +1469,29 @@
<angleOffset>0</angleOffset> <angleOffset>0</angleOffset>
<autoAttack>true</autoAttack> <autoAttack>true</autoAttack>
</li> </li>
<li Class="ArachnaeSwarm.HediffCompProperties_DrawMote">
<mote>ARA_Mote_Hivelord_Turret_Range</mote> <!-- 大小和range没有严格对应关系需要自己试出来drawSize -->
<hideMoteWhenNotDrafted>true</hideMoteWhenNotDrafted>
</li>
</comps> </comps>
</HediffDef> </HediffDef>
<ThingDef ParentName="MoteBase">
<defName>ARA_Mote_Hivelord_Turret_Range</defName>
<thingClass>MoteAttached</thingClass>
<altitudeLayer>LightingOverlay</altitudeLayer>
<drawOffscreen>true</drawOffscreen>
<mote>
<solidTime>9999999</solidTime>
<needsMaintenance>true</needsMaintenance>
</mote>
<graphicData>
<graphicClass>Graphic_Mote</graphicClass>
<texPath>Things/Mote/CombatCommandMask</texPath>
<shaderType>MoteGlow</shaderType>
<color>(32, 17, 0, 255)</color>
<drawSize>66</drawSize>
</graphicData>
</ThingDef>
<AbilityDef> <AbilityDef>
<defName>ARA_Skyraider_Empthrower</defName> <defName>ARA_Skyraider_Empthrower</defName>
<label>空天种转换——电磁风暴</label> <label>空天种转换——电磁风暴</label>
@@ -1559,8 +1580,29 @@
<angleOffset>0</angleOffset> <angleOffset>0</angleOffset>
<autoAttack>true</autoAttack> <autoAttack>true</autoAttack>
</li> </li>
<li Class="ArachnaeSwarm.HediffCompProperties_DrawMote">
<mote>ARA_Mote_Empthrower_Turret_Range</mote>
<hideMoteWhenNotDrafted>true</hideMoteWhenNotDrafted>
</li>
</comps> </comps>
</HediffDef> </HediffDef>
<ThingDef ParentName="MoteBase">
<defName>ARA_Mote_Empthrower_Turret_Range</defName>
<thingClass>MoteAttached</thingClass>
<altitudeLayer>LightingOverlay</altitudeLayer>
<drawOffscreen>true</drawOffscreen>
<mote>
<solidTime>9999999</solidTime>
<needsMaintenance>true</needsMaintenance>
</mote>
<graphicData>
<graphicClass>Graphic_Mote</graphicClass>
<texPath>Things/Mote/CombatCommandMask</texPath>
<shaderType>MoteGlow</shaderType>
<color>(13, 191, 200, 25)</color>
<drawSize>51</drawSize>
</graphicData>
</ThingDef>
<!-- 禁卫种 --> <!-- 禁卫种 -->
<HediffDef> <HediffDef>

View File

@@ -39,10 +39,10 @@
<raidCommonalityFromPointsCurve> <raidCommonalityFromPointsCurve>
<points> <points>
<li>(300, 0)</li> <li>(300, 0)</li>
<li>(700, 0)</li> <li>(700, 1)</li>
<li>(1400, 0)</li> <li>(1400, 1.8)</li>
<li>(2800, 0)</li> <li>(2800, 2.2)</li>
<li>(4000, 0)</li> <li>(4000, 2.6)</li>
</points> </points>
</raidCommonalityFromPointsCurve> </raidCommonalityFromPointsCurve>
<pawnGroupMakers> <pawnGroupMakers>
@@ -77,7 +77,7 @@
</options> </options>
</li> </li>
</pawnGroupMakers> </pawnGroupMakers>
<!-- <raidLootMaker>MechanoidRaidLootMaker</raidLootMaker> --> <raidLootMaker>ARA_Hostile_Hive_RaidLootMaker</raidLootMaker>
<raidLootValueFromPointsCurve> <raidLootValueFromPointsCurve>
<points> <points>
<li>(35, 8)</li> <li>(35, 8)</li>
@@ -85,6 +85,7 @@
<li>(1000, 250)</li> <li>(1000, 250)</li>
<li>(2000, 400)</li> <li>(2000, 400)</li>
<li>(4000, 500)</li> <li>(4000, 500)</li>
<li>(10000, 1500)</li>
</points> </points>
</raidLootValueFromPointsCurve> </raidLootValueFromPointsCurve>
<humanlikeFaction>true</humanlikeFaction> <humanlikeFaction>true</humanlikeFaction>
@@ -96,7 +97,7 @@
<li>Cloth</li> <li>Cloth</li>
</thingDefs> </thingDefs>
</apparelStuffFilter> </apparelStuffFilter>
<earliestRaidDays>0</earliestRaidDays> <earliestRaidDays>45</earliestRaidDays>
<permanentEnemy>true</permanentEnemy> <permanentEnemy>true</permanentEnemy>
<hostileToFactionlessHumanlikes>true</hostileToFactionlessHumanlikes> <hostileToFactionlessHumanlikes>true</hostileToFactionlessHumanlikes>
<maxPawnCostPerTotalPointsCurve> <maxPawnCostPerTotalPointsCurve>
@@ -116,4 +117,17 @@
<li MayRequire="Ludeon.RimWorld.Biotech">Children</li> <li MayRequire="Ludeon.RimWorld.Biotech">Children</li>
</disallowedRaidAgeRestrictions> </disallowedRaidAgeRestrictions>
</FactionDef> </FactionDef>
<ThingSetMakerDef>
<defName>ARA_Hostile_Hive_RaidLootMaker</defName>
<root Class="ThingSetMaker_MarketValue">
<fixedParams>
<filter>
<thingDefs>
<li>ARA_InsectJelly</li>
<li>ARA_Carapace</li>
</thingDefs>
</filter>
</fixedParams>
</root>
</ThingSetMakerDef>
</Defs> </Defs>

View File

@@ -718,6 +718,12 @@
</recipes> </recipes>
<comps> <comps>
<li Class="ArachnaeSwarm.CompProperties_UniquePawn">
<globalVariable>Unique_Arachnae_Queen</globalVariable>
<showDeathMessage>true</showDeathMessage>
<deathMessageKey>ARA_QueenAlreadyExists</deathMessageKey>
<!-- <killDamageDef>AcidBurn</killDamageDef> -->
</li>
<li Class="ArachnaeSwarm.CompProperties_HediffGiver"> <li Class="ArachnaeSwarm.CompProperties_HediffGiver">
<hediffs> <hediffs>
<li>ARA_Queen_0_Stage</li> <li>ARA_Queen_0_Stage</li>

View File

@@ -411,8 +411,8 @@
<warmupTime>0.5</warmupTime> <warmupTime>0.5</warmupTime>
<defaultProjectile>Bullet_ARA_RW_Toxic_Needle_MG</defaultProjectile> <defaultProjectile>Bullet_ARA_RW_Toxic_Needle_MG</defaultProjectile>
<range>25.9</range> <range>25.9</range>
<burstShotCount>36</burstShotCount> <burstShotCount>28</burstShotCount>
<ticksBetweenBurstShots>2</ticksBetweenBurstShots> <ticksBetweenBurstShots>4</ticksBetweenBurstShots>
<soundCast>SpitterSpit</soundCast> <soundCast>SpitterSpit</soundCast>
<targetParams> <targetParams>
<canTargetLocations>true</canTargetLocations> <canTargetLocations>true</canTargetLocations>
@@ -2131,13 +2131,13 @@
<tradeability>None</tradeability> <tradeability>None</tradeability>
<thingSetMakerTags Inherit="False" /> <thingSetMakerTags Inherit="False" />
<comps> <comps>
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo"> <!-- <li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
<cocoonDefs> <cocoonDefs>
<li>ARA_Cocoon_Weapon</li> <li>ARA_Cocoon_Weapon</li>
<li>ARA_Cocoon_Weapon_From_Death</li> <li>ARA_Cocoon_Weapon_From_Death</li>
<li>ARA_BioforgeIncubator_Thing</li> <li>ARA_BioforgeIncubator_Thing</li>
</cocoonDefs> </cocoonDefs>
</li> </li> -->
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon" MayRequire="Ludeon.RimWorld.Odyssey"> <li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon" MayRequire="Ludeon.RimWorld.Odyssey">
<forcedTraits> <forcedTraits>
<li>ARA_Weapon_Damage_Icez</li> <li>ARA_Weapon_Damage_Icez</li>

View File

@@ -120,10 +120,6 @@
<CleaningTimeFactor>0.6</CleaningTimeFactor> <CleaningTimeFactor>0.6</CleaningTimeFactor>
<Beauty>2</Beauty> <Beauty>2</Beauty>
</statBases> </statBases>
<costList>
<Steel>2</Steel>
<ARA_Carapace>1</ARA_Carapace>
</costList>
<pathCost>10</pathCost> <pathCost>10</pathCost>
<constructEffect>ConstructMetal</constructEffect> <constructEffect>ConstructMetal</constructEffect>
<constructionSkillPrerequisite>6</constructionSkillPrerequisite> <constructionSkillPrerequisite>6</constructionSkillPrerequisite>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Defs> <Defs>
<ThingDef Name="ARA_InteractiveEggSac_Base" ParentName="BuildingNaturalBase" Abstract="True"> <ThingDef Name="ARA_InteractiveEggSac_Base" ParentName="BuildingNaturalBase" Abstract="True">
<thingClass>Building</thingClass> <thingClass>ArachnaeSwarm.Building_Incubatable</thingClass>
<category>Building</category> <category>Building</category>
<size>(1,1)</size> <size>(1,1)</size>
<!-- <minifiedDef>MinifiedThing</minifiedDef> --> <!-- <minifiedDef>MinifiedThing</minifiedDef> -->
@@ -21,6 +21,7 @@
<rotatable>false</rotatable> <rotatable>false</rotatable>
<tickerType>Normal</tickerType> <tickerType>Normal</tickerType>
<terrainAffordanceNeeded>Light</terrainAffordanceNeeded> <terrainAffordanceNeeded>Light</terrainAffordanceNeeded>
<minifiedDef>MinifiedThing</minifiedDef>
<statBases> <statBases>
<Mass>10</Mass> <Mass>10</Mass>
<MaxHitPoints>20</MaxHitPoints> <MaxHitPoints>20</MaxHitPoints>
@@ -498,71 +499,39 @@
</li> </li>
</comps> </comps>
</ThingDef> </ThingDef>
<!-- 女皇卵 -->
<!-- 科技 --> <ThingDef ParentName="ARA_InteractiveEggSac_Base">
<ThingDef ParentName="ARA_CocoonSpew_Base_Proj"> <defName>ARA_InteractiveEggSac_Queen</defName>
<defName>ARA_Proj_EggSac_Techprint</defName> <label>阿拉克涅女皇种卵囊</label>
<graphicData> <description>用于孵化阿拉克涅女皇种的超巨型卵囊,表皮坚硬地堪比堡垒,内部蕴含的遗传物质和营养足以孵化出这个星球闻所未闻的庞然大物。</description>
<texPath>ArachnaeSwarm/Building/ARA_InteractiveEggSac_Techprint</texPath>
<graphicClass>Graphic_Single</graphicClass>
</graphicData>
<projectile>
<spawnsThingDef>ARA_InteractiveEggSac_Techprint</spawnsThingDef>
</projectile>
</ThingDef>
<ThingDef ParentName="ARA_Cocoon_Base">
<defName>ARA_InteractiveEggSac_Techprint</defName>
<label>阿拉克涅基因试验卵</label>
<description>一个脆弱、易燃、黏滑的囊状物,它无法孵化任何督虫,而是可以孵化一些特定的科技蓝图,阿拉克涅女皇种可以通过与其交互将其激活。\n\n该虫卵需要使用大量精华素维持工作并且能研究的项目以其落地时的研究完成度为准那些尚未解锁的科技将无法孵化其蓝图。</description>
<statBases>
<MarketValue>2000</MarketValue>
</statBases>
<descriptionHyperlinks> <descriptionHyperlinks>
<ThingDef>ARA_Gene_Essence</ThingDef> <ThingDef>ArachnaeQueen_Race</ThingDef>
</descriptionHyperlinks> </descriptionHyperlinks>
<graphicData> <graphicData>
<texPath>ArachnaeSwarm/Building/ARA_InteractiveEggSac_Techprint</texPath> <color>(0.9, 0.9 ,0.5)</color>
<graphicClass>Graphic_Single</graphicClass> <drawSize>(3,3)</drawSize>
<drawSize>(1.1,1.1)</drawSize>
<shadowData>
<volume>(0.7, 0.4, 0.7)</volume>
<offset>(0,0,-0.1)</offset>
</shadowData>
</graphicData> </graphicData>
<statBases>
<MarketValue>1200</MarketValue>
</statBases>
<size>(3,3)</size>
<comps> <comps>
<!-- The new, GrowthVat-style fuel component --> <li Class="CompProperties_Glower">
<li Class="ArachnaeSwarm.CompProperties_RefuelableNutrition"> <glowRadius>12</glowRadius>
<fuelCapacity>100</fuelCapacity> <glowColor>(230, 230, 128, 0)</glowColor>
<fuelLabel>精华素</fuelLabel>
<fuelFilter>
<thingDefs>
<li>ARA_Gene_Essence</li>
</thingDefs>
</fuelFilter>
<fuelConsumptionRate>0</fuelConsumptionRate> <!-- IMPORTANT: Disable base class consumption -->
<showAllowAutoRefuelToggle>false</showAllowAutoRefuelToggle>
<initialFuelPercent>0.02</initialFuelPercent>
<autoRefuelPercent>1</autoRefuelPercent>
<initialConfigurableTargetFuelLevel>0</initialConfigurableTargetFuelLevel>
</li> </li>
<!-- 研究生产组件 --> <li Class="ArachnaeSwarm.CompProperties_SpawnPawnFromList">
<li Class="ArachnaeSwarm.CompProperties_ResearchProducer"> <spawnablePawns>
<whitelist> <li>
<pawnKind>ARA_ArachnaeQueen</pawnKind>
<delayTicks>180000</delayTicks>
</li>
</spawnablePawns>
<!-- <whitelist>
<li>ARA_ArachnaeQueen</li> <li>ARA_ArachnaeQueen</li>
</whitelist> </whitelist> -->
<destroyOnSpawn>true</destroyOnSpawn> <destroyOnSpawn>true</destroyOnSpawn>
<damagePerTickWhenUnfueled>0.2</damagePerTickWhenUnfueled>
<minNutritionToStart>1.0</minNutritionToStart>
<nutritionPerResearchPoint>0.06</nutritionPerResearchPoint>
<productionTicksPerResearchPoint>30</productionTicksPerResearchPoint>
</li>
<li Class="ArachnaeSwarm.CompProperties_TemperatureRuinableDamage">
<minSafeTemperature>-30</minSafeTemperature>
<maxSafeTemperature>55</maxSafeTemperature>
<progressPerDegreePerTick>0.00005</progressPerDegreePerTick>
<damagePerTick>0.005</damagePerTick>
<recoveryRate>0.001</recoveryRate>
</li> </li>
</comps> </comps>
</ThingDef> </ThingDef>
@@ -1440,4 +1409,72 @@
</li> </li>
</comps> </comps>
</ThingDef> </ThingDef>
<!-- 科技 -->
<ThingDef ParentName="ARA_CocoonSpew_Base_Proj">
<defName>ARA_Proj_EggSac_Techprint</defName>
<graphicData>
<texPath>ArachnaeSwarm/Building/ARA_InteractiveEggSac_Techprint</texPath>
<graphicClass>Graphic_Single</graphicClass>
</graphicData>
<projectile>
<spawnsThingDef>ARA_InteractiveEggSac_Techprint</spawnsThingDef>
</projectile>
</ThingDef>
<ThingDef ParentName="ARA_Cocoon_Base">
<defName>ARA_InteractiveEggSac_Techprint</defName>
<label>阿拉克涅基因试验卵</label>
<description>一个脆弱、易燃、黏滑的囊状物,它无法孵化任何督虫,而是可以孵化一些特定的科技蓝图,阿拉克涅女皇种可以通过与其交互将其激活。\n\n该虫卵需要使用大量精华素维持工作并且能研究的项目以其落地时的研究完成度为准那些尚未解锁的科技将无法孵化其蓝图。</description>
<statBases>
<MarketValue>2000</MarketValue>
</statBases>
<descriptionHyperlinks>
<ThingDef>ARA_Gene_Essence</ThingDef>
</descriptionHyperlinks>
<graphicData>
<texPath>ArachnaeSwarm/Building/ARA_InteractiveEggSac_Techprint</texPath>
<graphicClass>Graphic_Single</graphicClass>
<drawSize>(1.1,1.1)</drawSize>
<shadowData>
<volume>(0.7, 0.4, 0.7)</volume>
<offset>(0,0,-0.1)</offset>
</shadowData>
</graphicData>
<comps>
<!-- The new, GrowthVat-style fuel component -->
<li Class="ArachnaeSwarm.CompProperties_RefuelableNutrition">
<fuelCapacity>100</fuelCapacity>
<fuelLabel>精华素</fuelLabel>
<fuelFilter>
<thingDefs>
<li>ARA_Gene_Essence</li>
</thingDefs>
</fuelFilter>
<fuelConsumptionRate>0</fuelConsumptionRate> <!-- IMPORTANT: Disable base class consumption -->
<showAllowAutoRefuelToggle>false</showAllowAutoRefuelToggle>
<initialFuelPercent>0.02</initialFuelPercent>
<autoRefuelPercent>1</autoRefuelPercent>
<initialConfigurableTargetFuelLevel>0</initialConfigurableTargetFuelLevel>
</li>
<!-- 研究生产组件 -->
<li Class="ArachnaeSwarm.CompProperties_ResearchProducer">
<whitelist>
<li>ARA_ArachnaeQueen</li>
</whitelist>
<destroyOnSpawn>true</destroyOnSpawn>
<damagePerTickWhenUnfueled>0.2</damagePerTickWhenUnfueled>
<minNutritionToStart>1.0</minNutritionToStart>
<nutritionPerResearchPoint>0.06</nutritionPerResearchPoint>
<productionTicksPerResearchPoint>30</productionTicksPerResearchPoint>
</li>
<li Class="ArachnaeSwarm.CompProperties_TemperatureRuinableDamage">
<minSafeTemperature>-30</minSafeTemperature>
<maxSafeTemperature>55</maxSafeTemperature>
<progressPerDegreePerTick>0.00005</progressPerDegreePerTick>
<damagePerTick>0.005</damagePerTick>
<recoveryRate>0.001</recoveryRate>
</li>
</comps>
</ThingDef>
</Defs> </Defs>

View File

@@ -221,9 +221,6 @@
</building> </building>
<repairEffect>EatVegetarian</repairEffect> <repairEffect>EatVegetarian</repairEffect>
<filthLeaving>Filth_Slime</filthLeaving> <filthLeaving>Filth_Slime</filthLeaving>
<costList>
<Steel>20</Steel>
</costList>
<statBases> <statBases>
<MaxHitPoints>10</MaxHitPoints> <MaxHitPoints>10</MaxHitPoints>
<Mass>4</Mass> <Mass>4</Mass>

View File

@@ -93,4 +93,9 @@
<ARA_NeedSpecificArachnaeToStartResearchProduction>需要{0}才能开始研究生产</ARA_NeedSpecificArachnaeToStartResearchProduction> <ARA_NeedSpecificArachnaeToStartResearchProduction>需要{0}才能开始研究生产</ARA_NeedSpecificArachnaeToStartResearchProduction>
<researchProjectsAvailable>可用的研究项目</researchProjectsAvailable> <researchProjectsAvailable>可用的研究项目</researchProjectsAvailable>
<ARA_TechprintProductionComplete>生产完成:{0}个{1}{2}研究所需)</ARA_TechprintProductionComplete> <ARA_TechprintProductionComplete>生产完成:{0}个{1}{2}研究所需)</ARA_TechprintProductionComplete>
<ARA_QueenAlreadyExists>新诞生女皇种被基因性痉挛杀死了——由于阿拉克涅虫群在蜂巢意识层面上的结构性保护,一个虫巢只能有一只女皇种。</ARA_QueenAlreadyExists>
<ARA_ResurrectionPrevented>没有来自更高级节点的允许,{0} 将从基因层面拒绝任何复活。</ARA_ResurrectionPrevented>
<CannotBeUninstalled>孵化期间无法重新安装</CannotBeUninstalled>
</LanguageData> </LanguageData>

View File

@@ -3,11 +3,63 @@
"WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\", "WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
"Documents": [ "Documents": [
{ {
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_drawmoteinrange\\hediffcomp_drawmoteinrange.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_arachnidgravengine.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_arachnidgravengine.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_incubatable.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_incubatable.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\building_comps\\ara_spawnpawnfromlist\\compspawnpawnfromlist.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_spawnpawnfromlist\\compspawnpawnfromlist.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\building_comps\\ara_spawnpawnfromlist\\compproperties_spawnpawnfromlist.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_spawnpawnfromlist\\compproperties_spawnpawnfromlist.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\ara_showspawnablepawnslist\\compabilityeffect_abilityshowspawnablepawns.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_showspawnablepawnslist\\compabilityeffect_abilityshowspawnablepawns.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\pawn_comps\\ara_uniquepawn\\patch_uniquepawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_uniquepawn\\patch_uniquepawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\pawn_comps\\ara_uniquepawn\\compuniquepawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_uniquepawn\\compuniquepawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\pawn_comps\\ara_uniquepawn\\compproperties_uniquepawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_uniquepawn\\compproperties_uniquepawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\buildings\\building_turretgunhasspeed.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_turretgunhasspeed.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\building_comps\\ara_building_refuelingvat\\building_refuelingvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_building_refuelingvat\\building_refuelingvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\building_comps\\ara_nutrientvat\\building_nutrientvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_nutrientvat\\building_nutrientvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\buildings\\building_catastrophemissilesilo\\building_catastrophemissilesilo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_catastrophemissilesilo\\building_catastrophemissilesilo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\buildings\\building_aranutrientdispenser\\building_aranutrientdispenser.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_aranutrientdispenser\\building_aranutrientdispenser.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\hediffs\\ara_drawmoteinrange\\hediffcomp_drawmoteinrange.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_drawmoteinrange\\hediffcomp_drawmoteinrange.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_drawmoteinrange\\hediffcomp_drawmoteinrange.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}, },
{ {
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_hivemind\\hediff_hivemindmaster.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\hediffs\\ara_hivemind\\hediff_hivemindmaster.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_hivemind\\hediff_hivemindmaster.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_hivemind\\hediff_hivemindmaster.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}, },
{ {
@@ -34,28 +86,189 @@
"DocumentGroups": [ "DocumentGroups": [
{ {
"DockedWidth": 200, "DockedWidth": 200,
"SelectedChildIndex": 1, "SelectedChildIndex": 0,
"Children": [ "Children": [
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "Building_ArachnidGravEngine.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ArachnidGravEngine.cs",
"RelativeDocumentMoniker": "Buildings\\Building_ArachnidGravEngine.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ArachnidGravEngine.cs",
"RelativeToolTip": "Buildings\\Building_ArachnidGravEngine.cs",
"ViewState": "AgIAAAMAAAAAAAAAAAAkwBUAAAAJAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T09:12:42.006Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "Building_Incubatable.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Incubatable.cs",
"RelativeDocumentMoniker": "Buildings\\Building_Incubatable.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Incubatable.cs",
"RelativeToolTip": "Buildings\\Building_Incubatable.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABAAAAARAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T08:39:15.745Z",
"EditorCaption": ""
},
{ {
"$type": "Bookmark", "$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}" "Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 0, "DocumentIndex": 2,
"Title": "CompSpawnPawnFromList.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SpawnPawnFromList\\CompSpawnPawnFromList.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_SpawnPawnFromList\\CompSpawnPawnFromList.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SpawnPawnFromList\\CompSpawnPawnFromList.cs",
"RelativeToolTip": "Building_Comps\\ARA_SpawnPawnFromList\\CompSpawnPawnFromList.cs",
"ViewState": "AgIAAAsAAAAAAAAAAAAIwBkAAAANAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T08:29:44.344Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "CompProperties_SpawnPawnFromList.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SpawnPawnFromList\\CompProperties_SpawnPawnFromList.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_SpawnPawnFromList\\CompProperties_SpawnPawnFromList.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SpawnPawnFromList\\CompProperties_SpawnPawnFromList.cs",
"RelativeToolTip": "Building_Comps\\ARA_SpawnPawnFromList\\CompProperties_SpawnPawnFromList.cs",
"ViewState": "AgIAAA8AAAAAAAAAAAAuwBoAAAAvAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T08:29:42.187Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 4,
"Title": "CompAbilityEffect_AbilityShowSpawnablePawns.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs",
"RelativeToolTip": "Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs",
"ViewState": "AgIAADgAAAAAAAAAAAAuwEwAAAA8AAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T08:29:37.669Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "Patch_UniquePawn.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\Patch_UniquePawn.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\Patch_UniquePawn.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\Patch_UniquePawn.cs",
"RelativeToolTip": "Pawn_Comps\\ARA_UniquePawn\\Patch_UniquePawn.cs",
"ViewState": "AgIAACUAAAAAAAAAAAAkwDEAAAAlAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T07:20:36.341Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 8,
"Title": "Building_TurretGunHasSpeed.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_TurretGunHasSpeed.cs",
"RelativeDocumentMoniker": "Buildings\\Building_TurretGunHasSpeed.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_TurretGunHasSpeed.cs",
"RelativeToolTip": "Buildings\\Building_TurretGunHasSpeed.cs",
"ViewState": "AgIAAL4CAAAAAAAAAAAAAL4CAABZAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T07:00:48.984Z"
},
{
"$type": "Document",
"DocumentIndex": 7,
"Title": "CompProperties_UniquePawn.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\CompProperties_UniquePawn.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\CompProperties_UniquePawn.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\CompProperties_UniquePawn.cs",
"RelativeToolTip": "Pawn_Comps\\ARA_UniquePawn\\CompProperties_UniquePawn.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T07:00:00.021Z"
},
{
"$type": "Document",
"DocumentIndex": 6,
"Title": "CompUniquePawn.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs",
"RelativeToolTip": "Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs",
"ViewState": "AgIAADQAAAAAAAAAAAAkwEYAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T07:00:02.43Z"
},
{
"$type": "Document",
"DocumentIndex": 9,
"Title": "Building_RefuelingVat.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
"RelativeToolTip": "Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
"ViewState": "AgIAAPUAAAAAAAAAAAAAAPUAAAA2AAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T07:00:47.792Z"
},
{
"$type": "Document",
"DocumentIndex": 10,
"Title": "Building_NutrientVat.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_NutrientVat\\Building_NutrientVat.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_NutrientVat\\Building_NutrientVat.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_NutrientVat\\Building_NutrientVat.cs",
"RelativeToolTip": "Building_Comps\\ARA_NutrientVat\\Building_NutrientVat.cs",
"ViewState": "AgIAAJUBAAAAAAAAAAAmwKgBAABmAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T07:00:43.042Z"
},
{
"$type": "Document",
"DocumentIndex": 11,
"Title": "Building_CatastropheMissileSilo.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CatastropheMissileSilo\\Building_CatastropheMissileSilo.cs",
"RelativeDocumentMoniker": "Buildings\\Building_CatastropheMissileSilo\\Building_CatastropheMissileSilo.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CatastropheMissileSilo\\Building_CatastropheMissileSilo.cs",
"RelativeToolTip": "Buildings\\Building_CatastropheMissileSilo\\Building_CatastropheMissileSilo.cs",
"ViewState": "AgIAALAAAAAAAAAAAAAAAL8AAABMAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T07:00:24.191Z"
},
{
"$type": "Document",
"DocumentIndex": 12,
"Title": "Building_ARANutrientDispenser.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ARANutrientDispenser\\Building_ARANutrientDispenser.cs",
"RelativeDocumentMoniker": "Buildings\\Building_ARANutrientDispenser\\Building_ARANutrientDispenser.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ARANutrientDispenser\\Building_ARANutrientDispenser.cs",
"RelativeToolTip": "Buildings\\Building_ARANutrientDispenser\\Building_ARANutrientDispenser.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAgAAACMAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T07:00:20.274Z"
},
{
"$type": "Document",
"DocumentIndex": 13,
"Title": "HediffComp_DrawMoteInRange.cs", "Title": "HediffComp_DrawMoteInRange.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_DrawMoteInRange\\HediffComp_DrawMoteInRange.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_DrawMoteInRange\\HediffComp_DrawMoteInRange.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_DrawMoteInRange\\HediffComp_DrawMoteInRange.cs", "RelativeDocumentMoniker": "Hediffs\\ARA_DrawMoteInRange\\HediffComp_DrawMoteInRange.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_DrawMoteInRange\\HediffComp_DrawMoteInRange.cs", "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_DrawMoteInRange\\HediffComp_DrawMoteInRange.cs",
"RelativeToolTip": "Hediffs\\ARA_DrawMoteInRange\\HediffComp_DrawMoteInRange.cs", "RelativeToolTip": "Hediffs\\ARA_DrawMoteInRange\\HediffComp_DrawMoteInRange.cs",
"ViewState": "AgIAABUAAAAAAAAAAAAIwBcAAABHAAAAAAAAAA==", "ViewState": "AgIAAAgAAAAAAAAAAADwvw4AAAAJAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T03:59:47.61Z", "WhenOpened": "2025-10-21T03:59:47.61Z"
"EditorCaption": ""
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 2, "DocumentIndex": 15,
"Title": "Hediff_HiveMindDrone.cs", "Title": "Hediff_HiveMindDrone.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\Hediff_HiveMindDrone.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\Hediff_HiveMindDrone.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\Hediff_HiveMindDrone.cs", "RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\Hediff_HiveMindDrone.cs",
@@ -67,7 +280,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 1, "DocumentIndex": 14,
"Title": "Hediff_HiveMindMaster.cs", "Title": "Hediff_HiveMindMaster.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs", "RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs",
@@ -75,12 +288,11 @@
"RelativeToolTip": "Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs", "RelativeToolTip": "Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs",
"ViewState": "AgIAADkAAAAAAAAAAAAgwI0AAAAAAAAAAAAAAA==", "ViewState": "AgIAADkAAAAAAAAAAAAgwI0AAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-20T17:25:29.183Z", "WhenOpened": "2025-10-20T17:25:29.183Z"
"EditorCaption": ""
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 3, "DocumentIndex": 16,
"Title": "CompAbilityEffect_BindDrone.cs", "Title": "CompAbilityEffect_BindDrone.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\CompAbilityEffect_BindDrone.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\CompAbilityEffect_BindDrone.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\CompAbilityEffect_BindDrone.cs", "RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\CompAbilityEffect_BindDrone.cs",
@@ -92,7 +304,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 4, "DocumentIndex": 17,
"Title": "CompProperties_AbilityBindDrone.cs", "Title": "CompProperties_AbilityBindDrone.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\CompProperties_AbilityBindDrone.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\CompProperties_AbilityBindDrone.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\CompProperties_AbilityBindDrone.cs", "RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\CompProperties_AbilityBindDrone.cs",
@@ -104,7 +316,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 5, "DocumentIndex": 18,
"Title": "Verb_ShootArc.cs", "Title": "Verb_ShootArc.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Verbs\\Verb_ShootArc.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Verbs\\Verb_ShootArc.cs",
"RelativeDocumentMoniker": "Verbs\\Verb_ShootArc.cs", "RelativeDocumentMoniker": "Verbs\\Verb_ShootArc.cs",

View File

@@ -100,6 +100,8 @@
<Compile Include="Abilities\ARA_ShowSpawnablePawnsList\CompAbilityEffect_AbilityShowSpawnablePawns.cs" /> <Compile Include="Abilities\ARA_ShowSpawnablePawnsList\CompAbilityEffect_AbilityShowSpawnablePawns.cs" />
<Compile Include="Abilities\ARA_ShowSpawnablePawnsList\CompProperties_AbilityShowSpawnablePawns.cs" /> <Compile Include="Abilities\ARA_ShowSpawnablePawnsList\CompProperties_AbilityShowSpawnablePawns.cs" />
<Compile Include="Abilities\CompAbilityEffect_TransformCorpse.cs" /> <Compile Include="Abilities\CompAbilityEffect_TransformCorpse.cs" />
<Compile Include="Buildings\Building_ArachnidGravEngine.cs" />
<Compile Include="Buildings\Building_Incubatable.cs" />
<Compile Include="Buildings\Building_TurretGunHasSpeed.cs" /> <Compile Include="Buildings\Building_TurretGunHasSpeed.cs" />
<Compile Include="Building_Comps\ARA_Building_RefuelingVat\Building_RefuelingVat.cs" /> <Compile Include="Building_Comps\ARA_Building_RefuelingVat\Building_RefuelingVat.cs" />
<Compile Include="Building_Comps\ARA_Building_RefuelingVat\CompProperties_RefuelingVat.cs" /> <Compile Include="Building_Comps\ARA_Building_RefuelingVat\CompProperties_RefuelingVat.cs" />
@@ -125,6 +127,9 @@
<Compile Include="Hediffs\ARA_DrawMoteInRange\HediffComp_DrawMoteInRange.cs" /> <Compile Include="Hediffs\ARA_DrawMoteInRange\HediffComp_DrawMoteInRange.cs" />
<Compile Include="Hediffs\HediffComp_LifespanDisplay.cs" /> <Compile Include="Hediffs\HediffComp_LifespanDisplay.cs" />
<Compile Include="Jobs\JobDriver_CarryPrisonerToRefuelingVat.cs" /> <Compile Include="Jobs\JobDriver_CarryPrisonerToRefuelingVat.cs" />
<Compile Include="Pawn_Comps\ARA_UniquePawn\CompProperties_UniquePawn.cs" />
<Compile Include="Pawn_Comps\ARA_UniquePawn\CompUniquePawn.cs" />
<Compile Include="Pawn_Comps\ARA_UniquePawn\Patch_UniquePawn.cs" />
<Compile Include="Storyteller\CustomRaidDef.cs" /> <Compile Include="Storyteller\CustomRaidDef.cs" />
<Compile Include="Storyteller\CustomRaidTracker.cs" /> <Compile Include="Storyteller\CustomRaidTracker.cs" />
<Compile Include="Storyteller\IncidentParmsExtensions.cs" /> <Compile Include="Storyteller\IncidentParmsExtensions.cs" />

View File

@@ -24,18 +24,16 @@ namespace ArachnaeSwarm
{ {
yield break; yield break;
} }
// 修改这里:只有当 whitelist 不为空时才检查白名单
if (Props.whitelist == null || !Props.whitelist.Contains(selPawn.kindDef)) if (Props.whitelist != null && Props.whitelist.Count > 0 && !Props.whitelist.Contains(selPawn.kindDef))
{ {
yield break; yield break;
} }
if (Props.spawnablePawns != null) if (Props.spawnablePawns != null)
{ {
foreach (PawnSpawnEntry entry in Props.spawnablePawns) foreach (PawnSpawnEntry entry in Props.spawnablePawns)
{ {
if (entry.pawnKind == null) continue; if (entry.pawnKind == null) continue;
if (entry.requiredResearch != null && !entry.requiredResearch.IsFinished) if (entry.requiredResearch != null && !entry.requiredResearch.IsFinished)
{ {
string disabledText = "ARA_Incubate".Translate(entry.pawnKind.label) + " (" + "Requires".Translate() + ": " + entry.requiredResearch.label + ")"; string disabledText = "ARA_Incubate".Translate(entry.pawnKind.label) + " (" + "Requires".Translate() + ": " + entry.requiredResearch.label + ")";

View File

@@ -0,0 +1,222 @@
using System;
using System.Collections.Generic;
using System.Linq;
using RimWorld;
using RimWorld.Planet;
using UnityEngine;
using Verse;
namespace ArachnaeSwarm
{
public class Building_ArachnidGravEngine : Building_GravEngine
{
// 通过 ModExtension 暴露的纹理路径
private ArachnidGravEngineExtension modExtension;
// 覆盖的纹理资源
private Texture2D customInspectCommandTex;
private CachedMaterial customOrbMat;
private Graphic customOnCooldownGraphic;
public ArachnidGravEngineExtension ModExtension
{
get
{
if (modExtension == null)
{
modExtension = def.GetModExtension<ArachnidGravEngineExtension>();
}
return modExtension;
}
}
// 重写 Graphic 属性以使用自定义纹理
public override Graphic Graphic
{
get
{
if (Find.TickManager.TicksGame >= cooldownCompleteTick)
{
return base.Graphic;
}
return CustomOnCooldownGraphic;
}
}
private Texture2D CustomInspectCommandTex
{
get
{
if (customInspectCommandTex == null && ModExtension?.inspectCommandTexPath != null)
{
customInspectCommandTex = ContentFinder<Texture2D>.Get(ModExtension.inspectCommandTexPath);
}
return customInspectCommandTex ?? ContentFinder<Texture2D>.Get("UI/Commands/Inspect");
}
}
private CachedMaterial CustomOrbMat
{
get
{
if (customOrbMat == null && ModExtension?.orbTexPath != null)
{
customOrbMat = new CachedMaterial(ModExtension.orbTexPath, ShaderDatabase.Cutout);
}
return customOrbMat ?? new CachedMaterial("Things/Building/GravEngine/GravEngine_Orb", ShaderDatabase.Cutout);
}
}
private Graphic CustomOnCooldownGraphic
{
get
{
if (customOnCooldownGraphic == null && ModExtension?.cooldownTexPath != null)
{
customOnCooldownGraphic = GraphicDatabase.Get<Graphic_Single>(
ModExtension.cooldownTexPath,
ShaderDatabase.Cutout,
Vector2.one * 3f,
Color.white);
}
return customOnCooldownGraphic ?? GraphicDatabase.Get<Graphic_Single>("Things/Building/GravEngine/GravEngine_Cooldown", ShaderDatabase.Cutout, Vector2.one * 3f, Color.white);
}
}
// 禁用检查系统 - 重写 Inspect 方法为空
public new void Inspect(bool silent = false)
{
// 完全禁用检查系统,不执行任何操作
// 虫群建筑不需要人类的研究检查流程
}
// 重写 GetGizmos 方法,移除检查相关的 gizmo
public override IEnumerable<Gizmo> GetGizmos()
{
foreach (Gizmo gizmo in base.GetGizmos())
{
// 过滤掉检查相关的 gizmo
if (gizmo is Command_Action command &&
command.defaultLabel?.Contains("CommandInspectGravEngine") == true)
{
continue;
}
yield return gizmo;
}
// 可以添加虫群特有的 gizmo
if (DebugSettings.ShowDevGizmos)
{
yield return new Command_Action
{
defaultLabel = "DEV: Spawn Arachnid Swarm",
action = delegate
{
// 虫群特有的调试功能
SpawnArachnidSwarm();
}
};
}
}
// 重写 GetFloatMenuOptions 方法,移除检查选项
public override IEnumerable<FloatMenuOption> GetFloatMenuOptions(Pawn selPawn)
{
foreach (FloatMenuOption floatMenuOption in base.GetFloatMenuOptions(selPawn))
{
// 过滤掉检查相关的选项
if (floatMenuOption.Label.Contains("CommandInspectGravEngine"))
{
continue;
}
yield return floatMenuOption;
}
}
// 重写 ClaimableBy 方法,移除检查限制
public override AcceptanceReport ClaimableBy(Faction by)
{
// 虫群建筑不需要检查就可以被认领
AcceptanceReport result = base.ClaimableBy(by);
if (!result.Accepted)
{
return result;
}
return true; // 总是返回 true忽略检查限制
}
// 重写 GetInspectString 方法,移除检查相关的文本
public override string GetInspectString()
{
string text = base.GetInspectString();
// 移除关于未检查的文本
if (text.Contains("GravEngineNotInspected"))
{
text = text.Replace("GravEngineNotInspected".Translate() + "\n", "");
}
// 添加虫群特有的信息
if (!string.IsNullOrEmpty(text))
{
text += "\n";
}
text += "ArachnidSwarmControl".Translate();
return text;
}
// 虫群特有的方法
private void SpawnArachnidSwarm()
{
// 虫群特有的生成逻辑
// 这里可以添加生成虫群单位的代码
Messages.Message("ArachnidSwarmActivated".Translate(), this, MessageTypeDefOf.PositiveEvent);
}
// 重写 DrawAt 方法以使用自定义材质
protected override void DrawAt(Vector3 drawLoc, bool flip = false)
{
base.DrawAt(drawLoc, flip);
if (base.Spawned)
{
if (Find.TickManager.TicksGame >= cooldownCompleteTick)
{
// 使用 Mathf 替代 MathF
drawLoc.z += 0.5f * (1f + Mathf.Sin(Mathf.PI * 2f * (float)GenTicks.TicksGame / 500f)) * 0.3f;
}
drawLoc.y += 0.03658537f;
Vector3 s = new Vector3(def.graphicData.drawSize.x, 1f, def.graphicData.drawSize.y);
// 使用自定义的球体材质
Graphics.DrawMesh(MeshPool.plane10Back, Matrix4x4.TRS(drawLoc, base.Rotation.AsQuat, s), CustomOrbMat.Material, 0, null, 0);
}
}
public override void SpawnSetup(Map map, bool respawningAfterLoad)
{
base.SpawnSetup(map, respawningAfterLoad);
// 虫群建筑自动属于玩家,不需要检查
if (base.Faction != Faction.OfPlayer)
{
SetFaction(Faction.OfPlayer);
}
// 标记为已检查,避免父类的检查逻辑
Find.ResearchManager.gravEngineInspected = true;
}
// 由于父类的私有字段无法访问,我们移除 UpdateSubstructureIfNeeded 的重写
// 如果需要修改子结构逻辑,可能需要通过其他方式
}
// ModExtension 定义,用于在 XML 中配置纹理路径
public class ArachnidGravEngineExtension : DefModExtension
{
public string inspectCommandTexPath;
public string orbTexPath;
public string cooldownTexPath;
public string swarmIconPath;
}
}

View File

@@ -0,0 +1,93 @@
using System.Collections.Generic;
using System.Linq;
using Verse;
using RimWorld;
namespace ArachnaeSwarm
{
public class Building_Incubatable : Building
{
private CompSpawnPawnFromList spawnComp;
public CompSpawnPawnFromList SpawnComp
{
get
{
if (spawnComp == null)
{
spawnComp = this.GetComp<CompSpawnPawnFromList>();
}
return spawnComp;
}
}
public bool IsHatching => SpawnComp?.IsHatching == true;
public override IEnumerable<Gizmo> GetGizmos()
{
foreach (Gizmo gizmo in base.GetGizmos())
{
// 如果正在孵化,过滤掉卸载相关的 gizmo
if (IsHatching && IsUninstallGizmo(gizmo))
{
continue;
}
yield return gizmo;
}
// 确保组件的 gizmo 也能正常显示
if (SpawnComp != null)
{
foreach (Gizmo compGizmo in SpawnComp.CompGetGizmosExtra())
{
yield return compGizmo;
}
}
}
private bool IsUninstallGizmo(Gizmo gizmo)
{
// 检查是否是卸载/重新安装相关的 gizmo
if (gizmo is Command_Action commandAction)
{
string label = commandAction.defaultLabel?.ToLower() ?? "";
string desc = commandAction.defaultDesc?.ToLower() ?? "";
return label.Contains("uninstall") ||
label.Contains("reinstall") ||
desc.Contains("uninstall") ||
desc.Contains("reinstall");
}
if (gizmo is Designator designator)
{
string label = designator.defaultLabel?.ToLower() ?? "";
string desc = designator.defaultDesc?.ToLower() ?? "";
return label.Contains("uninstall") ||
label.Contains("reinstall") ||
desc.Contains("uninstall") ||
desc.Contains("reinstall");
}
return false;
}
public override string GetInspectString()
{
string baseString = base.GetInspectString();
if (IsHatching)
{
if (!string.IsNullOrEmpty(baseString))
{
baseString += "\n";
}
baseString += "CannotBeUninstalled".Translate();
}
return baseString;
}
}
}

View File

@@ -0,0 +1,208 @@
using System.Collections.Generic;
using System.Linq;
using RimWorld;
using Verse;
namespace ArachnaeSwarm
{
public class MentalState_HiveMindCascade : MentalState
{
private bool hasCascaded = false;
public override void PostStart(string reason)
{
base.PostStart(reason);
// 发送通知
if (PawnUtility.ShouldSendNotificationAbout(pawn))
{
string labelText = def.beginLetterLabel.NullOrEmpty() ? def.label : def.beginLetterLabel;
TaggedString letterLabel = labelText.Formatted(pawn.LabelShort, pawn.Named("PAWN")).CapitalizeFirst();
TaggedString letterText = def.beginLetter.Formatted(pawn.LabelShort, pawn.Named("PAWN")).CapitalizeFirst();
if (reason != null)
{
letterText += "\n\n" + reason;
}
Find.LetterStack.ReceiveLetter(letterLabel, letterText, LetterDefOf.NegativeEvent, pawn);
}
// 立即执行级联传播
ExecuteCascadeBreakdown();
}
public override void MentalStateTick(int delta)
{
base.MentalStateTick(delta);
// 确保级联只执行一次
if (!hasCascaded)
{
ExecuteCascadeBreakdown();
}
// 设置强制恢复时间
if (this.forceRecoverAfterTicks <= 0)
{
this.forceRecoverAfterTicks = 300; // 5秒后恢复
}
// 如果级联已完成且超过恢复时间,则恢复
if (hasCascaded && age > forceRecoverAfterTicks)
{
RecoverFromState();
}
}
private void ExecuteCascadeBreakdown()
{
if (hasCascaded) return;
var extension = def.GetModExtension<MentalStateDefExtension_HiveMindCascade>();
if (extension?.mentalStatesToSpread == null || extension.mentalStatesToSpread.Count == 0)
{
Log.Error($"[ArachnaeSwarm] MentalState_HiveMindCascade: No mentalStatesToSpread defined for {def.defName}");
hasCascaded = true;
return;
}
// 获取主节点的HiveMindMaster hediff
var masterHediff = pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("ARA_HiveMindMaster")) as Hediff_HiveMindMaster;
if (masterHediff == null)
{
Log.Warning($"[ArachnaeSwarm] MentalState_HiveMindCascade: Pawn {pawn.LabelShort} does not have ARA_HiveMindMaster hediff");
hasCascaded = true;
return;
}
// 通过反射或其他方式获取无人机列表
var drones = GetDronesFromMaster(masterHediff);
if (drones == null || drones.Count == 0)
{
Log.Message($"[ArachnaeSwarm] MentalState_HiveMindCascade: No drones found for master {pawn.LabelShort}");
hasCascaded = true;
return;
}
int spreadCount = 0;
foreach (var drone in drones)
{
if (drone == null || drone.Dead || !drone.Spawned || drone.Destroyed)
continue;
// 随机选择一个精神崩溃状态
var randomMentalState = extension.mentalStatesToSpread.RandomElement();
if (randomMentalState == null)
continue;
// 强制无人机进入选定的精神崩溃状态
if (drone.mindState.mentalStateHandler.TryStartMentalState(randomMentalState, "HiveMindCascade", force: true))
{
spreadCount++;
Log.Message($"[ArachnaeSwarm] Cascaded {randomMentalState.defName} to drone {drone.LabelShort}");
}
else
{
Log.Warning($"[ArachnaeSwarm] Failed to cascade {randomMentalState.defName} to drone {drone.LabelShort}");
}
}
Log.Message($"[ArachnaeSwarm] HiveMindCascade: Successfully spread {spreadCount} mental breaks to drones");
hasCascaded = true;
// 显示级联完成的消息
if (spreadCount > 0 && PawnUtility.ShouldSendNotificationAbout(pawn))
{
Messages.Message("ARA_HiveMindCascadeComplete".Translate(pawn.LabelShort, spreadCount), pawn, MessageTypeDefOf.NegativeEvent);
}
}
/// <summary>
/// 通过反射获取HiveMindMaster中的无人机列表
/// </summary>
private List<Pawn> GetDronesFromMaster(Hediff_HiveMindMaster masterHediff)
{
// 方法1: 如果HiveMindMaster有公共属性暴露无人机列表
// return masterHediff.Drones; // 如果存在这样的属性
// 方法2: 通过反射访问私有字段
try
{
var dronesField = typeof(Hediff_HiveMindMaster).GetField("drones",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (dronesField != null)
{
return dronesField.GetValue(masterHediff) as List<Pawn>;
}
}
catch (System.Exception ex)
{
Log.Error($"[ArachnaeSwarm] Failed to access drones field via reflection: {ex.Message}");
}
// 方法3: 如果以上都失败,尝试通过其他方式
Log.Error($"[ArachnaeSwarm] Could not access drones list from HiveMindMaster");
return new List<Pawn>();
}
public override bool ForceRecoverFromState()
{
// 确保级联已经执行
if (!hasCascaded)
{
ExecuteCascadeBreakdown();
}
return base.ForceRecoverFromState();
}
public override void ExposeData()
{
base.ExposeData();
Scribe_Values.Look(ref hasCascaded, "hasCascaded", false);
}
}
public class MentalStateDefExtension_HiveMindCascade : DefModExtension
{
public List<MentalStateDef> mentalStatesToSpread;
// 可选:可以添加传播概率或其他参数
public float spreadChance = 1.0f;
public bool includeMasterInSpread = false;
}
public class MentalBreakWorker_HiveMindCascade : MentalBreakWorker
{
public override bool TryStart(Pawn pawn, string reason, bool causedByMood)
{
// 检查pawn是否有HiveMindMaster hediff
var hasHiveMindMaster = pawn.health.hediffSet.HasHediff(HediffDef.Named("ARA_HiveMindMaster"));
if (!hasHiveMindMaster)
{
Log.Message($"[ArachnaeSwarm] MentalBreakWorker_HiveMindCascade: Pawn {pawn.LabelShort} does not have ARA_HiveMindMaster, cannot start cascade");
return false;
}
// 调用基类方法启动精神状态
if (base.TryStart(pawn, reason, causedByMood))
{
Log.Message($"[ArachnaeSwarm] Started HiveMindCascade mental state on {pawn.LabelShort}");
return true;
}
return false;
}
public override float CommonalityFor(Pawn pawn, bool moodInduced = false)
{
// 只有拥有HiveMindMaster的pawn才能触发这种崩溃
var hasHiveMindMaster = pawn.health.hediffSet.HasHediff(HediffDef.Named("ARA_HiveMindMaster"));
if (!hasHiveMindMaster)
return 0f;
return base.CommonalityFor(pawn, moodInduced);
}
}
}

View File

@@ -0,0 +1,24 @@
using Verse;
namespace ArachnaeSwarm
{
public class CompProperties_UniquePawn : CompProperties
{
// 全局变量的唯一标识符
public string globalVariable;
// 可选杀死pawn时是否显示消息
public bool showDeathMessage = true;
// 可选:死亡消息的翻译键
public string deathMessageKey = "ARA_UniquePawnDeathMessage";
// 可选杀死pawn的方式
public DamageDef killDamageDef = null;
public CompProperties_UniquePawn()
{
this.compClass = typeof(CompUniquePawn);
}
}
}

View File

@@ -0,0 +1,151 @@
using System;
using RimWorld;
using Verse;
namespace ArachnaeSwarm
{
public class CompUniquePawn : ThingComp
{
private bool _checked = false;
private bool _scheduledForCheck = false;
public CompProperties_UniquePawn Props => (CompProperties_UniquePawn)this.props;
public override void PostSpawnSetup(bool respawningAfterLoad)
{
base.PostSpawnSetup(respawningAfterLoad);
// 基本安全检查
if (this.parent == null || !(this.parent is Pawn pawn) || !pawn.Spawned)
return;
// 只在首次生成时检查,不是加载存档时
if (respawningAfterLoad || _checked || _scheduledForCheck)
return;
// 确保属性有效
if (this.props == null || string.IsNullOrEmpty(Props?.globalVariable))
return;
try
{
// 延迟整个检查过程到下一帧
_scheduledForCheck = true;
LongEventHandler.QueueLongEvent(() =>
{
try
{
if (this.parent is Pawn delayedPawn && delayedPawn.Spawned && !_checked)
{
CheckAndHandleUniquePawn(delayedPawn);
_checked = true;
}
_scheduledForCheck = false;
}
catch (Exception ex)
{
Log.Error($"Error in delayed unique pawn check: {ex}");
_scheduledForCheck = false;
}
}, "ArachnaeSwarm_UniquePawnCheck", false, null);
}
catch (Exception ex)
{
Log.Error($"Error in CompUniquePawn.PostSpawnSetup: {ex}");
_scheduledForCheck = false;
}
}
private void CheckAndHandleUniquePawn(Pawn pawn)
{
try
{
string variable = Props.globalVariable;
if (string.IsNullOrEmpty(variable))
{
Log.Error("CompUniquePawn: globalVariable is null or empty");
return;
}
// 检查变量是否已存在
if (GlobalVariableManager.HasVariable(variable))
{
// 变量已存在杀死pawn
KillPawn(pawn, variable);
}
else
{
// 变量不存在,添加变量
GlobalVariableManager.SetVariable(variable);
if (Prefs.DevMode)
{
Log.Message($"Added global variable '{variable}' for pawn {pawn.Label}");
}
}
}
catch (Exception ex)
{
Log.Error($"Error in CheckAndHandleUniquePawn: {ex}");
}
}
private void KillPawn(Pawn pawn, string variable)
{
try
{
// 显示死亡消息
if (Props.showDeathMessage && !string.IsNullOrEmpty(Props.deathMessageKey))
{
string deathMessage = Props.deathMessageKey.Translate(pawn.Label, variable);
if (!string.IsNullOrEmpty(deathMessage))
{
Messages.Message(deathMessage, MessageTypeDefOf.NegativeEvent);
}
}
if (Prefs.DevMode)
{
Log.Message($"Killing pawn {pawn.Label} because global variable '{variable}' already exists");
}
// 使用更安全的延迟执行
LongEventHandler.QueueLongEvent(() =>
{
try
{
if (pawn != null && pawn.Spawned && !pawn.Destroyed)
{
if (Props.killDamageDef != null)
{
var damageInfo = new DamageInfo(Props.killDamageDef, 99999f, -1f, -1f);
pawn.TakeDamage(damageInfo);
}
else
{
pawn.Kill(null);
}
}
}
catch (Exception ex)
{
Log.Error($"Error in delayed pawn kill: {ex}");
}
}, "ArachnaeSwarm_KillDuplicatePawn", false, null);
}
catch (Exception ex)
{
Log.Error($"Error in KillPawn: {ex}");
}
}
public override void PostExposeData()
{
base.PostExposeData();
Scribe_Values.Look(ref _checked, "checked", false);
Scribe_Values.Look(ref _scheduledForCheck, "scheduledForCheck", false);
}
}
}

View File

@@ -0,0 +1,217 @@
using System.Collections.Generic;
using System.Reflection;
using HarmonyLib;
using RimWorld;
using Verse;
namespace ArachnaeSwarm
{
[StaticConstructorOnStartup]
public static class ModInit
{
static ModInit()
{
var harmony = new Harmony("ArachnaeSwarm.Mod");
harmony.PatchAll();
}
}
[HarmonyPatch(typeof(Game), "ExposeData")]
public static class Game_ExposeData_Patch
{
public static void Postfix()
{
GlobalVariableManager.ExposeData();
}
}
// 复活拦截补丁
[HarmonyPatch]
public static class ResurrectionUtility_Patch
{
private static MethodInfo TargetMethod()
{
// 尝试找到复活方法
return AccessTools.Method("ResurrectionUtility:TryResurrect") ??
AccessTools.Method("RimWorld.ResurrectionUtility:TryResurrect");
}
[HarmonyPrefix]
public static bool Prefix(Pawn pawn, ref bool __result)
{
try
{
// 检查 pawn 是否有 CompUniquePawn 组件
var comp = pawn?.GetComp<CompUniquePawn>();
if (comp != null && !string.IsNullOrEmpty(comp.Props?.globalVariable))
{
string variable = comp.Props.globalVariable;
// 如果全局变量已存在,阻止复活
if (GlobalVariableManager.HasVariable(variable))
{
// 显示阻止复活的消息
if (comp.Props.showDeathMessage && !string.IsNullOrEmpty(comp.Props.deathMessageKey))
{
string preventMessage = "ARA_ResurrectionPrevented".Translate(pawn.Label, variable);
if (string.IsNullOrEmpty(preventMessage) || preventMessage == "ARA_ResurrectionPrevented")
{
preventMessage = "无法复活 {0},因为 {1} 已经存在。".Translate(pawn.Label, variable);
}
Messages.Message(preventMessage, MessageTypeDefOf.NegativeEvent);
}
if (Prefs.DevMode)
{
Log.Message($"阻止复活 {pawn.Label},因为全局变量 '{variable}' 已存在");
}
__result = false; // 返回 false 表示复活失败
return false; // 跳过原始方法
}
}
}
catch (System.Exception ex)
{
Log.Error($"Error in resurrection prevention: {ex}");
}
return true; // 继续执行原始方法
}
}
// 带副作用的复活拦截补丁
[HarmonyPatch]
public static class ResurrectionUtility_Patch2
{
private static MethodInfo TargetMethod()
{
// 尝试找到带副作用的复活方法
return AccessTools.Method("ResurrectionUtility:TryResurrectWithSideEffects") ??
AccessTools.Method("RimWorld.ResurrectionUtility:TryResurrectWithSideEffects");
}
[HarmonyPrefix]
public static bool Prefix(Pawn pawn, ref bool __result)
{
try
{
// 检查 pawn 是否有 CompUniquePawn 组件
var comp = pawn?.GetComp<CompUniquePawn>();
if (comp != null && !string.IsNullOrEmpty(comp.Props?.globalVariable))
{
string variable = comp.Props.globalVariable;
// 如果全局变量已存在,阻止复活
if (GlobalVariableManager.HasVariable(variable))
{
// 显示阻止复活的消息
if (comp.Props.showDeathMessage && !string.IsNullOrEmpty(comp.Props.deathMessageKey))
{
string preventMessage = "ARA_ResurrectionPrevented".Translate(pawn.Label, variable);
if (string.IsNullOrEmpty(preventMessage) || preventMessage == "ARA_ResurrectionPrevented")
{
preventMessage = "无法复活 {0},因为 {1} 已经存在。".Translate(pawn.Label, variable);
}
Messages.Message(preventMessage, MessageTypeDefOf.NegativeEvent);
}
if (Prefs.DevMode)
{
Log.Message($"阻止复活 {pawn.Label},因为全局变量 '{variable}' 已存在");
}
__result = false; // 返回 false 表示复活失败
return false; // 跳过原始方法
}
}
}
catch (System.Exception ex)
{
Log.Error($"Error in resurrection prevention: {ex}");
}
return true; // 继续执行原始方法
}
}
public static class GlobalVariableManager
{
private static HashSet<string> _globalVariables;
private static bool _initialized = false;
private static void EnsureInitialized()
{
if (!_initialized)
{
_globalVariables = new HashSet<string>();
_initialized = true;
}
}
public static void ExposeData()
{
try
{
if (Scribe.mode == LoadSaveMode.Saving)
{
EnsureInitialized();
if (_globalVariables.Count > 0)
{
List<string> variablesList = new List<string>(_globalVariables);
Scribe_Collections.Look(ref variablesList, "ArachnaeSwarm_GlobalVariables", LookMode.Value);
}
}
else if (Scribe.mode == LoadSaveMode.LoadingVars)
{
List<string> variablesList = null;
Scribe_Collections.Look(ref variablesList, "ArachnaeSwarm_GlobalVariables", LookMode.Value);
if (variablesList != null)
{
_globalVariables = new HashSet<string>(variablesList);
}
else
{
_globalVariables = new HashSet<string>();
}
_initialized = true;
}
}
catch (System.Exception ex)
{
Log.Error($"Error in GlobalVariableManager.ExposeData: {ex}");
}
}
public static bool HasVariable(string variable)
{
EnsureInitialized();
return _globalVariables.Contains(variable);
}
public static void SetVariable(string variable)
{
EnsureInitialized();
_globalVariables.Add(variable);
}
public static bool RemoveVariable(string variable)
{
EnsureInitialized();
return _globalVariables.Remove(variable);
}
public static IEnumerable<string> GetAllVariables()
{
EnsureInitialized();
return _globalVariables;
}
public static void ClearAllVariables()
{
EnsureInitialized();
_globalVariables.Clear();
}
}
}