This commit is contained in:
2026-01-23 17:19:38 +08:00
parent 44f8cfb4f9
commit 78493879e2
20 changed files with 506 additions and 339 deletions

Binary file not shown.

View File

@@ -395,42 +395,6 @@
</AbilityDef>
<!-- 空天 -->
<AbilityDef>
<defName>ARA_BaseRace_Skyhive_Launcher</defName>
<label>天巢种喷射巢</label>
<description>将三只阿拉克涅天巢种辅虫发射到目标身上,天巢种将附着到敌人身上撕咬,脱落后仍然能继续对敌人展开攻击。</description>
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_BaseRace_Launcher</iconPath>
<cooldownTicksRange>5000</cooldownTicksRange>
<aiCanUse>true</aiCanUse>
<displayOrder>300</displayOrder>
<displayGizmoWhileUndrafted>false</displayGizmoWhileUndrafted>
<warmupStartSound>AcidSpray_Warmup</warmupStartSound>
<charges>3</charges>
<cooldownPerCharge>true</cooldownPerCharge>
<verbProperties>
<verbClass>Verb_CastAbility</verbClass>
<range>24</range>
<warmupTime>1</warmupTime>
<soundCast>AcidSpray_Resolve</soundCast>
<violent>false</violent>
<targetParams>
<canTargetPawns>True</canTargetPawns>
</targetParams>
</verbProperties>
<comps>
<li Class="ArachnaeSwarm.CompProperties_AbilityLaunchMultiProjectile">
<projectileDef>Bullet_ARA_RW_Basic_SkyHive_Gun</projectileDef>
<numProjectiles>3</numProjectiles>
</li>
<li Class="ArachnaeSwarm.CompProperties_AbilityNeedCost">
<customLabel>饮食</customLabel>
<showProgressBar>true</showProgressBar>
<needDef>Food</needDef>
<needCost>0.2</needCost>
<failMessage>营养值不足,需要进食</failMessage>
</li>
</comps>
</AbilityDef>
<AbilityDef>
<defName>ARA_Skyraider_jump</defName>
<label>高空机动</label>
@@ -1580,17 +1544,17 @@
</AbilityDef>
<AbilityDef>
<defName>ARA_Locust_Needle_Fire</defName>
<label>毒针</label>
<description>阿拉克涅督虫使用可以喷射剧毒尾针的毒针腺对敌方进行一轮射击。</description>
<label>毒针射</label>
<description>阿拉克涅蝗虫种使用可以喷射剧毒尾针的毒针腺对敌方进行一轮射击。</description>
<writeCombatLog>True</writeCombatLog>
<showPsycastEffects>False</showPsycastEffects>
<cooldownTicksRange>120</cooldownTicksRange>
<cooldownTicksRange>90</cooldownTicksRange>
<aiCanUse>true</aiCanUse>
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_Toxic_Needle_Fire</iconPath>
<verbProperties>
<verbClass>Verb_CastAbility</verbClass>
<range>24</range>
<warmupTime>1</warmupTime>
<warmupTime>0</warmupTime>
<soundCast>Heatspikes_Shot</soundCast>
<soundCastTail>Heatspikes_Tail</soundCastTail>
<targetParams>
@@ -1598,9 +1562,8 @@
</targetParams>
</verbProperties>
<comps>
<li Class="ArachnaeSwarm.CompProperties_AbilityLaunchMultiProjectile">
<li Class="CompProperties_AbilityLaunchProjectile">
<projectileDef>Bullet_ARA_RW_Basic_Fist_Needle_Gun</projectileDef>
<numProjectiles>1</numProjectiles>
</li>
</comps>
</AbilityDef>

View File

@@ -4,7 +4,7 @@
<defName>ARA_Possession</defName>
<label>阿拉克涅原虫</label>
<description>这个生物的身体被阿拉克涅原虫所夺取了,这具身体原本的主人已经没有可能再回来了。</description>
<hediffClass>ArachnaeSwarm.Hediff_Possession</hediffClass>
<hediffClass>ArachnaeSwarm.Hediff_Possession</hediffClass>
<defaultLabelColor>(0.6, 0.4, 0.8)</defaultLabelColor>
<isBad>false</isBad>
<scenarioCanAdd>false</scenarioCanAdd>

View File

@@ -340,7 +340,6 @@
</li>
</backstoryFiltersOverride>
<abilities>
<li>ARA_BaseRace_Skyhive_Launcher</li>
<li>ARA_Skyraider_jump</li>
</abilities>
<apparelTags>
@@ -629,7 +628,7 @@
</PawnKindDef>
<PawnKindDef ParentName="ARA_InsectKindBase">
<defName>ArachnaeBase_Race_Locust</defName>
<label>阿拉克涅爆裂</label>
<label>阿拉克涅蝗虫</label>
<race>ArachnaeBase_Race_Locust</race>
<lifeStages>
<li>

View File

@@ -21,7 +21,6 @@
<displayPriorityInCategory>8000</displayPriorityInCategory>
</StatDef>
<StatCategoryDef>
<defName>ARA_Incubation_StatCategory</defName>
<label>孵化相关数据</label>
@@ -70,4 +69,35 @@
<displayPriorityInCategory>2200</displayPriorityInCategory>
<showIfUndefined>false</showIfUndefined>
</StatDef>
<StatCategoryDef>
<defName>ARA_GestaltNetwork</defName>
<label>蜂巢网络</label>
<displayOrder>110</displayOrder>
</StatCategoryDef>
<StatDef>
<defName>ARA_GestaltBandwidth</defName>
<label>蜂巢网络容量</label>
<description>阿拉克涅虫群格式塔网络的最大节点限制,每一只阿拉克涅督虫都会影响网络的负荷,一些虫族会分担网络压力,另一些则会增加负载。当负载过大时,阿拉克涅女皇种的思维将遭到压迫,导致其心情和意识降低。</description>
<category>ARA_GestaltNetwork</category>
<defaultBaseValue>0</defaultBaseValue>
<toStringStyle>Integer</toStringStyle>
<hideAtValue>0</hideAtValue>
<minValue>0</minValue>
<displayPriorityInCategory>2200</displayPriorityInCategory>
<showIfUndefined>false</showIfUndefined>
</StatDef>
<StatDef>
<defName>ARA_GestaltBandwidthCost</defName>
<label>蜂巢网络负载</label>
<description>阿拉克涅督虫对格式塔网络产生的负荷,如果为负数,则代表此督虫会为格式塔网络分担压力。</description>
<category>ARA_GestaltNetwork</category>
<defaultBaseValue>0</defaultBaseValue>
<toStringStyle>Integer</toStringStyle>
<hideAtValue>0</hideAtValue>
<minValue>-999</minValue>
<displayPriorityInCategory>2201</displayPriorityInCategory>
<showIfUndefined>false</showIfUndefined>
</StatDef>
</Defs>

