This commit is contained in:
2025-09-30 17:32:20 +08:00
parent 80cbaff5fa
commit bda7419168
13 changed files with 520 additions and 167 deletions

Binary file not shown.

View File

@@ -293,7 +293,7 @@
<li>ARA_NeuroSwarm_jump</li>
<li>ARA_GuardianPsyField_On</li>
<li>ARA_GuardianPsyField_Off</li>
<!-- <li>ARA_Ability_Morph</li> -->
<li>ARA_Ability_Morph</li>
</abilities>
<apparelTags>
</apparelTags>

View File

@@ -25,32 +25,36 @@
<StatCategoryDef>
<defName>ARA_Incubation_StatCategory</defName>
<label>孵化相关数据</label>
<displayOrder>999</displayOrder>
<displayOrder>100</displayOrder>
</StatCategoryDef>
<StatDef>
<defName>ARA_IncubationCost</defName>
<!-- <workerClass>StatWorker_MeleeAverageDPS</workerClass> -->
<label>孵化所需营养</label>
<description>孵化该武装器官/织物所需的总营养</description>
<category>ARA_Incubation_StatCategory</category>
<defaultBaseValue>1</defaultBaseValue>
<minValue>0</minValue>
<toStringStyle>Integer</toStringStyle>
<forInformationOnly>true</forInformationOnly>
<toStringStyle>FloatOne</toStringStyle>
<formatString>{0} 份</formatString>
<!-- <minifiedThingInherits>true</minifiedThingInherits> -->
<displayPriorityInCategory>5010</displayPriorityInCategory>
<showIfUndefined>false</showIfUndefined>
<!-- <showOnUnhaulables>false</showOnUnhaulables>
<showIfUndefined>false</showIfUndefined> -->
<cacheable>true</cacheable>
</StatDef>
<StatDef>
<defName>ARA_IncubationTime</defName>
<!-- <workerClass>StatWorker_MeleeAverageDPS</workerClass> -->
<label>孵化所需时间</label>
<description>孵化该武装器官/织物所需的时间</description>
<category>ARA_Incubation_StatCategory</category>
<defaultBaseValue>1</defaultBaseValue>
<minValue>0</minValue>
<toStringStyle>Integer</toStringStyle>
<forInformationOnly>true</forInformationOnly>
<displayPriorityInCategory>5010</displayPriorityInCategory>
<showIfUndefined>false</showIfUndefined>
<toStringStyle>FloatOne</toStringStyle>
<formatString>{0} 天</formatString>
<!-- <minifiedThingInherits>true</minifiedThingInherits> -->
<displayPriorityInCategory>5011</displayPriorityInCategory>
<!-- <showOnUnhaulables>false</showOnUnhaulables> -->
<!-- <showIfUndefined>false</showIfUndefined> -->
<cacheable>true</cacheable>
</StatDef>
</Defs>

View File

