This commit is contained in:
Tourswen
2025-10-19 12:51:06 +08:00
parent 0c45c14570
commit 9dc9d7d6e3
40 changed files with 1837 additions and 423 deletions

Binary file not shown.

View File

@@ -520,7 +520,7 @@
<AbilityDef>
<defName>ARA_Ability_Possess</defName>
<label>原虫种突袭寄生</label>
<description>跃向目标,随后尝试使用长尾刺穿对象并截断其神经中枢信号,以自己的控制信号取而代之,进而完全侵占目标躯体。\n\n被侵占躯体的对象视为阿拉克涅虫族的一员需要接受女皇种的信息素标记并且不再拥有感情和高级需求仅作为躯壳活着。目标的技能熟练度和背景故事会替换为原虫种的技能熟练度和背景故事一旦宿主死亡原虫种将从宿主身上逃离。</description>
<description>跃向目标,随后尝试使用长尾刺穿对象并截断其神经中枢信号,以自己的控制信号取而代之,进而完全侵占目标躯体——它需要打穿护甲才能完成寄生,但是如果对关押的犯人和无行动能力者进行寄生,则必定成功。\n\n被侵占躯体的对象视为阿拉克涅虫族的一员需要接受女皇种的信息素标记并且不再拥有感情和高级需求仅作为躯壳活着。目标的技能熟练度和背景故事会替换为原虫种的技能熟练度和背景故事一旦宿主死亡原虫种将从宿主身上逃离。</description>
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_Ability_Possess</iconPath>
<cooldownTicksRange>800</cooldownTicksRange>
<casterMustBeCapableOfViolence>false</casterMustBeCapableOfViolence>
@@ -1249,6 +1249,7 @@
<li>ArachnaeBase_Race_Acidcut</li>
<li>ArachnaeBase_Race_Acidling</li>
<li>ArachnaeBase_Race_Skyhive</li>
<li>ArachnaeNode_Race_MimicNematode</li>
</targetRaces>
<!-- 其他参数和原版一样 -->

View File

@@ -249,7 +249,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>左眼</customLabel>
<customLabel>left eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -264,7 +264,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>右眼</customLabel>
<customLabel>right eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -892,7 +892,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>左眼</customLabel>
<customLabel>left eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -907,7 +907,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>右眼</customLabel>
<customLabel>right eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -1285,7 +1285,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>左眼</customLabel>
<customLabel>left eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -1300,7 +1300,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>右眼</customLabel>
<customLabel>right eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -1647,7 +1647,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>左眼</customLabel>
<customLabel>left eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -1662,7 +1662,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>右眼</customLabel>
<customLabel>right eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -2025,7 +2025,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>左眼</customLabel>
<customLabel>left eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -2040,7 +2040,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>右眼</customLabel>
<customLabel>right eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -2448,7 +2448,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>左眼</customLabel>
<customLabel>left eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -2463,7 +2463,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>右眼</customLabel>
<customLabel>right eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -2802,7 +2802,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>左眼</customLabel>
<customLabel>left eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -2817,7 +2817,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>右眼</customLabel>
<customLabel>right eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -3205,7 +3205,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>左眼</customLabel>
<customLabel>left eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -3220,7 +3220,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>右眼</customLabel>
<customLabel>right eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -3568,7 +3568,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>左眼</customLabel>
<customLabel>left eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -3583,7 +3583,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>右眼</customLabel>
<customLabel>right eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -3959,7 +3959,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>左眼</customLabel>
<customLabel>left eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>
@@ -3974,7 +3974,7 @@
</li>
<li>
<def>Eye</def>
<customLabel>右眼</customLabel>
<customLabel>right eye</customLabel>
<coverage>0.07</coverage>
<groups>
<li>FullHead</li>

View File

@@ -397,5 +397,42 @@
<FacialAnimation.SkinTypeDef ParentName="ArachnaeNode_Skin" MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Race_Praetorian_SkinNormal</defName>
<raceName>ArachnaeNode_Race_Praetorian</raceName>
</FacialAnimation.SkinTypeDef>
<FacialAnimation.BrowTypeDef ParentName="ArachnaeNode_Brow" MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Race_MimicNematode_BrowNormal</defName>
<raceName>ArachnaeNode_Race_MimicNematode</raceName>
</FacialAnimation.BrowTypeDef>
<FacialAnimation.EyeballTypeDef ParentName="ArachnaeNode_EyeA" MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Race_MimicNematode_EyeNormal</defName>
<raceName>ArachnaeNode_Race_MimicNematode</raceName>
</FacialAnimation.EyeballTypeDef>
<FacialAnimation.EyeballTypeDef ParentName="ArachnaeNode_EyeB" MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Race_MimicNematode_EyeNormal2</defName>
<raceName>ArachnaeNode_Race_MimicNematode</raceName>
</FacialAnimation.EyeballTypeDef>
<FacialAnimation.EyeballTypeDef ParentName="ArachnaeNode_EyeC" MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Race_MimicNematode_EyeNormal3</defName>
<raceName>ArachnaeNode_Race_MimicNematode</raceName>
</FacialAnimation.EyeballTypeDef>
<FacialAnimation.EyeballTypeDef ParentName="ArachnaeNode_EyeD" MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Race_MimicNematode_EyeNormal4</defName>
<raceName>ArachnaeNode_Race_MimicNematode</raceName>
</FacialAnimation.EyeballTypeDef>
<FacialAnimation.HeadTypeDef ParentName="ArachnaeNode_Head" MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Race_MimicNematode_HeadNormal</defName>
<raceName>ArachnaeNode_Race_MimicNematode</raceName>
</FacialAnimation.HeadTypeDef>
<FacialAnimation.LidTypeDef ParentName="ArachnaeNode_Lid" MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Race_MimicNematode_LidNormal</defName>
<raceName>ArachnaeNode_Race_MimicNematode</raceName>
</FacialAnimation.LidTypeDef>
<FacialAnimation.MouthTypeDef ParentName="ArachnaeNode_Mouth" MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Race_MimicNematode_MouthNormal</defName>
<raceName>ArachnaeNode_Race_MimicNematode</raceName>
</FacialAnimation.MouthTypeDef>
<FacialAnimation.SkinTypeDef ParentName="ArachnaeNode_Skin" MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Race_MimicNematode_SkinNormal</defName>
<raceName>ArachnaeNode_Race_MimicNematode</raceName>
</FacialAnimation.SkinTypeDef>
</Defs>

View File

@@ -10,7 +10,7 @@
<categoryTag>ARA_Hostile_Hive</categoryTag>
<requiredCountAtGameStart>1</requiredCountAtGameStart>
<factionNameMaker>ARA_New_Hive_NamerFaction</factionNameMaker>
<factionIconPath>Wula/World/WorldObjects/Expanding/Wula_FE_Faction</factionIconPath>
<factionIconPath>World/WorldObjects/Expanding/HoraxCult</factionIconPath>
<displayInFactionSelection>false</displayInFactionSelection>
<!-- <settlementGenerationWeight>1</settlementGenerationWeight> -->
<canSiege>false</canSiege>
@@ -22,7 +22,7 @@
</categories>
</li>
</backstoryFilters>
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<arrivalLayerWhitelist>
<li>Surface</li>
<!-- <li MayRequire="Ludeon.RimWorld.Odyssey">Orbit</li> -->

View File

@@ -8,7 +8,7 @@
<basicMemberKind>Colonist</basicMemberKind>
<pawnSingular>colonist</pawnSingular>
<pawnsPlural>colonists</pawnsPlural>
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<categoryTag>ARA_New_Hive</categoryTag>
<backstoryFilters>
<li>

View File

@@ -259,6 +259,16 @@
</renderNodeProperties>
</HediffDef>
<DamageDef ParentName="Beam">
<defName>ARA_Beam</defName>
<label>生物能射线</label>
<defaultDamage>5</defaultDamage>
<defaultArmorPenetration>2</defaultArmorPenetration>
<buildingDamageFactorImpassable>0.4</buildingDamageFactorImpassable>
<buildingDamageFactorPassable>0.2</buildingDamageFactorPassable>
</DamageDef>
<HediffDef>
<defName>ARA_ReinforceGasCoverd</defName>
<label>阿拉克涅信息素沾染</label>
@@ -359,6 +369,29 @@
</li>
</stages>
</HediffDef>
<HediffDef>
<defName>ARA_BeamAiming</defName>
<label>光束预热</label>
<description>阿拉克涅虫群的光束类能量武器在短暂瞄准后可以持续不断地射击。</description>
<defaultLabelColor>(0.52, 1, 0.95)</defaultLabelColor>
<hediffClass>HediffWithComps</hediffClass>
<comps>
<li Class="HediffCompProperties_DisappearsOnDeath" />
<li Class="HediffCompProperties_Disappears">
<disappearsAfterTicks>60</disappearsAfterTicks> <!-- 10 seconds -->
<showRemainingTime>true</showRemainingTime>
</li>
</comps>
<stages>
<li>
<label>完成</label>
<becomeVisible>true</becomeVisible>
<statFactors>
<AimingDelayFactor>0</AimingDelayFactor>
</statFactors>
</li>
</stages>
</HediffDef>
<HediffDef>
<defName>ARA_Fighter_Execution_Damage</defName>

View File

@@ -149,38 +149,6 @@
</modExtensions>
</HediffDef>
<RecipeDef ParentName="SurgeryFlesh">
<defName>ARA_CureBloodRot</defName>
<label>清除拟线虫感染</label>
<description>通过多种药物联合靶向治疗清除患者体内的阿拉克涅拟线种虫族感染,这种手术非常复杂,只能使用来自闪耀世界的医药进行。</description>
<workerClass>Recipe_RemoveHediff</workerClass>
<jobString>清除拟线虫感染.</jobString>
<workAmount>2000</workAmount>
<hideBodyPartNames>true</hideBodyPartNames>
<isViolation>false</isViolation>
<targetsBodyPart>false</targetsBodyPart>
<removesHediff>ARA_MimicNematode</removesHediff>
<successfullyRemovedHediffMessage>{0} 成功清除了 {1} 体内的拟线虫感染.</successfullyRemovedHediffMessage>
<skillRequirements>
<Medicine>5</Medicine>
</skillRequirements>
<ingredients>
<li>
<filter>
<thingDefs>
<li>MedicineUltratech</li>
</thingDefs>
</filter>
<count>2</count>
</li>
</ingredients>
<fixedIngredientFilter>
<categories>
<li>Medicine</li>
</categories>
</fixedIngredientFilter>
</RecipeDef>
<!-- 这是我们的主要变异体Hediff现在使用我们自己的可配置类 -->
<HediffDef>
<defName>ARA_MimicNematodeShambler</defName>

View File

@@ -66,6 +66,87 @@
<li>ARA_TumorSpew</li>
</abilities>
</PawnKindDef>
<AlienRace.RaceSettings>
<defName>ArachnaeQueen_RaceSettings</defName>
<pawnKindSettings>
<startingColonists>
<li>
<pawnKindEntries>
<li>
<kindDefs>
<li>ARA_ArachnaeQueen</li>
</kindDefs>
<chance>100.0</chance>
</li>
</pawnKindEntries>
<factionDefs>
<li>ARA_New_Hive</li>
</factionDefs>
</li>
</startingColonists>
<alienwandererkinds>
<li>
<pawnKindEntries>
<li>
<kindDefs>
<li>ARA_ArachnaeQueen</li>
<li>ArachnaeNode_Race_ShieldHead</li>
<li>ArachnaeNode_Race_WeaponSmith</li>
<li>ArachnaeNode_Race_Fighter</li>
<li>ArachnaeNode_Race_Facehugger</li>
<li>ArachnaeNode_Race_Myrmecocystus</li>
<li>ArachnaeNode_Race_Smokepop</li>
<li>ArachnaeNode_Race_NeuroSwarm</li>
<li>ArachnaeNode_Race_Skyraider</li>
<li>ArachnaeNode_Race_Praetorian</li>
<li>ARA_MimicNematodeShamblerSwarmer</li>
</kindDefs>
<chance>0</chance>
</li>
</pawnKindEntries>
<factionDefs>
<li>ARA_New_Hive</li>
</factionDefs>
</li>
</alienwandererkinds>
<alienslavekinds>
<li>
<kindDefs>
<li>ARA_ArachnaeQueen</li>
<li>ArachnaeNode_Race_ShieldHead</li>
<li>ArachnaeNode_Race_WeaponSmith</li>
<li>ArachnaeNode_Race_Fighter</li>
<li>ArachnaeNode_Race_Facehugger</li>
<li>ArachnaeNode_Race_Myrmecocystus</li>
<li>ArachnaeNode_Race_Smokepop</li>
<li>ArachnaeNode_Race_NeuroSwarm</li>
<li>ArachnaeNode_Race_Skyraider</li>
<li>ArachnaeNode_Race_Praetorian</li>
<li>ARA_MimicNematodeShamblerSwarmer</li>
</kindDefs>
<chance>0</chance>
</li>
</alienslavekinds>
<alienrefugeekinds>
<li>
<kindDefs>
<li>ARA_ArachnaeQueen</li>
<li>ArachnaeNode_Race_ShieldHead</li>
<li>ArachnaeNode_Race_WeaponSmith</li>
<li>ArachnaeNode_Race_Fighter</li>
<li>ArachnaeNode_Race_Facehugger</li>
<li>ArachnaeNode_Race_Myrmecocystus</li>
<li>ArachnaeNode_Race_Smokepop</li>
<li>ArachnaeNode_Race_NeuroSwarm</li>
<li>ArachnaeNode_Race_Skyraider</li>
<li>ArachnaeNode_Race_Praetorian</li>
<li>ARA_MimicNematodeShamblerSwarmer</li>
</kindDefs>
<chance>0</chance>
</li>
</alienrefugeekinds>
</pawnKindSettings>
</AlienRace.RaceSettings>
<PawnKindDef Name="ArachnaeNodeABasePawnKind" Abstract="True">
<combatPower>50</combatPower>

View File

