This commit is contained in:
2026-02-06 17:31:59 +08:00
parent b3403096fe
commit d69dc3bd95
15 changed files with 1149 additions and 77 deletions

Binary file not shown.

View File

@@ -226,15 +226,6 @@
</li> </li>
</stages> </stages>
</HediffDef> </HediffDef>
<HediffGiverSetDef>
<defName>ARA_NonPlayerHediffSet</defName>
<hediffGivers>
<li Class="ArachnaeSwarm.HediffGiver_NonPlayerFaction">
<hediff>ARA_NonPlayer_HiveMindDroneHediff</hediff>
<mtbDays>0.1</mtbDays> <!-- 很短的检查间隔 -->
</li>
</hediffGivers>
</HediffGiverSetDef>
<HediffDef> <HediffDef>
<defName>ARA_HiveMindWorker</defName> <defName>ARA_HiveMindWorker</defName>
<label>阿拉克涅辅虫</label> <label>阿拉克涅辅虫</label>

View File

@@ -21,7 +21,10 @@
<apparelMoney>300~500</apparelMoney> <apparelMoney>300~500</apparelMoney>
<weaponMoney>300~500</weaponMoney> <weaponMoney>300~500</weaponMoney>
<combatPower>100</combatPower> <combatPower>100</combatPower>
<startingHediffs> <startingHediffs Inherit="False">
<li>
<def>ARA_NonPlayer_HiveMindDroneHediff</def>
</li>
<li> <li>
<def>CrumblingMind</def> <def>CrumblingMind</def>
<severity>0.01</severity> <severity>0.01</severity>
@@ -53,7 +56,10 @@
<apparelMoney>300~500</apparelMoney> <apparelMoney>300~500</apparelMoney>
<weaponMoney>500~1200</weaponMoney> <weaponMoney>500~1200</weaponMoney>
<combatPower>150</combatPower> <combatPower>150</combatPower>
<startingHediffs> <startingHediffs Inherit="False">
<li>
<def>ARA_NonPlayer_HiveMindDroneHediff</def>
</li>
<li> <li>
<def>CrumblingMind</def> <def>CrumblingMind</def>
<severity>0.01</severity> <severity>0.01</severity>
@@ -85,7 +91,10 @@
<apparelMoney>400~700</apparelMoney> <apparelMoney>400~700</apparelMoney>
<weaponMoney>500~1200</weaponMoney> <weaponMoney>500~1200</weaponMoney>
<combatPower>100</combatPower> <combatPower>100</combatPower>
<startingHediffs> <startingHediffs Inherit="False">
<li>
<def>ARA_NonPlayer_HiveMindDroneHediff</def>
</li>
<li> <li>
<def>CrumblingMind</def> <def>CrumblingMind</def>
<severity>0.01</severity> <severity>0.01</severity>
@@ -117,7 +126,10 @@
<apparelMoney>500~900</apparelMoney> <apparelMoney>500~900</apparelMoney>
<weaponMoney>800~1800</weaponMoney> <weaponMoney>800~1800</weaponMoney>
<combatPower>250</combatPower> <combatPower>250</combatPower>
<startingHediffs> <startingHediffs Inherit="False">
<li>
<def>ARA_NonPlayer_HiveMindDroneHediff</def>
</li>
<li> <li>
<def>CrumblingMind</def> <def>CrumblingMind</def>
<severity>0.01</severity> <severity>0.01</severity>
@@ -145,7 +157,10 @@
<apparelMoney>600~1200</apparelMoney> <apparelMoney>600~1200</apparelMoney>
<weaponMoney>600~1000</weaponMoney> <weaponMoney>600~1000</weaponMoney>
<combatPower>320</combatPower> <combatPower>320</combatPower>
<startingHediffs> <startingHediffs Inherit="False">
<li>
<def>ARA_NonPlayer_HiveMindDroneHediff</def>
</li>
<li> <li>
<def>CrumblingMind</def> <def>CrumblingMind</def>
<severity>0.01</severity> <severity>0.01</severity>
@@ -183,7 +198,10 @@
<apparelMoney>500~900</apparelMoney> <apparelMoney>500~900</apparelMoney>
<weaponMoney>300~1200</weaponMoney> <weaponMoney>300~1200</weaponMoney>
<combatPower>380</combatPower> <combatPower>380</combatPower>
<startingHediffs> <startingHediffs Inherit="False">
<li>
<def>ARA_NonPlayer_HiveMindDroneHediff</def>
</li>
<li> <li>
<def>CrumblingMind</def> <def>CrumblingMind</def>
<severity>0.01</severity> <severity>0.01</severity>
@@ -215,7 +233,10 @@
<apparelMoney>600~1500</apparelMoney> <apparelMoney>600~1500</apparelMoney>
<weaponMoney>1200~2500</weaponMoney> <weaponMoney>1200~2500</weaponMoney>
<combatPower>450</combatPower> <combatPower>450</combatPower>
<startingHediffs> <startingHediffs Inherit="False">
<li>
<def>ARA_NonPlayer_HiveMindDroneHediff</def>
</li>
<li> <li>
<def>CrumblingMind</def> <def>CrumblingMind</def>
<severity>0.01</severity> <severity>0.01</severity>
@@ -243,7 +264,10 @@
<apparelMoney>1000~2500</apparelMoney> <apparelMoney>1000~2500</apparelMoney>
<weaponMoney>2000~3000</weaponMoney> <weaponMoney>2000~3000</weaponMoney>
<combatPower>600</combatPower> <combatPower>600</combatPower>
<startingHediffs> <startingHediffs Inherit="False">
<li>
<def>ARA_NonPlayer_HiveMindDroneHediff</def>
</li>
<li> <li>
<def>CrumblingMind</def> <def>CrumblingMind</def>
<severity>0.01</severity> <severity>0.01</severity>

View File