View File

@@ -222,7 +222,7 @@
<ThingDef ParentName="ArachnaeBase_Race">
<defName>ArachnaeBase_Race_Longpincer</defName>
<label>阿拉克涅坚颚种</label>
<description>阿拉克涅辅虫之一,拥有一对相较于其体型来说过于巨大的颚部,可以执行搬运、挖掘工作如果其监管者督虫处于征召状态,则会跟随督虫一起行动。</description>
<description>阿拉克涅辅虫之一,拥有一对相较于其体型来说过于巨大的颚部,可以执行搬运、挖掘工作如果其监管者督虫处于征召状态,则会跟随督虫一起行动。</description>
<statBases>
<MoveSpeed>5.5</MoveSpeed>
<ArmorRating_Blunt>0.45</ArmorRating_Blunt>
@@ -386,7 +386,7 @@
<ThingDef ParentName="ArachnaeBase_Race">
<defName>ArachnaeBase_Race_Acidcut</defName>
<label>阿拉克涅酸噬种</label>
<description>阿拉克涅辅虫之一,智力低下,依靠带酸液的颚撕咬敌军,因为身体结构简单而易于孕育如果其监管者督虫处于征召状态,则会跟随督虫一起行动。</description>
<description>阿拉克涅辅虫之一,智力低下,依靠带酸液的颚撕咬敌军,因为身体结构简单而易于孕育如果其监管者督虫处于征召状态,则会跟随督虫一起行动。</description>
<race>
<thinkTreeMain>ARA_Insect_Acidcut_Thinktree</thinkTreeMain>
<baseBodySize>0.3</baseBodySize>
@@ -458,7 +458,7 @@
<ThingDef ParentName="ArachnaeBase_Race">
<defName>ArachnaeBase_Race_Baneling</defName>
<label>阿拉克涅爆裂种</label>
<description>阿拉克涅辅虫之一,一般以自杀式袭击的方式伤害敌军,靠近敌人后就会引爆酸囊产生危险的酸性雾气,并留下菌毯以供后续虫族部队前进如果其监管者督虫处于征召状态,则会跟随督虫一起行动。</description>
<description>阿拉克涅辅虫之一,一般以自杀式袭击的方式伤害敌军,靠近敌人后就会引爆酸囊产生危险的酸性雾气,并留下菌毯以供后续虫族部队前进如果其监管者督虫处于征召状态,则会跟随督虫一起行动。</description>
<race>
<thinkTreeMain>ARA_Insect_Baneling_Thinktree</thinkTreeMain>
<baseBodySize>0.35</baseBodySize>
@@ -527,7 +527,7 @@
<ThingDef ParentName="ArachnaeBase_Race">
<defName>ArachnaeBase_Race_Empsuicider</defName>
<label>阿拉克涅电磁种</label>
<description>阿拉克涅辅虫之一智力低下一般以自杀式袭击的方式伤害敌军靠近敌人后就会释放EMP瘫痪附加的机械族如果其监管者督虫处于征召状态,则会跟随督虫一起行动。</description>
<description>阿拉克涅辅虫之一智力低下一般以自杀式袭击的方式伤害敌军靠近敌人后就会释放EMP瘫痪附加的机械族如果其监管者督虫处于征召状态,则会跟随督虫一起行动。</description>
<race>
<thinkTreeMain>ARA_Insect_Baneling_Thinktree</thinkTreeMain>
<baseBodySize>0.35</baseBodySize>
@@ -595,7 +595,7 @@
<ThingDef ParentName="ArachnaeBase_Race">
<defName>ArachnaeBase_Race_Skyhive</defName>
<label>阿拉克涅天巢种</label>
<description>阿拉克涅辅虫之一,拥有贴地飞行的能力,无论是攻击还是移动速度非常快。</description>
<description>阿拉克涅辅虫之一,拥有贴地飞行的能力,无论是攻击还是移动速度非常快。如果其监管者督虫处于征召状态,则会跟随督虫一起行动。</description>
<race>
<thinkTreeMain>ARA_Insect_Skyhive_Thinktree</thinkTreeMain>
<baseBodySize>0.3</baseBodySize>
@@ -678,8 +678,8 @@
</ThingDef>
<ThingDef ParentName="ArachnaeBase_Race">
<defName>ArachnaeBase_Race_Locust</defName>
<label>阿拉克涅天巢</label>
<description>阿拉克涅辅虫之一,拥有贴地飞行的能力,无论是攻击还是移动速度非常快</description>
<label>阿拉克涅蝗虫</label>
<description>阿拉克涅辅虫之一,是少数拥有高智能的辅虫单位,可以自行躲避危险,并使用毒针腺体向敌群射击。如果其监管者督虫处于征召状态,则会跟随督虫一起行动,但是会更倾向于保护其督虫而非主动上前迎敌</description>
<race>
<thinkTreeMain>ARA_Insect_Locust_Thinktree</thinkTreeMain>
<baseBodySize>0.36</baseBodySize>

View File