@@ -18,7 +18,7 @@
<li>ARA_Inner</li>
</tags>
<bodyPartGroups>
<li>Torso</li>
<li>Torso</li>
</bodyPartGroups>
<layers>
<li>OnSkin</li>
@@ -35,9 +35,9 @@
</ThingDef>
<ThingDef ParentName="ARA_ApparelOnSkinBase">
<defName>ARA_Bodystocking_White</defName>
<label>连身白丝</label>
<description>阿拉克涅虫群的装饰性织物,对于虫群来说应该是没啥用的东西。</description>
<defName>ARA_Bodystocking_White</defName>
<label>连身白丝</label>
<description>阿拉克涅虫群的装饰性织物,对于虫群来说应该是没啥用的东西。</description>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Cloth</ThingDef>
</descriptionHyperlinks>
@@ -54,12 +54,19 @@
</apparel>
<statBases>
<WorkToMake>3000</WorkToMake>
<ARA_IncubationCost>1</ARA_IncubationCost>
<ARA_IncubationTime>1</ARA_IncubationTime>
</statBases>
<comps>
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
<cocoonDef>ARA_Cocoon_Cloth</cocoonDef>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="ARA_ApparelOnSkinBase">
<defName>ARA_Bodystocking_Black</defName>
<label>连身黑丝</label>
<description>阿拉克涅虫群的装饰性织物,对于虫群来说应该是没啥用的东西。</description>
<defName>ARA_Bodystocking_Black</defName>
<label>连身黑丝</label>
<description>阿拉克涅虫群的装饰性织物,对于虫群来说应该是没啥用的东西。</description>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Cloth</ThingDef>
</descriptionHyperlinks>
@@ -76,12 +83,19 @@
</apparel>
<statBases>
<WorkToMake>3000</WorkToMake>
<ARA_IncubationCost>1</ARA_IncubationCost>
<ARA_IncubationTime>1</ARA_IncubationTime>
</statBases>
<comps>
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
<cocoonDef>ARA_Cocoon_Cloth</cocoonDef>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="ARA_ApparelOnSkinBase">
<defName>ARA_Latex_Catsuit</defName>
<label>紧身衣</label>
<description>阿拉克涅虫群的装饰性织物,对于虫群来说应该是没啥用的东西。</description>
<defName>ARA_Latex_Catsuit</defName>
<label>紧身衣</label>
<description>阿拉克涅虫群的装饰性织物,对于虫群来说应该是没啥用的东西。</description>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Cloth</ThingDef>
</descriptionHyperlinks>
@@ -98,12 +112,19 @@
</apparel>
<statBases>
<WorkToMake>3000</WorkToMake>
<ARA_IncubationCost>1</ARA_IncubationCost>
<ARA_IncubationTime>1</ARA_IncubationTime>
</statBases>
<comps>
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
<cocoonDef>ARA_Cocoon_Cloth</cocoonDef>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="ARA_ApparelOnSkinBase">
<defName>ARA_Pantyhose_Black</defName>
<label>黑丝裤袜</label>
<description>阿拉克涅虫群的装饰性织物,对于虫群来说应该是没啥用的东西。</description>
<defName>ARA_Pantyhose_Black</defName>
<label>黑丝裤袜</label>
<description>阿拉克涅虫群的装饰性织物,对于虫群来说应该是没啥用的东西。</description>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Cloth</ThingDef>
</descriptionHyperlinks>
@@ -120,12 +141,19 @@
</apparel>
<statBases>
<WorkToMake>3000</WorkToMake>
<ARA_IncubationCost>1</ARA_IncubationCost>
<ARA_IncubationTime>1</ARA_IncubationTime>
</statBases>
<comps>
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
<cocoonDef>ARA_Cocoon_Cloth</cocoonDef>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="ARA_ApparelOnSkinBase">
<defName>ARA_Pantyhose_White</defName>
<label>白丝裤袜</label>
<description>阿拉克涅虫群的装饰性织物,对于虫群来说应该是没啥用的东西。</description>
<defName>ARA_Pantyhose_White</defName>
<label>白丝裤袜</label>
<description>阿拉克涅虫群的装饰性织物,对于虫群来说应该是没啥用的东西。</description>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Cloth</ThingDef>
</descriptionHyperlinks>
@@ -142,7 +170,14 @@
</apparel>
<statBases>
<WorkToMake>3000</WorkToMake>
<ARA_IncubationCost>1</ARA_IncubationCost>
<ARA_IncubationTime>1</ARA_IncubationTime>
</statBases>
<comps>
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
<cocoonDef>ARA_Cocoon_Cloth</cocoonDef>
</li>
</comps>
</ThingDef>
<ThingDef Name="ARA_ClothBase" ParentName="ApparelMakeableBase" Abstract="True">
@@ -223,9 +258,9 @@
</statBases>
</ThingDef>
<ThingDef ParentName="ARA_ClothBase">
<defName>ARA_Maid_Uniform</defName>
<label>阿拉克涅女仆装</label>
<description>阿拉克涅督虫们所着织物中的一种,设计上修身轻便,可以使其在阿拉克捏菌毯上获得额外的工作速度,是她们永远服侍虫巢的形象的完美具现化。</description>
<defName>ARA_Maid_Uniform</defName>
<label>阿拉克涅女仆装</label>
<description>阿拉克涅督虫们所着织物中的一种,设计上修身轻便,可以使其在阿拉克捏菌毯上获得额外的工作速度,是她们永远服侍虫巢的形象的完美具现化。</description>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Cloth</ThingDef>
</descriptionHyperlinks>
@@ -242,10 +277,10 @@
</graphicData>
<apparel>
<bodyPartGroups>
<li>Torso</li>
<li>Shoulders</li>
<li>Arms</li>
<li>Legs</li>
<li>Torso</li>
<li>Shoulders</li>
<li>Arms</li>
<li>Legs</li>
</bodyPartGroups>
<layers>
<!-- <li>OnSkin</li> -->
@@ -255,17 +290,24 @@
</apparel>
<equippedStatOffsets>
</equippedStatOffsets>
<statBases>
<ARA_IncubationCost>10</ARA_IncubationCost>
<ARA_IncubationTime>2</ARA_IncubationTime>
</statBases>
<costStuffCount>0</costStuffCount>
<comps>
<li Class="CompProperties_CauseHediff_Apparel">
<hediff>ARA_TerrainWorkSpeedHediff</hediff>
</li>
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
<cocoonDef>ARA_Cocoon_Cloth</cocoonDef>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="ARA_ClothBase">
<defName>ARA_Bunny_Girl_Uniform</defName>
<label>阿拉克涅兔女郎装</label>
<description>阿拉克涅督虫们所着织物中的一种,紧紧贴合督虫们的身体曲线,可以使其在阿拉克捏菌毯上获得额外的移动速度。</description>
<defName>ARA_Bunny_Girl_Uniform</defName>
<label>阿拉克涅兔女郎装</label>
<description>阿拉克涅督虫们所着织物中的一种,紧紧贴合督虫们的身体曲线,可以使其在阿拉克捏菌毯上获得额外的移动速度。</description>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Cloth_1Stage</ThingDef>
</descriptionHyperlinks>
@@ -282,10 +324,10 @@
</graphicData>
<apparel>
<bodyPartGroups>
<li>Torso</li>
<li>Shoulders</li>
<li>Arms</li>
<li>Legs</li>
<li>Torso</li>
<li>Shoulders</li>
<li>Arms</li>
<li>Legs</li>
</bodyPartGroups>
<layers>
<!-- <li>OnSkin</li> -->
@@ -293,6 +335,10 @@
</layers>
<wornGraphicPath>ArachnaeSwarm/Apparel/ARA_Bunny_Girl_Uniform</wornGraphicPath>
</apparel>
<statBases>
<ARA_IncubationCost>120</ARA_IncubationCost>
<ARA_IncubationTime>2.5</ARA_IncubationTime>
</statBases>
<equippedStatOffsets>
</equippedStatOffsets>
<costStuffCount>0</costStuffCount>
@@ -300,14 +346,17 @@
<li Class="CompProperties_CauseHediff_Apparel">
<hediff>ARA_TerrainMoveSpeedHediff</hediff>
</li>
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
<cocoonDef>ARA_Cocoon_Cloth_1Stage</cocoonDef>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="ARA_ClothBase">
<defName>ARA_Nurse_Uniform</defName>
<label>阿拉克涅护士装</label>
<description>阿拉克涅督虫们所着织物中的一种,似乎是从人类的社会中得到了红十字元素的设计构思——只是虫群自己并不清楚为什么要使用这个标志。织物内部蕴含多根愈合素导管,可以让阿拉克涅虫族从菌毯中抽取营养以治疗其他个体。</description>
<defName>ARA_Nurse_Uniform</defName>
<label>阿拉克涅护士装</label>
<description>阿拉克涅督虫们所着织物中的一种,似乎是从人类的社会中得到了红十字元素的设计构思——只是虫群自己并不清楚为什么要使用这个标志。织物内部蕴含多根愈合素导管,可以让阿拉克涅虫族从菌毯中抽取营养以治疗其他个体。</description>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Cloth_2Stage</ThingDef>
<ThingDef>ARA_Cocoon_Cloth_1Stage</ThingDef>
<AbilityDef>ARA_TerrainHeal_Ability</AbilityDef>
</descriptionHyperlinks>
<recipeMaker>
@@ -318,15 +367,19 @@
<costList Inherit="False">
<ARA_Carapace>25</ARA_Carapace>
</costList>
<statBases>
<ARA_IncubationCost>350</ARA_IncubationCost>
<ARA_IncubationTime>5</ARA_IncubationTime>
</statBases>
<graphicData>
<texPath>ArachnaeSwarm/Apparel/ARA_Nurse_Uniform</texPath>
</graphicData>
<apparel>
<bodyPartGroups>
<li>Torso</li>
<li>Shoulders</li>
<li>Arms</li>
<li>Legs</li>
<li>Torso</li>
<li>Shoulders</li>
<li>Arms</li>
<li>Legs</li>
</bodyPartGroups>
<layers>
<!-- <li>OnSkin</li> -->
@@ -341,12 +394,15 @@
<li Class="CompProperties_CauseHediff_Apparel">
<hediff>ARA_TerrainHealHediff</hediff>
</li>
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
<cocoonDef>ARA_Cocoon_Cloth_1Stage</cocoonDef>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="ARA_ClothBase">
<defName>ARA_Wedding_Dress</defName>
<label>阿拉克涅花嫁连衣裙</label>
<description>阿拉克涅督虫们所着织物中的一种,拥有摄人心魄的力量,可以抽取菌毯的力量发动夺取心智的能力,让敌方调转枪口攻击自己人。</description>
<defName>ARA_Wedding_Dress</defName>
<label>阿拉克涅花嫁连衣裙</label>
<description>阿拉克涅督虫们所着织物中的一种,拥有摄人心魄的力量,可以抽取菌毯的力量发动夺取心智的能力,让敌方调转枪口攻击自己人。</description>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Cloth_2Stage</ThingDef>
<AbilityDef>ARA_TerrainTempt_Ability</AbilityDef>
@@ -364,10 +420,10 @@
</graphicData>
<apparel>
<bodyPartGroups>
<li>Torso</li>
<li>Shoulders</li>
<li>Arms</li>
<li>Legs</li>
<li>Torso</li>
<li>Shoulders</li>
<li>Arms</li>
<li>Legs</li>
</bodyPartGroups>
<layers>
<!-- <li>OnSkin</li> -->
@@ -375,6 +431,10 @@
</layers>
<wornGraphicPath>ArachnaeSwarm/Apparel/ARA_Wedding_Dress</wornGraphicPath>
</apparel>
<statBases>
<ARA_IncubationCost>350</ARA_IncubationCost>
<ARA_IncubationTime>5</ARA_IncubationTime>
</statBases>
<equippedStatOffsets>
</equippedStatOffsets>
<costStuffCount>0</costStuffCount>
@@ -382,12 +442,15 @@
<li Class="CompProperties_CauseHediff_Apparel">
<hediff>ARA_TerrainTemptHediff</hediff>
</li>
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
<cocoonDef>ARA_Cocoon_Cloth_2Stage</cocoonDef>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="ARA_ClothBase">
<defName>ARA_Dragoon_Uniform</defName>
<label>阿拉克涅卫兵装</label>
<description>阿拉克涅虫群中的高阶战士所着织物,她们能够发出震耳欲聋的咆哮,并且看上去给人一种意外的庄严感——只不过她们挥着咔咔作响的鳌钳将你的同伴撕裂时,所有美好的幻想都会成为泡影。</description>
<defName>ARA_Dragoon_Uniform</defName>
<label>阿拉克涅卫兵装</label>
<description>阿拉克涅虫群中的高阶战士所着织物,她们能够发出震耳欲聋的咆哮,并且看上去给人一种意外的庄严感——只不过她们挥着咔咔作响的鳌钳将你的同伴撕裂时,所有美好的幻想都会成为泡影。</description>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Cloth_2Stage</ThingDef>
<AbilityDef>ARA_TerrorRoar_Ability</AbilityDef>
@@ -405,10 +468,10 @@
</graphicData>
<apparel>
<bodyPartGroups>
<li>Torso</li>
<li>Shoulders</li>
<li>Arms</li>
<li>Legs</li>
<li>Torso</li>
<li>Shoulders</li>
<li>Arms</li>
<li>Legs</li>
</bodyPartGroups>
<layers>
<!-- <li>OnSkin</li> -->
@@ -416,6 +479,10 @@
</layers>
<wornGraphicPath>ArachnaeSwarm/Apparel/ARA_Dragoon_Uniform</wornGraphicPath>
</apparel>
<statBases>
<ARA_IncubationCost>500</ARA_IncubationCost>
<ARA_IncubationTime>10</ARA_IncubationTime>
</statBases>
<equippedStatOffsets>
</equippedStatOffsets>
<costStuffCount>0</costStuffCount>
@@ -423,12 +490,15 @@
<li Class="CompProperties_CauseHediff_Apparel">
<hediff>ARA_TerrainTerrorRoar_Hediff</hediff>
</li>
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
<cocoonDef>ARA_Cocoon_Cloth_2Stage</cocoonDef>
</li>
</comps>
</ThingDef>
<ApparelLayerDef>
<defName>Shield</defName>
<label>盾牌</label>
<drawOrder>275</drawOrder>
</ApparelLayerDef>
<ApparelLayerDef>
<defName>Shield</defName>
<label>盾牌</label>
<drawOrder>275</drawOrder>
</ApparelLayerDef>
</Defs>