@@ -188,6 +188,8 @@
<canBeScattered>false</canBeScattered> <canBeScattered>false</canBeScattered>
<abilities> <abilities>
<li>ARA_Suicide_Ability</li> <li>ARA_Suicide_Ability</li>
<li>ARA_RaceBaseSwarmProduceOff</li>
<li>ARA_RaceBaseSwarmProduceOn</li>
</abilities> </abilities>
<xenotypeSet> <xenotypeSet>
<xenotypeChances> <xenotypeChances>
@@ -211,6 +213,9 @@
<li>Violent</li> <li>Violent</li>
</requiredWorkTags> </requiredWorkTags>
<startingHediffs> <startingHediffs>
<li>
<def>ARA_HiveMindDrone</def>
</li>
</startingHediffs> </startingHediffs>
<moveSpeedFactorByTerrainTag> <moveSpeedFactorByTerrainTag>
<li> <li>
@@ -234,8 +239,6 @@
</li> </li>
</backstoryFiltersOverride> </backstoryFiltersOverride>
<abilities> <abilities>
<li>ARA_RaceBaseSwarmProduceOff</li>
<li>ARA_RaceBaseSwarmProduceOn</li>
<li>ARA_AcidSprayBurst</li> <li>ARA_AcidSprayBurst</li>
</abilities> </abilities>
<apparelTags> <apparelTags>
@@ -259,10 +262,6 @@
<apparelTags> <apparelTags>
</apparelTags> </apparelTags>
<apparelMoney>0</apparelMoney> <apparelMoney>0</apparelMoney>
<abilities>
<li>ARA_RaceBaseSwarmProduceOff</li>
<li>ARA_RaceBaseSwarmProduceOn</li>
</abilities>
</PawnKindDef> </PawnKindDef>
<PawnKindDef Name="ArachnaeNode_Race_WeaponSmith" ParentName="ArachnaeNodeABasePawnKind"> <PawnKindDef Name="ArachnaeNode_Race_WeaponSmith" ParentName="ArachnaeNodeABasePawnKind">
<defName>ArachnaeNode_Race_WeaponSmith</defName> <defName>ArachnaeNode_Race_WeaponSmith</defName>
@@ -281,10 +280,6 @@
<apparelTags> <apparelTags>
</apparelTags> </apparelTags>
<apparelMoney>0</apparelMoney> <apparelMoney>0</apparelMoney>
<abilities>
<li>ARA_RaceBaseSwarmProduceOff</li>
<li>ARA_RaceBaseSwarmProduceOn</li>
</abilities>
</PawnKindDef> </PawnKindDef>
<PawnKindDef Name="ArachnaeNode_Race_Facehugger" ParentName="ArachnaeNodeABasePawnKind"> <PawnKindDef Name="ArachnaeNode_Race_Facehugger" ParentName="ArachnaeNodeABasePawnKind">
<defName>ArachnaeNode_Race_Facehugger</defName> <defName>ArachnaeNode_Race_Facehugger</defName>
@@ -322,6 +317,11 @@
</categories> </categories>
</li> </li>
</backstoryFiltersOverride> </backstoryFiltersOverride>
<startingHediffs>
<li>
<def>ARA_RaceBaseSwarmProduceSwitchHediff</def>
</li>
</startingHediffs>
<apparelTags> <apparelTags>
</apparelTags> </apparelTags>
<apparelMoney>0</apparelMoney> <apparelMoney>0</apparelMoney>
@@ -340,12 +340,11 @@
</categories> </categories>
</li> </li>
</backstoryFiltersOverride> </backstoryFiltersOverride>
<abilities> <startingHediffs>
<li>ARA_RaceBaseSwarmProduceOff</li> <li>
<li>ARA_RaceBaseSwarmProduceOn</li> <def>ARA_RaceBaseSwarmProduceSwitchHediff</def>
</abilities> </li>
<apparelTags> </startingHediffs>
</apparelTags>
<apparelMoney>0</apparelMoney> <apparelMoney>0</apparelMoney>
</PawnKindDef> </PawnKindDef>
<PawnKindDef Name="ArachnaeNode_Race_Skyraider" ParentName="ArachnaeNodeABasePawnKind"> <PawnKindDef Name="ArachnaeNode_Race_Skyraider" ParentName="ArachnaeNodeABasePawnKind">
@@ -370,8 +369,11 @@
<abilities> <abilities>
<li>ARA_Skyraider_jump</li> <li>ARA_Skyraider_jump</li>
</abilities> </abilities>
<apparelTags> <startingHediffs>
</apparelTags> <li>
<def>ARA_RaceBaseSwarmProduceSwitchHediff</def>
</li>
</startingHediffs>
<apparelMoney>0</apparelMoney> <apparelMoney>0</apparelMoney>
<modExtensions> <modExtensions>
<li Class="ArachnaeSwarm.SuperCarryExtension"> <li Class="ArachnaeSwarm.SuperCarryExtension">
@@ -426,8 +428,11 @@
</categories> </categories>
</li> </li>
</backstoryFiltersOverride> </backstoryFiltersOverride>
<apparelTags> <startingHediffs>
</apparelTags> <li>
<def>ARA_RaceBaseSwarmProduceSwitchHediff</def>
</li>
</startingHediffs>
<apparelMoney>0</apparelMoney> <apparelMoney>0</apparelMoney>
</PawnKindDef> </PawnKindDef>
<PawnKindDef Name="ARA_MimicNematodeShamblerBase" ParentName="ArachnaeNodeABasePawnKind" Abstract="True"> <PawnKindDef Name="ARA_MimicNematodeShamblerBase" ParentName="ArachnaeNodeABasePawnKind" Abstract="True">

View File

@@ -648,7 +648,6 @@
<comps> <comps>
<li Class="ArachnaeSwarm.CompProperties_HediffGiver"> <li Class="ArachnaeSwarm.CompProperties_HediffGiver">
<hediffs> <hediffs>
<li>ARA_HiveMindDrone</li>
<li>ARA_HiveStrength_Low</li> <li>ARA_HiveStrength_Low</li>
<li>ARA_Hive_Cannot_Speak</li> <li>ARA_Hive_Cannot_Speak</li>
</hediffs> </hediffs>

View File

@@ -119,7 +119,6 @@
<hediffGiverSets> <hediffGiverSets>
<li>OrganicStandard</li> <li>OrganicStandard</li>
<li>Human</li> <li>Human</li>
<li>ARA_NonPlayerHediffSet</li>
</hediffGiverSets> </hediffGiverSets>
</race> </race>
<recipes> <recipes>

View File

@@ -126,4 +126,99 @@
<traverseSound>TraversePitGate</traverseSound> <traverseSound>TraversePitGate</traverseSound>
</portal> </portal>
</ThingDef> </ThingDef>
<ThingDef>
<defName>ARA_WormholePortal_Spawner</defName>
<label>掘进中的虫洞</label>
<description>一只阿拉克涅坑道种的尾部正在地下活动——毫无疑问,它很快就要破土而出了!</description>
<thingClass>ArachnaeSwarm.BuildingGroundSpawner_WormholePortal</thingClass>
<destroyable>false</destroyable>
<holdsRoof>true</holdsRoof>
<selectable>true</selectable>
<tickerType>Normal</tickerType>
<useHitPoints>false</useHitPoints>
<drawerType>RealtimeOnly</drawerType>
<size>(2, 2)</size>
<uiIconPath>UI/Icons/UndergroundEmergence</uiIconPath>
<building>
<groundSpawnerSustainedEffecter>EmergencePointSustained2X2</groundSpawnerSustainedEffecter>
<groundSpawnerCompleteEffecter>EmergencePointComplete2X2</groundSpawnerCompleteEffecter>
<groundSpawnerThingToSpawn>ARA_WormholePortal_B</groundSpawnerThingToSpawn>
<groundSpawnerSpawnDelay>600</groundSpawnerSpawnDelay>
<groundSpawnerDestroyAdjacent>true</groundSpawnerDestroyAdjacent>
<groundSpawnerSustainerSound>PitBurrowOpening</groundSpawnerSustainerSound>
</building>
<modExtensions>
<li Class="ArachnaeSwarm.WormholePortalSpawnerExtension">
<minEmergeDelayTicks>600</minEmergeDelayTicks>
<maxEmergeDelayTicks>600</maxEmergeDelayTicks>
<requiresOpenSky>false</requiresOpenSky>
<minSpaceRadius>3</minSpaceRadius>
<destroyTerrain>true</destroyTerrain>
<destroyBuildings>false</destroyBuildings>
</li>
</modExtensions>
</ThingDef>
<ThingDef ParentName="BuildingBase">
<defName>ARA_WormholePortal_Enermy</defName>
<label>阿拉克涅坑道种尾部出口</label>
<description>阿拉克涅坑道种的尾巴,是其狭长身躯形成的地下通路的出口。</description>
<rotatable>false</rotatable>
<graphicData>
<texPath>ArachnaeSwarm/Building/ARA_Wormhole_B</texPath>
<graphicClass>Graphic_Single</graphicClass>
<shaderType>CutoutComplex</shaderType>
<drawSize>(4,4)</drawSize>
<shadowData>
<volume>(2.6, 2.5, 1.6)</volume>
<offset>(0,0,-0.1)</offset>
</shadowData>
</graphicData>
<altitudeLayer>Building</altitudeLayer>
<passability>Impassable</passability>
<statBases>
<MaxHitPoints>500</MaxHitPoints>
<Flammability>0.5</Flammability>
</statBases>
<size>(2,2)</size>
<comps>
<li Class="ArachnaeSwarm.CompProperties_WormholePortal">
<initialDelayTicks>60</initialDelayTicks>
<jumpIntervalTicks>30</jumpIntervalTicks>
<stunDurationTicks>60</stunDurationTicks>
<deactivationDelayTicks>120</deactivationDelayTicks>
<!-- <activationSound>PsycastPsychicPulse</activationSound>
<deactivationSound>PsycastPsychicPulse</deactivationSound>
<jumpSound>PsycastPsychicPulse</jumpSound> -->
<!-- <activationEffecter>PsycastPsychicPulse</activationEffecter>
<deactivationEffecter>PsycastPsychicPulse</deactivationEffecter> -->
<!-- <perJumpEffecter>PsycastSkipEffect</perJumpEffecter>
<jumpEffecter>PawnFlyerLanding</jumpEffecter> -->
<useColorCycling>false</useColorCycling>
<!-- <colorCycleSpeed>0.5</colorCycleSpeed> -->
</li>
</comps>
<tradeability>None</tradeability>
</ThingDef>
<!-- 到达模式定义 -->
<PawnsArrivalModeDef>
<defName>ARA_WormholePortal</defName>
<label>虫洞传送门</label>
<description>通过虫洞传送门到达</description>
<workerClass>ArachnaeSwarm.PawnsArrivalModeWorker_WormholePortal</workerClass>
<selectionWeightCurve>
<points>
<li>(0, 0)</li>
<li>(500, 0.3)</li>
<li>(1000, 0.5)</li>
<li>(2000, 0.7)</li>
</points>
</selectionWeightCurve>
<forQuickMilitaryAid>false</forQuickMilitaryAid>
<techLevel>Industrial</techLevel>
</PawnsArrivalModeDef>
</Defs> </Defs>