@@ -777,4 +777,70 @@
<ARA_InsectJelly>5</ARA_InsectJelly>
</costList>
</ThingDef>
<!-- 杂项手术 -->
<RecipeDef ParentName="SurgeryFlesh">
<defName>ARA_CureAcid</defName>
<label>解除神经毒素</label>
<description>阿拉克涅虫群可以使用愈合素解除阿拉克涅神经毒素的影响,使得猎物恢复正常。</description>
<workerClass>Recipe_RemoveHediff</workerClass>
<jobString>解除神经毒素.</jobString>
<workAmount>2000</workAmount>
<hideBodyPartNames>true</hideBodyPartNames>
<isViolation>false</isViolation>
<targetsBodyPart>false</targetsBodyPart>
<removesHediff>ARA_ToxicBuildup</removesHediff>
<successfullyRemovedHediffMessage>{0} 成功清除了 {1} 体内的阿拉克涅神经毒素.</successfullyRemovedHediffMessage>
<skillRequirements>
<Medicine>5</Medicine>
</skillRequirements>
<ingredients>
<li>
<filter>
<thingDefs>
<li>ARA_Medicine</li>
</thingDefs>
</filter>
<count>2</count>
</li>
</ingredients>
<fixedIngredientFilter>
<categories>
<li>Medicine</li>
</categories>
</fixedIngredientFilter>
</RecipeDef>
<RecipeDef ParentName="SurgeryFlesh">
<defName>ARA_CureBloodRot</defName>
<label>清除拟线虫感染</label>
<description>通过多种药物联合靶向治疗清除患者体内的阿拉克涅拟线种虫族感染,这种手术非常复杂,只能使用来自闪耀世界的医药进行。</description>
<workerClass>Recipe_RemoveHediff</workerClass>
<jobString>清除拟线虫感染.</jobString>
<workAmount>2000</workAmount>
<hideBodyPartNames>true</hideBodyPartNames>
<isViolation>false</isViolation>
<targetsBodyPart>false</targetsBodyPart>
<removesHediff>ARA_MimicNematode</removesHediff>
<successfullyRemovedHediffMessage>{0} 成功清除了 {1} 体内的拟线虫感染.</successfullyRemovedHediffMessage>
<skillRequirements>
<Medicine>5</Medicine>
</skillRequirements>
<ingredients>
<li>
<filter>
<thingDefs>
<li>MedicineUltratech</li>
</thingDefs>
</filter>
<count>2</count>
</li>
</ingredients>
<fixedIngredientFilter>
<categories>
<li>Medicine</li>
</categories>
</fixedIngredientFilter>
</RecipeDef>
</Defs>

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<ResearchProjectDef Abstract="True" Name="ARA_techBase">
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<tab>ARA_ResearchTab</tab>
<heldByFactionCategoryTags Inherit="False" />
</ResearchProjectDef>
<ResearchProjectDef Abstract="True" Name="ARA_techBase_Needtechprint" ParentName="ARA_techBase">
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<tab>ARA_ResearchTab</tab>
<techprintCount>1</techprintCount>
<techprintCommonality>0</techprintCommonality>
@@ -139,8 +139,7 @@
<li>ARA_Technology_1NPT</li>
</prerequisites>
</ResearchProjectDef>
<!-- 等素材画好再启用 -->
<!-- 能量发展 -->
<ResearchProjectDef ParentName="ARA_techBase">
<defName>ARA_Technology_1THD</defName>
<label>节点THD-1"灵能闪电"</label>
@@ -226,6 +225,18 @@
<li>ARA_Technology_2WMT</li>
</prerequisites>
</ResearchProjectDef>
<ResearchProjectDef ParentName="ARA_techBase_Needtechprint">
<defName>ARA_Technology_6MEN</defName>
<label>节点MEN-6"拟线"</label>
<description>允许女皇种孵化新的虫族——拟线体,一种出生时躯体便已经被阿拉克涅拟线种寄生的虫族,便宜廉价并且可以快速得到的炮灰,倒是没什么纪律性就是了。\n\n阿拉克涅虫群所有需要蓝图的科技其蓝图只能通过女皇种的基因试验卵获取。</description>
<baseCost>1800</baseCost>
<researchViewX>7.50</researchViewX>
<researchViewY>2.10</researchViewY>
<requiredResearchBuilding>ARA_ResearchBench</requiredResearchBuilding>
<prerequisites>
<li>ARA_Technology_2MED</li>
</prerequisites>
</ResearchProjectDef>
<!-- 织物发展 -->
<ResearchProjectDef ParentName="ARA_techBase">
<defName>ARA_Technology_4DIL</defName>
@@ -567,7 +578,7 @@
<!-- 药物发展 -->
<ResearchProjectDef ParentName="ARA_techBase">
<defName>ARA_Technology_2MED</defName>
<label>节点MED-2"拟线种"</label>
<label>节点MED-2"侵蚀寄生"</label>
<description>允许蜜罐种使用拟线种寄生的能力,并在医药茧中解锁拟线种抑制剂的制作。</description>
<baseCost>1600</baseCost>
<researchViewX>6.50</researchViewX>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Defs>
<MutantDef Abstract="True" Name="ARA_BaseMutantEntity">
<consideredSubhuman>true</consideredSubhuman>
<canCarryPawns>false</canCarryPawns>
@@ -75,7 +74,7 @@
<restoreLegs>true</restoreLegs>
<defaultFaction>PlayerColony</defaultFaction>
<standingAnimation>ARA_ShamblerSway</standingAnimation>
<canOpenDoors>false</canOpenDoors>
<canOpenDoors>true</canOpenDoors>
<makesFootprints>false</makesFootprints>
<tameable>false</tameable>
<clearMutantStatusOnDeath>true</clearMutantStatusOnDeath>

View File

@@ -727,6 +727,13 @@
<path>ArachnaeSwarm/Things/ARA_HiveNode/Addons/ArachnaeNode_Race_Myrmecocystus_Addons_Stomach</path>
<inFrontOfBody>false</inFrontOfBody>
<scaleWithPawnDrawsize>true</scaleWithPawnDrawsize>
<conditions>
<Apparel>
<hiddenUnderApparelTag>
<li>ARA_PowerArmor</li>
</hiddenUnderApparelTag>
</Apparel>
</conditions>
</li>
</bodyAddons>
</alienPartGenerator>
@@ -870,6 +877,13 @@
</offsets>
<inFrontOfBody>true</inFrontOfBody>
<scaleWithPawnDrawsize>true</scaleWithPawnDrawsize>
<conditions>
<Apparel>
<hiddenUnderApparelTag>
<li>ARA_PowerArmor</li>
</hiddenUnderApparelTag>
</Apparel>
</conditions>
</li>
<li>
<path>ArachnaeSwarm/Things/ARA_HiveNode/Addons/ArachnaeNode_Race_Addons_ShieldBody</path>
@@ -890,6 +904,13 @@
<inFrontOfBody>true</inFrontOfBody>
<layerInvert>false</layerInvert>
<scaleWithPawnDrawsize>true</scaleWithPawnDrawsize>
<conditions>
<Apparel>
<hiddenUnderApparelTag>
<li>ARA_PowerArmor</li>
</hiddenUnderApparelTag>
</Apparel>
</conditions>
</li>
</bodyAddons>
</alienPartGenerator>
@@ -1013,6 +1034,13 @@
<layerOffset>-0.275</layerOffset>
</north>
</offsets>
<conditions>
<Apparel>
<hiddenUnderApparelTag>
<li>ARA_PowerArmor</li>
</hiddenUnderApparelTag>
</Apparel>
</conditions>
</li>
</bodyAddons>
</alienPartGenerator>
@@ -1129,6 +1157,13 @@
<path>ArachnaeSwarm/Things/ARA_HiveNode/Addons/ArachnaeNode_Race_Addons_Fighter_Claw</path>
<inFrontOfBody>true</inFrontOfBody>
<scaleWithPawnDrawsize>true</scaleWithPawnDrawsize>
<conditions>
<Apparel>
<hiddenUnderApparelTag>
<li>ARA_PowerArmor</li>
</hiddenUnderApparelTag>
</Apparel>
</conditions>
</li>
<li>
<path>ArachnaeSwarm/Things/ARA_HiveNode/Addons/ArachnaeNode_Race_Addons_Fighter_Tail</path>
@@ -1139,6 +1174,13 @@
<layerOffset>-0.275</layerOffset>
</north>
</offsets>
<conditions>
<Apparel>
<hiddenUnderApparelTag>
<li>ARA_PowerArmor</li>
</hiddenUnderApparelTag>
</Apparel>
</conditions>
</li>
</bodyAddons>
</alienPartGenerator>
@@ -1350,6 +1392,13 @@
<layerOffset>-0.275</layerOffset>
</north>
</offsets>
<conditions>
<Apparel>
<hiddenUnderApparelTag>
<li>ARA_PowerArmor</li>
</hiddenUnderApparelTag>
</Apparel>
</conditions>
</li>
</bodyAddons>
</alienPartGenerator>
@@ -1491,6 +1540,9 @@
<li>ARA_TrainMelee</li>
</recipeList>
<onlyDoRaceRestrictedRecipes>false</onlyDoRaceRestrictedRecipes>
<blackApparelList>
<li>ARA_SpiderOne_PowerArmor</li>
</blackApparelList>
</raceRestriction>
</alienRace>
@@ -1697,6 +1749,9 @@
</generalSettings>
<raceRestriction>
<onlyEatRaceRestrictedFood>true</onlyEatRaceRestrictedFood>
<blackApparelList>
<li>ARA_SpiderOne_PowerArmor</li>
</blackApparelList>
</raceRestriction>
</alienRace>
@@ -1808,6 +1863,11 @@
<drawnLaying>true</drawnLaying>
</Posture>
<RotStage>Fresh,Rotting</RotStage>
<Apparel>
<hiddenUnderApparelTag>
<li>ARA_PowerArmor</li>
</hiddenUnderApparelTag>
</Apparel>
</conditions>
<offsets>
<west>
@@ -1850,6 +1910,11 @@
<bodyPart>Head</bodyPart>
<drawWithoutPart>false</drawWithoutPart>
</BodyPart>
<Apparel>
<hiddenUnderApparelTag>
<li>ARA_PowerArmor</li>
</hiddenUnderApparelTag>
</Apparel>
</conditions>
</li>
<li>
@@ -1871,6 +1936,13 @@
<inFrontOfBody>true</inFrontOfBody>
<layerInvert>false</layerInvert>
<scaleWithPawnDrawsize>true</scaleWithPawnDrawsize>
<conditions>
<Apparel>
<hiddenUnderApparelTag>
<li>ARA_PowerArmor</li>
</hiddenUnderApparelTag>
</Apparel>
</conditions>
</li>
</bodyAddons>
</alienPartGenerator>
@@ -1984,7 +2056,7 @@
<alienPartGenerator>
<!-- 额外身体部件 -->
<bodyAddons>
<li>
<!-- <li>
<path>ArachnaeSwarm/Things/ARA_HiveNode/Addons/ArachnaeNode_Race_Addons_Fighter_Tail</path>
<inFrontOfBody>false</inFrontOfBody>
<scaleWithPawnDrawsize>true</scaleWithPawnDrawsize>
@@ -1993,7 +2065,7 @@
<layerOffset>-0.275</layerOffset>
</north>
</offsets>
</li>
</li> -->
</bodyAddons>
</alienPartGenerator>
</generalSettings>

View File

@@ -10,7 +10,7 @@
<graphicClass>Graphic_Single</graphicClass>
<drawSize>0.85</drawSize>
</graphicData>
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<statBases>
<MarketValue>10</MarketValue>
<Mass>0.5</Mass>
@@ -61,7 +61,7 @@
<ARA_IncubationCost>30</ARA_IncubationCost>
<ARA_IncubationTime>8</ARA_IncubationTime>
</statBases>
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<ingestible>
<drugCategory>Medical</drugCategory> <!-- 定义为医疗品,而非娱乐品 -->
<outcomeDoers>

View File

@@ -74,8 +74,9 @@
<label>Frost cloud</label>
<graphicData>
<texPath>Things/Gas/Puff</texPath>
<shaderType>MoteGlow</shaderType>
<drawSize>2.6</drawSize>
<color>(0.52, 1, 0.95,0.5)</color>
<color>(0.52, 1, 0.95,0.35)</color>
</graphicData>
<gas>
<expireSeconds>

View File

@@ -8,7 +8,7 @@
<graphicData>
<graphicClass>Graphic_Multi</graphicClass>
<drawSize>(1,1)</drawSize>
<texPath>ArachnaeSwarm/Apparel/ARA_Bunny_Girl_Uniform</texPath>
<texPath>ArachnaeSwarm/Apparel/ARA_Building_SpiderOne</texPath>
</graphicData>
<descriptionHyperlinks>
<ThingDef>ARA_SpiderOne_PowerArmor</ThingDef>
@@ -63,11 +63,29 @@
<tickerType>Normal</tickerType>
<modExtensions>
<li Class="ArachnaeSwarm.PowerArmorExtension">
<structurePointsMax>500</structurePointsMax>
<buildingDef>ARA_Building_SpiderOne</buildingDef>
<structurePointsMax>1000</structurePointsMax>
<fuelConsumptionRate>1.0</fuelConsumptionRate>
<hediffOnEmptyFuel>ARA_PowerArmor_NoFuel</hediffOnEmptyFuel>
<fuelConsumptionRate>0.5</fuelConsumptionRate>
<powerArmorWeapon>ARA_RW_Icez_Mortar_Turretgun</powerArmorWeapon>
<defaultWeaponSetIndex>0</defaultWeaponSetIndex>
<weaponSets>
<li>
<label>冻结武装</label>
<description>使用伤害较低但是能造成强大区域减益效果的冰冻系武器,以提高虫群面对敌方炮火的生存率。</description>
<weapon>ARA_RW_Icez_Mortar</weapon> <!-- 这里使用实际的武器定义 -->
<hediffsToAdd>
<!-- <li>ARA_CombatStim</li> -->
</hediffsToAdd>
</li>
<li>
<label>高能武装</label>
<description>使用拥有极致对单伤害的高能系武器,以快速点杀对方高价值目标。</description>
<weapon>ARA_RW_Lighting_Cannon</weapon> <!-- 这里使用实际的武器定义 -->
<hediffsToAdd>
<!-- <li>ARA_CombatStim</li> -->
</hediffsToAdd>
</li>
</weaponSets>
</li>
</modExtensions>
<recipeMaker>
@@ -82,6 +100,9 @@
<texPath>ArachnaeSwarm/Apparel/ARA_Bunny_Girl_Uniform</texPath>
</graphicData>
<apparel>
<tags>
<li>ARA_PowerArmor</li>
</tags>
<bodyPartGroups>
<li>Torso</li>
<li>Shoulders</li>
@@ -92,7 +113,14 @@
<!-- <li>OnSkin</li> -->
<li>Middle</li>
</layers>
<wornGraphicPath>ArachnaeSwarm/Apparel/ARA_Bunny_Girl_Uniform</wornGraphicPath>
<wornGraphicPath>ArachnaeSwarm/Apparel/ARA_SpiderOne_PowerArmor</wornGraphicPath>
<drawData>
<scale>2.1</scale>
<dataEast>
<layer>350</layer>
<offset>(0, 0, -0.4)</offset>
</dataEast>
</drawData>
</apparel>
<statBases>
<ARA_IncubationCost>120</ARA_IncubationCost>

View File