View File

@@ -31,6 +31,8 @@
<statBases>
<WorkToMake>1000</WorkToMake>
<Mass>5</Mass>
<ARA_IncubationCost>25</ARA_IncubationCost>
<ARA_IncubationTime>2.5</ARA_IncubationTime>
</statBases>
<tools Inherit="False">
<li>
@@ -66,6 +68,11 @@
<thingSetMakerTags>
<li>RewardStandardQualitySuper</li>
</thingSetMakerTags>
<comps>
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
<cocoonDef>ARA_Cocoon_Weapon</cocoonDef>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="BaseMeleeWeapon_Sharp_Quality">
<defName>ARA_MW_Cartilage_Whip</defName>
@@ -261,6 +268,8 @@
<AccuracyMedium>0.45</AccuracyMedium>
<AccuracyLong>0.3</AccuracyLong>
<RangedWeapon_Cooldown>1.25</RangedWeapon_Cooldown>
<ARA_IncubationCost>15</ARA_IncubationCost>
<ARA_IncubationTime>1</ARA_IncubationTime>
</statBases>
<verbs>
<li>
@@ -307,6 +316,9 @@
</li>
</tools>
<comps>
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
<cocoonDef>ARA_Cocoon_Weapon</cocoonDef>
</li>
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon" MayRequire="Ludeon.RimWorld.Odyssey">
<forcedTraits>
<li>ARA_Weapon_Damage_Toxid</li>