@@ -537,7 +537,7 @@
<ComfyTemperatureMin>-3000</ComfyTemperatureMin>
<ComfyTemperatureMax>3000</ComfyTemperatureMax>
<BandwidthCost>1</BandwidthCost>
<ARA_GestaltBandwidthCost>1</ARA_GestaltBandwidthCost>
</statBases>
<race>
@@ -1723,6 +1723,8 @@
<ArmorRating_Heat>0</ArmorRating_Heat>
<!-- <MaxNutrition>1</MaxNutrition> -->
<ARA_GestaltBandwidthCost>-3</ARA_GestaltBandwidthCost>
</statBases>
<race>

View File

@@ -614,7 +614,7 @@
<!-- 在野外采集的营养 -->
<ForagedNutritionPerDay>0</ForagedNutritionPerDay>
<MechBandwidth>8</MechBandwidth>
<ARA_GestaltBandwidth>15</ARA_GestaltBandwidth>
<MechControlGroups>1</MechControlGroups>
</statBases>

View File

@@ -352,7 +352,6 @@
<building>
<workTableRoomRole>Laboratory</workTableRoomRole>
<deconstructible>false</deconstructible>
<repairable>false</repairable>
</building>
<descriptionHyperlinks>
<ThingDef>ARA_Gene_Essence</ThingDef>

View File