@@ -25,7 +25,7 @@
<thingSetMakerTags Inherit="False" />
<uiIconScale>1</uiIconScale>
<!-- <equippedAngleOffset>-65</equippedAngleOffset> -->
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<!-- <equippedAngleOffset>-25</equippedAngleOffset> -->
<costStuffCount>0</costStuffCount>
<stuffCategories Inherit="False" />
@@ -100,7 +100,7 @@
</graphicData>
<uiIconScale>1</uiIconScale>
<!-- <equippedAngleOffset>-65</equippedAngleOffset> -->
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<!-- <equippedAngleOffset>-25</equippedAngleOffset> -->
<costStuffCount>0</costStuffCount>
<stuffCategories Inherit="False" />
@@ -188,7 +188,7 @@
</graphicData>
<uiIconScale>0.8</uiIconScale>
<!-- <equippedAngleOffset>-65</equippedAngleOffset> -->
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<!-- <equippedAngleOffset>-25</equippedAngleOffset> -->
<costStuffCount>0</costStuffCount>
<stuffCategories Inherit="False" />
@@ -262,7 +262,7 @@
<label>武装器官"拳针枪"</label>
<description>阿拉克涅虫群督虫使用基础远程武装器官,外表就像一只拳套,可以通过神经束缠绕接在阿拉克涅督虫的辅肢上。这种武器小巧轻盈,虽然射程很短,但是面对敌人时能喷出一整排的带毒尖刺,把对手扎个透心凉。</description>
<tickerType>Normal</tickerType>
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Weapon</ThingDef>
</descriptionHyperlinks>
@@ -341,7 +341,8 @@
<li>ARA_BioforgeIncubator_Thing</li>
</cocoonDefs>
</li>
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon" MayRequire="Ludeon.RimWorld.Odyssey">
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon"
MayRequire="Ludeon.RimWorld.Odyssey">
<forcedTraits>
<li>ARA_Weapon_Damage_Toxid</li>
</forcedTraits>
@@ -374,7 +375,7 @@
<label>武装器官"风暴刺针枪"</label>
<description>阿拉克涅虫群督虫所使用的武装器官,拥有五排刺针管道,可以在联结神经束的指挥下交替发射大量的毒针,虽然准度较差但是威力不逊色于人类所使用的机枪。</description>
<tickerType>Normal</tickerType>
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Weapon_1Stage</ThingDef>
</descriptionHyperlinks>
@@ -439,7 +440,8 @@
<li>ARA_BioforgeIncubator_Thing</li>
</cocoonDefs>
</li>
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon" MayRequire="Ludeon.RimWorld.Odyssey">
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon"
MayRequire="Ludeon.RimWorld.Odyssey">
<forcedTraits>
<li>ARA_Weapon_Damage_Toxid</li>
</forcedTraits>
@@ -472,7 +474,7 @@
<label>武装器官"绽放刺枪"</label>
<description>阿拉克涅虫群督虫所使用的武装器官,拥有双联装多排刺针短程管道,发射精度较差但是一次可以发射大量弹药,威力丝毫不逊色于人类的霰弹枪。</description>
<tickerType>Normal</tickerType>
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Weapon_1Stage</ThingDef>
</descriptionHyperlinks>
@@ -537,7 +539,8 @@
<li>ARA_BioforgeIncubator_Thing</li>
</cocoonDefs>
</li>
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon" MayRequire="Ludeon.RimWorld.Odyssey">
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon"
MayRequire="Ludeon.RimWorld.Odyssey">
<forcedTraits>
<li>ARA_Weapon_Damage_Toxid</li>
</forcedTraits>
@@ -588,7 +591,7 @@
<label>武装器官"血链棘刺炮"</label>
<description>阿拉克涅虫群的大型武装器官,拥有张牙舞爪的侵略性外形,其口器与一连串可以增生巨型棘刺的血链相连,并通过肌肉压缩获得极高的膛压以射出腔内破坏力惊人的棘刺。虫群从人类的武器上获得了灵感,为血链刺加入了伴生激素,使得血链棘刺炮的射速会随着射击的持续而增加。</description>
<tickerType>Normal</tickerType>
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Weapon_2Stage</ThingDef>
</descriptionHyperlinks>
@@ -704,7 +707,7 @@
<label>武装器官"宽刃梭镖枪"</label>
<description>阿拉克涅虫群的武装器官,虽然体积不是很大,但是通过肌肉压缩射出的棘刺穿透力极强,可以打穿成排的敌军。除此之外,这种武装器官也在下颌增生了一把小型骨刃,以供虫群使用其抵御近身威胁。</description>
<tickerType>Normal</tickerType>
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Weapon_2Stage</ThingDef>
</descriptionHyperlinks>
@@ -767,7 +770,8 @@
<li>ARA_BioforgeIncubator_Thing</li>
</cocoonDefs>
</li>
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon" MayRequire="Ludeon.RimWorld.Odyssey">
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon"
MayRequire="Ludeon.RimWorld.Odyssey">
<forcedTraits>
<li>ARA_Weapon_OverPenetrate</li>
</forcedTraits>
@@ -803,7 +807,7 @@
<label>武装器官"酸液枪"</label>
<description>阿拉克涅虫群督虫使用基础远程武装器官,可以通过肌肉的瞬间加压喷出阿拉克涅酸液。这种酸液能覆盖目标并灼烧所有粘上酸液的敌人。</description>
<tickerType>Normal</tickerType>
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Weapon</ThingDef>
</descriptionHyperlinks>
@@ -870,7 +874,8 @@
<li>ARA_BioforgeIncubator_Thing</li>
</cocoonDefs>
</li>
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon" MayRequire="Ludeon.RimWorld.Odyssey">
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon"
MayRequire="Ludeon.RimWorld.Odyssey">
<forcedTraits>
<li>ARA_Weapon_Damage_Acid</li>
</forcedTraits>
@@ -915,7 +920,7 @@
<label>武装器官"炎酸炮"</label>
<description>阿拉克涅虫群的大型远程武装器官,拥有布满酸腺的液囊和强健的肌肉纤管,可以向瞄准的方向喷射火酸热熔气团,覆盖范围内的敌人并融化它们的装甲和血肉。</description>
<tickerType>Normal</tickerType>
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Weapon_1Stage</ThingDef>
</descriptionHyperlinks>
@@ -986,7 +991,8 @@
<li>ARA_BioforgeIncubator_Thing</li>
</cocoonDefs>
</li>
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon" MayRequire="Ludeon.RimWorld.Odyssey">
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon"
MayRequire="Ludeon.RimWorld.Odyssey">
<forcedTraits>
<li>ARA_Huge_Weapon</li>
<li>ARA_Weapon_Damage_Acid</li>
@@ -1068,7 +1074,7 @@
<label>武装器官"腐蚀臼炮"</label>
<description>阿拉克涅虫群督虫使用大型远程武装器官,膛内布满了强健的肌肉组织,可以在一瞬间的收缩后将一团酸液发射到空中,以在安全距离下对敌人的集群进行轰炸。</description>
<tickerType>Normal</tickerType>
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Weapon_2Stage</ThingDef>
</descriptionHyperlinks>
@@ -1136,7 +1142,8 @@
<li>ARA_BioforgeIncubator_Thing</li>
</cocoonDefs>
</li>
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon" MayRequire="Ludeon.RimWorld.Odyssey">
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon"
MayRequire="Ludeon.RimWorld.Odyssey">
<forcedTraits>
<li>ARA_Huge_Weapon</li>
<li>ARA_Weapon_Damage_Acid</li>
@@ -1190,7 +1197,7 @@
<label>武装器官"双眼天灾枪"</label>
<description>阿拉克涅虫群督虫使用基础远程武装器官,状似人类的手枪,可以发射由爆裂种辅虫构成的导弹。这种武装器官适应性和追踪能力很强,即使是不擅长射击的虫族使用这种武器也能有很好的表现。</description>
<tickerType>Normal</tickerType>
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Weapon_2Stage</ThingDef>
</descriptionHyperlinks>
@@ -1325,7 +1332,7 @@
<label>武装器官"迅发天灾炮"</label>
<description>阿拉克涅虫群的大型武装器官,可以以排山倒海的架势射出成排由爆裂种辅虫构成的导弹,强大的火力使其成为虫族构建血肉军团的核心之一。</description>
<tickerType>Normal</tickerType>
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Weapon_2Stage</ThingDef>
</descriptionHyperlinks>
@@ -1460,7 +1467,7 @@
<label>武装器官"天巢种之巢"</label>
<description>阿拉克涅虫群督虫使用的远程武装器官,内部的腔室孕育了大量的天巢种,督虫们会将其作为导弹发射出去,这些天巢种在敌人后将持续啃咬敌人一段时间,并且从敌人身上脱落后也将继续攻击。</description>
<tickerType>Normal</tickerType>
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Weapon_1Stage</ThingDef>
</descriptionHyperlinks>
@@ -1527,7 +1534,8 @@
<li>ARA_BioforgeIncubator_Thing</li>
</cocoonDefs>
</li>
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon" MayRequire="Ludeon.RimWorld.Odyssey">
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon"
MayRequire="Ludeon.RimWorld.Odyssey">
<forcedTraits>
<li>ARA_Weapon_Damage_Spawn</li>
</forcedTraits>
@@ -1593,7 +1601,7 @@
<label>武装器官"生物电导线"</label>
<description>阿拉克涅虫群督虫使用的大型远程武装器官,通过从携带大量电荷的细胞中释放能量,虫群可以使用这种武装器官在敌人的集群中发起连锁闪电打击。</description>
<tickerType>Normal</tickerType>
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Weapon_1Stage</ThingDef>
</descriptionHyperlinks>
@@ -1644,7 +1652,8 @@
<beamGroundFleckDef>Fleck_BeamBurn</beamGroundFleckDef>
<beamFleckChancePerTick>0.32</beamFleckChancePerTick>
<beamEndEffecterDef>GraserBeam_End</beamEndEffecterDef>
<beamLineFleckDef>ARA_Arc_Beam_Fleck</beamLineFleckDef> <!-- Fallback for base verb properties -->
<beamLineFleckDef>ARA_Arc_Beam_Fleck</beamLineFleckDef> <!-- Fallback for base verb
properties -->
<beamCurvature>1</beamCurvature> <!-- 让光束更弯曲一点 -->
<flecksPerCell>1</flecksPerCell>
@@ -1684,7 +1693,8 @@
<li>ARA_BioforgeIncubator_Thing</li>
</cocoonDefs>
</li>
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon" MayRequire="Ludeon.RimWorld.Odyssey">
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon"
MayRequire="Ludeon.RimWorld.Odyssey">
<forcedTraits>
<li>ARA_Huge_Weapon</li>
<li>ARA_Weapon_Damage_LightingChain</li>
@@ -1742,7 +1752,7 @@
</graphicData>
<uiIconScale>1</uiIconScale>
<!-- <equippedAngleOffset>-65</equippedAngleOffset> -->
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<!-- <equippedAngleOffset>-25</equippedAngleOffset> -->
<costStuffCount>0</costStuffCount>
<stuffCategories Inherit="False" />
@@ -1971,7 +1981,7 @@
<label>武装器官"霜星之巢"</label>
<description>一种特殊的远程武装器官,只会在阿拉克涅的共生肌群上出现。其可以发射成排极度冰冷的霜冻气团,冻结目标区域的敌军,使其受到冻伤伤害的同时变得行动缓慢。</description>
<tickerType>Normal</tickerType>
<techLevel>Animal</techLevel>
<techLevel>Medieval</techLevel>
<graphicData>
<texPath>ArachnaeSwarm/Weapon/ARA_RW_Acid_Mortar</texPath>
<graphicClass>Graphic_Single</graphicClass>
@@ -2079,4 +2089,130 @@
<recipeMaker Inherit="False">
</recipeMaker>
</ThingDef>
<ThingDef ParentName="BaseWeaponTurret">
<defName>ARA_RW_Lighting_Cannon</defName>
<label>武装器官"透镜管"</label>
<description>一种特殊的远程武装器官,只会在阿拉克涅的共生肌群上出现。其高精度的透镜可以在经过短暂的瞄准后可以汇聚恐怖的生物能,直接转化为高能射线融化目标。由于其预热机制,它在切换目标时很费劲,但是一旦被其盯上将顷刻气化。</description>
<tradeability>None</tradeability>
<destroyOnDrop>true</destroyOnDrop>
<graphicData>
<texPath>ArachnaeSwarm/Weapon/ARA_RW_Acid_Mortar</texPath>
<graphicClass>Graphic_Single</graphicClass>
<drawSize>1.5</drawSize>
</graphicData>
<statBases>
<Mass>2.6</Mass>
<AccuracyTouch>0.60</AccuracyTouch>
<AccuracyShort>0.80</AccuracyShort>
<AccuracyMedium>0.90</AccuracyMedium>
<AccuracyLong>0.85</AccuracyLong>
<RangedWeapon_Cooldown>0</RangedWeapon_Cooldown>
</statBases>
<verbs>
<li Class="ArachnaeSwarm.VerbPropertiesExplosiveBeam">
<verbClass>ArachnaeSwarm.Verb_ShootBeamExplosive</verbClass>
<!-- 基础射线参数 -->
<hasStandardCommand>true</hasStandardCommand>
<warmupTime>5</warmupTime>
<range>45</range>
<burstShotCount>3</burstShotCount>
<ticksBetweenBurstShots>1</ticksBetweenBurstShots>
<beamDamageDef>ARA_Beam</beamDamageDef>
<!-- 消除射线偏移的参数 -->
<beamFullWidthRange>1000</beamFullWidthRange>
<beamWidth>-1</beamWidth>
<beamMaxDeviation>0</beamMaxDeviation>
<beamCurvature>0</beamCurvature>
<beamStartOffset>0</beamStartOffset>
<!-- 视觉和音效 -->
<muzzleFlashScale>0</muzzleFlashScale>
<soundCastBeam>BeamGraser_Shooting</soundCastBeam>
<beamGroundFleckDef>Fleck_BeamBurn</beamGroundFleckDef>
<beamFleckChancePerTick>0.32</beamFleckChancePerTick>
<beamMoteDef>Mote_ARA_RW_Lighting_Cannon_Beam</beamMoteDef>
<beamEndEffecterDef>GraserBeam_End</beamEndEffecterDef>
<screenShakeFactor>0.35</screenShakeFactor>
<!-- 火焰效果 -->
<beamChanceToStartFire>0.6</beamChanceToStartFire>
<beamChanceToAttachFire>0.6</beamChanceToAttachFire>
<beamFireSizeRange>0.25</beamFireSizeRange>
<!-- 其他射线属性 -->
<beamHitsNeighborCells>true</beamHitsNeighborCells>
<beamLineFleckChanceCurve>
<points>
<li>(0, 0)</li>
<li>(0.65, 0.4)</li>
<li>(1, 0.75)</li>
</points>
</beamLineFleckChanceCurve>
<!-- 攻击目标设置 -->
<targetParams>
<canTargetLocations>true</canTargetLocations>
</targetParams>
<!-- 每发都爆炸 -->
<enableExplosion>false</enableExplosion>
<!-- <explosionShotInterval>1</explosionShotInterval>
<explosionRadius>0</explosionRadius>
<explosionDamageDef>Wula_Dark_Matter_Flame</explosionDamageDef>
<explosionDamage>15</explosionDamage>
<explosionSound>Explosion_Bomb</explosionSound>
<chanceToStartFire>0.6</chanceToStartFire> -->
</li>
</verbs>
<generateCommonality>0</generateCommonality>
<tradeability>None</tradeability>
<thingSetMakerTags Inherit="False" />
<comps>
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon" MayRequire="Ludeon.RimWorld.Odyssey">
<forcedTraits>
<li>ARA_Huge_Weapon</li>
<li>ARA_Weapon_ChainReload</li>
</forcedTraits>
<numTraitsRange>
<min>2</min>
<max>2</max>
</numTraitsRange>
</li>
<li Class="ArachnaeSwarm.CompProperties_GiveHediffOnShot">
<hediffDef>ARA_BeamAiming</hediffDef>
<severityToAdd>1</severityToAdd>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="MoteBase">
<defName>Mote_ARA_RW_Lighting_Cannon_Beam</defName>
<thingClass>MoteDualAttached</thingClass>
<altitudeLayer>MoteOverhead</altitudeLayer>
<mote>
<fadeInTime>0.2</fadeInTime>
<fadeOutTime>0.3</fadeOutTime>
<solidTime>999999</solidTime>
<needsMaintenance>True</needsMaintenance>
<rotateTowardsTarget>True</rotateTowardsTarget>
<scaleToConnectTargets>True</scaleToConnectTargets>
<fadeOutUnmaintained>True</fadeOutUnmaintained>
</mote>
<drawOffscreen>true</drawOffscreen>
<graphicData>
<texPath>Things/Mote/GraserBeam</texPath>
<color>(249, 28, 35, 255)</color>
<graphicClass>Graphic_MoteWithAgeSecs</graphicClass>
<shaderType>MoteBeam</shaderType>
<shaderParameters>
<_ExtraTexA>/Things/Mote/BeamSecondaryNoise_A</_ExtraTexA>
<_ExtraTexB>/Things/Mote/BeamSecondaryNoise_B</_ExtraTexB>
<_ScrollSpeedA>-4 </_ScrollSpeedA>
<_ScrollSpeedB>3</_ScrollSpeedB>
<_Intensity>2</_Intensity>
</shaderParameters>
</graphicData>
</ThingDef>
</Defs>

View File

@@ -227,6 +227,7 @@
<ThingDef>ArachnaeNode_Race_WeaponSmith</ThingDef>
<ThingDef>ArachnaeNode_Race_Fighter</ThingDef>
<ThingDef>ArachnaeNode_Race_Facehugger</ThingDef>
<ThingDef>ArachnaeNode_Race_MimicNematode</ThingDef>
</descriptionHyperlinks>
<graphicData>
<drawSize>(1.2,1.2)</drawSize>
@@ -260,6 +261,11 @@
<delayTicks>120000</delayTicks>
<requiredResearch>ARA_Technology_4KYC</requiredResearch>
</li>
<li>
<pawnKind>ARA_MimicNematodeShamblerSwarmer</pawnKind>
<delayTicks>600</delayTicks>
<requiredResearch>ARA_Technology_6MEN</requiredResearch>
</li>
</spawnablePawns>
<whitelist>
<li>ARA_ArachnaeQueen</li>
@@ -363,6 +369,7 @@
<ThingDef>ArachnaeNode_Race_WeaponSmith</ThingDef>
<ThingDef>ArachnaeNode_Race_Fighter</ThingDef>
<ThingDef>ArachnaeNode_Race_Facehugger</ThingDef>
<ThingDef>ArachnaeNode_Race_MimicNematode</ThingDef>
</descriptionHyperlinks>
<graphicData>
<drawSize>(1.2,1.2)</drawSize>
@@ -399,7 +406,7 @@
<li>
<pawnKind>ARA_MimicNematodeShamblerSwarmer</pawnKind>
<delayTicks>60000</delayTicks>
<requiredResearch>ARA_Technology_2MED</requiredResearch>
<requiredResearch>ARA_Technology_6MEN</requiredResearch>
</li>
</spawnablePawns>
<whitelist>
@@ -1408,7 +1415,7 @@
<showAllowAutoRefuelToggle>false</showAllowAutoRefuelToggle>
<initialFuelPercent>0.2</initialFuelPercent>
<autoRefuelPercent>1</autoRefuelPercent>
<initialConfigurableTargetFuelLevel>999</initialConfigurableTargetFuelLevel>
<initialConfigurableTargetFuelLevel>30</initialConfigurableTargetFuelLevel>
</li>
</comps>
</ThingDef>
@@ -1429,7 +1436,7 @@
<showAllowAutoRefuelToggle>false</showAllowAutoRefuelToggle>
<initialFuelPercent>1</initialFuelPercent>
<autoRefuelPercent>1</autoRefuelPercent>
<initialConfigurableTargetFuelLevel>999</initialConfigurableTargetFuelLevel>
<initialConfigurableTargetFuelLevel>30</initialConfigurableTargetFuelLevel>
</li>
</comps>
</ThingDef>