View File

@@ -515,6 +515,9 @@
<descriptionHyperlinks>
<ThingDef>ARA_Bodystocking_White</ThingDef>
<ThingDef>ARA_Bodystocking_Black</ThingDef>
<ThingDef>ARA_Latex_Catsuit</ThingDef>
<ThingDef>ARA_Pantyhose_Black</ThingDef>
<ThingDef>ARA_Pantyhose_White</ThingDef>
<ThingDef>ARA_Maid_Uniform</ThingDef>
</descriptionHyperlinks>
@@ -535,25 +538,6 @@
</li>
<!-- The refactored producer component -->
<li Class="ArachnaeSwarm.CompProperties_InteractiveProducer">
<processes>
<li>
<thingDef>ARA_Bodystocking_White</thingDef>
<productionTicks>6000</productionTicks>
<totalNutritionNeeded>1</totalNutritionNeeded>
</li>
<li>
<thingDef>ARA_Bodystocking_Black</thingDef>
<productionTicks>6000</productionTicks>
<totalNutritionNeeded>1</totalNutritionNeeded>
</li>
<li>
<thingDef>ARA_Maid_Uniform</thingDef>
<productionTicks>18000</productionTicks>
<totalNutritionNeeded>15</totalNutritionNeeded>
<requiredResearch>ARA_Technology_4DIL</requiredResearch>
</li>
</processes>
<whitelist>
<li>ArachnaeNode_Race_WeaponSmith</li>
</whitelist>
@@ -633,26 +617,6 @@
</li>
<!-- The refactored producer component -->
<li Class="ArachnaeSwarm.CompProperties_InteractiveProducer">
<processes>
<li>
<thingDef>ARA_MW_Bone_Sword</thingDef>
<productionTicks>60000</productionTicks>
<totalNutritionNeeded>15</totalNutritionNeeded>
</li>
<li>
<thingDef>ARA_RW_Basic_Fist_Needle_Gun</thingDef>
<productionTicks>40000</productionTicks>
<totalNutritionNeeded>10</totalNutritionNeeded>
<requiredResearch>ARA_Technology_5PAV</requiredResearch>
</li>
<li>
<thingDef>ARA_RW_Basic_Acid_Bladder_Gun</thingDef>
<productionTicks>80000</productionTicks>
<totalNutritionNeeded>30</totalNutritionNeeded>
<requiredResearch>ARA_Technology_7VXI</requiredResearch>
</li>
</processes>
<whitelist>
<li>ArachnaeNode_Race_WeaponSmith</li>
</whitelist>
@@ -729,8 +693,8 @@
</li>
<!-- The refactored producer component -->
<li Class="ArachnaeSwarm.CompProperties_InteractiveProducer">
<processes>
</processes>
<!-- <processes>
</processes> -->
<whitelist>
<li>ArachnaeNode_Race_WeaponSmith</li>
@@ -813,7 +777,7 @@
</li>
<!-- The refactored producer component -->
<li Class="ArachnaeSwarm.CompProperties_InteractiveProducer">
<processes>
<!-- <processes>
<li>
<thingDef>ARA_MW_Cartilage_Whip</thingDef>
<productionTicks>240000</productionTicks>
@@ -838,7 +802,7 @@
<totalNutritionNeeded>25</totalNutritionNeeded>
<requiredResearch>ARA_Technology_6SPV</requiredResearch>
</li>
</processes>
</processes> -->
<whitelist>
<li>ArachnaeNode_Race_WeaponSmith</li>
@@ -916,8 +880,8 @@
</li>
<!-- The refactored producer component -->
<li Class="ArachnaeSwarm.CompProperties_InteractiveProducer">
<processes>
</processes>
<!-- <processes>
</processes> -->
<whitelist>
<li>ArachnaeNode_Race_WeaponSmith</li>
@@ -999,7 +963,7 @@
</li>
<!-- The refactored producer component -->
<li Class="ArachnaeSwarm.CompProperties_InteractiveProducer">
<processes>
<!-- <processes>
<li>
<thingDef>ARA_RW_Basic_SniperCannon_Gun</thingDef>
<productionTicks>480000</productionTicks>
@@ -1018,7 +982,7 @@
<totalNutritionNeeded>80</totalNutritionNeeded>
<requiredResearch>ARA_Technology_2MEL</requiredResearch>
</li>
</processes>
</processes> -->
<whitelist>
<li>ArachnaeNode_Race_WeaponSmith</li>
@@ -1104,7 +1068,7 @@
</li>
<!-- The refactored producer component -->
<li Class="ArachnaeSwarm.CompProperties_InteractiveProducer">
<processes>
<!-- <processes>
<li>
<thingDef>ARA_Medicine</thingDef>
<productionTicks>36000</productionTicks>
@@ -1116,7 +1080,7 @@
<totalNutritionNeeded>20</totalNutritionNeeded>
<requiredResearch>ARA_Technology_2MED</requiredResearch>
</li>
</processes>
</processes> -->
<whitelist>
<li>ArachnaeNode_Race_Myrmecocystus</li>