@@ -3,40 +3,36 @@
"WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_corpsevat\\building_corpsevat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_corpsevat\\building_corpsevat.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_plant\\jobgiver_grower.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_plant\\jobgiver_grower.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_corpsevat\\jobdriver_haulcorpsetovat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_corpsevat\\jobdriver_haulcorpsetovat.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_clean\\jobgiver_cleaner.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_clean\\jobgiver_cleaner.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_dormancyvat\\building_dormancyvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_dormancyvat\\building_dormancyvat.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_huggingface\\hediff_possession.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_huggingface\\hediff_possession.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_corpsevat\\corpsevatextension.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_corpsevat\\corpsevatextension.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_huggingface\\compabilityeffect_possess.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_huggingface\\compabilityeffect_possess.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_followproducer\\thinknode_conditionalnotproducedbymechcarrier.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_followproducer\\thinknode_conditionalnotproducedbymechcarrier.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_buildingterrainspawn\\compdelayedterrainspawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_buildingterrainspawn\\compdelayedterrainspawn.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_flight\\pawn_flighttrackerpatches.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_flight\\pawn_flighttrackerpatches.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_hediffterrainspawn\\compproperties_hediffterrainspawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_hediffterrainspawn\\compproperties_hediffterrainspawn.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_flight\\compproperties_pawnflight.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_flight\\compproperties_pawnflight.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_hediffterrainspawn\\comphediffterrainspawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_hediffterrainspawn\\comphediffterrainspawn.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_productionqueue\\hediffcompproperties_productionqueue.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_productionqueue\\hediffcompproperties_productionqueue.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_productionqueue\\hediffcomp_productionqueue.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_productionqueue\\hediffcomp_productionqueue.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_ootheca\\building_ootheca.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_ootheca\\building_ootheca.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
"DocumentGroupContainers": [
@@ -46,125 +42,115 @@
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 2,
"SelectedChildIndex": 1,
"Children": [
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "CorpseVatExtension.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CorpseVat\\CorpseVatExtension.cs",
"RelativeDocumentMoniker": "Buildings\\Building_CorpseVat\\CorpseVatExtension.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CorpseVat\\CorpseVatExtension.cs",
"RelativeToolTip": "Buildings\\Building_CorpseVat\\CorpseVatExtension.cs",
"ViewState": "AgIAAAYAAAAAAAAAAAAAABkAAAAIAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-23T04:01:21.774Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "JobDriver_HaulCorpseToVat.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CorpseVat\\JobDriver_HaulCorpseToVat.cs",
"RelativeDocumentMoniker": "Buildings\\Building_CorpseVat\\JobDriver_HaulCorpseToVat.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CorpseVat\\JobDriver_HaulCorpseToVat.cs",
"RelativeToolTip": "Buildings\\Building_CorpseVat\\JobDriver_HaulCorpseToVat.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAA0AAAA0AAAAAAAAAA==",
"Title": "JobGiver_Cleaner.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_Clean\\JobGiver_Cleaner.cs",
"RelativeDocumentMoniker": "Jobs\\JobDriver_Clean\\JobGiver_Cleaner.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_Clean\\JobGiver_Cleaner.cs",
"RelativeToolTip": "Jobs\\JobDriver_Clean\\JobGiver_Cleaner.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABYAAABwAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-23T04:01:20.292Z",
"WhenOpened": "2026-01-23T08:51:58.899Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "Building_CorpseVat.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CorpseVat\\Building_CorpseVat.cs",
"RelativeDocumentMoniker": "Buildings\\Building_CorpseVat\\Building_CorpseVat.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CorpseVat\\Building_CorpseVat.cs",
"RelativeToolTip": "Buildings\\Building_CorpseVat\\Building_CorpseVat.cs",
"ViewState": "AgIAAEYBAAAAAAAAAAAawFgBAAAMAAAAAAAAAA==",
"Title": "JobGiver_Grower.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_Plant\\JobGiver_Grower.cs",
"RelativeDocumentMoniker": "Jobs\\JobDriver_Plant\\JobGiver_Grower.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_Plant\\JobGiver_Grower.cs",
"RelativeToolTip": "Jobs\\JobDriver_Plant\\JobGiver_Grower.cs",
"ViewState": "AgIAAFMAAAAAAAAAAAAQwGEAAAAvAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-23T04:01:18.535Z",
"WhenOpened": "2026-01-23T08:51:03.439Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "Building_DormancyVat.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_DormancyVat\\Building_DormancyVat.cs",
"RelativeDocumentMoniker": "Buildings\\Building_DormancyVat\\Building_DormancyVat.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_DormancyVat\\Building_DormancyVat.cs",
"RelativeToolTip": "Buildings\\Building_DormancyVat\\Building_DormancyVat.cs",
"ViewState": "AgIAACUAAAAAAAAAAIA8wDcAAAAAAAAAAAAAAA==",
"Title": "Hediff_Possession.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HuggingFace\\Hediff_Possession.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_HuggingFace\\Hediff_Possession.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HuggingFace\\Hediff_Possession.cs",
"RelativeToolTip": "Abilities\\ARA_HuggingFace\\Hediff_Possession.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABMAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-23T03:49:32.234Z",
"WhenOpened": "2026-01-23T08:50:05.221Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "CompAbilityEffect_Possess.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HuggingFace\\CompAbilityEffect_Possess.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_HuggingFace\\CompAbilityEffect_Possess.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HuggingFace\\CompAbilityEffect_Possess.cs",
"RelativeToolTip": "Abilities\\ARA_HuggingFace\\CompAbilityEffect_Possess.cs",
"ViewState": "AgIAAHcAAAAAAAAAAAAAAIkAAAA5AAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-23T08:50:01.549Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 4,
"Title": "CompDelayedTerrainSpawn.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_BuildingTerrainSpawn\\CompDelayedTerrainSpawn.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_BuildingTerrainSpawn\\CompDelayedTerrainSpawn.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_BuildingTerrainSpawn\\CompDelayedTerrainSpawn.cs",
"RelativeToolTip": "Building_Comps\\ARA_BuildingTerrainSpawn\\CompDelayedTerrainSpawn.cs",
"ViewState": "AgIAAFEAAAAAAAAAAAAAAF8AAAA+AAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-23T08:46:06.784Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "CompProperties_HediffTerrainSpawn.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HediffTerrainSpawn\\CompProperties_HediffTerrainSpawn.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_HediffTerrainSpawn\\CompProperties_HediffTerrainSpawn.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HediffTerrainSpawn\\CompProperties_HediffTerrainSpawn.cs",
"RelativeToolTip": "Hediffs\\ARA_HediffTerrainSpawn\\CompProperties_HediffTerrainSpawn.cs",
"ViewState": "AgIAAAUAAAAAAAAAAAAtwBkAAAAxAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-23T08:44:14.682Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 6,
"Title": "CompHediffTerrainSpawn.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HediffTerrainSpawn\\CompHediffTerrainSpawn.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_HediffTerrainSpawn\\CompHediffTerrainSpawn.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HediffTerrainSpawn\\CompHediffTerrainSpawn.cs",
"RelativeToolTip": "Hediffs\\ARA_HediffTerrainSpawn\\CompHediffTerrainSpawn.cs",
"ViewState": "AgIAAKIAAAAAAAAAAAAawLQAAAAMAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-23T08:44:10.075Z",
"EditorCaption": ""
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
},
{
"$type": "Document",
"DocumentIndex": 4,
"Title": "ThinkNode_ConditionalNotProducedByMechCarrier.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FollowProducer\\ThinkNode_ConditionalNotProducedByMechCarrier.cs",
"RelativeDocumentMoniker": "Jobs\\JobDriver_FollowProducer\\ThinkNode_ConditionalNotProducedByMechCarrier.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FollowProducer\\ThinkNode_ConditionalNotProducedByMechCarrier.cs",
"RelativeToolTip": "Jobs\\JobDriver_FollowProducer\\ThinkNode_ConditionalNotProducedByMechCarrier.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAoAAAA+AAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-23T02:44:35.619Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "Pawn_FlightTrackerPatches.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_Flight\\Pawn_FlightTrackerPatches.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_Flight\\Pawn_FlightTrackerPatches.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_Flight\\Pawn_FlightTrackerPatches.cs",
"RelativeToolTip": "Pawn_Comps\\ARA_Flight\\Pawn_FlightTrackerPatches.cs",
"ViewState": "AgIAAB0AAAAAAAAAAAAuwEsAAAAfAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-22T14:03:17.973Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 6,
"Title": "CompProperties_PawnFlight.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_Flight\\CompProperties_PawnFlight.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_Flight\\CompProperties_PawnFlight.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_Flight\\CompProperties_PawnFlight.cs",
"RelativeToolTip": "Pawn_Comps\\ARA_Flight\\CompProperties_PawnFlight.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAA4AAAAeAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-22T14:02:45.434Z"
},
{
"$type": "Document",
"DocumentIndex": 8,
"Title": "HediffComp_ProductionQueue.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_ProductionQueue\\HediffComp_ProductionQueue.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_ProductionQueue\\HediffComp_ProductionQueue.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_ProductionQueue\\HediffComp_ProductionQueue.cs",
"RelativeToolTip": "Hediffs\\ARA_ProductionQueue\\HediffComp_ProductionQueue.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAB8AAAAMAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-22T10:31:06.201Z"
},
{
"$type": "Document",
"DocumentIndex": 7,
"Title": "HediffCompProperties_ProductionQueue.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_ProductionQueue\\HediffCompProperties_ProductionQueue.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_ProductionQueue\\HediffCompProperties_ProductionQueue.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_ProductionQueue\\HediffCompProperties_ProductionQueue.cs",
"RelativeToolTip": "Hediffs\\ARA_ProductionQueue\\HediffCompProperties_ProductionQueue.cs",
"ViewState": "AgIAAB8AAAAAAAAAAAAewEoAAAApAAAAAAAAAA==",
"Title": "Building_Ootheca.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\Building_Ootheca.cs",
"RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\Building_Ootheca.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\Building_Ootheca.cs",
"RelativeToolTip": "Buildings\\Building_Ootheca\\Building_Ootheca.cs",
"ViewState": "AgIAALwAAAAAAAAAAAAowC4BAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-22T09:30:17.721Z"
"WhenOpened": "2026-01-23T08:31:14.555Z",
"EditorCaption": ""
}
]
}

View File

@@ -85,4 +85,16 @@ namespace ArachnaeSwarm
DefOfHelper.EnsureInitializedInCtor(typeof(ARA_ThoughtDefOf));
}
}
[DefOf]
public static class ARA_StatDefOf
{
public static StatDef ARA_GestaltBandwidth;
public static StatDef ARA_GestaltBandwidthCost;
static ARA_StatDefOf()
{
DefOfHelper.EnsureInitializedInCtor(typeof(ARA_StatDefOf));
}
}
}

View File