View File

@@ -527,9 +527,9 @@
</li>
<li>
<pawnKind>ARA_MimicNematodeShamblerSwarmer</pawnKind>
<delayTicks>60000</delayTicks>
<delayTicks>600</delayTicks>
<totalNutritionNeeded>10.0</totalNutritionNeeded>
<requiredResearch>ARA_Technology_2MED</requiredResearch>
<requiredResearch>ARA_Technology_6MEN</requiredResearch>
</li>
</spawnablePawns>
</li>

View File

@@ -124,26 +124,23 @@
<comps>
<li Class="CompProperties_Forbiddable"/>
<li Class="ArachnaeSwarm.CompProperties_ForceTargetable" />
<li Class="CompProperties_Refuelable">
<fuelLabel>弹药</fuelLabel>
<fuelGizmoLabel>弹药</fuelGizmoLabel>
<outOfFuelMessage>缺少弹药</outOfFuelMessage>
<li Class="ArachnaeSwarm.CompProperties_RefuelableNutrition_WithKey">
<saveKeysPrefix>nutrition</saveKeysPrefix>
<fuelCapacity>3</fuelCapacity>
<initialFuelPercent>1</initialFuelPercent>
<fuelFilter>
<thingDefs>
<li>ARA_DummyAmmo</li>
<li>ARA_InsectJelly</li>
</thingDefs>
</fuelFilter>
<fuelCapacity>26</fuelCapacity>
<initialFuelPercent>1</initialFuelPercent>
<autoRefuelPercent>1</autoRefuelPercent>
<showFuelGizmo>true</showFuelGizmo>
<fuelGizmoLabel>虫蜜</fuelGizmoLabel>
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
<targetFuelLevelConfigurable>true</targetFuelLevelConfigurable>
<consumeFuelOnlyWhenUsed>true</consumeFuelOnlyWhenUsed>
<destroyOnNoFuel>true</destroyOnNoFuel>
</li>
<li Class="CompProperties_MechPowerCell">
<totalPowerTicks>600000</totalPowerTicks>
<killWhenDepleted>false</killWhenDepleted>
<labelOverride>寿命</labelOverride>
<tooltipOverride>这种半植物生命的寿命转瞬即逝。</tooltipOverride>
<li Class="CompProperties_Lifespan">
<lifespanTicks>3600000</lifespanTicks>
</li>
</comps>
<passability>PassThroughOnly</passability>
@@ -195,7 +192,7 @@
<burstShotCount>2</burstShotCount>
<soundCast>SpitterSpit</soundCast>
<muzzleFlashScale>9</muzzleFlashScale>
<consumeFuelPerShot>1</consumeFuelPerShot>
<consumeFuelPerShot>0.05</consumeFuelPerShot>
</li>
</verbs>
</ThingDef>
@@ -245,7 +242,7 @@
<!-- 正确的配置方式 -->
<modExtensions>
<li Class="ArachnaeSwarm.TrapReleaseRandomExtension">
<detectionRadius>25</detectionRadius>
<detectionRadius>5</detectionRadius>
<countToSpawn>3</countToSpawn>
<pawnKinds>
<li>ArachnaeBase_Race_Acidling</li>
@@ -301,7 +298,9 @@
<li Class="CompProperties_Forbiddable" />
<li Class="ArachnaeSwarm.CompProperties_RefuelableNutrition_WithKey">
<saveKeysPrefix>nutrition</saveKeysPrefix>
<fuelCapacity>5.0</fuelCapacity>
<fuelCapacity>100.0</fuelCapacity>
<initialConfigurableTargetFuelLevel>100</initialConfigurableTargetFuelLevel>
<initialFuelPercent>1</initialFuelPercent>
<fuelFilter>
<thingDefs>
<li>ARA_InsectJelly</li>
@@ -312,29 +311,6 @@
<targetFuelLevelConfigurable>true</targetFuelLevelConfigurable>
<consumeFuelOnlyWhenUsed>true</consumeFuelOnlyWhenUsed>
</li>
<li Class="CompProperties_Refuelable">
<fuelLabel>弹药</fuelLabel>
<fuelGizmoLabel>弹药</fuelGizmoLabel>
<outOfFuelMessage>缺少弹药</outOfFuelMessage>
<fuelFilter>
<thingDefs>
<li>ARA_DummyAmmo</li>
</thingDefs>
</fuelFilter>
<fuelCapacity>100</fuelCapacity>
<initialFuelPercent>1</initialFuelPercent>
<autoRefuelPercent>1</autoRefuelPercent>
<showFuelGizmo>true</showFuelGizmo>
<consumeFuelOnlyWhenUsed>true</consumeFuelOnlyWhenUsed>
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
<targetFuelLevelConfigurable>true</targetFuelLevelConfigurable>
</li>
<li Class="ArachnaeSwarm.CompProperties_NutritionToFuelConverter">
<checkInterval>300</checkInterval>
<nutritionCost>1</nutritionCost>
<workAmount>300</workAmount>
<fuelAmount>50</fuelAmount>
</li>
<li Class="ArachnaeSwarm.CompProperties_ForceTargetable" />
<li Class="ArachnaeSwarm.CompProperties_DelayedTerrainSpawn">
<terrainToSpawn>ARA_InsectCreep</terrainToSpawn>
@@ -464,7 +440,8 @@
<li Class="CompProperties_Forbiddable" />
<li Class="ArachnaeSwarm.CompProperties_RefuelableNutrition_WithKey">
<saveKeysPrefix>nutrition</saveKeysPrefix>
<fuelCapacity>5.0</fuelCapacity>
<fuelCapacity>18</fuelCapacity>
<initialFuelPercent>1</initialFuelPercent>
<fuelFilter>
<thingDefs>
<li>ARA_InsectJelly</li>
@@ -475,29 +452,6 @@
<targetFuelLevelConfigurable>true</targetFuelLevelConfigurable>
<consumeFuelOnlyWhenUsed>true</consumeFuelOnlyWhenUsed>
</li>
<li Class="CompProperties_Refuelable">
<fuelLabel>弹药</fuelLabel>
<fuelGizmoLabel>弹药</fuelGizmoLabel>
<outOfFuelMessage>缺少弹药</outOfFuelMessage>
<fuelFilter>
<thingDefs>
<li>ARA_DummyAmmo</li>
</thingDefs>
</fuelFilter>
<fuelCapacity>20</fuelCapacity>
<initialFuelPercent>1</initialFuelPercent>
<autoRefuelPercent>1</autoRefuelPercent>
<showFuelGizmo>true</showFuelGizmo>
<consumeFuelOnlyWhenUsed>true</consumeFuelOnlyWhenUsed>
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
<targetFuelLevelConfigurable>true</targetFuelLevelConfigurable>
</li>
<li Class="ArachnaeSwarm.CompProperties_NutritionToFuelConverter">
<checkInterval>300</checkInterval>
<nutritionCost>0.5</nutritionCost>
<workAmount>600</workAmount>
<fuelAmount>1</fuelAmount>
</li>
<li Class="ArachnaeSwarm.CompProperties_ForceTargetable" />
<li Class="ArachnaeSwarm.CompProperties_DelayedTerrainSpawn">
<terrainToSpawn>ARA_InsectCreep</terrainToSpawn>
@@ -580,7 +534,7 @@
<soundCastTail>GunTail_Light</soundCastTail>
<muzzleFlashScale>16</muzzleFlashScale>
<requireLineOfSight>false</requireLineOfSight>
<consumeFuelPerShot>0.5</consumeFuelPerShot>
<consumeFuelPerShot>3</consumeFuelPerShot>
<targetParams>
<canTargetLocations>true</canTargetLocations>
</targetParams>
@@ -650,7 +604,7 @@
<comps>
<li Class="ArachnaeSwarm.CompProperties_RefuelableNutrition_WithKey">
<saveKeysPrefix>nutrition</saveKeysPrefix>
<fuelCapacity>5.0</fuelCapacity>
<fuelCapacity>50.0</fuelCapacity>
<fuelFilter>
<thingDefs>
<li>ARA_InsectJelly</li>
@@ -661,29 +615,6 @@
<targetFuelLevelConfigurable>true</targetFuelLevelConfigurable>
<consumeFuelOnlyWhenUsed>true</consumeFuelOnlyWhenUsed>
</li>
<li Class="CompProperties_Refuelable">
<fuelLabel>导弹</fuelLabel>
<fuelGizmoLabel>导弹</fuelGizmoLabel>
<outOfFuelMessage>缺少导弹</outOfFuelMessage>
<fuelFilter>
<thingDefs>
<li>ARA_CatastropheMissile_Shell</li>
</thingDefs>
</fuelFilter>
<fuelCapacity>10</fuelCapacity>
<initialFuelPercent>0</initialFuelPercent>
<autoRefuelPercent>1</autoRefuelPercent>
<showFuelGizmo>true</showFuelGizmo>
<consumeFuelOnlyWhenUsed>true</consumeFuelOnlyWhenUsed>
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
<targetFuelLevelConfigurable>true</targetFuelLevelConfigurable>
</li>
<li Class="ArachnaeSwarm.CompProperties_NutritionToFuelConverter">
<checkInterval>300</checkInterval>
<nutritionCost>20</nutritionCost>
<workAmount>6000</workAmount>
<fuelAmount>1</fuelAmount>
</li>
<li Class="CompProperties_Forbiddable" />
<li Class="CompProperties_Breakdownable" />
<li Class="ArachnaeSwarm.CompProperties_ForceTargetable" />
@@ -750,7 +681,7 @@
<verbClass>ArachnaeSwarm.Verb_ShootWithOffset</verbClass>
<hasStandardCommand>true</hasStandardCommand>
<defaultProjectile>Projectile_CatastropheMissile</defaultProjectile>
<consumeFuelPerShot>1</consumeFuelPerShot>
<consumeFuelPerShot>10</consumeFuelPerShot>
<warmupTime>3.0</warmupTime>
<forcedMissRadius>1</forcedMissRadius>
<isMortar>true</isMortar>

View File

@@ -214,7 +214,7 @@
</li>
<!-- Eat random things out of curiosity -->
<li Class="ThinkNode_ChancePerHour_Constant">
<!-- <li Class="ThinkNode_ChancePerHour_Constant">
<mtbDays>60</mtbDays>
<subNodes>
<li Class="ThinkNode_Tagger">
@@ -224,7 +224,7 @@
</subNodes>
</li>
</subNodes>
</li>
</li> -->
<!-- Satisfy basic needs -->
<li Class="ThinkNode_Subtree">

View File

@@ -1,12 +1,31 @@
<?xml version="1.0" encoding="utf-8" ?>
<LanguageData>
<!-- Power Armor Interaction -->
<EnterPowerArmor>进入 {0}</EnterPowerArmor>
<CannotEnterPowerArmor>无法进入外骨骼</CannotEnterPowerArmor>
<PowerArmorBroken>{0} 已经被损毁!</PowerArmorBroken>
<!-- Job Reports -->
<ARA_EnterPowerArmor>进入动力甲</ARA_EnterPowerArmor>
<!-- Gizmo Labels -->
<StructurePoints>结构点</StructurePoints>
<!-- Messages -->
<PowerArmorBroken>{0} 已被摧毁!驾驶员 {1} 被暴露在外。</PowerArmorBroken>
<!-- 武装方案相关 -->
<ARA_UnknownScheme>未知</ARA_UnknownScheme>
<ARA_SchemeFormat>方案 {0}</ARA_SchemeFormat>
<!-- 消息提示 -->
<ARA_PowerArmorDamaged>动力装甲损坏</ARA_PowerArmorDamaged>
<ARA_SwitchedToMode>已切换至{0}模式</ARA_SwitchedToMode>
<ARA_EquipPowerArmorFailed>装备动力装甲失败:配置错误</ARA_EquipPowerArmorFailed>
<ARA_AlreadySelectedScheme>当前已选择此方案</ARA_AlreadySelectedScheme>
<!-- Gizmo 按钮文本 -->
<ARA_SwitchWeapon>切换武装: {0}</ARA_SwitchWeapon>
<ARA_SwitchWeaponDesc>切换到下一个武装配置方案\n当前: {0}\n可用方案: {1}</ARA_SwitchWeaponDesc>
<ARA_SwitchToScheme>直接切换到{0}</ARA_SwitchToScheme>
<!-- 默认值 -->
<ARA_Default>默认</ARA_Default>
</LanguageData>

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<LanguageData>
<!-- Job Reports -->
<ARA_EnterPowerArmor>进入动力甲</ARA_EnterPowerArmor>
<!-- Gizmo Labels -->
<StructurePoints>结构点</StructurePoints>
<!-- Messages -->
<PowerArmorBroken>{0} 已被摧毁!驾驶员 {1} 被暴露在外。</PowerArmorBroken>
</LanguageData>

View File

@@ -3,13 +3,41 @@
"WorkspaceRootPath": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\building_comps\\compnutritiontofuelconverter.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\compnutritiontofuelconverter.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\powerarmor\\ara_powerarmor.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:powerarmor\\ara_powerarmor.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\building_comps\\ara_compinteractiveproducer\\compinteractiveproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\powerarmor\\jobdriver_enterpowerarmor.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:powerarmor\\jobdriver_enterpowerarmor.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\powerarmor\\comppowerarmorstation.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:powerarmor\\comppowerarmorstation.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\powerarmor\\gizmo_structurepanel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:powerarmor\\gizmo_structurepanel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|E:\\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|E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\building_comps\\ara_nutrientvat\\building_nutrientvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_nutrientvat\\building_nutrientvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\building_comps\\ara_building_refuelingvat\\building_refuelingvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_building_refuelingvat\\building_refuelingvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\building_comps\\ara_compinteractiveproducer\\compinteractiveproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_compinteractiveproducer\\compinteractiveproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\building_comps\\compnutritiontofuelconverter.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\compnutritiontofuelconverter.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\building_comps\\ara_compinteractiveproducer\\compresearchproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_compinteractiveproducer\\compresearchproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
@@ -22,28 +50,114 @@
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 1,
"SelectedChildIndex": 4,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "CompPowerArmorStation.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PowerArmor\\CompPowerArmorStation.cs",
"RelativeDocumentMoniker": "PowerArmor\\CompPowerArmorStation.cs",
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PowerArmor\\CompPowerArmorStation.cs",
"RelativeToolTip": "PowerArmor\\CompPowerArmorStation.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAwAAAAmAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-18T16:40:43.953Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "JobDriver_EnterPowerArmor.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PowerArmor\\JobDriver_EnterPowerArmor.cs",
"RelativeDocumentMoniker": "PowerArmor\\JobDriver_EnterPowerArmor.cs",
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PowerArmor\\JobDriver_EnterPowerArmor.cs",
"RelativeToolTip": "PowerArmor\\JobDriver_EnterPowerArmor.cs",
"ViewState": "AgIAAGUAAAAAAAAAAAAAAIwAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-18T16:33:18.657Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "Gizmo_StructurePanel.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PowerArmor\\Gizmo_StructurePanel.cs",
"RelativeDocumentMoniker": "PowerArmor\\Gizmo_StructurePanel.cs",
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PowerArmor\\Gizmo_StructurePanel.cs",
"RelativeToolTip": "PowerArmor\\Gizmo_StructurePanel.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-18T16:32:53.277Z"
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "ARA_PowerArmor.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PowerArmor\\ARA_PowerArmor.cs",
"RelativeDocumentMoniker": "PowerArmor\\ARA_PowerArmor.cs",
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PowerArmor\\ARA_PowerArmor.cs",
"RelativeToolTip": "PowerArmor\\ARA_PowerArmor.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAACQAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-18T16:30:55.497Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 4,
"Title": "CompAbilityEffect_Possess.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HuggingFace\\CompAbilityEffect_Possess.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_HuggingFace\\CompAbilityEffect_Possess.cs",
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HuggingFace\\CompAbilityEffect_Possess.cs",
"RelativeToolTip": "Abilities\\ARA_HuggingFace\\CompAbilityEffect_Possess.cs",
"ViewState": "AgIAACwAAAAAAAAAAAAkwDsAAAAtAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-18T13:31:46.288Z"
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "Building_NutrientVat.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_NutrientVat\\Building_NutrientVat.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_NutrientVat\\Building_NutrientVat.cs",
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_NutrientVat\\Building_NutrientVat.cs",
"RelativeToolTip": "Building_Comps\\ARA_NutrientVat\\Building_NutrientVat.cs",
"ViewState": "AgIAAAgAAAAAAAAAAAAQwBAAAAAIAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-18T11:56:31.022Z"
},
{
"$type": "Document",
"DocumentIndex": 6,
"Title": "Building_RefuelingVat.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
"RelativeToolTip": "Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
"ViewState": "AgIAAGcAAAAAAAAAAAAAAI4AAAAgAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-18T11:56:12.333Z"
},
{
"$type": "Document",
"DocumentIndex": 8,
"Title": "CompNutritionToFuelConverter.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\CompNutritionToFuelConverter.cs",
"RelativeDocumentMoniker": "Building_Comps\\CompNutritionToFuelConverter.cs",
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\CompNutritionToFuelConverter.cs",
"RelativeToolTip": "Building_Comps\\CompNutritionToFuelConverter.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAKEAAAAcAAAAAAAAAA==",
"ViewState": "AgIAAGEAAAAAAAAAAAAQwHYAAAAJAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-17T11:32:00.484Z",
"EditorCaption": ""
"WhenOpened": "2025-10-17T11:32:00.484Z"
},
{
"$type": "Document",
"DocumentIndex": 2,
"DocumentIndex": 9,
"Title": "CompResearchProducer.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CompInteractiveProducer\\CompResearchProducer.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_CompInteractiveProducer\\CompResearchProducer.cs",
@@ -55,16 +169,15 @@
},
{
"$type": "Document",
"DocumentIndex": 1,
"DocumentIndex": 7,
"Title": "CompInteractiveProducer.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CompInteractiveProducer\\CompInteractiveProducer.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_CompInteractiveProducer\\CompInteractiveProducer.cs",
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CompInteractiveProducer\\CompInteractiveProducer.cs",
"RelativeToolTip": "Building_Comps\\ARA_CompInteractiveProducer\\CompInteractiveProducer.cs",
"ViewState": "AgIAAJYBAAAAAAAAAAAUwKoBAAAAAAAAAAAAAA==",
"ViewState": "AgIAAAwAAAAAAAAAAAAgwGYAAABWAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-17T09:00:51.526Z",
"EditorCaption": ""
"WhenOpened": "2025-10-17T09:00:51.526Z"
}
]
}