View File

@@ -3,12 +3,8 @@
"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\\abilities\\ara_destroyownbodypart\\compabilityeffect_destroyownbodypart.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_destroyownbodypart\\compabilityeffect_destroyownbodypart.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_destroyownbodypart\\compproperties_abilitydestroyownbodypart.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_destroyownbodypart\\compproperties_abilitydestroyownbodypart.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\\stat\\statworker_incubationinfo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:stat\\statworker_incubationinfo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
"DocumentGroupContainers": [
@@ -18,35 +14,23 @@
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 2,
"SelectedChildIndex": 1,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "CompProperties_AbilityDestroyOwnBodyPart.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_DestroyOwnBodyPart\\CompProperties_AbilityDestroyOwnBodyPart.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_DestroyOwnBodyPart\\CompProperties_AbilityDestroyOwnBodyPart.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_DestroyOwnBodyPart\\CompProperties_AbilityDestroyOwnBodyPart.cs",
"RelativeToolTip": "Abilities\\ARA_DestroyOwnBodyPart\\CompProperties_AbilityDestroyOwnBodyPart.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-09-28T08:57:43.206Z"
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "CompAbilityEffect_DestroyOwnBodyPart.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_DestroyOwnBodyPart\\CompAbilityEffect_DestroyOwnBodyPart.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_DestroyOwnBodyPart\\CompAbilityEffect_DestroyOwnBodyPart.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_DestroyOwnBodyPart\\CompAbilityEffect_DestroyOwnBodyPart.cs",
"RelativeToolTip": "Abilities\\ARA_DestroyOwnBodyPart\\CompAbilityEffect_DestroyOwnBodyPart.cs",
"ViewState": "AgIAADYAAAAAAAAAAAAIwGIAAAAJAAAAAAAAAA==",
"Title": "StatWorker_IncubationInfo.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Stat\\StatWorker_IncubationInfo.cs",
"RelativeDocumentMoniker": "Stat\\StatWorker_IncubationInfo.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Stat\\StatWorker_IncubationInfo.cs",
"RelativeToolTip": "Stat\\StatWorker_IncubationInfo.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-09-28T08:57:31.224Z",
"WhenOpened": "2025-09-30T08:38:06.014Z",
"EditorCaption": ""
}
]

View File

@@ -170,9 +170,12 @@
<Compile Include="Hediffs\WULA_HediffDamgeShield\DRMDamageShield.cs" />
<Compile Include="Hediffs\WULA_HediffDamgeShield\Hediff_DamageShield.cs" />
<Compile Include="Hediff_DynamicInterceptor.cs" />
<Compile Include="Stat\StatWorker_IncubationInfo.cs" />
<Compile Include="ThingComp_GuardianPsyField.cs" />
<Compile Include="Harmony_ProjectileInterceptor.cs" />
<Compile Include="MainHarmony.cs" />
<Compile Include="Thing_Comps\ARA_CompExtraIncubationInfo\CompExtraIncubationInfo.cs" />
<Compile Include="Thing_Comps\ARA_CompExtraIncubationInfo\CompProperties_ExtraIncubationInfo.cs" />
<Compile Include="Thing_Comps\CompAndPatch_GiveHediffOnShot.cs" />
<Compile Include="Pawn_Comps\ARA_AutoMechCarrier\CompAutoMechCarrier.cs" />
<Compile Include="Pawn_Comps\ARA_AutoMechCarrier\CompProperties_AutoMechCarrier.cs" />

View File