@@ -4,7 +4,7 @@ using Verse;
namespace ArachnaeSwarm
{
public class Hediff_Possession : HediffWithComps, IThingHolder
public class Hediff_Possession : Hediff_High, IThingHolder
{
public ThingOwner casterContainer;
public OriginalPawnData originalHostData;

View File

@@ -21,6 +21,9 @@ namespace ArachnaeSwarm
// 工作定义
private static readonly JobDef HaulCorpseToVatJobDef = DefDatabase<JobDef>.GetNamedSilentFail("ARA_HaulCorpseToVat");
private const int MaxDistanceForAutoAssignment = 30; // 自动分配工作的最大距离
// 反射缓存
private static System.Reflection.MethodInfo corpseDrawAtMethod;
#endregion
#region
@@ -28,7 +31,6 @@ namespace ArachnaeSwarm
private Corpse selectedCorpse;
private int startTick = -1;
private Graphic cachedTopGraphic;
private CompPowerTrader powerComp;
private CorpseVatExtension vatExtension;
// 绘制相关
@@ -41,7 +43,6 @@ namespace ArachnaeSwarm
public bool HasCorpse => selectedCorpse != null && innerContainer.Contains(selectedCorpse);
public virtual bool IsContentsSuspended => true;
public ThingOwner SearchableContents => innerContainer;
public CompPowerTrader PowerComp => powerComp ??= GetComp<CompPowerTrader>();
// 扩展属性
public CorpseVatExtension VatExtension => vatExtension ??= def.GetModExtension<CorpseVatExtension>();
@@ -65,6 +66,14 @@ namespace ArachnaeSwarm
return cachedTopGraphic;
}
}
// 静态构造函数
static Building_CorpseVat()
{
// 使用反射获取DrawAt方法
corpseDrawAtMethod = typeof(Corpse).GetMethod("DrawAt",
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
}
#endregion
#region
@@ -136,12 +145,6 @@ namespace ArachnaeSwarm
return "CorpseVat_Occupied".Translate();
}
// 检查是否有电源需求且是否供电
if (VatExtension != null && VatExtension.requiresPower && (PowerComp == null || !PowerComp.PowerOn))
{
return "CorpseVat_NoPower".Translate();
}
// 检查尸体是否有效
if (corpse == null || corpse.Destroyed)
{
@@ -239,10 +242,6 @@ namespace ArachnaeSwarm
{
VatExtension.ejectSound.PlayOneShot(new TargetInfo(Position, Map));
}
// 发送消息
Messages.Message("CorpseVat_CorpseEjected".Translate(droppedCorpse.InnerPawn?.LabelShortCap ?? "Unknown"),
MessageTypeDefOf.NeutralEvent);
}
}
}
@@ -505,7 +504,8 @@ namespace ArachnaeSwarm
if (Map == null)
yield break;
foreach (Thing thing in Map.listerThings.ThingsOfDef(ThingDefOf.Corpse))
// 使用 ThingRequestGroup.Corpse 获取所有尸体
foreach (Thing thing in Map.listerThings.ThingsInGroup(ThingRequestGroup.Corpse))
{
Corpse corpse = thing as Corpse;
if (corpse != null && CanAcceptCorpse(corpse).Accepted)
@@ -551,17 +551,6 @@ namespace ArachnaeSwarm
{
base.Tick();
// 检查电源
if (VatExtension != null && VatExtension.requiresPower && (PowerComp == null || !PowerComp.PowerOn))
{
if (HasCorpse)
{
Messages.Message("CorpseVat_PowerLost".Translate(), MessageTypeDefOf.CautionInput);
EjectContents();
}
return;
}
// 检查尸体状态
if (HasCorpse && (selectedCorpse.Destroyed || !innerContainer.Contains(selectedCorpse)))
{
@@ -617,10 +606,23 @@ namespace ArachnaeSwarm
// 调整高度
corpseDrawPos.y += Altitudes.AltIncVect.y * 3f;
// 绘制尸体
// 注意:由于尸体在容器中,其正常绘制方法可能不会自动调用
// 我们需要手动调用绘制方法
selectedCorpse.DrawAt(corpseDrawPos);
// 绘制尸体 - 使用反射调用受保护的DrawAt方法
if (corpseDrawAtMethod != null)
{
try
{
corpseDrawAtMethod.Invoke(selectedCorpse, new object[] { corpseDrawPos, false });
}
catch (Exception ex)
{
Log.Error($"Failed to draw corpse: {ex.Message}");
}
}
else
{
// 如果反射失败,使用替代方法绘制
DrawCorpseAlternative(corpseDrawPos);
}
// 如果需要特殊的绘制效果,可以在这里添加
if (VatExtension != null && VatExtension.drawPreservationEffect)
@@ -629,6 +631,26 @@ namespace ArachnaeSwarm
}
}
/// <summary>
/// 替代的绘制尸体方法
/// </summary>
private void DrawCorpseAlternative(Vector3 position)
{
if (selectedCorpse == null)
return;
// 尝试使用公开的方法绘制
try
{
// 使用DynamicDrawPhaseAt方法
selectedCorpse.DynamicDrawPhaseAt(DrawPhase.Draw, position);
}
catch (Exception ex)
{
Log.Error($"Failed to draw corpse (alternative): {ex.Message}");
}
}
/// <summary>
/// 绘制保存效果
/// </summary>
@@ -650,24 +672,6 @@ namespace ArachnaeSwarm
if (sb.Length > 0)
sb.AppendLine();
// 电源状态
if (VatExtension != null && VatExtension.requiresPower)
{
if (PowerComp == null)
{
sb.Append("CorpseVat_NoPowerComp".Translate());
}
else if (!PowerComp.PowerOn)
{
sb.Append("CorpseVat_PowerOff".Translate());
}
else
{
sb.Append("CorpseVat_PowerOn".Translate());
}
sb.AppendLine();
}
// 内容状态
if (HasCorpse)
{
@@ -677,15 +681,6 @@ namespace ArachnaeSwarm
sb.Append("CorpseVat_Contains".Translate(innerPawn.LabelCap));
sb.AppendLine();
// 显示保存时间
if (startTick > 0)
{
int ticksInVat = Find.TickManager.TicksGame - startTick;
string timeStr = ticksInVats.ToStringTicksToPeriod();
sb.Append("CorpseVat_PreservationTime".Translate(timeStr));
sb.AppendLine();
}
// 显示腐烂状态
CompRottable rottable = selectedCorpse.TryGetComp<CompRottable>();
if (rottable != null)
@@ -752,7 +747,6 @@ namespace ArachnaeSwarm
sb.AppendLine($"是否有尸体: {HasCorpse}");
sb.AppendLine($"是否工作中: {Working}");
sb.AppendLine($"开始Tick: {startTick}");
sb.AppendLine($"电源: {(PowerComp?.PowerOn == true ? "" : "")}");
if (HasCorpse)
{
@@ -764,36 +758,12 @@ namespace ArachnaeSwarm
sb.AppendLine($"扩展配置: {(VatExtension != null ? "" : "")}");
if (VatExtension != null)
{
sb.AppendLine($"需要电源: {VatExtension.requiresPower}");
sb.AppendLine($"减缓腐烂: {VatExtension.slowDecayRate}");
sb.AppendLine($"顶部贴图: {VatExtension.topGraphicPath}");
}
return sb.ToString();
}
/// <summary>
/// 获取所有可用尸体的统计信息
/// </summary>
public string GetAvailableCorpsesInfo()
{
StringBuilder sb = new StringBuilder();
var corpses = GetAvailableCorpses().ToList();
sb.AppendLine("=== 可用尸体列表 ===");
sb.AppendLine($"总计: {corpses.Count}");
sb.AppendLine();
foreach (Corpse corpse in corpses)
{
sb.AppendLine(GetCorpseLabel(corpses));
sb.AppendLine($" 位置: {corpse.Position}");
sb.AppendLine($" 距离: {corpse.Position.DistanceTo(Position):F0}m");
sb.AppendLine();
}
return sb.ToString();
}
#endregion
}
}