View File

@@ -40,8 +40,76 @@ namespace ArachnaeSwarm
public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
{
base.Apply(target, dest);
// 新增:检查目标是否无法行动(倒地)
if (target.Pawn != null && IsTargetImmobilized(target.Pawn))
{
Log.Message($"[夺舍] 目标 {target.Pawn.LabelShort} 无法行动,直接执行夺舍");
DoPossession(this.parent.pawn, target.Pawn);
}
else
{
Log.Message($"[夺舍] 目标可以行动,执行标准夺舍流程");
DoPossession(this.parent.pawn, target.Pawn);
}
}
// 新增:检查目标是否无法行动
private bool IsTargetImmobilized(Pawn target)
{
if (target == null) return false;
// 检查是否倒地
if (target.Downed)
{
Log.Message($"[夺舍] 目标 {target.LabelShort} 处于倒地状态");
return true;
}
// 检查是否无法移动
if (!target.health.capacities.CapableOf(PawnCapacityDefOf.Moving))
{
Log.Message($"[夺舍] 目标 {target.LabelShort} 无法移动");
return true;
}
// 检查是否有严重的移动障碍
if (target.health.hediffSet.HasHediff(HediffDefOf.Anesthetic) ||
target.health.hediffSet.HasHediff(HediffDefOf.CryptosleepSickness) ||
target.health.hediffSet.HasHediff(HediffDefOf.FoodPoisoning))
{
Log.Message($"[夺舍] 目标 {target.LabelShort} 有严重的移动障碍");
return true;
}
// 检查是否被束缚或囚禁
if (target.IsPrisoner || target.HostFaction != null)
{
Log.Message($"[夺舍] 目标 {target.LabelShort} 被囚禁或束缚");
return true;
}
return false;
}
// 新增:计算寄生成功率
private float CalculateSuccessChance(Pawn targetPawn, float damageDealt = 0f)
{
// 如果目标无法行动100%成功率
if (IsTargetImmobilized(targetPawn))
{
Log.Message($"[夺舍] 目标 {targetPawn.LabelShort} 无法行动,寄生成功率: 100%");
return 1f;
}
// 正常计算成功率
float baseChance = Props.successChance.RandomInRange;
float bonusFromDamage = damageDealt * Props.successChanceBonusPerDamage;
float finalChance = Mathf.Clamp01(baseChance + bonusFromDamage);
Log.Message($"[夺舍] 目标 {targetPawn.LabelShort} 可以行动,寄生成功率: {finalChance:P0} (基础: {baseChance:P0}, 伤害加成: {bonusFromDamage:P0})");
return finalChance;
}
private void DoPossession(Pawn caster, Pawn targetPawn)
{
@@ -146,10 +214,10 @@ namespace ArachnaeSwarm
if (damageResult.totalDamageDealt > 0)
{
float baseChance = Props.successChance.RandomInRange;
float bonusFromDamage = damageResult.totalDamageDealt * Props.successChanceBonusPerDamage;
float finalChance = Mathf.Clamp01(baseChance + bonusFromDamage);
Log.Message($"[Possess] Base chance: {baseChance}, Bonus: {bonusFromDamage}, Final chance: {finalChance}");
// 修改:使用新的成功率计算方法
float finalChance = CalculateSuccessChance(targetPawn, damageResult.totalDamageDealt);
Log.Message($"[Possess] Final chance: {finalChance:P0}");
if (Rand.Chance(finalChance))
{

View File

@@ -130,7 +130,7 @@ namespace ArachnaeSwarm
DamageInfo acidDamage = new DamageInfo(
acidDamageDef,
0.1f, // 每次0.1点伤害
1.5f, // 每次1.5点伤害
2f, // 护甲穿透
-1f, // 随机角度
instigator: null,

View File

@@ -38,6 +38,11 @@ namespace ArachnaeSwarm
private int spawnTick = -1; // 新增:记录生成时间
private const int COOLDOWN_TICKS = 120; // 新增120 tick冷却时间
// 新增:修复负时间相关字段
private int lastNegativeTimeCheckTick = -1;
private const int NEGATIVE_TIME_CHECK_INTERVAL = 60; // 每60ticks检查一次
private bool hasFixedNegativeTime = false; // 标记是否已经修复过负时间问题
private CompRefuelableNutrition _fuelComp;
private static readonly Texture2D CancelIcon = ContentFinder<Texture2D>.Get("UI/Designators/Cancel");
@@ -79,6 +84,83 @@ namespace ArachnaeSwarm
}
}
// 新增获取剩余生产时间ticks
public int RemainingProductionTicks
{
get
{
if (!InProduction || productionUntilTick <= 0) return 0;
return Mathf.Max(0, productionUntilTick - Find.TickManager.TicksGame);
}
}
// 新增:检查是否存在负时间问题
private bool HasNegativeTimeProblem
{
get
{
if (!InProduction || productionUntilTick <= 0) return false;
int remainingTicks = productionUntilTick - Find.TickManager.TicksGame;
return remainingTicks < -10; // 小于-10ticks认为有问题
}
}
// 新增:修复负时间问题
private void FixNegativeTimeProblem()
{
if (!InProduction || _selectedProcess == null)
{
Log.Warning($"Attempted to fix negative time but no process is selected. Resetting production.");
ResetProduction();
return;
}
int currentTicks = Find.TickManager.TicksGame;
int remainingTicks = productionUntilTick - currentTicks;
Log.Warning($"Detected negative production time for {parent.Label}. " +
$"Current: {currentTicks}, Target: {productionUntilTick}, Remaining: {remainingTicks}. " +
$"Process: {_selectedProcess.thingDef?.defName ?? "Unknown"}, Expected Duration: {_selectedProcess.productionTicks}");
// 计算应该设置的正确结束时间
int correctEndTick = currentTicks + _selectedProcess.productionTicks;
// 如果偏差太大,直接完成生产
if (remainingTicks < -_selectedProcess.productionTicks)
{
Log.Warning($"Negative time too large ({remainingTicks} ticks). Forcing production completion.");
FinishProduction();
return;
}
// 否则重置为正确的剩余时间
productionUntilTick = correctEndTick;
hasFixedNegativeTime = true;
Log.Message($"Fixed negative production time for {parent.Label}. " +
$"New target: {productionUntilTick}, New remaining: {_selectedProcess.productionTicks} ticks");
// 发送消息通知(开发模式)
if (Prefs.DevMode)
{
Messages.Message($"Fixed negative production time for {parent.Label}. Remaining: {_selectedProcess.productionTicks.ToStringTicksToPeriod()}",
MessageTypeDefOf.SilentInput);
}
}
// 新增:定期检查负时间问题
private void CheckForNegativeTime()
{
if (Find.TickManager.TicksGame > lastNegativeTimeCheckTick + NEGATIVE_TIME_CHECK_INTERVAL)
{
if (HasNegativeTimeProblem && !hasFixedNegativeTime)
{
FixNegativeTimeProblem();
}
lastNegativeTimeCheckTick = Find.TickManager.TicksGame;
}
}
public override void PostSpawnSetup(bool respawningAfterLoad)
{
base.PostSpawnSetup(respawningAfterLoad);
@@ -90,6 +172,17 @@ namespace ArachnaeSwarm
{
spawnTick = Find.TickManager.TicksGame;
}
// 新增:初始化负时间检查
lastNegativeTimeCheckTick = Find.TickManager.TicksGame;
hasFixedNegativeTime = false;
// 新增:立即检查一次负时间问题
if (InProduction && HasNegativeTimeProblem)
{
Log.Warning($"Detected negative production time on spawn for {parent.Label}");
FixNegativeTimeProblem();
}
}
public override void PostExposeData()
@@ -104,6 +197,8 @@ namespace ArachnaeSwarm
Scribe_Values.Look(ref ticksUnderOptimalConditions, "ticksUnderOptimalConditions", 0);
Scribe_Values.Look(ref temperaturePenaltyPercent, "temperaturePenaltyPercent", 0f);
Scribe_Values.Look(ref spawnTick, "spawnTick", -1); // 新增:序列化生成时间
Scribe_Values.Look(ref lastNegativeTimeCheckTick, "lastNegativeTimeCheckTick", -1);
Scribe_Values.Look(ref hasFixedNegativeTime, "hasFixedNegativeTime", false);
// 加载时重建 selectedProcess
if (Scribe.mode == LoadSaveMode.LoadingVars && selectedProcessThingDef != null)
@@ -138,6 +233,12 @@ namespace ArachnaeSwarm
Log.Warning($"Abnormal production time detected for {selectedProcessThingDef.defName}. Recalculating.");
productionUntilTick = Find.TickManager.TicksGame + _selectedProcess.productionTicks;
}
// 新增:检查负时间问题
else if (HasNegativeTimeProblem)
{
Log.Warning($"Negative production time detected on load for {selectedProcessThingDef.defName}. Fixing.");
FixNegativeTimeProblem();
}
}
}
}
@@ -241,6 +342,10 @@ namespace ArachnaeSwarm
public override void CompTick()
{
base.CompTick();
// 新增:定期检查负时间问题
CheckForNegativeTime();
if (InProduction && productionUntilTick > 0)
{
// 关键修复:添加时间戳有效性检查
@@ -251,6 +356,13 @@ namespace ArachnaeSwarm
return;
}
// 新增再次检查负时间问题在每次tick时
if (HasNegativeTimeProblem && !hasFixedNegativeTime)
{
FixNegativeTimeProblem();
return; // 修复后跳过本次tick的逻辑
}
if (FuelComp == null) return;
bool hasFuel = FuelComp.HasFuel;
@@ -341,6 +453,9 @@ namespace ArachnaeSwarm
temperaturePenaltyPercent = 0f;
float nutritionPerDay = (_selectedProcess.totalNutritionNeeded / _selectedProcess.productionTicks) * 60000f;
FuelComp.currentConsumptionRate = nutritionPerDay;
// 新增:重置负时间修复标记
hasFixedNegativeTime = false;
}
public (QualityCategory quality, float baseScore, float penalty) GetEstimatedQualityDetails()
@@ -495,6 +610,7 @@ namespace ArachnaeSwarm
productionUntilTick = -1;
ticksUnderOptimalConditions = 0;
temperaturePenaltyPercent = 0f;
hasFixedNegativeTime = false; // 新增:重置修复标记
}
// 新增:绘制进度条的方法
@@ -570,6 +686,13 @@ namespace ArachnaeSwarm
// 生产进度条
float progress = ProductionProgress;
int remainingTicks = productionUntilTick - Find.TickManager.TicksGame;
// 新增:显示负时间警告
if (remainingTicks < -10)
{
sb.AppendLine("<color=red>WARNING: Negative production time detected! Auto-fixing...</color>");
}
sb.AppendLine("Progress".Translate() + ": " + GetProgressBar(progress) + " " + progress.ToStringPercent("F0"));
sb.AppendLine("TimeLeft".Translate() + ": " + remainingTicks.ToStringTicksToPeriod());
@@ -624,12 +747,16 @@ namespace ArachnaeSwarm
drawPos.y += 0.15f; // 稍微抬高一点
float progress = ProductionProgress;
// 新增:负时间警告颜色(红色)
Color barColor = HasNegativeTimeProblem ? Color.red : Color.green;
GenDraw.DrawFillableBar(new GenDraw.FillableBarRequest
{
center = drawPos,
size = new Vector2(1f, 0.15f),
fillPercent = progress,
filledMat = SolidColorMaterials.SimpleSolidColorMaterial(Color.green),
filledMat = SolidColorMaterials.SimpleSolidColorMaterial(barColor),
unfilledMat = SolidColorMaterials.SimpleSolidColorMaterial(Color.gray),
margin = 0.1f,
rotation = Rot4.North
@@ -690,8 +817,53 @@ namespace ArachnaeSwarm
{
float progress = ProductionProgress;
var qualityDetails = GetEstimatedQualityDetails();
Messages.Message($"Progress: {progress:P0}\nBase Score: {qualityDetails.baseScore:P0}\nPenalty: {qualityDetails.penalty:P0}\nFinal: {qualityDetails.quality}",
MessageTypeDefOf.SilentInput);
int remainingTicks = productionUntilTick - Find.TickManager.TicksGame;
string message = $"Progress: {progress:P0}\n" +
$"Base Score: {qualityDetails.baseScore:P0}\n" +
$"Penalty: {qualityDetails.penalty:P0}\n" +
$"Final: {qualityDetails.quality}\n" +
$"Remaining Ticks: {remainingTicks}\n" +
$"Has Negative Time: {HasNegativeTimeProblem}\n" +
$"Fixed Before: {hasFixedNegativeTime}";
Messages.Message(message, MessageTypeDefOf.SilentInput);
}
};
// 新增:调试命令手动触发负时间修复
yield return new Command_Action
{
defaultLabel = "Debug: Fix Negative Time",
action = () =>
{
if (HasNegativeTimeProblem)
{
FixNegativeTimeProblem();
Messages.Message("Manually triggered negative time fix", MessageTypeDefOf.SilentInput);
}
else
{
Messages.Message("No negative time problem detected", MessageTypeDefOf.SilentInput);
}
}
};
// 新增:调试命令模拟负时间问题
yield return new Command_Action
{
defaultLabel = "Debug: Simulate Negative Time",
action = () =>
{
if (InProduction)
{
productionUntilTick = Find.TickManager.TicksGame - 1000; // 设置为1000ticks前
hasFixedNegativeTime = false;
Messages.Message("Simulated negative time problem (-1000 ticks)", MessageTypeDefOf.SilentInput);
}
else
{
Messages.Message("Not in production", MessageTypeDefOf.SilentInput);
}
}
};
}

View File