@@ -8,11 +8,9 @@ using Verse.AI;
namespace ArachnaeSwarm
{
// V14: Final refactor to work with the new GrowthVat-style fuel comp.
public class CompProperties_InteractiveProducer : CompProperties
{
public List<ProcessDef> processes;
// 不再需要手动配置 processes 列表
public List<PawnKindDef> whitelist;
public IntRange spawnCount = new IntRange(1, 1);
public bool destroyOnSpawn;
@@ -21,7 +19,7 @@ namespace ArachnaeSwarm
public float penaltyPerDegreePerTick = 0.00001f;
public List<QualityThreshold> qualityThresholds;
public float damagePerTickWhenUnfueled = 0.2f;
public float minNutritionToStart = 0.1f; // Minimum fuel required to start a process
public float minNutritionToStart = 0.1f;
public CompProperties_InteractiveProducer()
{
@@ -36,12 +34,27 @@ namespace ArachnaeSwarm
private int productionUntilTick = -1;
private int ticksUnderOptimalConditions;
private float temperaturePenaltyPercent;
private List<ProcessDef> _cachedProcesses;
private CompRefuelableNutrition _fuelComp;
private static readonly Texture2D CancelIcon = ContentFinder<Texture2D>.Get("UI/Designators/Cancel");
public bool InProduction => _selectedProcess != null;
public CompProperties_InteractiveProducer Props => (CompProperties_InteractiveProducer)props;
// 自动生成的 ProcessDef 列表
public List<ProcessDef> Processes
{
get
{
if (_cachedProcesses == null)
{
BuildProcessList();
}
return _cachedProcesses;
}
}
private CompRefuelableNutrition FuelComp
{
get
@@ -55,12 +68,126 @@ namespace ArachnaeSwarm
{
base.PostSpawnSetup(respawningAfterLoad);
_fuelComp = parent.GetComp<CompRefuelableNutrition>();
BuildProcessList(); // 确保进程列表在生成时构建
}
public override void PostExposeData()
{
base.PostExposeData();
// ... (Scribe logic is the same as V11) ...
// 序列化 selectedProcess 的 thingDef 而不是整个 ProcessDef
ThingDef selectedProcessThingDef = _selectedProcess?.thingDef;
Scribe_Defs.Look(ref selectedProcessThingDef, "selectedProcessThingDef");
Scribe_Values.Look(ref productionUntilTick, "productionUntilTick", -1);
Scribe_Values.Look(ref ticksUnderOptimalConditions, "ticksUnderOptimalConditions", 0);
Scribe_Values.Look(ref temperaturePenaltyPercent, "temperaturePenaltyPercent", 0f);
// 加载时重建 selectedProcess
if (Scribe.mode == LoadSaveMode.LoadingVars && selectedProcessThingDef != null)
{
// 确保 Processes 列表已构建
if (_cachedProcesses == null)
{
BuildProcessList();
}
// 根据 thingDef 找到对应的 ProcessDef
_selectedProcess = Processes.FirstOrDefault(p => p.thingDef == selectedProcessThingDef);
// 如果找不到对应的 ProcessDef重置生产状态
if (_selectedProcess == null)
{
Log.Warning($"Could not find ProcessDef for {selectedProcessThingDef.defName} after loading. Resetting production.");
ResetProduction();
}
}
}
// 自动构建 ProcessDef 列表的方法
private void BuildProcessList()
{
_cachedProcesses = new List<ProcessDef>();
// 扫描所有定义了 CompExtraIncubationInfo 的物品
foreach (ThingDef thingDef in DefDatabase<ThingDef>.AllDefs)
{
// 检查是否是服装或武器
if (thingDef.IsApparel || thingDef.IsWeapon)
{
var incubationCompProps = thingDef.GetCompProperties<CompProperties_ExtraIncubationInfo>();
if (incubationCompProps != null && incubationCompProps.cocoonDef == parent.def)
{
// 获取研究前提 - 从 recipeMaker 中获取
ResearchProjectDef researchPrerequisite = null;
// 方法1从 recipeMaker.researchPrerequisite 获取
if (thingDef.recipeMaker?.researchPrerequisite != null)
{
researchPrerequisite = thingDef.recipeMaker.researchPrerequisite;
}
// 方法2从 recipeMaker.researchPrerequisites 获取第一个
else if (thingDef.recipeMaker?.researchPrerequisites?.Count > 0)
{
researchPrerequisite = thingDef.recipeMaker.researchPrerequisites[0];
}
// 方法3从 thingDef.researchPrerequisites 获取(备用)
else if (thingDef.researchPrerequisites?.Count > 0)
{
researchPrerequisite = thingDef.researchPrerequisites[0];
}
// 创建 ProcessDef
ProcessDef process = new ProcessDef
{
thingDef = thingDef,
productionTicks = GetIncubationTimeTicks(thingDef),
totalNutritionNeeded = GetIncubationCost(thingDef),
requiredResearch = researchPrerequisite
};
_cachedProcesses.Add(process);
}
}
}
// 按物品名称排序以便更好的 UI 显示
_cachedProcesses.SortBy(p => p.thingDef.label);
}
// 获取孵化时间(转换为 ticks
private int GetIncubationTimeTicks(ThingDef thingDef)
{
StatDef incubationTimeStat = DefDatabase<StatDef>.GetNamedSilentFail("ARA_IncubationTime");
if (incubationTimeStat != null && thingDef.statBases != null)
{
var statValue = thingDef.statBases.FirstOrDefault(s => s.stat == incubationTimeStat);
if (statValue != null)
{
// ARA_IncubationTime 是以天为单位,转换为 ticks (1天 = 60000 ticks)
return Mathf.RoundToInt(statValue.value * 60000f);
}
}
// 默认值1 天
return 60000;
}
// 获取孵化所需营养
private float GetIncubationCost(ThingDef thingDef)
{
StatDef incubationCostStat = DefDatabase<StatDef>.GetNamedSilentFail("ARA_IncubationCost");
if (incubationCostStat != null && thingDef.statBases != null)
{
var statValue = thingDef.statBases.FirstOrDefault(s => s.stat == incubationCostStat);
if (statValue != null)
{
return statValue.value;
}
}
// 默认值10 营养
return 10f;
}
public override void CompTick()
@@ -70,8 +197,6 @@ namespace ArachnaeSwarm
{
if (FuelComp == null) return;
// Nutrition consumption is now handled by CompRefuelableNutrition's CompTick.
// We just need to check if there is any fuel left.
bool hasFuel = FuelComp.HasFuel;
if (!hasFuel)
@@ -110,7 +235,8 @@ namespace ArachnaeSwarm
yield break;
}
foreach (var process in Props.processes)
// 使用自动生成的 Processes 列表
foreach (var process in Processes)
{
if (process.requiredResearch != null && !process.requiredResearch.IsFinished)
{
@@ -135,7 +261,6 @@ namespace ArachnaeSwarm
productionUntilTick = Find.TickManager.TicksGame + _selectedProcess.productionTicks;
ticksUnderOptimalConditions = 0;
temperaturePenaltyPercent = 0f;
// Set the consumption rate on the fuel comp (nutrition per day)
float nutritionPerDay = (_selectedProcess.totalNutritionNeeded / _selectedProcess.productionTicks) * 60000f;
FuelComp.currentConsumptionRate = nutritionPerDay;
}
@@ -144,25 +269,21 @@ namespace ArachnaeSwarm
{
if (!InProduction || Props.qualityThresholds.NullOrEmpty())
{
return (QualityCategory.Normal, 0f, 0f); // Default or no quality system
return (QualityCategory.Normal, 0f, 0f);
}
// Estimate progress based on optimal ticks vs total ticks
float progress = (float)ticksUnderOptimalConditions / _selectedProcess.productionTicks;
// Apply temperature penalty
float finalQualityPercent = Mathf.Clamp01(progress - temperaturePenaltyPercent);
QualityCategory finalQuality = QualityCategory.Awful;
// Find the best quality that meets the threshold
foreach (var threshold in Props.qualityThresholds.OrderByDescending(q => q.threshold))
{
if (finalQualityPercent >= threshold.threshold)
{
finalQuality = threshold.quality;
break; // Exit after finding the highest met quality
break;
}
}
// If no threshold is met, it will remain the lowest quality
if (finalQuality == QualityCategory.Awful && Props.qualityThresholds.Any())
{
finalQuality = Props.qualityThresholds.OrderBy(q => q.threshold).First().quality;
@@ -179,27 +300,22 @@ namespace ArachnaeSwarm
return;
}
// 1. Determine final quality
var qualityDetails = GetEstimatedQualityDetails();
QualityCategory finalQuality = qualityDetails.quality;
// 2. Create and spawn the item
for (int i = 0; i < Props.spawnCount.RandomInRange; i++)
{
Thing product = ThingMaker.MakeThing(_selectedProcess.thingDef);
product.TryGetComp<CompQuality>()?.SetQuality(finalQuality, ArtGenerationContext.Colony);
// Spawn the item near the parent building
GenPlace.TryPlaceThing(product, parent.Position, parent.Map, ThingPlaceMode.Near);
}
// 3. Destroy self if configured
if (Props.destroyOnSpawn)
{
parent.Destroy(DestroyMode.Vanish);
}
// 4. Reset state
ResetProduction();
}
@@ -221,13 +337,11 @@ namespace ArachnaeSwarm
int remainingTicks = productionUntilTick - Find.TickManager.TicksGame;
sb.AppendLine("TimeLeft".Translate() + ": " + remainingTicks.ToStringTicksToPeriod());
// Quality Details
var qualityDetails = GetEstimatedQualityDetails();
sb.AppendLine("EstimatedQuality".Translate() + ": " + qualityDetails.quality.GetLabel());
sb.AppendLine($" {"QualityScore".Translate()}: {qualityDetails.baseScore.ToStringPercent("F0")}");
sb.AppendLine($" {"TemperaturePenalty".Translate()}: -{qualityDetails.penalty.ToStringPercent("F0")}");
// Temperature Details
string tempStr = "CurrentTemperature".Translate(parent.AmbientTemperature.ToStringTemperature("F0"));
tempStr += $" ({"SafeTemperatureRange".Translate()}: {Props.minSafeTemperature.ToStringTemperature("F0")} ~ {Props.maxSafeTemperature.ToStringTemperature("F0")})";
sb.AppendLine(tempStr);
@@ -236,7 +350,9 @@ namespace ArachnaeSwarm
}
if (!InProduction)
{
return "ARA_NeedArachnaeToStartIncubation".Translate();
// 显示可生产的物品数量
int availableProcesses = Processes.Count(p => p.requiredResearch == null || p.requiredResearch.IsFinished);
return "ARA_NeedArachnaeToStartIncubation".Translate() + $" ({availableProcesses} items available)";
}
return null;
}
@@ -255,4 +371,4 @@ namespace ArachnaeSwarm
}
}
}
}
}