View File

@@ -21,7 +21,6 @@ namespace ArachnaeSwarm
public bool drawPreservationEffect = true; // 是否绘制保存效果
// ===== 功能配置 =====
public bool requiresPower = true; // 是否需要电源
public float slowDecayRate = 0.1f; // 腐烂减缓率0-10=完全停止腐烂1=正常腐烂)
// ===== 音效配置 =====
@@ -32,7 +31,6 @@ namespace ArachnaeSwarm
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.AppendLine("=== CorpseVat 配置摘要 ===");
sb.AppendLine($"需要电源: {requiresPower}");
sb.AppendLine($"减缓腐烂: {(slowDecayRate * 100):F0}%");
sb.AppendLine($"顶部贴图: {topGraphicPath ?? ""}");
sb.AppendLine($"绘制偏移: {corpseDrawOffset}");

View File

@@ -1,4 +1,6 @@
using RimWorld;
using System.Collections.Generic;
using UnityEngine;
using Verse;
using Verse.AI;
@@ -7,66 +9,230 @@ namespace ArachnaeSwarm
/// <summary>
/// 自定义的搬运尸体工作驱动
/// </summary>
public class JobDriver_HaulCorpseToVat : JobDriver_HaulToContainer
public class JobDriver_HaulCorpseToVat : JobDriver_HaulToContainer, IBuildableDriver
{
protected override Toil CarryToContainerToil()
// 自定义工作效果器
private Effecter workEffecter;
// 工作间隔tick
private const int WorkEffectInterval = 80;
/// <summary>
/// 获取要搬运的尸体
/// </summary>
private Corpse CorpseToCarry => job.targetA.Thing as Corpse;
/// <summary>
/// 获取尸体保存罐
/// </summary>
private Building_CorpseVat CorpseVat => job.targetB.Thing as Building_CorpseVat;
/// <summary>
/// 构建工作流程
/// </summary>
protected override IEnumerable<Toil> MakeNewToils()
{
Toil toil = base.CarryToContainerToil();
// 添加失败条件
this.FailOn(() => CorpseToCarry == null || CorpseToCarry.Destroyed);
this.FailOn(() => CorpseVat == null || CorpseVat.Destroyed);
// 添加自定义行为
toil.AddPreTickAction(() =>
// 添加自定义失败条件:检查尸体是否仍然可以被接受
this.FailOn(() =>
{
Corpse corpse = TargetThingA as Corpse;
Building_CorpseVat vat = TargetThingB as Building_CorpseVat;
if (corpse != null && vat != null && pawn != null)
{
// 检查距离,如果太远可以取消工作
float distance = corpse.Position.DistanceTo(vat.Position);
if (distance > 100f) // 最大距离限制
{
pawn.jobs.EndCurrentJob(JobCondition.Incompletable);
}
}
if (CorpseToCarry == null || CorpseVat == null)
return true;
AcceptanceReport report = CorpseVat.CanAcceptCorpse(CorpseToCarry);
return !report.Accepted;
});
return toil;
}
protected override Toil FindCarryToCellToil()
{
Toil toil = base.FindCarryToCellToil();
// 添加额外条件检查
toil.AddFailCondition(() =>
// 添加自定义失败条件:检查距离是否过远
this.FailOn(() =>
{
Corpse corpse = TargetThingA as Corpse;
Building_CorpseVat vat = TargetThingB as Building_CorpseVat;
if (corpse == null || corpse.Destroyed || vat == null || vat.Destroyed)
{
if (CorpseToCarry == null || CorpseVat == null)
return true;
float distance = CorpseToCarry.Position.DistanceTo(CorpseVat.Position);
return distance > 100f; // 最大距离100格
});
// 调用基类的工作流程
foreach (Toil toil in base.MakeNewToils())
{
// 我们可以对每个toil进行自定义修改
if (toil.defaultCompleteMode == ToilCompleteMode.Delay)
{
// 这是等待/工作toil添加自定义效果
toil.AddPreTickAction(() =>
{
UpdateWorkEffecter(toil);
});
toil.AddFinishAction(() =>
{
CleanupWorkEffecter();
});
}
// 检查尸体是否仍然可以被接受
yield return toil;
}
}
/// <summary>
/// 更新工作效果器
/// </summary>
private void UpdateWorkEffecter(Toil toil)
{
if (CorpseVat == null || !pawn.IsHashIntervalTick(WorkEffectInterval))
return;
// 创建或更新效果器
if (workEffecter == null && WorkEffecter != null)
{
workEffecter = WorkEffecter.Spawn();
workEffecter.Trigger(CorpseVat, CorpseVat);
}
workEffecter?.EffectTick(CorpseVat, CorpseVat);
}
/// <summary>
/// 清理工作效果器
/// </summary>
private void CleanupWorkEffecter()
{
workEffecter?.Cleanup();
workEffecter = null;
}
/// <summary>
/// 重写报告字符串
/// </summary>
public override string GetReport()
{
if (CorpseToCarry == null || CorpseVat == null)
return "ReportHaulingUnknown".Translate();
Pawn innerPawn = CorpseToCarry.InnerPawn;
string pawnName = innerPawn?.LabelCap ?? "Unknown";
return "CorpseVat_ReportHauling".Translate(pawnName, CorpseVat.LabelShort);
}
/// <summary>
/// 重写预留方法
/// </summary>
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
// 调用基类预留
bool result = base.TryMakePreToilReservations(errorOnFailed);
if (result && Prefs.DevMode)
{
Log.Message($"JobDriver_HaulCorpseToVat: 成功预留 {CorpseToCarry?.LabelCap ?? "null"} 到 {CorpseVat?.LabelCap ?? "null"}");
}
return result;
}
/// <summary>
/// 添加自定义准备步骤
/// </summary>
protected override void ModifyPrepareToil(Toil toil)
{
base.ModifyPrepareToil(toil);
// 添加自定义准备步骤
toil.AddPreInitAction(() =>
{
if (CorpseToCarry != null && CorpseVat != null)
{
// 记录开始时间
Log.Message($"开始搬运尸体 {CorpseToCarry.InnerPawn?.LabelCap ?? "Unknown"} 到 {CorpseVat.LabelCap}");
}
});
}
/// <summary>
/// 获取调试信息
/// </summary>
public string GetDebugInfo()
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.AppendLine("=== JobDriver_HaulCorpseToVat 调试信息 ===");
sb.AppendLine($"Pawn: {pawn?.LabelCap ?? "null"}");
sb.AppendLine($"Corpse: {CorpseToCarry?.InnerPawn?.LabelCap ?? "null"}");
sb.AppendLine($"Vat: {CorpseVat?.LabelCap ?? "null"}");
sb.AppendLine($"工作状态: {(CorpseToCarry != null && CorpseVat != null ? "" : "")}");
if (CorpseToCarry != null && CorpseVat != null)
{
float distance = CorpseToCarry.Position.DistanceTo(CorpseVat.Position);
sb.AppendLine($"距离: {distance:F1} 格");
AcceptanceReport report = CorpseVat.CanAcceptCorpse(CorpseToCarry);
sb.AppendLine($"尸体是否可接受: {report.Accepted}");
if (!report.Accepted)
sb.AppendLine($"原因: {report.Reason}");
}
return sb.ToString();
}
}
/// <summary>
/// 简化的搬运尸体工作驱动(如果需要更简单的版本)
/// </summary>
public class JobDriver_HaulCorpseToVatSimple : JobDriver_HaulToContainer
{
protected override IEnumerable<Toil> MakeNewToils()
{
// 基本工作流程
this.FailOnDestroyedOrNull(TargetIndex.A);
this.FailOnDestroyedOrNull(TargetIndex.B);
this.FailOnForbidden(TargetIndex.B);
// 获取尸体和建筑
Corpse corpse = TargetThingA as Corpse;
Building_CorpseVat vat = TargetThingB as Building_CorpseVat;
// 添加自定义失败条件
this.FailOn(() =>
{
if (corpse == null || vat == null)
return true;
// 检查是否仍然可以接受
AcceptanceReport report = vat.CanAcceptCorpse(corpse);
return !report.Accepted;
});
return toil;
// 检查距离
this.FailOn(() =>
{
if (corpse == null || vat == null)
return true;
float distance = corpse.Position.DistanceTo(vat.Position);
return distance > 100f;
});
// 调用基类工作流程
foreach (Toil toil in base.MakeNewToils())
{
yield return toil;
}
}
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
// 尸体和建筑预留
if (!pawn.Reserve(TargetA, job, 1, -1, null, errorOnFailed))
{
// 简单预留:只预留尸体和建筑
if (!pawn.Reserve(job.targetA, job, 1, -1, null, errorOnFailed))
return false;
}
if (!pawn.Reserve(TargetB, job, 1, -1, null, errorOnFailed))
{
if (!pawn.Reserve(job.targetB, job, 1, -1, null, errorOnFailed))
return false;
}
return true;
}
}