@@ -36,6 +36,11 @@ namespace ArachnaeSwarm
private int spawnTick = -1;
private const int COOLDOWN_TICKS = 120;
// 新增:修复负时间相关字段
private int lastNegativeTimeCheckTick = -1;
private const int NEGATIVE_TIME_CHECK_INTERVAL = 60; // 每60ticks检查一次
private bool hasFixedNegativeTime = false; // 标记是否已经修复过负时间问题
private CompRefuelableNutrition _fuelComp;
private static readonly Texture2D CancelIcon = ContentFinder<Texture2D>.Get("UI/Designators/Cancel");
@@ -77,6 +82,83 @@ namespace ArachnaeSwarm
}
}
// 新增获取剩余生产时间ticks
public int RemainingProductionTicks
{
get
{
if (!InProduction || productionUntilTick <= 0) return 0;
return Mathf.Max(0, productionUntilTick - Find.TickManager.TicksGame);
}
}
// 新增:检查是否存在负时间问题
private bool HasNegativeTimeProblem
{
get
{
if (!InProduction || productionUntilTick <= 0) return false;
int remainingTicks = productionUntilTick - Find.TickManager.TicksGame;
return remainingTicks < -10; // 小于-10ticks认为有问题
}
}
// 新增:修复负时间问题
private void FixNegativeTimeProblem()
{
if (!InProduction || _selectedProcess == null)
{
Log.Warning($"Attempted to fix negative time but no process is selected. Resetting production.");
ResetProduction();
return;
}
int currentTicks = Find.TickManager.TicksGame;
int remainingTicks = productionUntilTick - currentTicks;
Log.Warning($"Detected negative research production time for {parent.Label}. " +
$"Current: {currentTicks}, Target: {productionUntilTick}, Remaining: {remainingTicks}. " +
$"Research: {_selectedProcess.researchDef?.defName ?? "Unknown"}, Expected Duration: {_selectedProcess.productionTicks}");
// 计算应该设置的正确结束时间
int correctEndTick = currentTicks + _selectedProcess.productionTicks;
// 如果偏差太大,直接完成生产
if (remainingTicks < -_selectedProcess.productionTicks)
{
Log.Warning($"Negative time too large ({remainingTicks} ticks). Forcing production completion.");
FinishProduction();
return;
}
// 否则重置为正确的剩余时间
productionUntilTick = correctEndTick;
hasFixedNegativeTime = true;
Log.Message($"Fixed negative research production time for {parent.Label}. " +
$"New target: {productionUntilTick}, New remaining: {_selectedProcess.productionTicks} ticks");
// 发送消息通知(开发模式)
if (Prefs.DevMode)
{
Messages.Message($"Fixed negative research production time for {parent.Label}. Remaining: {_selectedProcess.productionTicks.ToStringTicksToPeriod()}",
MessageTypeDefOf.SilentInput);
}
}
// 新增:定期检查负时间问题
private void CheckForNegativeTime()
{
if (Find.TickManager.TicksGame > lastNegativeTimeCheckTick + NEGATIVE_TIME_CHECK_INTERVAL)
{
if (HasNegativeTimeProblem && !hasFixedNegativeTime)
{
FixNegativeTimeProblem();
}
lastNegativeTimeCheckTick = Find.TickManager.TicksGame;
}
}
public override void PostSpawnSetup(bool respawningAfterLoad)
{
base.PostSpawnSetup(respawningAfterLoad);
@@ -87,6 +169,17 @@ namespace ArachnaeSwarm
{
spawnTick = Find.TickManager.TicksGame;
}
// 新增:初始化负时间检查
lastNegativeTimeCheckTick = Find.TickManager.TicksGame;
hasFixedNegativeTime = false;
// 新增:立即检查一次负时间问题
if (InProduction && HasNegativeTimeProblem)
{
Log.Warning($"Detected negative research production time on spawn for {parent.Label}");
FixNegativeTimeProblem();
}
}
public override void PostExposeData()
@@ -99,6 +192,8 @@ namespace ArachnaeSwarm
Scribe_Values.Look(ref productionUntilTick, "productionUntilTick", -1);
Scribe_Values.Look(ref spawnTick, "spawnTick", -1);
Scribe_Values.Look(ref lastNegativeTimeCheckTick, "lastNegativeTimeCheckTick", -1);
Scribe_Values.Look(ref hasFixedNegativeTime, "hasFixedNegativeTime", false);
// 加载时重建 selectedProcess
if (Scribe.mode == LoadSaveMode.LoadingVars && selectedProcessResearchDef != null)
@@ -127,6 +222,12 @@ namespace ArachnaeSwarm
Log.Warning($"Abnormal production time detected for {selectedProcessResearchDef.defName}. Recalculating.");
productionUntilTick = Find.TickManager.TicksGame + _selectedProcess.productionTicks;
}
// 新增:检查负时间问题
else if (HasNegativeTimeProblem)
{
Log.Warning($"Negative production time detected on load for {selectedProcessResearchDef.defName}. Fixing.");
FixNegativeTimeProblem();
}
}
}
}
@@ -231,6 +332,9 @@ namespace ArachnaeSwarm
{
base.CompTick();
// 新增:定期检查负时间问题
CheckForNegativeTime();
if (InProduction && productionUntilTick > 0)
{
if (productionUntilTick <= 0)
@@ -240,6 +344,13 @@ namespace ArachnaeSwarm
return;
}
// 新增再次检查负时间问题在每次tick时
if (HasNegativeTimeProblem && !hasFixedNegativeTime)
{
FixNegativeTimeProblem();
return; // 修复后跳过本次tick的逻辑
}
if (FuelComp == null) return;
bool hasFuel = FuelComp.HasFuel;
@@ -315,6 +426,9 @@ namespace ArachnaeSwarm
float nutritionPerDay = (_selectedProcess.totalNutritionNeeded / _selectedProcess.productionTicks) * 60000f;
FuelComp.currentConsumptionRate = nutritionPerDay;
// 新增:重置负时间修复标记
hasFixedNegativeTime = false;
}
private void FinishProduction()
@@ -417,6 +531,7 @@ namespace ArachnaeSwarm
if (FuelComp != null) FuelComp.currentConsumptionRate = 0f;
_selectedProcess = null;
productionUntilTick = -1;
hasFixedNegativeTime = false; // 新增:重置修复标记
}
// 进度条显示
@@ -449,6 +564,13 @@ namespace ArachnaeSwarm
float progress = ProductionProgress;
int remainingTicks = productionUntilTick - Find.TickManager.TicksGame;
// 新增:显示负时间警告
if (remainingTicks < -10)
{
sb.AppendLine("<color=red>WARNING: Negative production time detected! Auto-fixing...</color>");
}
sb.AppendLine("Progress".Translate() + ": " + GetProgressBar(progress) + " " + progress.ToStringPercent("F0"));
sb.AppendLine("TimeLeft".Translate() + ": " + remainingTicks.ToStringTicksToPeriod());
sb.AppendLine("TechprintsToProduce".Translate() + ": " + _selectedProcess.techprintCount);
@@ -487,12 +609,16 @@ namespace ArachnaeSwarm
drawPos.y += 0.15f;
float progress = ProductionProgress;
// 新增:负时间警告颜色(红色)
Color barColor = HasNegativeTimeProblem ? Color.red : Color.green;
GenDraw.DrawFillableBar(new GenDraw.FillableBarRequest
{
center = drawPos,
size = new Vector2(1f, 0.15f),
fillPercent = progress,
filledMat = SolidColorMaterials.SimpleSolidColorMaterial(Color.green),
filledMat = SolidColorMaterials.SimpleSolidColorMaterial(barColor),
unfilledMat = SolidColorMaterials.SimpleSolidColorMaterial(Color.gray),
margin = 0.1f,
rotation = Rot4.North
@@ -522,6 +648,62 @@ namespace ArachnaeSwarm
defaultLabel = "Debug: Force Finish",
action = () => FinishProduction()
};
// 新增:调试命令显示详细进度信息
yield return new Command_Action
{
defaultLabel = "Debug: Show Progress Info",
action = () =>
{
float progress = ProductionProgress;
int remainingTicks = productionUntilTick - Find.TickManager.TicksGame;
string message = $"Progress: {progress:P0}\n" +
$"Remaining Ticks: {remainingTicks}\n" +
$"Has Negative Time: {HasNegativeTimeProblem}\n" +
$"Fixed Before: {hasFixedNegativeTime}\n" +
$"Research: {_selectedProcess.researchDef?.defName ?? "Unknown"}\n" +
$"Techprints: {_selectedProcess.techprintCount}";
Messages.Message(message, MessageTypeDefOf.SilentInput);
}
};
// 新增:调试命令手动触发负时间修复
yield return new Command_Action
{
defaultLabel = "Debug: Fix Negative Time",
action = () =>
{
if (HasNegativeTimeProblem)
{
FixNegativeTimeProblem();
Messages.Message("Manually triggered negative time fix", MessageTypeDefOf.SilentInput);
}
else
{
Messages.Message("No negative time problem detected", MessageTypeDefOf.SilentInput);
}
}
};
// 新增:调试命令模拟负时间问题
yield return new Command_Action
{
defaultLabel = "Debug: Simulate Negative Time",
action = () =>
{
if (InProduction)
{
productionUntilTick = Find.TickManager.TicksGame - 1000; // 设置为1000ticks前
hasFixedNegativeTime = false;
Messages.Message("Simulated negative time problem (-1000 ticks)", MessageTypeDefOf.SilentInput);
}
else
{
Messages.Message("Not in production", MessageTypeDefOf.SilentInput);
}
}
};
}
}
}

View File