View File

@@ -0,0 +1,172 @@
using RimWorld;
using Verse;
using System.Linq;
namespace ArachnaeSwarm
{
// ARA_IncubationCost 的 StatWorker
public class StatWorker_IncubationCost : StatWorker
{
public override bool ShouldShowFor(StatRequest req)
{
try
{
// 只在拥有 CompProperties_ExtraIncubationInfo 的 ThingDef 上显示
if (!base.ShouldShowFor(req))
return false;
return HasIncubationComp(req);
}
catch (System.Exception ex)
{
Log.Warning($"Error in StatWorker_IncubationCost.ShouldShowFor for {req.Def?.defName}: {ex.Message}");
return false;
}
}
public override float GetValueUnfinalized(StatRequest req, bool applyPostProcess = true)
{
try
{
// 从 ThingDef 的 statBases 中获取值
if (req.Def is ThingDef thingDef)
{
var statModifier = thingDef.statBases?.FirstOrDefault(s => s.stat == this.stat);
if (statModifier != null)
{
return statModifier.value;
}
}
return base.GetValueUnfinalized(req, applyPostProcess);
}
catch (System.Exception ex)
{
Log.Warning($"Error in StatWorker_IncubationCost.GetValueUnfinalized for {req.Def?.defName}: {ex.Message}");
return 0f;
}
}
public override string GetExplanationUnfinalized(StatRequest req, ToStringNumberSense numberSense)
{
try
{
if (!HasIncubationComp(req))
return string.Empty;
float value = GetValueUnfinalized(req);
return "IncubationCostDesc".Translate(value);
}
catch (System.Exception ex)
{
Log.Warning($"Error in StatWorker_IncubationCost.GetExplanationUnfinalized for {req.Def?.defName}: {ex.Message}");
return string.Empty;
}
}
private bool HasIncubationComp(StatRequest req)
{
try
{
ThingDef thingDef = req.Def as ThingDef ?? req.Thing?.def;
return thingDef?.comps?.Any(c => c is CompProperties_ExtraIncubationInfo) == true;
}
catch (System.Exception ex)
{
Log.Warning($"Error in StatWorker_IncubationCost.HasIncubationComp for {req.Def?.defName}: {ex.Message}");
return false;
}
}
}
// ARA_IncubationTime 的 StatWorker
public class StatWorker_IncubationTime : StatWorker
{
public override bool ShouldShowFor(StatRequest req)
{
try
{
// 只在拥有 CompProperties_ExtraIncubationInfo 的 ThingDef 上显示
if (!base.ShouldShowFor(req))
return false;
return HasIncubationComp(req);
}
catch (System.Exception ex)
{
Log.Warning($"Error in StatWorker_IncubationTime.ShouldShowFor for {req.Def?.defName}: {ex.Message}");
return false;
}
}
public override float GetValueUnfinalized(StatRequest req, bool applyPostProcess = true)
{
try
{
// 从 ThingDef 的 statBases 中获取值
if (req.Def is ThingDef thingDef)
{
var statModifier = thingDef.statBases?.FirstOrDefault(s => s.stat == this.stat);
if (statModifier != null)
{
return statModifier.value;
}
}
return base.GetValueUnfinalized(req, applyPostProcess);
}
catch (System.Exception ex)
{
Log.Warning($"Error in StatWorker_IncubationTime.GetValueUnfinalized for {req.Def?.defName}: {ex.Message}");
return 0f;
}
}
public override string GetExplanationUnfinalized(StatRequest req, ToStringNumberSense numberSense)
{
try
{
if (!HasIncubationComp(req))
return string.Empty;
float value = GetValueUnfinalized(req);
return "IncubationTimeDesc".Translate(value);
}
catch (System.Exception ex)
{
Log.Warning($"Error in StatWorker_IncubationTime.GetExplanationUnfinalized for {req.Def?.defName}: {ex.Message}");
return string.Empty;
}
}
public override string GetStatDrawEntryLabel(StatDef stat, float value, ToStringNumberSense numberSense, StatRequest req, bool finalized = true)
{
try
{
if (!HasIncubationComp(req))
return base.GetStatDrawEntryLabel(stat, value, numberSense, req, finalized);
return value + " days";
}
catch (System.Exception ex)
{
Log.Warning($"Error in StatWorker_IncubationTime.GetStatDrawEntryLabel for {req.Def?.defName}: {ex.Message}");
return value.ToString();
}
}
private bool HasIncubationComp(StatRequest req)
{
try
{
ThingDef thingDef = req.Def as ThingDef ?? req.Thing?.def;
return thingDef?.comps?.Any(c => c is CompProperties_ExtraIncubationInfo) == true;
}
catch (System.Exception ex)
{
Log.Warning($"Error in StatWorker_IncubationTime.HasIncubationComp for {req.Def?.defName}: {ex.Message}");
return false;
}
}
}
}

View File

@@ -0,0 +1,13 @@
using RimWorld;
using Verse;
namespace ArachnaeSwarm
{
public class CompExtraIncubationInfo : ThingComp
{
public CompProperties_ExtraIncubationInfo Props => (CompProperties_ExtraIncubationInfo)props;
// 公开属性,供其他组件读取
public ThingDef CocoonDef => Props.cocoonDef;
}
}

View File

@@ -0,0 +1,15 @@
using RimWorld;
using Verse;
namespace ArachnaeSwarm
{
public class CompProperties_ExtraIncubationInfo : CompProperties
{
// 指定的茧建筑定义
public ThingDef cocoonDef;
public CompProperties_ExtraIncubationInfo()
{
compClass = typeof(CompExtraIncubationInfo);
}
}
}