View File

@@ -1,6 +1,7 @@
// File: Building_Ootheca.cs
using RimWorld;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using Verse;
@@ -199,24 +200,107 @@ namespace ArachnaeSwarm
builder.AppendLine(config.pawnKind.LabelCap);
return builder.ToString().TrimEndNewlines();
}
// === 幼虫交互 ===
public void CallLarva()
{
// 检查是否已经有幼虫在操作或正在孵化
if (isIncubating || assignedLarva != null) return;
// 获取当前选中的所有同类建筑
var selectedOothecas = GetSelectedOothecas();
// 如果选择了多个,检查是否有其他卵已经启动召唤
if (selectedOothecas.Count > 1)
{
// 检查是否有其他卵已经分配了幼虫
foreach (var ootheca in selectedOothecas)
{
if (ootheca != this && ootheca.assignedLarva != null)
{
// 已经有其他卵开始召唤幼虫了,跳过
return;
}
}
// 检查是否有其他卵已经处于孵化状态
foreach (var ootheca in selectedOothecas)
{
if (ootheca != this && ootheca.isIncubating)
{
// 已经有其他卵在孵化了,跳过
return;
}
}
// 如果是同时按下gizmo我们希望只有一个卵响应
// 我们可以使用一个简单的规则:只让最近选择的一个卵响应
// 这里我们选择第一个(可能是玩家最后点击的,取决于选择顺序)
// 或者我们可以使用位置排序
if (!IsFirstValidOotheca(selectedOothecas))
{
return;
}
}
var larva = FindLarva();
if (larva == null)
{
Messages.Message("ARA_OothecaIncubator.NoLarvaeFound".Translate(), MessageTypeDefOf.RejectInput);
return;
}
var job = JobMaker.MakeJob(ARA_JobDefOf.ARA_OperateIncubator, this);
larva.jobs.TryTakeOrderedJob(job, JobTag.MiscWork);
assignedLarva = larva;
Messages.Message("ARA_OothecaIncubator.LarvaCalled".Translate(), MessageTypeDefOf.PositiveEvent);
}
/// <summary>
/// 获取当前选中的所有Building_Ootheca
/// </summary>
private List<Building_Ootheca> GetSelectedOothecas()
{
List<Building_Ootheca> result = new List<Building_Ootheca>();
if (Find.Selector == null)
return result;
// 获取所有选中的建筑
var selected = Find.Selector.SelectedObjects;
foreach (var obj in selected)
{
if (obj is Building_Ootheca ootheca && ootheca.Map == this.Map)
{
result.Add(ootheca);
}
}
return result;
}
/// <summary>
/// 判断当前建筑是否是第一个有效的卵(用于多选时只让一个响应)
/// </summary>
private bool IsFirstValidOotheca(List<Building_Ootheca> oothecas)
{
// 过滤掉无效的(正在孵化或已有幼虫的)
var validOothecas = oothecas.Where(o =>
!o.isIncubating &&
o.assignedLarva == null
).ToList();
if (validOothecas.Count == 0)
return false;
// 排序规则:我们可以使用多种规则
// 1. 按距离玩家视角中心排序(最近的优先)
// 2. 按位置排序XZ坐标
// 3. 按建筑ID排序稳定的顺序
// 这里我们使用简单的排序按建筑位置X坐标为主Z坐标为辅
var sorted = validOothecas.OrderBy(o => o.Position.x).ThenBy(o => o.Position.z).ToList();
// 返回是否是第一个
return sorted.First() == this;
}
private Pawn FindLarva()
{
float searchRadius = 30f;

View File

@@ -29,10 +29,10 @@ namespace ArachnaeSwarm
public List<Pawn> ControlledPawns => controlledPawns;
// 计算已使用的带宽(包括超载部分)
public int UsedBandwidth => (int)ControlledPawns.Sum(p => p.GetStatValue(StatDefOf.BandwidthCost));
public int UsedBandwidth => (int)ControlledPawns.Sum(p => p.GetStatValue(ARA_StatDefOf.ARA_GestaltBandwidthCost));
// 计算基础带宽限制
public int TotalBandwidth => (int)pawn.GetStatValue(StatDefOf.MechBandwidth);
public int TotalBandwidth => (int)pawn.GetStatValue(ARA_StatDefOf.ARA_GestaltBandwidth);
// 计算总可用控制组
public int TotalAvailableControlGroups => (int)pawn.GetStatValue(StatDefOf.MechControlGroups);

View File

@@ -111,14 +111,6 @@ namespace ArachnaeSwarm
{
continue; // 跳过有排除tag的地面
}
// === 新增检查是否只影响自己的Creep ===
if (Props.affectOwnCreepOnly && currentTerrain.tags != null &&
currentTerrain.tags.Contains("ARA_Creep"))
{
// 这里可以添加派系检查逻辑
// 例如只覆盖自己派系的Creep
}
// 应用地形变化
map.terrainGrid.SetTerrain(current, Props.terrainToSpawn);
affectedCells.Add(current);
@@ -187,33 +179,6 @@ namespace ArachnaeSwarm
return true;
}
// 2. 检查允许性(如果启用)
if (Props.checkAffordances && terrain.affordances != null && Props.excludeAffordances != null)
{
foreach (var affordance in terrain.affordances)
{
if (affordance != null && Props.excludeAffordances.Contains(affordance.defName))
{
return true;
}
}
}
// 3. 检查优先地形(如果启用智能覆盖)
if (Props.smartOverlay && Props.IsPreferredTerrain(terrain))
{
return true;
}
// 4. 检查路径(如果启用路径保护)
if (Props.preservePaths)
{
if (IsPathCell(cell, map))
{
return true;
}
}
// 5. 检查是否是水或其他特殊地形
if (terrain.IsWater || terrain.defName.Contains("Water") || terrain.defName.Contains("Marsh"))
{

View File

@@ -22,19 +22,12 @@ namespace ArachnaeSwarm
public List<string> excludedTerrainTags = null; // 要排除的tag列表
public bool useDefaultExclusions = true; // 是否使用默认排除项ARA_Creep和ARA_Incubator_Nutrient_Solution
// === 新增:扩展检查选项 ===
public bool checkAffordances = false; // 是否检查地形允许性affordances
public List<string> excludeAffordances = null; // 要排除的允许性列表
// === 新增:智能覆盖选项 ===
public bool smartOverlay = false; // 是否智能覆盖(仅覆盖"较差"的地形)
public List<TerrainDef> preferredTerrains = null; // 优先地形列表,这些不会被覆盖
public bool preservePaths = false; // 是否保留路径
// === 新增:行为选项 ===
public bool onlyWhenOnCreep = false; // 是否只在Creep上生效
public bool ignoreOccupiedCells = true; // 是否忽略被占用的单元格
public bool affectOwnCreepOnly = false; // 是否只影响自己的Creep如果有派系
public bool ignoreOccupiedCells = false; // 是否忽略被占用的单元格
// === 新增:视觉效果选项 ===
public EffecterDef spawnEffecter = null; // 生成地形时的效果