View File

@@ -2,28 +2,40 @@
"Version": 1, "Version": 1,
"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\\pawnsarrivalmode\\pawnsarrivalmodeworker_wormholeportal.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawnsarrivalmode\\pawnsarrivalmodeworker_wormholeportal.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_wormholeportal\\comp_wormholeportal.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_wormholeportal\\comp_wormholeportal.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_wormholeportal\\compproperties_wormholeportal.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_wormholeportal\\compproperties_wormholeportal.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\\uniquepawnmanager.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\\uniquepawnmanager.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_uniquepawn\\uniquepawnmanager.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_uniquepawn\\uniquepawnmanager.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}", "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}" "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\\needs\\need_honeyproduction.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\\needs\\need_honeyproduction.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:needs\\need_honeyproduction.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:needs\\need_honeyproduction.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\\jobs\\jobdriver_extracthoney\\jobdriver_extracthoney.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\\jobs\\jobdriver_extracthoney\\jobdriver_extracthoney.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_extracthoney\\jobdriver_extracthoney.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_extracthoney\\jobdriver_extracthoney.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\\needs\\need_chitinarmor.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\\needs\\need_chitinarmor.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:needs\\need_chitinarmor.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:needs\\need_chitinarmor.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_psychicloaddump\\compabilityeffect_psychicloaddump.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_psychicloaddump\\compabilityeffect_psychicloaddump.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_psychicloaddump\\compabilityeffect_psychicloaddump.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_psychicloaddump\\compabilityeffect_psychicloaddump.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}, },
{ {
@@ -111,19 +123,58 @@
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 0, "DocumentIndex": 0,
"Title": "PawnsArrivalModeWorker_WormholePortal.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PawnsArrivalMode\\PawnsArrivalModeWorker_WormholePortal.cs",
"RelativeDocumentMoniker": "PawnsArrivalMode\\PawnsArrivalModeWorker_WormholePortal.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PawnsArrivalMode\\PawnsArrivalModeWorker_WormholePortal.cs*",
"RelativeToolTip": "PawnsArrivalMode\\PawnsArrivalModeWorker_WormholePortal.cs*",
"ViewState": "AgIAADEBAAAAAAAAAAAkwEABAABSAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-06T09:04:02.296Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "CompProperties_WormholePortal.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_WormholePortal\\CompProperties_WormholePortal.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_WormholePortal\\CompProperties_WormholePortal.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_WormholePortal\\CompProperties_WormholePortal.cs",
"RelativeToolTip": "Building_Comps\\ARA_WormholePortal\\CompProperties_WormholePortal.cs",
"ViewState": "AgIAAAMAAAAAAAAAAAAuwBoAAAAIAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-06T09:03:50.674Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "Comp_WormholePortal.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_WormholePortal\\Comp_WormholePortal.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_WormholePortal\\Comp_WormholePortal.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_WormholePortal\\Comp_WormholePortal.cs",
"RelativeToolTip": "Building_Comps\\ARA_WormholePortal\\Comp_WormholePortal.cs",
"ViewState": "AgIAABQBAAAAAAAAAAAowCcBAAAJAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-06T09:01:19.98Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "UniquePawnManager.cs", "Title": "UniquePawnManager.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\UniquePawnManager.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\UniquePawnManager.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\UniquePawnManager.cs", "RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\UniquePawnManager.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\UniquePawnManager.cs", "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\UniquePawnManager.cs",
"RelativeToolTip": "Pawn_Comps\\ARA_UniquePawn\\UniquePawnManager.cs", "RelativeToolTip": "Pawn_Comps\\ARA_UniquePawn\\UniquePawnManager.cs",
"ViewState": "AgIAAIYAAAAAAAAAAAAUwJ4AAAANAAAAAAAAAA==", "ViewState": "AgIAAHQAAAAAAAAAAAAiwJEAAAAJAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-05T03:36:35.207Z", "WhenOpened": "2026-02-05T03:36:35.207Z",
"EditorCaption": "" "EditorCaption": ""
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 1, "DocumentIndex": 4,
"Title": "CompUniquePawn.cs", "Title": "CompUniquePawn.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\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", "RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs",
@@ -131,12 +182,11 @@
"RelativeToolTip": "Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs", "RelativeToolTip": "Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs",
"ViewState": "AgIAAKgAAAAAAAAAAAAtwLkAAAARAAAAAAAAAA==", "ViewState": "AgIAAKgAAAAAAAAAAAAtwLkAAAARAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-05T03:36:24.458Z", "WhenOpened": "2026-02-05T03:36:24.458Z"
"EditorCaption": ""
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 3, "DocumentIndex": 6,
"Title": "JobDriver_ExtractHoney.cs", "Title": "JobDriver_ExtractHoney.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_ExtractHoney\\JobDriver_ExtractHoney.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_ExtractHoney\\JobDriver_ExtractHoney.cs",
"RelativeDocumentMoniker": "Jobs\\JobDriver_ExtractHoney\\JobDriver_ExtractHoney.cs", "RelativeDocumentMoniker": "Jobs\\JobDriver_ExtractHoney\\JobDriver_ExtractHoney.cs",
@@ -144,12 +194,11 @@
"RelativeToolTip": "Jobs\\JobDriver_ExtractHoney\\JobDriver_ExtractHoney.cs", "RelativeToolTip": "Jobs\\JobDriver_ExtractHoney\\JobDriver_ExtractHoney.cs",
"ViewState": "AgIAAAQAAAAAAAAAAAAswBMAAAAJAAAAAAAAAA==", "ViewState": "AgIAAAQAAAAAAAAAAAAswBMAAAAJAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-05T03:32:58.466Z", "WhenOpened": "2026-02-05T03:32:58.466Z"
"EditorCaption": ""
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 2, "DocumentIndex": 5,
"Title": "Need_HoneyProduction.cs", "Title": "Need_HoneyProduction.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Needs\\Need_HoneyProduction.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Needs\\Need_HoneyProduction.cs",
"RelativeDocumentMoniker": "Needs\\Need_HoneyProduction.cs", "RelativeDocumentMoniker": "Needs\\Need_HoneyProduction.cs",
@@ -157,12 +206,11 @@
"RelativeToolTip": "Needs\\Need_HoneyProduction.cs", "RelativeToolTip": "Needs\\Need_HoneyProduction.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAoAAAAIAAAAAAAAAA==", "ViewState": "AgIAAAAAAAAAAAAAAAAAAAoAAAAIAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-05T03:21:22.655Z", "WhenOpened": "2026-02-05T03:21:22.655Z"
"EditorCaption": ""
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 4, "DocumentIndex": 7,
"Title": "Need_ChitinArmor.cs", "Title": "Need_ChitinArmor.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Needs\\Need_ChitinArmor.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Needs\\Need_ChitinArmor.cs",
"RelativeDocumentMoniker": "Needs\\Need_ChitinArmor.cs", "RelativeDocumentMoniker": "Needs\\Need_ChitinArmor.cs",
@@ -170,12 +218,11 @@
"RelativeToolTip": "Needs\\Need_ChitinArmor.cs", "RelativeToolTip": "Needs\\Need_ChitinArmor.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-05T03:21:22.016Z", "WhenOpened": "2026-02-05T03:21:22.016Z"
"EditorCaption": ""
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 6, "DocumentIndex": 9,
"Title": "CompProperties_AbilityPsychicLoadDump.cs", "Title": "CompProperties_AbilityPsychicLoadDump.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicLoadDump\\CompProperties_AbilityPsychicLoadDump.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicLoadDump\\CompProperties_AbilityPsychicLoadDump.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_PsychicLoadDump\\CompProperties_AbilityPsychicLoadDump.cs", "RelativeDocumentMoniker": "Abilities\\ARA_PsychicLoadDump\\CompProperties_AbilityPsychicLoadDump.cs",
@@ -187,7 +234,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 5, "DocumentIndex": 8,
"Title": "CompAbilityEffect_PsychicLoadDump.cs", "Title": "CompAbilityEffect_PsychicLoadDump.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicLoadDump\\CompAbilityEffect_PsychicLoadDump.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicLoadDump\\CompAbilityEffect_PsychicLoadDump.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_PsychicLoadDump\\CompAbilityEffect_PsychicLoadDump.cs", "RelativeDocumentMoniker": "Abilities\\ARA_PsychicLoadDump\\CompAbilityEffect_PsychicLoadDump.cs",
@@ -195,12 +242,11 @@
"RelativeToolTip": "Abilities\\ARA_PsychicLoadDump\\CompAbilityEffect_PsychicLoadDump.cs", "RelativeToolTip": "Abilities\\ARA_PsychicLoadDump\\CompAbilityEffect_PsychicLoadDump.cs",
"ViewState": "AgIAAAgAAAAAAAAAAAAowBIAAAASAAAAAAAAAA==", "ViewState": "AgIAAAgAAAAAAAAAAAAowBIAAAASAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-04T08:36:23.647Z", "WhenOpened": "2026-02-04T08:36:23.647Z"
"EditorCaption": ""
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 10, "DocumentIndex": 13,
"Title": "CompAbilityEffect_PsychicResearchHarvest.cs", "Title": "CompAbilityEffect_PsychicResearchHarvest.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicResearchHarvest\\CompAbilityEffect_PsychicResearchHarvest.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicResearchHarvest\\CompAbilityEffect_PsychicResearchHarvest.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_PsychicResearchHarvest\\CompAbilityEffect_PsychicResearchHarvest.cs", "RelativeDocumentMoniker": "Abilities\\ARA_PsychicResearchHarvest\\CompAbilityEffect_PsychicResearchHarvest.cs",
@@ -212,7 +258,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 14, "DocumentIndex": 17,
"Title": "CompProperties_AbilityPsychicLoadCost.cs", "Title": "CompProperties_AbilityPsychicLoadCost.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicLoadCost\\CompProperties_AbilityPsychicLoadCost.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicLoadCost\\CompProperties_AbilityPsychicLoadCost.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_PsychicLoadCost\\CompProperties_AbilityPsychicLoadCost.cs", "RelativeDocumentMoniker": "Abilities\\ARA_PsychicLoadCost\\CompProperties_AbilityPsychicLoadCost.cs",
@@ -224,7 +270,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 13, "DocumentIndex": 16,
"Title": "SwarmSpellUtility.cs", "Title": "SwarmSpellUtility.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_SwarmSpellHolder\\SwarmSpellUtility.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_SwarmSpellHolder\\SwarmSpellUtility.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_SwarmSpellHolder\\SwarmSpellUtility.cs", "RelativeDocumentMoniker": "Pawn_Comps\\ARA_SwarmSpellHolder\\SwarmSpellUtility.cs",
@@ -236,7 +282,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 9, "DocumentIndex": 12,
"Title": "CompAbilityEffect_PsychicLoadCost.cs", "Title": "CompAbilityEffect_PsychicLoadCost.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicLoadCost\\CompAbilityEffect_PsychicLoadCost.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicLoadCost\\CompAbilityEffect_PsychicLoadCost.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_PsychicLoadCost\\CompAbilityEffect_PsychicLoadCost.cs", "RelativeDocumentMoniker": "Abilities\\ARA_PsychicLoadCost\\CompAbilityEffect_PsychicLoadCost.cs",
@@ -248,7 +294,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 7, "DocumentIndex": 10,
"Title": "Comp_SwarmSpellHolder.cs", "Title": "Comp_SwarmSpellHolder.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_SwarmSpellHolder\\Comp_SwarmSpellHolder.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_SwarmSpellHolder\\Comp_SwarmSpellHolder.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_SwarmSpellHolder\\Comp_SwarmSpellHolder.cs", "RelativeDocumentMoniker": "Pawn_Comps\\ARA_SwarmSpellHolder\\Comp_SwarmSpellHolder.cs",
@@ -260,7 +306,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 8, "DocumentIndex": 11,
"Title": "Gizmo_SwarmSpellStatus.cs", "Title": "Gizmo_SwarmSpellStatus.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_SwarmSpellHolder\\Gizmo_SwarmSpellStatus.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_SwarmSpellHolder\\Gizmo_SwarmSpellStatus.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_SwarmSpellHolder\\Gizmo_SwarmSpellStatus.cs", "RelativeDocumentMoniker": "Pawn_Comps\\ARA_SwarmSpellHolder\\Gizmo_SwarmSpellStatus.cs",
@@ -272,7 +318,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 15, "DocumentIndex": 18,
"Title": "CompAbilityEffect_HediffGacha.cs", "Title": "CompAbilityEffect_HediffGacha.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HediffGacha\\CompAbilityEffect_HediffGacha.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HediffGacha\\CompAbilityEffect_HediffGacha.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_HediffGacha\\CompAbilityEffect_HediffGacha.cs", "RelativeDocumentMoniker": "Abilities\\ARA_HediffGacha\\CompAbilityEffect_HediffGacha.cs",
@@ -284,7 +330,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 12, "DocumentIndex": 15,
"Title": "CompFighterInvisible.cs", "Title": "CompFighterInvisible.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_Fighter_Invisible\\CompFighterInvisible.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_Fighter_Invisible\\CompFighterInvisible.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_Fighter_Invisible\\CompFighterInvisible.cs", "RelativeDocumentMoniker": "Pawn_Comps\\ARA_Fighter_Invisible\\CompFighterInvisible.cs",
@@ -296,7 +342,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 11, "DocumentIndex": 14,
"Title": "CompProperties_AbilityPsychicResearchHarvest.cs", "Title": "CompProperties_AbilityPsychicResearchHarvest.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicResearchHarvest\\CompProperties_AbilityPsychicResearchHarvest.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicResearchHarvest\\CompProperties_AbilityPsychicResearchHarvest.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_PsychicResearchHarvest\\CompProperties_AbilityPsychicResearchHarvest.cs", "RelativeDocumentMoniker": "Abilities\\ARA_PsychicResearchHarvest\\CompProperties_AbilityPsychicResearchHarvest.cs",
@@ -308,7 +354,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 16, "DocumentIndex": 19,
"Title": "CompAbilityEffect_HediffRestriction.cs", "Title": "CompAbilityEffect_HediffRestriction.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HediffRestriction\\CompAbilityEffect_HediffRestriction.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HediffRestriction\\CompAbilityEffect_HediffRestriction.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_HediffRestriction\\CompAbilityEffect_HediffRestriction.cs", "RelativeDocumentMoniker": "Abilities\\ARA_HediffRestriction\\CompAbilityEffect_HediffRestriction.cs",
@@ -320,7 +366,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 17, "DocumentIndex": 20,
"Title": "Window_HediffSelection.cs", "Title": "Window_HediffSelection.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HediffGacha\\Window_HediffSelection.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HediffGacha\\Window_HediffSelection.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_HediffGacha\\Window_HediffSelection.cs", "RelativeDocumentMoniker": "Abilities\\ARA_HediffGacha\\Window_HediffSelection.cs",
@@ -332,7 +378,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 18, "DocumentIndex": 21,
"Title": "ARA_PowerArmor.cs", "Title": "ARA_PowerArmor.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PowerArmor\\ARA_PowerArmor.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PowerArmor\\ARA_PowerArmor.cs",
"RelativeDocumentMoniker": "PowerArmor\\ARA_PowerArmor.cs", "RelativeDocumentMoniker": "PowerArmor\\ARA_PowerArmor.cs",
@@ -344,7 +390,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 19, "DocumentIndex": 22,
"Title": "PawnCapacityWorker_PsychicStange.cs", "Title": "PawnCapacityWorker_PsychicStange.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PawnCapacityWorker\\PawnCapacityWorker_PsychicStange.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PawnCapacityWorker\\PawnCapacityWorker_PsychicStange.cs",
"RelativeDocumentMoniker": "PawnCapacityWorker\\PawnCapacityWorker_PsychicStange.cs", "RelativeDocumentMoniker": "PawnCapacityWorker\\PawnCapacityWorker_PsychicStange.cs",
@@ -356,7 +402,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 21, "DocumentIndex": 24,
"Title": "CompAbilityEffect_PsychicBrainburn.cs", "Title": "CompAbilityEffect_PsychicBrainburn.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\PsychicBrainburn\\CompAbilityEffect_PsychicBrainburn.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\PsychicBrainburn\\CompAbilityEffect_PsychicBrainburn.cs",
"RelativeDocumentMoniker": "Abilities\\PsychicBrainburn\\CompAbilityEffect_PsychicBrainburn.cs", "RelativeDocumentMoniker": "Abilities\\PsychicBrainburn\\CompAbilityEffect_PsychicBrainburn.cs",
@@ -368,7 +414,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 20, "DocumentIndex": 23,
"Title": "ARA_DefOf.cs", "Title": "ARA_DefOf.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_DefOf.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_DefOf.cs",
"RelativeDocumentMoniker": "ARA_DefOf.cs", "RelativeDocumentMoniker": "ARA_DefOf.cs",
@@ -380,7 +426,7 @@
}, },
{ {
"$type": "Document", "$type": "Document",
"DocumentIndex": 22, "DocumentIndex": 25,
"Title": "CompAutoMechCarrier.cs", "Title": "CompAutoMechCarrier.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_AutoMechCarrier\\CompAutoMechCarrier.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_AutoMechCarrier\\CompAutoMechCarrier.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_AutoMechCarrier\\CompAutoMechCarrier.cs", "RelativeDocumentMoniker": "Pawn_Comps\\ARA_AutoMechCarrier\\CompAutoMechCarrier.cs",

View File

@@ -42,9 +42,13 @@
<Compile Include="Abilities\ARA_PsychicLoadDump\CompProperties_AbilityPsychicLoadDump.cs" /> <Compile Include="Abilities\ARA_PsychicLoadDump\CompProperties_AbilityPsychicLoadDump.cs" />
<Compile Include="Abilities\ARA_PsychicResearchHarvest\CompAbilityEffect_PsychicResearchHarvest.cs" /> <Compile Include="Abilities\ARA_PsychicResearchHarvest\CompAbilityEffect_PsychicResearchHarvest.cs" />
<Compile Include="Abilities\ARA_PsychicResearchHarvest\CompProperties_AbilityPsychicResearchHarvest.cs" /> <Compile Include="Abilities\ARA_PsychicResearchHarvest\CompProperties_AbilityPsychicResearchHarvest.cs" />
<Compile Include="Buildings\BuildingGroundSpawner_WormholePortal.cs" />
<Compile Include="Buildings\Building_CorpseVat\Building_CorpseVat.cs" /> <Compile Include="Buildings\Building_CorpseVat\Building_CorpseVat.cs" />
<Compile Include="Buildings\Building_CorpseVat\CorpseVatExtension.cs" /> <Compile Include="Buildings\Building_CorpseVat\CorpseVatExtension.cs" />
<Compile Include="Buildings\Building_CorpseVat\JobDriver_HaulCorpseToVat.cs" /> <Compile Include="Buildings\Building_CorpseVat\JobDriver_HaulCorpseToVat.cs" />
<Compile Include="Building_Comps\ARA_WormholePortal\CompProperties_WormholePortal.cs" />
<Compile Include="Building_Comps\ARA_WormholePortal\Comp_WormholePortal.cs" />
<Compile Include="Building_Comps\ARA_WormholePortal\WormholePortalSpawnerExtension.cs" />
<Compile Include="Damage\DamageDefExtension_TerrainCover.cs" /> <Compile Include="Damage\DamageDefExtension_TerrainCover.cs" />
<Compile Include="Damage\DamageWorker_ExplosionWithTerrain.cs" /> <Compile Include="Damage\DamageWorker_ExplosionWithTerrain.cs" />
<Compile Include="Hediffs\ARA_GestaltNode\CompGestalt.cs" /> <Compile Include="Hediffs\ARA_GestaltNode\CompGestalt.cs" />
@@ -339,6 +343,7 @@
<Compile Include="Needs\Need_ChitinArmor.cs" /> <Compile Include="Needs\Need_ChitinArmor.cs" />
<Compile Include="Needs\Need_HoneyProduction.cs" /> <Compile Include="Needs\Need_HoneyProduction.cs" />
<Compile Include="PawnCapacityWorker\PawnCapacityWorker_PsychicStange.cs" /> <Compile Include="PawnCapacityWorker\PawnCapacityWorker_PsychicStange.cs" />
<Compile Include="PawnsArrivalMode\PawnsArrivalModeWorker_WormholePortal.cs" />
<Compile Include="Pawn_Comps\ARA_AutoMechCarrier\CompAutoMechCarrier.cs" /> <Compile Include="Pawn_Comps\ARA_AutoMechCarrier\CompAutoMechCarrier.cs" />
<Compile Include="Pawn_Comps\ARA_AutoMechCarrier\CompProducedByMechCarrier.cs" /> <Compile Include="Pawn_Comps\ARA_AutoMechCarrier\CompProducedByMechCarrier.cs" />
<Compile Include="Pawn_Comps\ARA_AutoMechCarrier\CompProperties_AutoMechCarrier.cs" /> <Compile Include="Pawn_Comps\ARA_AutoMechCarrier\CompProperties_AutoMechCarrier.cs" />

View File

@@ -0,0 +1,91 @@
using RimWorld;
using UnityEngine;
using Verse;
namespace ArachnaeSwarm
{
/// <summary>
/// 虫洞传送门组件属性
/// </summary>
public class CompProperties_WormholePortal : CompProperties
{
#region
/// <summary>
/// 初始延迟ticks
/// </summary>
public int initialDelayTicks = 60; // 1秒
/// <summary>
/// 单位跳出间隔ticks
/// </summary>
public int jumpIntervalTicks = 30; // 0.5秒
/// <summary>
/// 单位跳出时的眩晕时间ticks
/// </summary>
public int stunDurationTicks = 60; // 1秒
#endregion
#region
/// <summary>
/// 激活音效
/// </summary>
public SoundDef activationSound = null;
/// <summary>
/// 停用音效
/// </summary>
public SoundDef deactivationSound = null;
/// <summary>
/// 跳出音效
/// </summary>
public SoundDef jumpSound = null;
/// <summary>
/// 激活效果器
/// </summary>
public EffecterDef activationEffecter = null;
/// <summary>
/// 停用效果器
/// </summary>
public EffecterDef deactivationEffecter = null;
/// <summary>
/// 每次跳出效果器
/// </summary>
public EffecterDef perJumpEffecter = null;
/// <summary>
/// 单位跳出效果器
/// </summary>
public EffecterDef jumpEffecter = null;
#endregion
#region
/// <summary>
/// 活跃时的材质
/// </summary>
public GraphicData activeGraphicData = null;
/// <summary>
/// 颜色循环
/// </summary>
public bool useColorCycling = true;
/// <summary>
/// 颜色循环速度
/// </summary>
public float colorCycleSpeed = 0.5f;
#endregion
#region
public CompProperties_WormholePortal()
{
compClass = typeof(Comp_WormholePortal);
}
#endregion
}
}

View File

@@ -0,0 +1,336 @@
using RimWorld;
using System.Collections.Generic;
using System.Linq;
using Verse;
using Verse.Sound;
namespace ArachnaeSwarm
{
/// <summary>
/// 虫洞传送门组件
/// 处理从虫洞中跳出单位
/// </summary>
public class Comp_WormholePortal : ThingComp
{
#region
private List<Pawn> emergingPawns = new List<Pawn>();
private int currentPawnIndex = 0;
private int ticksUntilNextJump = 0;
private bool isActive = false;
private int activateTick = -1;
#endregion
#region
public CompProperties_WormholePortal Props => (CompProperties_WormholePortal)props;
/// <summary>
/// 还有多少单位等待跳出
/// </summary>
public int RemainingPawns => emergingPawns.Count - currentPawnIndex;
/// <summary>
/// 虫洞是否活跃
/// </summary>
public bool IsActive => isActive;
/// <summary>
/// 激活后经过的时间
/// </summary>
public int TicksSinceActivation
{
get
{
if (!isActive || activateTick < 0)
return 0;
return Find.TickManager.TicksGame - activateTick;
}
}
#endregion
#region
public override void PostSpawnSetup(bool respawningAfterLoad)
{
base.PostSpawnSetup(respawningAfterLoad);
if (respawningAfterLoad)
return;
// 非加载生成时,准备激活
PrepareForActivation();
}
public override void CompTick()
{
base.CompTick();
if (!isActive || emergingPawns.NullOrEmpty() || currentPawnIndex >= emergingPawns.Count)
return;
// 计时下一个单位跳出
if (ticksUntilNextJump > 0)
{
ticksUntilNextJump--;
return;
}
// 跳出当前单位
JumpNextPawn();
// 设置下一个单位的跳出间隔
if (currentPawnIndex < emergingPawns.Count)
{
ticksUntilNextJump = Props.jumpIntervalTicks;
}
}
public void PostDeSpawn(Map map)
{
// 虫洞消失时,销毁剩余未跳出的单位
DestroyRemainingPawns();
}
public override void PostDestroy(DestroyMode mode, Map previousMap)
{
base.PostDestroy(mode, previousMap);
// 虫洞被摧毁时,销毁剩余未跳出的单位
DestroyRemainingPawns();
}
#endregion
#region
/// <summary>
/// 设置要跳出的单位
/// </summary>
public void SetEmergingPawns(List<Pawn> pawns)
{
emergingPawns = pawns ?? new List<Pawn>();
currentPawnIndex = 0;
}
/// <summary>
/// 激活虫洞
/// </summary>
public void Activate()
{
if (isActive)
return;
isActive = true;
activateTick = Find.TickManager.TicksGame;
// 设置第一个单位的跳出计时
if (emergingPawns.Count > 0)
{
ticksUntilNextJump = Props.initialDelayTicks;
}
// 播放激活效果
PlayActivationEffects();
}
/// <summary>
/// 获取虫洞状态描述
/// </summary>
public string GetStatusDescription()
{
if (!isActive)
return "休眠中";
if (RemainingPawns <= 0)
return "已完成";
return $"跳出中: {RemainingPawns} 个单位剩余";
}
#endregion
#region
/// <summary>
/// 准备激活
/// </summary>
private void PrepareForActivation()
{
// 可以在这里添加预热效果
// 例如:粒子效果、声音等
}
/// <summary>
/// 跳出下一个单位
/// </summary>
private void JumpNextPawn()
{
if (currentPawnIndex >= emergingPawns.Count)
return;
Pawn pawn = emergingPawns[currentPawnIndex];
currentPawnIndex++;
// 确保单位存在且有效
if (pawn == null || pawn.Destroyed)
{
Log.Warning("[虫洞传送门] 尝试跳出无效单位");
return;
}
// 生成单位
TrySpawnPawn(pawn);
// 播放跳出效果
PlayJumpEffects();
// 如果所有单位都已跳出,关闭虫洞
if (currentPawnIndex >= emergingPawns.Count)
{
StartDeactivation();
}
}
/// <summary>
/// 尝试生成单位
/// </summary>
private void TrySpawnPawn(Pawn pawn)
{
try
{
Map map = parent.Map;
if (map == null)
return;
// 找到虫洞周围的可行走位置
if (CellFinder.TryFindRandomCellNear(parent.Position, map, 2,
c => c.Walkable(map) && c.InBounds(map) && !c.Fogged(map), out IntVec3 spawnCell))
{
// 生成单位
GenSpawn.Spawn(pawn, spawnCell, map);
// 应用跳出效果
ApplyJumpEffectsToPawn(pawn, spawnCell);
}
else
{
// 如果找不到位置,在虫洞位置生成
GenSpawn.Spawn(pawn, parent.Position, map);
Log.Warning($"[虫洞传送门] 无法找到合适位置,在虫洞位置生成 {pawn.Label}");
}
}
catch (System.Exception ex)
{
Log.Error($"[虫洞传送门] 跳出单位失败: {ex.Message}");
}
}
/// <summary>
/// 应用跳出效果给单位
/// </summary>
private void ApplyJumpEffectsToPawn(Pawn pawn, IntVec3 spawnCell)
{
// 短暂眩晕效果
if (Props.stunDurationTicks > 0)
{
pawn.stances.stunner.StunFor(Props.stunDurationTicks, parent);
}
// 播放音效
if (Props.jumpSound != null)
{
Props.jumpSound.PlayOneShot(new TargetInfo(spawnCell, parent.Map));
}
// 显示效果
if (Props.jumpEffecter != null)
{
Effecter effecter = Props.jumpEffecter.Spawn();
effecter.Trigger(new TargetInfo(spawnCell, parent.Map), new TargetInfo(spawnCell, parent.Map));
effecter.Cleanup();
}
}
/// <summary>
/// 播放激活效果
/// </summary>
private void PlayActivationEffects()
{
if (Props.activationSound != null)
{
Props.activationSound.PlayOneShot(new TargetInfo(parent.Position, parent.Map));
}
if (Props.activationEffecter != null)
{
Effecter effecter = Props.activationEffecter.Spawn();
effecter.Trigger(new TargetInfo(parent.Position, parent.Map), new TargetInfo(parent.Position, parent.Map));
effecter.Cleanup();
}
}
/// <summary>
/// 播放跳出效果
/// </summary>
private void PlayJumpEffects()
{
if (Props.perJumpEffecter != null)
{
Effecter effecter = Props.perJumpEffecter.Spawn();
effecter.Trigger(new TargetInfo(parent.Position, parent.Map), new TargetInfo(parent.Position, parent.Map));
effecter.Cleanup();
}
}
/// <summary>
/// 开始停用虫洞
/// </summary>
private void StartDeactivation()
{
// 播放停用效果
if (Props.deactivationSound != null)
{
Props.deactivationSound.PlayOneShot(new TargetInfo(parent.Position, parent.Map));
}
if (Props.deactivationEffecter != null)
{
Effecter effecter = Props.deactivationEffecter.Spawn();
effecter.Trigger(new TargetInfo(parent.Position, parent.Map), new TargetInfo(parent.Position, parent.Map));
effecter.Cleanup();
}
}
/// <summary>
/// 销毁剩余未跳出的单位
/// </summary>
private void DestroyRemainingPawns()
{
if (emergingPawns.NullOrEmpty())
return;
for (int i = currentPawnIndex; i < emergingPawns.Count; i++)
{
Pawn pawn = emergingPawns[i];
if (pawn != null && !pawn.Destroyed)
{
pawn.Destroy();
}
}
}
#endregion
#region
public override void PostExposeData()
{
base.PostExposeData();
Scribe_Collections.Look(ref emergingPawns, "emergingPawns", LookMode.Reference);
Scribe_Values.Look(ref currentPawnIndex, "currentPawnIndex", 0);
Scribe_Values.Look(ref ticksUntilNextJump, "ticksUntilNextJump", 0);
Scribe_Values.Look(ref isActive, "isActive", false);
Scribe_Values.Look(ref activateTick, "activateTick", -1);
if (Scribe.mode == LoadSaveMode.PostLoadInit)
{
// 清理空引用
emergingPawns?.RemoveAll(p => p == null);
}
}
#endregion
}
}

View File

@@ -0,0 +1,40 @@
using Verse;
namespace ArachnaeSwarm
{
/// <summary>
/// 虫洞传送门生成器扩展
/// </summary>
public class WormholePortalSpawnerExtension : DefModExtension
{
/// <summary>
/// 最小跳出延迟ticks
/// </summary>
public int minEmergeDelayTicks = 180; // 3秒
/// <summary>
/// 最大跳出延迟ticks
/// </summary>
public int maxEmergeDelayTicks = 300; // 5秒
/// <summary>
/// 是否需要露天
/// </summary>
public bool requiresOpenSky = true;
/// <summary>
/// 最小空间半径
/// </summary>
public int minSpaceRadius = 3;
/// <summary>
/// 是否破坏地形
/// </summary>
public bool destroyTerrain = true;
/// <summary>
/// 是否破坏建筑
/// </summary>
public bool destroyBuildings = false;
}
}

View File

@@ -0,0 +1,54 @@
using RimWorld;
using System.Collections.Generic;
using Verse;
namespace ArachnaeSwarm
{
/// <summary>
/// 自定义虫洞传送门生成器
/// </summary>
public class BuildingGroundSpawner_WormholePortal : BuildingGroundSpawner
{
// 存储要传递的Pawn列表
public List<Pawn> emergingPawns = new List<Pawn>();
// 延迟参数
public IntRange? customEmergeDelay = null;
protected override void PostMakeInt()
{
base.PostMakeInt();
// 创建虫洞传送门
ThingDef portalDef = DefDatabase<ThingDef>.GetNamed("ARA_WormholePortal");
if (portalDef != null)
{
thingToSpawn = ThingMaker.MakeThing(portalDef);
// 设置Pawn列表
Comp_WormholePortal comp = thingToSpawn.TryGetComp<Comp_WormholePortal>();
if (comp != null && emergingPawns != null)
{
comp.SetEmergingPawns(emergingPawns);
}
}
}
protected override IntRange ResultSpawnDelay
{
get
{
if (customEmergeDelay.HasValue)
return customEmergeDelay.Value;
return base.ResultSpawnDelay;
}
}
public override void ExposeData()
{
base.ExposeData();
Scribe_Collections.Look(ref emergingPawns, "emergingPawns", LookMode.Reference);
Scribe_Values.Look(ref customEmergeDelay, "customEmergeDelay");
}
}
}

View File

@@ -0,0 +1,387 @@
using RimWorld;
using System.Collections.Generic;
using System.Linq;
using Verse;
namespace ArachnaeSwarm
{
/// <summary>
/// 虫洞传送门到达模式
/// 在地图边缘生成虫洞传送门生成器,预热后生成虫洞传送门,单位从虫洞中跳出
/// </summary>
public class PawnsArrivalModeWorker_WormholePortal : PawnsArrivalModeWorker
{
#region
private const float MIN_EDGE_DISTANCE = 5f; // 最小边缘距离
private const float MAX_EDGE_DISTANCE = 20f; // 最大边缘距离
private const int MIN_SPACE_RADIUS = 3; // 需要的最小空间半径
private const int MAX_SPAWNERS_PER_GROUP = 3; // 每组最大生成器数量
private const int DEFAULT_EMERGE_DELAY_TICKS = 60; // 默认跳出延迟1秒
#endregion
#region
/// <summary>
/// 单位到达
/// </summary>
public override void Arrive(List<Pawn> pawns, IncidentParms parms)
{
Map map = parms.target as Map;
if (map == null || pawns.NullOrEmpty())
return;
if (!TryResolveRaidSpawnCenter(parms))
return;
// 将Pawn分组每组由一个传送门生成器处理
List<List<Pawn>> pawnGroups = SplitPawnsIntoGroups(pawns, parms);
// 为每组生成一个虫洞传送门生成器
int spawnedCount = 0;
foreach (var group in pawnGroups)
{
if (TrySpawnWormholePortalGroup(group, parms))
{
spawnedCount++;
}
// 限制每组数量
if (spawnedCount >= MAX_SPAWNERS_PER_GROUP)
break;
}
}
/// <summary>
/// 旅行运输器到达
/// </summary>
public override void TravellingTransportersArrived(List<ActiveTransporterInfo> transporters, Map map)
{
// 虫洞传送门不支持运输器到达
Log.Warning("[虫洞传送门] 不支持运输器到达模式");
base.TravellingTransportersArrived(transporters, map);
}
/// <summary>
/// 尝试解析袭击生成中心
/// </summary>
public override bool TryResolveRaidSpawnCenter(IncidentParms parms)
{
Map map = parms.target as Map;
if (map == null)
return false;
// 如果没有指定生成中心,找到地图边缘的位置
if (!parms.spawnCenter.IsValid)
{
if (!TryFindEdgeSpawnCenter(map, out IntVec3 spawnCenter))
{
// 如果找不到边缘位置,使用默认的掉落中心
spawnCenter = DropCellFinder.FindRaidDropCenterDistant(map);
}
parms.spawnCenter = spawnCenter;
}
parms.spawnRotation = Rot4.Random;
return true;
}
/// <summary>
/// 判断是否可以在指定地图使用
/// </summary>
public override bool CanUseOnMap(Map map)
{
// 检查地图是否允许此到达模式
if (map == null)
return false;
// 检查是否有足够的空间生成虫洞
return HasEnoughSpaceForWormhole(map);
}
#endregion
#region
/// <summary>
/// 将Pawn分成组
/// </summary>
private List<List<Pawn>> SplitPawnsIntoGroups(List<Pawn> pawns, IncidentParms parms)
{
List<List<Pawn>> groups = new List<List<Pawn>>();
if (pawns.NullOrEmpty())
return groups;
// 根据点数计算每组大小
int groupSize = CalculateGroupSize(parms);
// 如果组大小为1或更小每个Pawn单独一组
if (groupSize <= 1)
{
foreach (var pawn in pawns)
{
groups.Add(new List<Pawn> { pawn });
}
return groups;
}
// 分组
List<Pawn> currentGroup = new List<Pawn>();
foreach (var pawn in pawns)
{
currentGroup.Add(pawn);
if (currentGroup.Count >= groupSize)
{
groups.Add(currentGroup);
currentGroup = new List<Pawn>();
}
}
// 添加剩余的Pawn
if (currentGroup.Count > 0)
{
groups.Add(currentGroup);
}
return groups;
}
/// <summary>
/// 计算每组大小
/// </summary>
private int CalculateGroupSize(IncidentParms parms)
{
// 根据点数动态调整组大小
float points = parms.points;
if (points <= 500f)
return 1;
else if (points <= 1000f)
return 2;
else if (points <= 2000f)
return 3;
else
return 4;
}
/// <summary>
/// 尝试生成虫洞传送门组
/// </summary>
private bool TrySpawnWormholePortalGroup(List<Pawn> pawns, IncidentParms parms)
{
Map map = parms.target as Map;
if (map == null || pawns.NullOrEmpty())
return false;
// 找到合适的生成位置(靠近边缘,有足够空间)
if (!TryFindWormholeSpawnPosition(map, out IntVec3 spawnPosition))
return false;
// 创建虫洞传送门生成器
return SpawnWormholePortalSpawner(map, spawnPosition, pawns, parms);
}
/// <summary>
/// 尝试找到虫洞生成位置
/// </summary>
private bool TryFindWormholeSpawnPosition(Map map, out IntVec3 spawnPosition)
{
spawnPosition = IntVec3.Invalid;
// 尝试在地图边缘区域查找
// 使用CellRect.WholeMap而不是CellsInMapRandomOrder
CellRect mapRect = CellRect.WholeMap(map);
// 定义边缘区域(地图边界向内一定距离)
int edgeWidth = 5;
CellRect edgeRect = new CellRect(
edgeWidth,
edgeWidth,
map.Size.x - edgeWidth * 2,
map.Size.z - edgeWidth * 2);
// 在地图边界但不是边缘区域内部查找
for (int attempts = 0; attempts < 30; attempts++)
{
IntVec3 candidate;
// 随机选择边界
if (Rand.Value < 0.25f) // 北边界
{
candidate = new IntVec3(Rand.Range(0, map.Size.x), 0, map.Size.z - 1);
}
else if (Rand.Value < 0.5f) // 南边界
{
candidate = new IntVec3(Rand.Range(0, map.Size.x), 0, 0);
}
else if (Rand.Value < 0.75f) // 东边界
{
candidate = new IntVec3(map.Size.x - 1, 0, Rand.Range(0, map.Size.z));
}
else // 西边界
{
candidate = new IntVec3(0, 0, Rand.Range(0, map.Size.z));
}
// 检查位置是否有效
if (IsValidWormholePosition(candidate, map))
{
spawnPosition = candidate;
return true;
}
}
// 如果找不到边界位置,尝试在地图任意位置查找
for (int attempts = 0; attempts < 20; attempts++)
{
IntVec3 candidate = CellFinder.RandomCell(map);
if (IsValidWormholePosition(candidate, map))
{
spawnPosition = candidate;
return true;
}
}
return false;
}
/// <summary>
/// 检查是否为有效的虫洞位置
/// </summary>
private bool IsValidWormholePosition(IntVec3 position, Map map)
{
if (!position.InBounds(map))
return false;
if (!position.Standable(map))
return false;
if (position.Fogged(map))
return false;
// 检查是否有足够的空间3x3区域
CellRect requiredRect = new CellRect(position.x - 1, position.z - 1, 3, 3);
// 修复:检查矩形是否完全包含在地图内
if (!requiredRect.InBounds(map))
return false;
// 检查区域内所有单元格是否都可行走
foreach (IntVec3 cell in requiredRect)
{
if (!cell.InBounds(map) || !cell.Walkable(map))
return false;
// 检查是否有其他建筑阻挡
if (cell.GetEdifice(map) != null)
return false;
// 检查是否有屋顶(虫洞需要露天)
if (cell.Roofed(map))
return false;
}
return true;
}
/// <summary>
/// 生成虫洞传送门生成器
/// </summary>
private bool SpawnWormholePortalSpawner(Map map, IntVec3 position, List<Pawn> pawns, IncidentParms parms)
{
try
{
ThingDef spawnerDef = DefDatabase<ThingDef>.GetNamedSilentFail("ARA_WormholePortal_Spawner");
if (spawnerDef == null)
{
Log.Error("[虫洞传送门] 未找到ARA_WormholePortal_Spawner定义");
return false;
}
// 创建自定义生成器
BuildingGroundSpawner_WormholePortal spawner = (BuildingGroundSpawner_WormholePortal)ThingMaker.MakeThing(spawnerDef);
// 设置参数
spawner.emergingPawns = pawns;
// 设置延迟
WormholePortalSpawnerExtension spawnerExt = spawnerDef.GetModExtension<WormholePortalSpawnerExtension>();
if (spawnerExt != null)
{
spawner.customEmergeDelay = new IntRange(
spawnerExt.minEmergeDelayTicks,
spawnerExt.maxEmergeDelayTicks);
}
// 生成到地图
GenSpawn.Spawn(spawner, position, map);
return true;
}
catch (System.Exception ex)
{
Log.Error($"[虫洞传送门] 生成虫洞传送门生成器失败: {ex.Message}\n{ex.StackTrace}");
return false;
}
}
/// <summary>
/// 尝试找到边缘生成中心
/// </summary>
private bool TryFindEdgeSpawnCenter(Map map, out IntVec3 spawnCenter)
{
spawnCenter = IntVec3.Invalid;
// 尝试在地图四个边缘区域查找
List<IntVec3> edgeCells = new List<IntVec3>();
// 北边缘
for (int x = 0; x < map.Size.x; x += 5)
{
IntVec3 cell = new IntVec3(x, 0, map.Size.z - 1);
if (cell.InBounds(map) && cell.Walkable(map) && !cell.Fogged(map))
edgeCells.Add(cell);
}
// 南边缘
for (int x = 0; x < map.Size.x; x += 5)
{
IntVec3 cell = new IntVec3(x, 0, 0);
if (cell.InBounds(map) && cell.Walkable(map) && !cell.Fogged(map))
edgeCells.Add(cell);
}
// 东边缘
for (int z = 0; z < map.Size.z; z += 5)
{
IntVec3 cell = new IntVec3(map.Size.x - 1, 0, z);
if (cell.InBounds(map) && cell.Walkable(map) && !cell.Fogged(map))
edgeCells.Add(cell);
}
// 西边缘
for (int z = 0; z < map.Size.z; z += 5)
{
IntVec3 cell = new IntVec3(0, 0, z);
if (cell.InBounds(map) && cell.Walkable(map) && !cell.Fogged(map))
edgeCells.Add(cell);
}
if (edgeCells.Count > 0)
{
spawnCenter = edgeCells.RandomElement();
return true;
}
return false;
}
/// <summary>
/// 检查地图是否有足够的空间生成虫洞
/// </summary>
private bool HasEnoughSpaceForWormhole(Map map)
{
// 简单检查:地图是否至少有一定大小
return map.Size.x >= 50 && map.Size.z >= 50;
}
#endregion
}
}