@@ -123,8 +123,8 @@ namespace ArachnaeSwarm
DamageInfo acidDamage = new DamageInfo(
acidDamageDef,
1f, // 每次1点伤害
0.1f, // 轻微护甲穿透
3f, // 每次3点伤害
2f, // 轻微护甲穿透
-1f, // 随机角度
instigator: null,
hitPart: targetPart

View File

@@ -80,6 +80,13 @@ namespace ArachnaeSwarm
Pawn pawn = parent as Pawn;
if (pawn == null) return;
// 添加:如果有关闭 Hediff不处理缺失的寿命 Hediff
if (HasShutdownHediff)
{
Log.Message($"Lifespan hediff missing for {pawn.Label}, but shutdown hediff is present. This is expected behavior.");
return;
}
Log.Warning($"Lifespan hediff missing for {pawn.Label}. This should not happen. Forcing death.");
// 立即处死pawn
@@ -105,6 +112,20 @@ namespace ArachnaeSwarm
Pawn pawn = parent as Pawn;
if (pawn == null) return null;
// 添加:如果有关闭 Hediff不创建或返回寿命 Hediff
if (HasShutdownHediff)
{
// 如果已经存在寿命 Hediff可以选择移除它
var existingHediff = pawn.health.hediffSet.GetFirstHediffOfDef(Props.lifespanHediff);
if (existingHediff != null)
{
Log.Message($"Shutdown hediff present for {pawn.Label}. Removing lifespan hediff.");
pawn.health.RemoveHediff(existingHediff);
lifespanHediff = null;
}
return null;
}
// 首先尝试查找现有的寿命Hediff
if (lifespanHediff == null || lifespanHediff.pawn != pawn)
{
@@ -132,6 +153,19 @@ namespace ArachnaeSwarm
Pawn pawn = parent as Pawn;
if (pawn == null) return;
// 添加:如果有关闭 Hediff不进行同步
if (HasShutdownHediff)
{
// 确保移除可能存在的寿命 Hediff
var existingHediff = pawn.health.hediffSet.GetFirstHediffOfDef(Props.lifespanHediff);
if (existingHediff != null)
{
pawn.health.RemoveHediff(existingHediff);
lifespanHediff = null;
}
return;
}
var hediff = GetOrCreateLifespanHediff();
if (hediff == null)
{
@@ -167,6 +201,13 @@ namespace ArachnaeSwarm
Pawn pawn = parent as Pawn;
if (pawn == null) return;
// 添加:如果有关闭 Hediff不写入数据
if (HasShutdownHediff)
{
Log.Message($"Cannot write comp data to hediff: Shutdown hediff is present for {pawn.Label}");
return;
}
var hediff = GetOrCreateLifespanHediff();
if (hediff == null)
{
@@ -185,6 +226,20 @@ namespace ArachnaeSwarm
Pawn pawn = parent as Pawn;
if (pawn == null) return;
// 添加:如果有关闭 Hediff不进行 Hediff 校验
if (HasShutdownHediff)
{
// 确保移除可能存在的寿命 Hediff
var existingHediff = pawn.health.hediffSet.GetFirstHediffOfDef(Props.lifespanHediff);
if (existingHediff != null)
{
pawn.health.RemoveHediff(existingHediff);
lifespanHediff = null;
Log.Message($"Removed lifespan hediff for {pawn.Label} due to shutdown hediff presence");
}
return;
}
// 检查寿命Hediff是否存在
var currentHediff = pawn.health.hediffSet.GetFirstHediffOfDef(Props.lifespanHediff);
@@ -201,6 +256,19 @@ namespace ArachnaeSwarm
}
}
// 新增:检查是否需要创建寿命 Hediff
private bool ShouldCreateLifespanHediff()
{
// 如果有关闭 Hediff不应该创建寿命 Hediff
if (HasShutdownHediff)
{
return false;
}
// 其他创建条件...
return true;
}
public override void PostSpawnSetup(bool respawningAfterLoad)
{
if (!ModLister.CheckBiotechOrAnomalyOrOdyssey("Node swarm lifetime"))
@@ -222,12 +290,20 @@ namespace ArachnaeSwarm
lastHediffSyncTick = Find.TickManager.TicksGame;
lastHediffMissingCheckTick = Find.TickManager.TicksGame;
// 添加:检查是否需要创建寿命 Hediff
if (ShouldCreateLifespanHediff())
{
// 确保寿命Hediff存在
GetOrCreateLifespanHediff();
// 初始同步
SyncLifespanWithHediff();
}
else
{
Log.Message($"Skipping lifespan hediff creation for {parent.Label} due to shutdown hediff");
}
}
public override IEnumerable<Gizmo> CompGetGizmosExtra()
{
@@ -254,12 +330,38 @@ namespace ArachnaeSwarm
}
if (DebugSettings.ShowDevGizmos)
{
// 新增:显示关闭 Hediff 状态
yield return new Command_Action
{
defaultLabel = "DEV: 显示关闭Hediff状态",
action = delegate
{
Pawn pawn = parent as Pawn;
if (pawn != null)
{
string message = $"关闭Hediff状态:\n" +
$"HasShutdownHediff: {HasShutdownHediff}\n" +
$"Shutdown Hediff Def: {Props.immuteHediff?.defName ?? "None"}\n" +
$"实际存在: {(Props.immuteHediff != null ? pawn.health.hediffSet.HasHediff(Props.immuteHediff).ToString() : "N/A")}";
Messages.Message(message, MessageTypeDefOf.SilentInput);
Log.Message(message);
}
}
};
// 新增:补满寿命调试命令
yield return new Command_Action
{
defaultLabel = "DEV: 补满寿命",
action = delegate
{
// 添加:检查关闭 Hediff
if (HasShutdownHediff)
{
Messages.Message("无法补满寿命:存在关闭系统的 Hediff", MessageTypeDefOf.RejectInput);
return;
}
powerTicksLeft = (int)(Props.lifetimeDays * 60000);
WriteCompDataToHediff(); // 使用新的写入方法
Log.Message($"已补满寿命: {parent.Label} 剩余 {DaysLeft:F1} 天");
@@ -273,6 +375,13 @@ namespace ArachnaeSwarm
defaultLabel = "DEV: 剩余0.01%寿命",
action = delegate
{
// 添加:检查关闭 Hediff
if (HasShutdownHediff)
{
Messages.Message("无法设置寿命:存在关闭系统的 Hediff", MessageTypeDefOf.RejectInput);
return;
}
int totalTicks = (int)(Props.lifetimeDays * 60000);
powerTicksLeft = (int)(totalTicks * 0.0001f); // 0.01%
WriteCompDataToHediff(); // 使用新的写入方法
@@ -288,6 +397,13 @@ namespace ArachnaeSwarm
defaultLabel = "DEV: 归零寿命",
action = delegate
{
// 添加:检查关闭 Hediff
if (HasShutdownHediff)
{
Messages.Message("无法归零寿命:存在关闭系统的 Hediff", MessageTypeDefOf.RejectInput);
return;
}
powerTicksLeft = 0;
WriteCompDataToHediff(); // 使用新的写入方法
Log.Message($"已归零寿命: {parent.Label} 将立即死亡");
@@ -320,13 +436,16 @@ namespace ArachnaeSwarm
$"剩余天数: {DaysLeft:F4}\n" +
$"总天数: {TotalDays:F1}\n" +
$"百分比: {PercentFull:P4}\n" +
$"已耗尽: {depleted}";
$"已耗尽: {depleted}\n" +
$"关闭Hediff存在: {HasShutdownHediff}";
Messages.Message(message, MessageTypeDefOf.SilentInput);
Log.Message(message);
}
else
{
Messages.Message("未找到寿命hediff", MessageTypeDefOf.SilentInput);
string message = $"未找到寿命hediff\n" +
$"关闭Hediff存在: {HasShutdownHediff}";
Messages.Message(message, MessageTypeDefOf.SilentInput);
}
}
};
@@ -362,6 +481,13 @@ namespace ArachnaeSwarm
defaultLabel = "DEV: 强制同步",
action = delegate
{
// 添加:检查关闭 Hediff
if (HasShutdownHediff)
{
Messages.Message("无法同步:存在关闭系统的 Hediff", MessageTypeDefOf.RejectInput);
return;
}
SyncLifespanWithHediff();
var hediff = GetOrCreateLifespanHediff();
if (hediff != null)
@@ -482,10 +608,18 @@ namespace ArachnaeSwarm
// 立即检查hediff是否存在
ValidateHediffState();
// 添加:检查是否需要创建寿命 Hediff
if (ShouldCreateLifespanHediff())
{
// 确保寿命Hediff存在并同步
GetOrCreateLifespanHediff();
SyncLifespanWithHediff();
}
else
{
Log.Message($"Skipping lifespan hediff creation for {parent.Label} after load due to shutdown hediff");
}
}
}
}

View File

@@ -2,9 +2,31 @@ using RimWorld;
using UnityEngine;
using Verse;
using System.Collections.Generic;
using System.Linq;
namespace ArachnaeSwarm
{
public static class ARA_Translations
{
// 武装方案相关
public static readonly string UnknownScheme = "ARA_UnknownScheme";
public static readonly string SchemeFormat = "ARA_SchemeFormat";
// 消息提示
public static readonly string PowerArmorDamaged = "ARA_PowerArmorDamaged";
public static readonly string SwitchedToMode = "ARA_SwitchedToMode";
public static readonly string EquipPowerArmorFailed = "ARA_EquipPowerArmorFailed";
public static readonly string AlreadySelectedScheme = "ARA_AlreadySelectedScheme";
// Gizmo 按钮文本
public static readonly string SwitchWeapon = "ARA_SwitchWeapon";
public static readonly string SwitchWeaponDesc = "ARA_SwitchWeaponDesc";
public static readonly string SwitchToScheme = "ARA_SwitchToScheme";
// 默认值
public static readonly string Default = "ARA_Default";
}
public interface IStructurePoints
{
float StructurePoints { get; }
@@ -13,13 +35,28 @@ namespace ArachnaeSwarm
string Label { get; }
}
public class PowerArmorWeaponSet
{
public string label; // 方案名称显示在UI上
public string description; // 方案描述显示在按钮的desc上
public ThingDef weapon; // 武器定义
public List<HediffDef> hediffsToAdd; // 切换到此方案时添加的Hediff
public List<HediffDef> hediffsToRemove; // 切换到此方案时移除的Hediff
public string iconPath; // 可选的图标路径
}
public class PowerArmorExtension : DefModExtension
{
public ThingDef buildingDef;
public float structurePointsMax = 500f;
public HediffDef hediffOnEmptyFuel;
public float fuelConsumptionRate = 0.5f; // Nutrition per day
public ThingDef powerArmorWeapon;
// 废弃原来的单个武器,改用列表
public List<PowerArmorWeaponSet> weaponSets = new List<PowerArmorWeaponSet>();
// 默认武装方案索引
public int defaultWeaponSetIndex = 0;
}
[StaticConstructorOnStartup]
@@ -52,8 +89,18 @@ namespace ArachnaeSwarm
public float StructurePointsPercent => StructurePoints / StructurePointsMax;
public Building sourceBuilding;
private ThingWithComps originalWeapon; // Still needed to store pawn's original weapon
private ThingWithComps currentPowerArmorWeapon; // Track the currently equipped power armor weapon
private ThingWithComps originalWeapon;
private ThingWithComps currentPowerArmorWeapon;
// 新增字段:武装方案管理
private int currentWeaponSetIndex = 0;
private List<Hediff> activeHediffs = new List<Hediff>();
public int CurrentWeaponSetIndex => currentWeaponSetIndex;
public PowerArmorWeaponSet CurrentWeaponSet =>
Ext?.weaponSets != null && Ext.weaponSets.Count > currentWeaponSetIndex ?
Ext.weaponSets[currentWeaponSetIndex] : null;
public int WeaponSetCount => Ext?.weaponSets?.Count ?? 0;
public void SetOriginalWeapon(ThingWithComps weapon)
{
@@ -66,6 +113,280 @@ namespace ArachnaeSwarm
}
#endregion
#region /
public override void Notify_Equipped(Pawn pawn)
{
base.Notify_Equipped(pawn);
// 设置默认武装方案
currentWeaponSetIndex = Ext?.defaultWeaponSetIndex ?? 0;
// 应用初始武装方案
ApplyWeaponSet(pawn, CurrentWeaponSet);
Log.Message($"[PA_Debug] 装备动力装甲,应用武装方案: {CurrentWeaponSet?.label ?? ""}");
}
public override void Notify_Unequipped(Pawn pawn)
{
// 清除所有激活的Hediff
foreach (var hediff in activeHediffs)
{
if (pawn.health.hediffSet.hediffs.Contains(hediff))
{
pawn.health.RemoveHediff(hediff);
}
}
activeHediffs.Clear();
base.Notify_Unequipped(pawn);
// 原有卸下逻辑保持不变...
if (Ext?.weaponSets != null && Ext.weaponSets.Count > 0)
{
// 销毁当前动力装甲武器
if (currentPowerArmorWeapon != null)
{
if (pawn?.equipment != null && pawn.equipment.Contains(currentPowerArmorWeapon))
{
pawn.equipment.Remove(currentPowerArmorWeapon);
}
else if (pawn?.inventory?.innerContainer != null && pawn.inventory.innerContainer.Contains(currentPowerArmorWeapon))
{
pawn.inventory.innerContainer.Remove(currentPowerArmorWeapon);
}
else if (currentPowerArmorWeapon.Spawned)
{
currentPowerArmorWeapon.DeSpawn();
}
string destroyedWeaponLabel = currentPowerArmorWeapon.Label;
currentPowerArmorWeapon.Destroy();
Log.Message($"[PA_Debug] Notify_Unequipped: 销毁动力装甲武器 {destroyedWeaponLabel}.");
currentPowerArmorWeapon = null;
}
// 恢复原始武器
if (originalWeapon != null && pawn?.equipment != null)
{
string originalWeaponLabel = originalWeapon.Label;
pawn.equipment.MakeRoomFor(originalWeapon);
pawn.equipment.AddEquipment(originalWeapon);
Log.Message($"[PA_Debug] Notify_Unequipped: 恢复原始武器 {originalWeaponLabel}.");
originalWeapon = null;
}
}
Building building = sourceBuilding;
// 如果源建筑引用丢失,创建新建筑作为回退
if (building == null)
{
ThingDef buildingDef = Ext?.buildingDef;
if (buildingDef == null)
{
Log.Error($"[ArachnaeSwarm] 动力装甲 {this.def.defName} 卸下但在其PowerArmorExtension中未定义buildingDef且源建筑引用丢失。");
this.Destroy(DestroyMode.Vanish);
return;
}
building = (Building)ThingMaker.MakeThing(buildingDef);
}
// 同步健康值回建筑
building.HitPoints = Mathf.Max(1, Mathf.RoundToInt(this.StructurePoints));
// 同步燃料回建筑
var apparelFuelComp = this.GetComp<CompRefuelableNutrition>();
var buildingFuelComp = building.GetComp<CompRefuelableNutrition>();
if (apparelFuelComp != null && buildingFuelComp != null)
{
buildingFuelComp.ConsumeFuel(buildingFuelComp.Fuel);
buildingFuelComp.ReceiveFuel(apparelFuelComp.Fuel);
}
// 同步质量回建筑
if (this.TryGetComp<CompQuality>() is CompQuality apparelQuality && building.TryGetComp<CompQuality>() is CompQuality buildingQuality)
{
buildingQuality.SetQuality(apparelQuality.Quality, ArtGenerationContext.Colony);
}
Log.Message($"[PA_Debug] Notify_Unequipped: 生成建筑前 (ID: {building.thingIDNumber}) - HitPoints: {building.HitPoints}, StackCount: {building.stackCount}");
// 确保建筑堆叠数至少为1
if (building.stackCount <= 0)
{
building.stackCount = 1;
Log.Warning($"[PA_Debug] Notify_Unequipped: 修正建筑 (ID: {building.thingIDNumber}) 堆叠数为1因为原为0。");
}
// 设置派系
building.SetFaction(pawn.Faction);
// 重新生成原始建筑实例
GenPlace.TryPlaceThing(building, pawn.Position, pawn.Map, ThingPlaceMode.Near);
Log.Message($"[PA_Debug] Notify_Unequipped: 生成建筑后 (ID: {building.thingIDNumber}) - HitPoints: {building.HitPoints}, StackCount: {building.stackCount}");
}
#endregion
#region
/// <summary>
/// 切换到下一个武装方案
/// </summary>
public void CycleToNextWeaponSet()
{
if (WeaponSetCount <= 1) return;
var oldSet = CurrentWeaponSet;
currentWeaponSetIndex = (currentWeaponSetIndex + 1) % WeaponSetCount;
var newSet = CurrentWeaponSet;
Log.Message($"[PA_Debug] 切换武装方案: {oldSet?.label ?? ""} -> {newSet?.label ?? ""}");
ApplyWeaponSet(Wearer, newSet, oldSet);
}
/// <summary>
/// 切换到指定索引的武装方案
/// </summary>
public void SwitchToWeaponSet(int index)
{
if (index < 0 || index >= WeaponSetCount) return;
var oldSet = CurrentWeaponSet;
currentWeaponSetIndex = index;
var newSet = CurrentWeaponSet;
Log.Message($"[PA_Debug] 切换到武装方案: {oldSet?.label ?? ""} -> {newSet?.label ?? ""}");
ApplyWeaponSet(Wearer, newSet, oldSet);
}
/// <summary>
/// 应用指定的武装方案
/// </summary>
private void ApplyWeaponSet(Pawn pawn, PowerArmorWeaponSet newSet, PowerArmorWeaponSet oldSet = null)
{
if (pawn == null) return;
// 移除旧方案的Hediff
if (oldSet?.hediffsToRemove != null)
{
foreach (var hediffDef in oldSet.hediffsToRemove)
{
var hediff = pawn.health.hediffSet.GetFirstHediffOfDef(hediffDef);
if (hediff != null)
{
pawn.health.RemoveHediff(hediff);
}
}
}
// 清除当前激活的Hediff
foreach (var hediff in activeHediffs.ToList())
{
if (pawn.health.hediffSet.hediffs.Contains(hediff))
{
pawn.health.RemoveHediff(hediff);
}
}
activeHediffs.Clear();
// 添加新方案的Hediff
if (newSet?.hediffsToAdd != null)
{
foreach (var hediffDef in newSet.hediffsToAdd)
{
var hediff = pawn.health.GetOrAddHediff(hediffDef);
activeHediffs.Add(hediff);
Log.Message($"[PA_Debug] 添加Hediff: {hediffDef.defName}");
}
}
// 处理武器切换
HandleWeaponSwitch(pawn, newSet);
// 显示切换消息
if (newSet != null)
{
Messages.Message(ARA_Translations.SwitchedToMode.Translate(newSet.label), pawn, MessageTypeDefOf.NeutralEvent);
}
}
/// <summary>
/// 处理武器切换逻辑
/// </summary>
private void HandleWeaponSwitch(Pawn pawn, PowerArmorWeaponSet newSet)
{
if (pawn?.equipment == null) return;
// 销毁当前动力装甲武器
if (currentPowerArmorWeapon != null)
{
if (pawn.equipment.Contains(currentPowerArmorWeapon))
{
pawn.equipment.Remove(currentPowerArmorWeapon);
}
currentPowerArmorWeapon.Destroy();
currentPowerArmorWeapon = null;
Log.Message($"[PA_Debug] 销毁当前动力装甲武器");
}
// 如果新方案有武器,装备新武器
if (newSet?.weapon != null)
{
ThingWithComps weapon = (ThingWithComps)ThingMaker.MakeThing(newSet.weapon);
// 同步武器质量
if (this.TryGetComp<CompQuality>() is CompQuality apparelQuality &&
weapon.TryGetComp<CompQuality>() is CompQuality weaponQuality)
{
weaponQuality.SetQuality(apparelQuality.Quality, ArtGenerationContext.Colony);
}
pawn.equipment.MakeRoomFor(weapon);
pawn.equipment.AddEquipment(weapon);
SetCurrentPowerArmorWeapon(weapon);
Log.Message($"[PA_Debug] 装备新武器: {weapon.Label}");
}
// 如果没有武器,恢复原始武器
else if (originalWeapon != null)
{
pawn.equipment.MakeRoomFor(originalWeapon);
pawn.equipment.AddEquipment(originalWeapon);
Log.Message($"[PA_Debug] 恢复原始武器: {originalWeapon.Label}");
}
}
/// <summary>
/// 获取武装方案显示名称
/// </summary>
public string GetWeaponSetDisplayName(int index)
{
if (index < 0 || index >= WeaponSetCount) return ARA_Translations.UnknownScheme.Translate();
var set = Ext.weaponSets[index];
return set.label ?? ARA_Translations.SchemeFormat.Translate(index + 1);
}
/// <summary>
/// 获取武装方案描述
/// </summary>
public string GetWeaponSetDescription(int index)
{
if (index < 0 || index >= WeaponSetCount) return string.Empty;
var set = Ext.weaponSets[index];
// 如果设置了自定义描述,使用自定义描述
if (!string.IsNullOrEmpty(set.description))
{
return set.description;
}
// 否则使用默认的翻译文本
return ARA_Translations.SwitchToScheme.Translate(
set.label ?? ARA_Translations.SchemeFormat.Translate(index + 1));
}
#endregion
#region Ticker
protected override void Tick()
{
@@ -82,15 +403,11 @@ namespace ArachnaeSwarm
var fuelComp = this.GetComp<CompRefuelableNutrition>();
if (fuelComp != null)
{
// Set the consumption rate on every tick. This value is then used by CompRefuelableNutrition's CompTick.
// We use the value from our PowerArmorExtension, ensuring it's always active.
// 设置消耗率
fuelComp.currentConsumptionRate = Ext?.fuelConsumptionRate ?? 0f;
// We must explicitly call the component's Tick, as Apparel's base Tick does not.
// This will trigger the consumption logic inside CompRefuelableNutrition.
fuelComp.CompTick();
// Handle hediff for empty fuel, checked frequently for responsiveness.
// 处理空燃料Hediff
if (this.Wearer.IsHashIntervalTick(60))
{
var hediffDef = Ext?.hediffOnEmptyFuel;
@@ -117,31 +434,72 @@ namespace ArachnaeSwarm
}
#endregion
#region Data
#region
public override void ExposeData()
{
base.ExposeData();
Scribe_Values.Look(ref structurePoints, "structurePoints", -1f);
Scribe_References.Look(ref sourceBuilding, "sourceBuilding");
Scribe_References.Look(ref originalWeapon, "originalWeapon");
Scribe_References.Look(ref currentPowerArmorWeapon, "currentPowerArmorWeapon"); // Save/load current power armor weapon
Scribe_References.Look(ref currentPowerArmorWeapon, "currentPowerArmorWeapon");
Scribe_Values.Look(ref currentWeaponSetIndex, "currentWeaponSetIndex", 0);
// 注意Hediff不需要保存因为会在加载时重新应用
}
#endregion
#region Gizmo
public override IEnumerable<Gizmo> GetWornGizmos()
{
// Always yield base gizmos first.
// 基础Gizmo
foreach (var gizmo in base.GetWornGizmos())
{
yield return gizmo;
}
// Yield our custom structure points gizmo.
// 结构点面板
yield return new Gizmo_StructurePanel(this);
// Yield the default gizmos from the CompRefuelable component.
// This will provide the standard RimWorld fuel gizmo.
// 武装方案切换按钮(只有在有多个方案时显示)
if (WeaponSetCount > 1)
{
// 主切换按钮(已注释,但保留翻译)
/*
yield return new Command_Action
{
defaultLabel = ARA_Translations.SwitchWeapon.Translate(CurrentWeaponSet?.label ?? ARA_Translations.Default.Translate()),
defaultDesc = ARA_Translations.SwitchWeaponDesc.Translate(
CurrentWeaponSet?.label ?? ARA_Translations.Default.Translate(),
WeaponSetCount),
icon = ContentFinder<Texture2D>.Get("UI/Commands/Attack") ?? BaseContent.BadTex,
action = CycleToNextWeaponSet
};
*/
// 为每个武装方案提供单独的切换按钮
for (int i = 0; i < WeaponSetCount; i++)
{
int currentIndex = i; // 创建局部变量捕获当前索引
var set = Ext.weaponSets[currentIndex];
var command = new Command_Action
{
defaultLabel = set.label ?? ARA_Translations.SchemeFormat.Translate(currentIndex + 1),
defaultDesc = GetWeaponSetDescription(currentIndex), // 使用新的描述获取方法
icon = set.iconPath != null ? ContentFinder<Texture2D>.Get(set.iconPath) : ContentFinder<Texture2D>.Get("UI/Commands/Attack"),
action = () => SwitchToWeaponSet(currentIndex) // 使用局部变量
};
// 正确禁用当前已选择的方案按钮
if (currentIndex == currentWeaponSetIndex)
{
command.Disable(ARA_Translations.AlreadySelectedScheme.Translate());
}
yield return command;
}
}
// 燃料组件Gizmo
var fuelComp = this.GetComp<CompRefuelableNutrition>();
if (fuelComp != null)
{
@@ -153,104 +511,7 @@ namespace ArachnaeSwarm
}
#endregion
#region State-Switching
public override void Notify_Unequipped(Pawn pawn)
{
base.Notify_Unequipped(pawn);
// Handle power armor weapon destruction and original weapon restoration
if (Ext?.powerArmorWeapon != null)
{
// Destroy the power armor weapon, wherever it might be.
// We track it with currentPowerArmorWeapon, so we don't rely on pawn.equipment.Primary.
if (currentPowerArmorWeapon != null)
{
if (pawn?.equipment != null && pawn.equipment.Contains(currentPowerArmorWeapon))
{
pawn.equipment.Remove(currentPowerArmorWeapon);
}
else if (pawn?.inventory?.innerContainer != null && pawn.inventory.innerContainer.Contains(currentPowerArmorWeapon))
{
pawn.inventory.innerContainer.Remove(currentPowerArmorWeapon);
}
// If it's on the map, destroy it there.
else if (currentPowerArmorWeapon.Spawned)
{
currentPowerArmorWeapon.DeSpawn();
}
string destroyedWeaponLabel = currentPowerArmorWeapon.Label;
currentPowerArmorWeapon.Destroy();
Log.Message($"[PA_Debug] Notify_Unequipped: Destroyed power armor weapon {destroyedWeaponLabel}.");
currentPowerArmorWeapon = null;
}
// Restore original weapon if saved
if (originalWeapon != null && pawn?.equipment != null)
{
string originalWeaponLabel = originalWeapon.Label;
pawn.equipment.MakeRoomFor(originalWeapon);
pawn.equipment.AddEquipment(originalWeapon);
Log.Message($"[PA_Debug] Notify_Unequipped: Restored original weapon {originalWeaponLabel}.");
originalWeapon = null;
}
}
Building building = sourceBuilding;
// If the source building reference is lost, create a new one as a fallback.
if (building == null)
{
ThingDef buildingDef = Ext?.buildingDef;
if (buildingDef == null)
{
Log.Error($"[ArachnaeSwarm] Power Armor {this.def.defName} unequipped, but has no buildingDef defined in its PowerArmorExtension and the source building reference was lost.");
this.Destroy(DestroyMode.Vanish);
return;
}
building = (Building)ThingMaker.MakeThing(buildingDef);
}
// Sync health back to the building, ensuring it's at least 1 to prevent it from being destroyed instantly.
building.HitPoints = Mathf.Max(1, Mathf.RoundToInt(this.StructurePoints));
// Sync fuel back to the building
var apparelFuelComp = this.GetComp<CompRefuelableNutrition>();
var buildingFuelComp = building.GetComp<CompRefuelableNutrition>();
if (apparelFuelComp != null && buildingFuelComp != null)
{
// Reset building fuel and then set it to the apparel's current fuel to avoid overflow.
buildingFuelComp.ConsumeFuel(buildingFuelComp.Fuel);
buildingFuelComp.ReceiveFuel(apparelFuelComp.Fuel);
}
// Sync quality back to building
if (this.TryGetComp<CompQuality>() is CompQuality apparelQuality && building.TryGetComp<CompQuality>() is CompQuality buildingQuality)
{
buildingQuality.SetQuality(apparelQuality.Quality, ArtGenerationContext.Colony);
}
Log.Message($"[PA_Debug] Notify_Unequipped: Before spawning building (ID: {building.thingIDNumber}) - HitPoints: {building.HitPoints}, StackCount: {building.stackCount}");
// Ensure stackCount is at least 1 for buildings, as 0 stackCount causes errors during spawning
if (building.stackCount <= 0)
{
building.stackCount = 1;
Log.Warning($"[PA_Debug] Notify_Unequipped: Corrected building (ID: {building.thingIDNumber}) stackCount to 1 as it was 0.");
}
// Set the faction to the pawn's faction before spawning
building.SetFaction(pawn.Faction);
// Re-spawn the original building instance
GenPlace.TryPlaceThing(building, pawn.Position, pawn.Map, ThingPlaceMode.Near);
Log.Message($"[PA_Debug] Notify_Unequipped: After spawning building (ID: {building.thingIDNumber}) - HitPoints: {building.HitPoints}, StackCount: {building.stackCount}");
// The destruction is now handled by the Tick() method when it detects Wearer is null.
// This is the safest way to implement delayed self-destruction.
}
#endregion
#region Damage Handling - THE FINAL, CORRECT IMPLEMENTATION
#region
public override bool CheckPreAbsorbDamage(DamageInfo dinfo)
{
if (this.Wearer == null || !dinfo.Def.harmsHealth || dinfo.Amount <= 0.001f)
@@ -267,7 +528,7 @@ namespace ArachnaeSwarm
if (this.StructurePoints <= 0)
{
Messages.Message("PowerArmorBroken".Translate(this.Label, this.Wearer.LabelShort), this, MessageTypeDefOf.NegativeEvent);
Messages.Message(ARA_Translations.PowerArmorDamaged.Translate(this.Label, this.Wearer.LabelShort), this, MessageTypeDefOf.NegativeEvent);
this.Destroy(DestroyMode.KillFinalize);
}
}
@@ -276,7 +537,7 @@ namespace ArachnaeSwarm
EffecterDefOf.Deflect_Metal_Bullet.SpawnAttached(this.Wearer, this.Wearer.Map, 1f);
}
// By returning true, we tell the game the damage has been fully handled and should not proceed to the pawn.
// 返回true表示伤害已被完全处理不应继续传递给pawn
return true;
}

View File

@@ -20,80 +20,167 @@ namespace ArachnaeSwarm
this.FailOnDespawnedNullOrForbidden(BuildingInd);
this.FailOnSomeonePhysicallyInteracting(BuildingInd);
// 第一步:移动到动力装甲站
yield return Toils_Goto.GotoThing(BuildingInd, PathEndMode.InteractionCell);
// 第二步等待装备过程120 ticks = 2秒
yield return Toils_General.Wait(120, BuildingInd).WithProgressBarToilDelay(BuildingInd);
// 第三步:执行装备动力装甲
Toil enter = new Toil();
enter.initAction = () =>
{
Pawn actor = enter.actor;
var building = (Building)actor.CurJob.GetTarget(BuildingInd).Thing;
// Get the CompProperties from the building's new component
// 获取动力装甲站的组件属性
var compProps = building.GetComp<CompPowerArmorStation>()?.Props;
if (compProps != null && compProps.apparelDef != null)
{
// Create the apparel
// 创建动力装甲装备
ARA_PowerArmor apparel = (ARA_PowerArmor)ThingMaker.MakeThing(compProps.apparelDef);
// CRITICAL STEP: Link the apparel back to the building
// 关键步骤:将装备链接回建筑
apparel.sourceBuilding = building;
// Sync health from building to apparel
// 从建筑同步健康值到装备
apparel.StructurePoints = building.HitPoints;
// Sync fuel from building to apparel
// 从建筑同步燃料到装备
var buildingFuelComp = building.GetComp<CompRefuelableNutrition>();
var apparelFuelComp = apparel.GetComp<CompRefuelableNutrition>();
if (buildingFuelComp != null && apparelFuelComp != null)
{
// 重置装备燃料并同步建筑燃料
apparelFuelComp.ConsumeFuel(apparelFuelComp.Fuel); // 先清空
apparelFuelComp.ReceiveFuel(buildingFuelComp.Fuel);
Log.Message($"[PA_Debug] 同步燃料: 建筑 {buildingFuelComp.Fuel} -> 装备 {apparelFuelComp.Fuel}");
}
// Sync quality
if (building.TryGetComp<CompQuality>() is CompQuality buildingQuality && apparel.TryGetComp<CompQuality>() is CompQuality apparelQuality)
// 同步质量
if (building.TryGetComp<CompQuality>() is CompQuality buildingQuality &&
apparel.TryGetComp<CompQuality>() is CompQuality apparelQuality)
{
apparelQuality.SetQuality(buildingQuality.Quality, ArtGenerationContext.Colony);
Log.Message($"[PA_Debug] 同步质量: {buildingQuality.Quality}");
}
// Wear the apparel. The second argument 'false' is lockWhileWorn.
// The third argument 'false' is playerForced, which is CRITICAL.
// If playerForced is true, the game automatically locks the apparel.
actor.apparel.Wear(apparel, false, false);
// Handle weapon switching
if (apparel.Ext.powerArmorWeapon != null)
// 保存原始武器(如果有)
ThingWithComps originalWeapon = actor.equipment?.Primary;
if (originalWeapon != null)
{
if (actor.equipment.Primary != null)
{
apparel.SetOriginalWeapon(actor.equipment.Primary);
actor.equipment.TryDropEquipment(actor.equipment.Primary, out _, actor.Position, false);
apparel.SetOriginalWeapon(originalWeapon);
Log.Message($"[PA_Debug] 保存原始武器: {originalWeapon.Label}");
}
ThingWithComps weapon = (ThingWithComps)ThingMaker.MakeThing(apparel.Ext.powerArmorWeapon);
// 获取动力装甲扩展和默认武装方案
var powerArmorExt = apparel.Ext;
PowerArmorWeaponSet defaultSet = null;
// Sync weapon quality with armor quality
if (apparel.TryGetComp<CompQuality>() is CompQuality existingApparelQuality && weapon.TryGetComp<CompQuality>() is CompQuality weaponQuality)
// 确定要使用的武装方案
if (powerArmorExt?.weaponSets != null && powerArmorExt.weaponSets.Count > 0)
{
// 使用默认方案索引,确保在有效范围内
int defaultIndex = powerArmorExt.defaultWeaponSetIndex;
if (defaultIndex < 0 || defaultIndex >= powerArmorExt.weaponSets.Count)
{
defaultIndex = 0; // 回退到第一个方案
}
defaultSet = powerArmorExt.weaponSets[defaultIndex];
Log.Message($"[PA_Debug] 使用武装方案: {defaultSet?.label ?? ""} (索引: {defaultIndex})");
// 如果默认方案有武器,需要卸下原始武器
if (defaultSet?.weapon != null && originalWeapon != null)
{
// 卸下原始武器,为动力装甲武器腾出位置
if (actor.equipment.Contains(originalWeapon))
{
actor.equipment.Remove(originalWeapon);
Log.Message($"[PA_Debug] 卸下原始武器: {originalWeapon.Label}");
}
// 创建并装备动力装甲武器
ThingWithComps powerArmorWeapon = (ThingWithComps)ThingMaker.MakeThing(defaultSet.weapon);
// 同步武器质量与装甲质量
if (apparel.TryGetComp<CompQuality>() is CompQuality existingApparelQuality &&
powerArmorWeapon.TryGetComp<CompQuality>() is CompQuality weaponQuality)
{
weaponQuality.SetQuality(existingApparelQuality.Quality, ArtGenerationContext.Colony);
}
actor.equipment.MakeRoomFor(weapon);
actor.equipment.AddEquipment(weapon);
// Track the power armor weapon so it can be destroyed later
apparel.SetCurrentPowerArmorWeapon(weapon);
}
// 装备动力装甲武器
actor.equipment.MakeRoomFor(powerArmorWeapon);
actor.equipment.AddEquipment(powerArmorWeapon);
apparel.SetCurrentPowerArmorWeapon(powerArmorWeapon);
// Despawn the building
building.DeSpawn();
Log.Message($"[PA_Debug] 装备动力装甲武器: {powerArmorWeapon.Label}");
}
// 如果默认方案没有武器,但原始武器存在,保留原始武器
else if (originalWeapon != null)
{
Log.Message($"[PA_Debug] 默认方案无武器,保留原始武器: {originalWeapon.Label}");
}
}
else
{
Log.Error($"[ArachnaeSwarm] Power Armor Building {building.def.defName} is missing CompProperties_PowerArmorStation or apparelDef.");
Log.Message($"[PA_Debug] 无武装方案配置,使用原有逻辑");
// 如果没有武装方案配置,就不进行武器切换
// 保留殖民者的原始武器
if (originalWeapon != null)
{
Log.Message($"[PA_Debug] 无武装方案,保留原始武器: {originalWeapon.Label}");
}
else
{
Log.Message($"[PA_Debug] 无武装方案,且无原始武器");
}
}
// 穿戴装备
// 第三个参数 'false' 是 playerForced这很关键
// 如果 playerForced 为 true游戏会自动锁定装备
actor.apparel.Wear(apparel, false, false);
Log.Message($"[PA_Debug] 成功穿戴动力装甲: {apparel.Label}");
// 销毁建筑
building.DeSpawn();
Log.Message($"[PA_Debug] 销毁动力装甲站建筑");
// 显示成功消息
Messages.Message($"{actor.LabelShort} 已装备{apparel.Label}", actor, MessageTypeDefOf.PositiveEvent);
}
else
{
Log.Error($"[ArachnaeSwarm] 动力装甲建筑 {building.def.defName} 缺少 CompProperties_PowerArmorStation 或 apparelDef。");
// 显示错误消息
Messages.Message("装备动力装甲失败:配置错误", actor, MessageTypeDefOf.NegativeEvent);
}
};
enter.defaultCompleteMode = ToilCompleteMode.Instant;
yield return enter;
}
// 添加失败处理
public override string GetReport()
{
return "正在装备动力装甲...";
}
}
// 可选的:为动力装甲站添加工作定义
[DefOf]
public static class JobDefOf_ARA
{
public static JobDef ARA_EnterPowerArmor;
static JobDefOf_ARA()
{
DefOfHelper.EnsureInitializedInCtor(typeof(JobDefOf_ARA));
}
}
}

View File

@@ -79,4 +79,24 @@ namespace ArachnaeSwarm
disappearsComp?.ResetElapsedTicks();
}
}
// 新增补丁:为 Verb_ShootBeamExplosive 添加支持
[HarmonyPatch(typeof(Verb_ShootBeamExplosive), "TryCastShot")]
public static class Patch_Verb_ShootBeamExplosive_TryCastShot
{
public static void Postfix(Verb_ShootBeamExplosive __instance, bool __result)
{
if (!__result) return;
if (__instance.CasterPawn == null || __instance.EquipmentSource == null) return;
CompGiveHediffOnShot comp = __instance.EquipmentSource.GetComp<CompGiveHediffOnShot>();
if (comp == null || comp.Props.hediffDef == null) return;
Hediff hediff = __instance.CasterPawn.health.GetOrAddHediff(comp.Props.hediffDef);
hediff.Severity += comp.Props.severityToAdd;
var disappearsComp = hediff.TryGetComp<HediffComp_Disappears>();
disappearsComp?.ResetElapsedTicks();
}
}
}