10 Commits

Author SHA1 Message Date
ProjectKoi-Kalo\Kalo
390128f503 暂存 2025-09-08 23:31:22 +08:00
ProjectKoi-Kalo\Kalo
8a0fbe32e8 暂存 2025-09-08 21:59:11 +08:00
ProjectKoi-Kalo\Kalo
24a0ed126b 暂存 2025-09-08 21:39:32 +08:00
ProjectKoi-Kalo\Kalo
8d6c992f1f 暂存2 2025-09-08 20:09:22 +08:00
ProjectKoi-Kalo\Kalo
30ee96a196 zz暂存 2025-09-08 20:05:20 +08:00
ProjectKoi-Kalo\Kalo
ebe217223d 2025-09-08 18:34:28 +08:00
ProjectKoi-Kalo\Kalo
82b3855fc8 暂存物品池 2025-09-08 18:26:12 +08:00
ProjectKoi-Kalo\Kalo
1a102fcf31 暂存 2025-09-08 18:05:15 +08:00
Tourswen
f72fb7e62e 修改描述,合并虫卵 2025-09-08 17:27:18 +08:00
ProjectKoi-Kalo\Kalo
ec20d84344 暂存 2025-09-08 15:35:19 +08:00
48 changed files with 1245 additions and 1172 deletions

Binary file not shown.

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<AbilityDef Name="ARA_EggSpew_Base" Abstract="True">
<cooldownTicksRange>5000</cooldownTicksRange>
<aiCanUse>false</aiCanUse>
@@ -31,7 +30,6 @@
</li>
</comps>
</AbilityDef>
<ThingDef Name="ARA_EggSpew_Base_Proj" ParentName="BaseGrenadeProjectile" Abstract="True">
<thingClass>Projectile_SpawnsThing</thingClass>
<graphicData>
@@ -45,7 +43,6 @@
<tryAdjacentFreeSpaces>true</tryAdjacentFreeSpaces>
</projectile>
</ThingDef>
<AbilityDef Name="ARA_CocoonSpew_Base" Abstract="True">
<cooldownTicksRange>5000</cooldownTicksRange>
<aiCanUse>true</aiCanUse>
@@ -72,7 +69,6 @@
</li>
</comps>
</AbilityDef>
<ThingDef Name="ARA_CocoonSpew_Base_Proj" ParentName="BaseGrenadeProjectile" Abstract="True">
<label>阿拉克涅孵化茧</label>
<thingClass>Projectile_SpawnsThing</thingClass>
@@ -88,22 +84,6 @@
</projectile>
</ThingDef>
<AbilityDef ParentName="ARA_EggSpew_Base">
<defName>ARA_EggSpew_BaseFighter</defName>
<label>生育虫卵-战士虫</label>
<description>从卵巢中排出一颗休眠的虫卵,阿拉克涅女皇种可以通过与其交互将其激活,并选择孵化的督虫虫族类型——参阅虫卵的具体信息,了解各个督虫的特点。</description>
<iconPath>UI/Commands/EggSpew</iconPath>
<comps>
<li Class="CompProperties_AbilityLaunchProjectile">
<projectileDef>ARA_Proj_EggSac_BaseFighter</projectileDef>
</li>
<li Class="ArachnaeSwarm.CompProperties_AbilityResearchPrereq">
<requiredResearch>ARA_Technology_1KYC</requiredResearch>
<failMessage>需要科技 基因节点KYC-1"战士虫" 以解锁此孵化路径</failMessage>
</li>
</comps>
</AbilityDef>
<AbilityDef ParentName="ARA_EggSpew_Base">
<defName>ARA_EggSpew</defName>
<label>生育虫卵</label>
@@ -115,6 +95,4 @@
</li>
</comps>
</AbilityDef>
</Defs>

View File

@@ -20,7 +20,7 @@
<cooldownTicksRange>600</cooldownTicksRange>
<verbProperties>
<verbClass>ArachnaeSwarm.Verb_CastAbilityTrackingCharge</verbClass>
<label>tracking charge</label>
<label>追踪冲撞</label>
<targetParams>
<canTargetPawns>true</canTargetPawns>
<canTargetBuildings>false</canTargetBuildings>
@@ -28,7 +28,7 @@
<canTargetMechs>true</canTargetMechs>
<canTargetSelf>false</canTargetSelf>
</targetParams>
<range>60</range>
<range>30</range>
<warmupTime>1.0</warmupTime>
</verbProperties>
<comps>
@@ -49,5 +49,4 @@
</li>
</comps>
</AbilityDef>
</Defs>

View File

@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<AnimationDef>
<defName>ARA_FlyEast</defName>
<durationTicks>60</durationTicks>
<keyframeParts>
<li>
<key>ARA_Flight_Attachment</key>
<value>
<keyframes>
<li><graphicState>ARA_FlyEast_0</graphicState><tick>0</tick></li>
<li><graphicState>ARA_FlyEast_1</graphicState><tick>4</tick></li>
<li><graphicState>ARA_FlyEast_2</graphicState><tick>8</tick></li>
<li><graphicState>ARA_FlyEast_3</graphicState><tick>12</tick></li>
<li><graphicState>ARA_FlyEast_4</graphicState><tick>16</tick></li>
<li><graphicState>ARA_FlyEast_5</graphicState><tick>20</tick></li>
<li><graphicState>ARA_FlyEast_6</graphicState><tick>24</tick></li>
<li><graphicState>ARA_FlyEast_7</graphicState><tick>28</tick></li>
</keyframes>
</value>
</li>
<li>
<key>Root</key>
<value><workerType>AnimationWorker_Keyframes</workerType><keyframes>
<li><tick>0</tick><offset>(0,0,-0.05)</offset></li>
<li><tick>30</tick><offset>(0,0,0.05)</offset></li>
<li><tick>60</tick><offset>(0,0,-0.05)</offset></li>
</keyframes></value>
</li>
</keyframeParts>
</AnimationDef>
<AnimationDef>
<defName>ARA_FlyNorth</defName>
<durationTicks>60</durationTicks>
<keyframeParts>
<li>
<key>ARA_Flight_Attachment</key>
<value>
<keyframes>
<li><graphicState>ARA_FlyNorth_0</graphicState><tick>0</tick></li>
<li><graphicState>ARA_FlyNorth_1</graphicState><tick>4</tick></li>
<li><graphicState>ARA_FlyNorth_2</graphicState><tick>8</tick></li>
<li><graphicState>ARA_FlyNorth_3</graphicState><tick>12</tick></li>
<li><graphicState>ARA_FlyNorth_4</graphicState><tick>16</tick></li>
<li><graphicState>ARA_FlyNorth_5</graphicState><tick>20</tick></li>
<li><graphicState>ARA_FlyNorth_6</graphicState><tick>24</tick></li>
<li><graphicState>ARA_FlyNorth_7</graphicState><tick>28</tick></li>
</keyframes>
</value>
</li>
<li>
<key>Root</key>
<value><workerType>AnimationWorker_Keyframes</workerType><keyframes>
<li><tick>0</tick><offset>(0,0,-0.05)</offset></li>
<li><tick>30</tick><offset>(0,0,0.05)</offset></li>
<li><tick>60</tick><offset>(0,0,-0.05)</offset></li>
</keyframes></value>
</li>
</keyframeParts>
</AnimationDef>
<AnimationDef>
<defName>ARA_FlySouth</defName>
<durationTicks>60</durationTicks>
<keyframeParts>
<li>
<key>ARA_Flight_Attachment</key>
<value>
<keyframes>
<li><graphicState>ARA_FlySouth_0</graphicState><tick>0</tick></li>
<li><graphicState>ARA_FlySouth_1</graphicState><tick>4</tick></li>
<li><graphicState>ARA_FlySouth_2</graphicState><tick>8</tick></li>
<li><graphicState>ARA_FlySouth_3</graphicState><tick>12</tick></li>
<li><graphicState>ARA_FlySouth_4</graphicState><tick>16</tick></li>
<li><graphicState>ARA_FlySouth_5</graphicState><tick>20</tick></li>
<li><graphicState>ARA_FlySouth_6</graphicState><tick>24</tick></li>
<li><graphicState>ARA_FlySouth_7</graphicState><tick>28</tick></li>
</keyframes>
</value>
</li>
<li>
<key>Root</key>
<value><workerType>AnimationWorker_Keyframes</workerType><keyframes>
<li><tick>0</tick><offset>(0,0,-0.05)</offset></li>
<li><tick>30</tick><offset>(0,0,0.05)</offset></li>
<li><tick>60</tick><offset>(0,0,-0.05)</offset></li>
</keyframes></value>
</li>
</keyframeParts>
</AnimationDef>
</Defs>

View File

@@ -1,84 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_normal</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>1</duration>
<browShapeDef>normal</browShapeDef>
<lidShapeDef>normal</lidShapeDef>
<mouthShapeDef>normal</mouthShapeDef>
<headShapeDef>normal</headShapeDef>
</li>
</animationFrames>
<priority>0</priority>
</FacialAnimation.FaceAnimationDef>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_eyeMoving</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>15</duration>
<eyeballOffset>(-0.005,0,0)</eyeballOffset>
</li>
</animationFrames>
<priority>1002</priority>
<roopIntervalMin>30 </roopIntervalMin>
<roopIntervalMax>500</roopIntervalMax>
</FacialAnimation.FaceAnimationDef>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_eyeMoving2</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>15</duration>
<eyeballOffset>(0.005,0,0)</eyeballOffset>
</li>
</animationFrames>
<priority>1001</priority>
<roopIntervalMin>30 </roopIntervalMin>
<roopIntervalMax>500</roopIntervalMax>
</FacialAnimation.FaceAnimationDef>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_eyeFlicker</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>3</duration>
</li>
</animationFrames>
<priority>1001</priority>
<roopIntervalMin>10 </roopIntervalMin>
<roopIntervalMax>30</roopIntervalMax>
</FacialAnimation.FaceAnimationDef>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_blink</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>3</duration>
<browOffset>(0,0,-0.005)</browOffset>
<lidOffset>(0,0,-0.005)</lidOffset>
<lidShapeDef>normal</lidShapeDef>
</li>
<li>
<duration>12</duration>
<browOffset>(0,0,-0.01)</browOffset>
<lidShapeDef>close</lidShapeDef>
</li>
<li>
<duration>3</duration>
<browOffset>(0,0,-0.005)</browOffset>
<lidOffset>(0,0,-0.005)</lidOffset>
<lidShapeDef>normal</lidShapeDef>
</li>
</animationFrames>
<roopIntervalMin>30 </roopIntervalMin>
<roopIntervalMax>500</roopIntervalMax>
<priority>1000</priority>
</FacialAnimation.FaceAnimationDef>
</Defs>

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<!-- 裸体想法 -->
<!-- <FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Thought_Naked</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>1</duration>
<headShapeDef>blush</headShapeDef>
<browShapeDef>s-shaped</browShapeDef>
</li>
</animationFrames>
<priority>200</priority>
<targetThoughtDefs>
<li>Naked</li>
<li>GroinUncovered_Disapproved_Male</li>
<li>GroinUncovered_Disapproved_Female</li>
<li>GroinOrChestUncovered_Disapproved_Male</li>
<li>GroinOrChestUncovered_Disapproved_Female</li>
<li>GroinChestOrHairUncovered_Disapproved_Male</li>
<li>GroinChestOrHairUncovered_Disapproved_Female</li>
<li>GroinChestHairOrFaceUncovered_Disapproved_Male</li>
<li>GroinChestHairOrFaceUncovered_Disapproved_Female</li>
</targetThoughtDefs>
</FacialAnimation.FaceAnimationDef> -->
</Defs>

View File

@@ -1,37 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_AttackMelee</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>1</duration>
<browShapeDef>angled</browShapeDef>
<mouthShapeDef>open</mouthShapeDef>
<browOffset>(0,0,-0.00875)</browOffset>
<lidOffset>(0.0,0,-0.005)</lidOffset>
</li>
</animationFrames>
<targetJobs>
<li>AttackMelee</li>
</targetJobs>
<priority>10200</priority>
</FacialAnimation.FaceAnimationDef>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>AttackMelee2</defName>
<animationFrames>
<li>
<duration>1</duration>
<browShapeDef>angled</browShapeDef>
<mouthShapeDef>normal</mouthShapeDef>
</li>
</animationFrames>
<targetJobs>
<li>AttackMelee</li>
</targetJobs>
<priority>10201</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
</FacialAnimation.FaceAnimationDef>
</Defs>

View File

@@ -1,37 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_AttackStatic</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>1</duration>
<browShapeDef>angled</browShapeDef>
<mouthShapeDef>open</mouthShapeDef>
<browOffset>(0,0,-0.00875)</browOffset>
<lidOffset>(0.0,0,-0.005)</lidOffset>
</li>
</animationFrames>
<targetJobs>
<li>AttackStatic</li>
</targetJobs>
<priority>10200</priority>
</FacialAnimation.FaceAnimationDef>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>AttackStatic2</defName>
<animationFrames>
<li>
<duration>1</duration>
<browShapeDef>angled</browShapeDef>
<mouthShapeDef>normal</mouthShapeDef>
</li>
</animationFrames>
<targetJobs>
<li>AttackStatic</li>
</targetJobs>
<priority>10201</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
</FacialAnimation.FaceAnimationDef>
</Defs>

View File

@@ -1,67 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_DoBill</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>1</duration>
<lidOffset>(0,0,-0.00625)</lidOffset>
<eyeballOffset>(0.0,0,-0.0075)</eyeballOffset>
<headOffset>(0,0,-0.0007)</headOffset>
<browShapeDef>normal</browShapeDef>
<browOffset>(0,0,-0.00325)</browOffset>
<mouthOffset>(0,0,-0.00125)</mouthOffset>
</li>
</animationFrames>
<roopIntervalMin>0</roopIntervalMin>
<roopIntervalMax>0</roopIntervalMax>
<targetJobs>
<li>DoBill</li>
</targetJobs>
<priority>10000</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
</FacialAnimation.FaceAnimationDef>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_DoBill2</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>3</duration>
<lidOffset>(0,0,-0.0035)</lidOffset>
<eyeballOffset>(0.0,0,-0.00375)</eyeballOffset>
<headOffset>(0,0,-0.0035)</headOffset>
<browShapeDef>normal</browShapeDef>
<browOffset>(0,0,-0.00025)</browOffset>
<mouthOffset>(0,0,-0.000625)</mouthOffset>
</li>
<li>
<duration>6</duration>
<lidOffset>(0,0,-0.007)</lidOffset>
<eyeballOffset>(0.0,0,-0.00525)</eyeballOffset>
<headOffset>(0,0,-0.0075)</headOffset>
<browShapeDef>normal</browShapeDef>
<browOffset>(0,0,-0.00375)</browOffset>
<mouthOffset>(0,0,-0.00125)</mouthOffset>
</li>
<li>
<duration>3</duration>
<lidOffset>(0,0,-0.0035)</lidOffset>
<eyeballOffset>(0.0,0,-0.00375)</eyeballOffset>
<headOffset>(0,0,-0.0035)</headOffset>
<browShapeDef>normal</browShapeDef>
<browOffset>(0,0,-0.00025)</browOffset>
<mouthOffset>(0,0,-0.000625)</mouthOffset>
</li>
</animationFrames>
<roopIntervalMin>100</roopIntervalMin>
<roopIntervalMax>200</roopIntervalMax>
<targetJobs>
<li>DoBill</li>
</targetJobs>
<priority>10001</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
</FacialAnimation.FaceAnimationDef>
</Defs>

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Goto</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>1</duration>
<browShapeDef>angled</browShapeDef>
<mouthShapeDef>normal</mouthShapeDef>
<headOffset>(0.0,0,-0.0025)</headOffset>
</li>
</animationFrames>
<targetJobs>
<li>Goto</li>
</targetJobs>
<priority>10300</priority>
</FacialAnimation.FaceAnimationDef>
</Defs>

View File

@@ -1,32 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Ingest</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>4</duration>
<headOffset>(0.0,0,0.0025)</headOffset>
<mouthShapeDef>open</mouthShapeDef>
</li>
<li>
<duration>4</duration>
<headOffset>(0.0,0,0.005)</headOffset>
<mouthShapeDef>open</mouthShapeDef>
</li>
<li>
<duration>6</duration>
<headOffset>(0.0,0,0)</headOffset>
<mouthShapeDef>normal</mouthShapeDef>
</li>
</animationFrames>
<roopIntervalMin>0</roopIntervalMin>
<roopIntervalMax>30</roopIntervalMax>
<targetJobs>
<li>Ingest</li>
</targetJobs>
<priority>10</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
</FacialAnimation.FaceAnimationDef>
</Defs>

View File

@@ -1,76 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_laydown</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>1</duration>
<browShapeDef>flat</browShapeDef>
<lidShapeDef>close</lidShapeDef>
<mouthShapeDef>normal</mouthShapeDef>
</li>
</animationFrames>
<roopIntervalMin>0</roopIntervalMin>
<roopIntervalMax>0</roopIntervalMax>
<targetJobs>
<li>LayDown</li>
</targetJobs>
<priority>10001</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
</FacialAnimation.FaceAnimationDef>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_laydown2</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>240</duration>
<mouthShapeDef>open</mouthShapeDef>
</li>
</animationFrames>
<roopIntervalMin>100</roopIntervalMin>
<roopIntervalMax>500</roopIntervalMax>
<targetJobs>
<li>LayDown</li>
</targetJobs>
<priority>10002</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
</FacialAnimation.FaceAnimationDef>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_laydown3</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>15</duration>
<lidOffset>(0.0,0,0.0015)</lidOffset>
<headOffset>(0,0,0.0035)</headOffset>
<browOffset>(0,0,0.00025)</browOffset>
<mouthOffset>(0,0,0.000625)</mouthOffset>
</li>
<li>
<duration>60</duration>
<lidOffset>(0.0,0,0.00275)</lidOffset>
<headOffset>(0,0,0.0075)</headOffset>
<browOffset>(0,0,0.00375)</browOffset>
<mouthOffset>(0,0,0.00125)</mouthOffset>
</li>
<li>
<duration>10</duration>
<lidOffset>(0.0,0,0.0015)</lidOffset>
<headOffset>(0,0,0.0035)</headOffset>
<browOffset>(0,0,0.00025)</browOffset>
<mouthOffset>(0,0,0.000625)</mouthOffset>
</li>
</animationFrames>
<roopIntervalMin>40</roopIntervalMin>
<roopIntervalMax>200</roopIntervalMax>
<targetJobs>
<li>LayDown</li>
</targetJobs>
<priority>10003</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
</FacialAnimation.FaceAnimationDef>
</Defs>

View File

@@ -1,80 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Lovin</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>8</duration>
<browShapeDef>s-shaped</browShapeDef>
<headOffset>(0.0,0,0.00125)</headOffset>
<browOffset>(0.0,0,-0.005)</browOffset>
<lidShapeDef>close</lidShapeDef>
<lidOffset>(0.0,0,-0.001)</lidOffset>
<eyeballOffset>(0.0,0,0.0075)</eyeballOffset>
<mouthShapeDef>open</mouthShapeDef>
<headShapeDef>blush</headShapeDef>
</li>
<li>
<duration>8</duration>
<browShapeDef>s-shaped</browShapeDef>
<headOffset>(0.0,0,-0.00375)</headOffset>
<browOffset>(0.0,0,-0.0075)</browOffset>
<lidShapeDef>close</lidShapeDef>
<lidOffset>(0.0,0,-0.0015)</lidOffset>
<eyeballOffset>(0.0,0,0.0075)</eyeballOffset>
<mouthShapeDef>open</mouthShapeDef>
<mouthOffset>(0,0,-0.002)</mouthOffset>
<headShapeDef>blush</headShapeDef>
</li>
<li>
<duration>8</duration>
<browShapeDef>s-shaped</browShapeDef>
<headOffset>(0.0,0,0.0075)</headOffset>
<browOffset>(0.0,0,0.00125)</browOffset>
<lidShapeDef>close</lidShapeDef>
<lidOffset>(0.0,0,0.001)</lidOffset>
<eyeballOffset>(0.0,0,0.0075)</eyeballOffset>
<mouthShapeDef>open</mouthShapeDef>
<mouthOffset>(0,0,-0.001)</mouthOffset>
<headShapeDef>blush</headShapeDef>
</li>
</animationFrames>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
<targetJobs>
<li>Lovin</li>
<li>MLI_Jobs_MassLoveIn</li>
<li>MLI_Jobs_SingleLoveIn</li>
</targetJobs>
<priority>10400</priority>
</FacialAnimation.FaceAnimationDef>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Lovin2</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>240</duration>
<browShapeDef>s-shaped</browShapeDef>
<headOffset>(0.0,0,0.01)</headOffset>
<browOffset>(0.0,0,-0.00)</browOffset>
<lidShapeDef>normal</lidShapeDef>
<lidOffset>(0.0,0,-0.001)</lidOffset>
<mouthOffset>(0,0,-0.001)</mouthOffset>
<eyeballOffset>(0.0,0,0.005)</eyeballOffset>
<mouthShapeDef>normal</mouthShapeDef>
<headShapeDef>blush</headShapeDef>
</li>
</animationFrames>
<roopIntervalMin>240</roopIntervalMin>
<roopIntervalMax>240</roopIntervalMax>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
<targetJobs>
<li>Lovin</li>
<li>MLI_Jobs_MassLoveIn</li>
<li>MLI_Jobs_SingleLoveIn</li>
</targetJobs>
<priority>10500</priority>
</FacialAnimation.FaceAnimationDef>
</Defs>

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Mine</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>10</duration>
<lidOffset>(0,0,0.005)</lidOffset>
<headOffset>(0,0,0)</headOffset>
<browShapeDef>angled</browShapeDef>
<mouthOffset>(0,0,0.0025)</mouthOffset>
<mouthShapeDef>open</mouthShapeDef>
</li>
<li>
<duration>5</duration>
<lidOffset>(0,0,0.01)</lidOffset>
<headOffset>(0,0,-0.01)</headOffset>
<browShapeDef>angled</browShapeDef>
<mouthOffset>(0,0,-0.0025)</mouthOffset>
<mouthShapeDef>open</mouthShapeDef>
</li>
</animationFrames>
<roopIntervalMin>0</roopIntervalMin>
<roopIntervalMax>0</roopIntervalMax>
<targetJobs>
<li>Mine</li>
</targetJobs>
<priority>10000</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
</FacialAnimation.FaceAnimationDef>
</Defs>

View File

@@ -1,78 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_RemoveApparel</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>10</duration>
<lidOffset>(0,0,0.0)</lidOffset>
<eyeballOffset>(-0.005,0,0.005)</eyeballOffset>
<mouthShapeDef>open</mouthShapeDef>
<headShapeDef>blush</headShapeDef>
</li>
<li>
<duration>10</duration>
<lidOffset>(0,0,0.0)</lidOffset>
<eyeballOffset>(0.005,0,0.005)</eyeballOffset>
<mouthShapeDef>open</mouthShapeDef>
<headShapeDef>blush</headShapeDef>
</li>
<li>
<duration>10</duration>
<lidOffset>(0,0,0.0)</lidOffset>
<eyeballOffset>(0,0,0.005)</eyeballOffset>
<mouthShapeDef>open</mouthShapeDef>
<headShapeDef>blush</headShapeDef>
</li>
</animationFrames>
<targetJobs>
<li>RemoveApparel</li>
</targetJobs>
<priority>105</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
<roopIntervalMin>30 </roopIntervalMin>
<roopIntervalMax>300</roopIntervalMax>
</FacialAnimation.FaceAnimationDef>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_RemoveApparel2</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>1</duration>
<browShapeDef>s-shaped</browShapeDef>
<lidShapeDef>normal</lidShapeDef>
<eyeballOffset>(0.0,0,0.005)</eyeballOffset>
<headShapeDef>blush</headShapeDef>
</li>
</animationFrames>
<targetJobs>
<li>RemoveApparel</li>
</targetJobs>
<priority>104</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
</FacialAnimation.FaceAnimationDef>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_RemoveApparel3</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>120</duration>
<browShapeDef>flat</browShapeDef>
<lidShapeDef>close</lidShapeDef>
<headOffset>(0.0,0,0.005)</headOffset>
<headShapeDef>blush</headShapeDef>
</li>
</animationFrames>
<targetJobs>
<li>RemoveApparel</li>
</targetJobs>
<priority>110</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
<roopIntervalMin>30 </roopIntervalMin>
<roopIntervalMax>300</roopIntervalMax>
</FacialAnimation.FaceAnimationDef>
</Defs>

View File

@@ -1,100 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Research</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>10</duration>
<lidOffset>(0,0,-0.005)</lidOffset>
<headOffset>(0,0,-0.01)</headOffset>
<browShapeDef>flat</browShapeDef>
<mouthShapeDef>normal</mouthShapeDef>
<mouthOffset>(0,0,-0.00375)</mouthOffset>
</li>
</animationFrames>
<targetJobs>
<li>Research</li>
</targetJobs>
<priority>10001</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
</FacialAnimation.FaceAnimationDef>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Research2</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>4</duration>
<browOffset>(0,0,0.00325)</browOffset>
<lidOffset>(0,0,0.00625)</lidOffset>
<headOffset>(0,0,0.005)</headOffset>
<browShapeDef>normal</browShapeDef>
<mouthShapeDef>open</mouthShapeDef>
</li>
<li>
<duration>40</duration>
<browOffset>(0,0,0.00625)</browOffset>
<lidOffset>(0,0,0.00875)</lidOffset>
<headOffset>(0,0,0.01)</headOffset>
<browShapeDef>normal</browShapeDef>
<mouthOffset>(0,0,0.0025)</mouthOffset>
<mouthShapeDef>open</mouthShapeDef>
</li>
<li>
<duration>3</duration>
<browOffset>(0,0,0.00625)</browOffset>
<lidOffset>(0,0,0.00875)</lidOffset>
<headOffset>(0,0,0.01)</headOffset>
<lidShapeDef>close</lidShapeDef>
<browShapeDef>normal</browShapeDef>
<mouthOffset>(0,0,0.0025)</mouthOffset>
<mouthShapeDef>open</mouthShapeDef>
</li>
<li>
<duration>20</duration>
<browOffset>(0,0,0.00625)</browOffset>
<lidOffset>(0,0,0.00875)</lidOffset>
<headOffset>(0,0,0.01)</headOffset>
<browShapeDef>normal</browShapeDef>
<mouthOffset>(0,0,0.0025)</mouthOffset>
<mouthShapeDef>open</mouthShapeDef>
</li>
<li>
<duration>3</duration>
<browOffset>(0,0,0.00625)</browOffset>
<lidOffset>(0,0,0.00875)</lidOffset>
<headOffset>(0,0,0.01)</headOffset>
<lidShapeDef>close</lidShapeDef>
<browShapeDef>normal</browShapeDef>
<mouthOffset>(0,0,0.0025)</mouthOffset>
<mouthShapeDef>open</mouthShapeDef>
</li>
<li>
<duration>40</duration>
<browOffset>(0,0,0.00625)</browOffset>
<lidOffset>(0,0,0.00875)</lidOffset>
<headOffset>(0,0,0.01)</headOffset>
<browShapeDef>normal</browShapeDef>
<mouthOffset>(0,0,0.0025)</mouthOffset>
<mouthShapeDef>open</mouthShapeDef>
</li>
<li>
<duration>8</duration>
<browOffset>(0,0,0.00325)</browOffset>
<lidOffset>(0,0,0.00625)</lidOffset>
<headOffset>(0,0,0.005)</headOffset>
<browShapeDef>normal</browShapeDef>
<mouthShapeDef>open</mouthShapeDef>
</li>
</animationFrames>
<roopIntervalMin>900</roopIntervalMin>
<roopIntervalMax>1200</roopIntervalMax>
<targetJobs>
<li>Research</li>
</targetJobs>
<priority>10002</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
</FacialAnimation.FaceAnimationDef>
</Defs>

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_SocialRelax</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>1</duration>
<browShapeDef>normal</browShapeDef>
<lidShapeDef>close</lidShapeDef>
</li>
</animationFrames>
<targetJobs>
<li>SocialRelax</li>
</targetJobs>
<priority>10200</priority>
</FacialAnimation.FaceAnimationDef>
</Defs>

View File

@@ -1,35 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_StandAndBeSociallyActive</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>3</duration>
<browShapeDef>normal</browShapeDef>
<headOffset>(0.0,0,-0.0025)</headOffset>
<mouthShapeDef>open</mouthShapeDef>
</li>
<li>
<duration>3</duration>
<browShapeDef>normal</browShapeDef>
<headOffset>(0.0,0,-0.005)</headOffset>
<mouthShapeDef>open</mouthShapeDef>
</li>
<li>
<duration>3</duration>
<browShapeDef>normal</browShapeDef>
<headOffset>(0.0,0,0)</headOffset>
<mouthShapeDef>normal</mouthShapeDef>
</li>
</animationFrames>
<roopIntervalMin>0</roopIntervalMin>
<roopIntervalMax>100</roopIntervalMax>
<targetJobs>
<li>StandAndBeSociallyActive</li>
</targetJobs>
<priority>10</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
</FacialAnimation.FaceAnimationDef>
</Defs>

View File

@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Strip</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>10</duration>
<lidOffset>(0,0,0.0)</lidOffset>
<eyeballOffset>(-0.005,0,0.005)</eyeballOffset>
<headShapeDef>blush</headShapeDef>
</li>
<li>
<duration>10</duration>
<lidOffset>(0,0,0.0)</lidOffset>
<eyeballOffset>(0.005,0,0.005)</eyeballOffset>
<headShapeDef>blush</headShapeDef>
</li>
<li>
<duration>10</duration>
<lidOffset>(0,0,0.0)</lidOffset>
<eyeballOffset>(0,0,0.005)</eyeballOffset>
<headShapeDef>blush</headShapeDef>
</li>
</animationFrames>
<targetJobs>
<li>Strip</li>
</targetJobs>
<priority>105</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
<roopIntervalMin>30 </roopIntervalMin>
<roopIntervalMax>300</roopIntervalMax>
</FacialAnimation.FaceAnimationDef>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>Strip2</defName>
<animationFrames>
<li>
<duration>1</duration>
<browShapeDef>s-shaped</browShapeDef>
<lidShapeDef>normal</lidShapeDef>
<mouthShapeDef>open</mouthShapeDef>
<headShapeDef>blush</headShapeDef>
</li>
</animationFrames>
<targetJobs>
<li>Strip</li>
</targetJobs>
<priority>106</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
</FacialAnimation.FaceAnimationDef>
</Defs>

View File

@@ -1,84 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_WaitCombat</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>1</duration>
<browShapeDef>angled</browShapeDef>
<mouthShapeDef>normal</mouthShapeDef>
</li>
</animationFrames>
<targetJobs>
<li>Wait_Combat</li>
</targetJobs>
<priority>10200</priority>
</FacialAnimation.FaceAnimationDef>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Wait_Combat_Rare</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>15</duration>
<browShapeDef>normal</browShapeDef>
</li>
<li>
<duration>4</duration>
<browOffset>(0,0,-0.00375)</browOffset>
<browShapeDef>flat</browShapeDef>
<lidShapeDef>close</lidShapeDef>
<lidOffset>(0,0,-0.0025)</lidOffset>
<headOffset>(0,0,-0.00625)</headOffset>
<mouthShapeDef>open</mouthShapeDef>
</li>
<li>
<duration>45</duration>
<browOffset>(0,0,-0.01)</browOffset>
<browShapeDef>s-shaped</browShapeDef>
<lidShapeDef>close</lidShapeDef>
<lidOffset>(0,0,-0.005)</lidOffset>
<headOffset>(0,0,-0.0175)</headOffset>
<mouthShapeDef>open</mouthShapeDef>
<mouthOffset>(0,0,-0.005)</mouthOffset>
</li>
<li>
<duration>30</duration>
<browOffset>(0,0,-0.01)</browOffset>
<browShapeDef>s-shaped</browShapeDef>
<lidShapeDef>close</lidShapeDef>
<lidOffset>(0,0,-0.005)</lidOffset>
<headOffset>(0,0,-0.015)</headOffset>
<mouthShapeDef>open</mouthShapeDef>
<mouthOffset>(0,0,-0.005)</mouthOffset>
</li>
<li>
<duration>7</duration>
<browOffset>(0,0,-0.00375)</browOffset>
<browShapeDef>s-shaped</browShapeDef>
<lidShapeDef>close</lidShapeDef>
<lidOffset>(0,0,-0.0025)</lidOffset>
<headOffset>(0,0,-0.0085)</headOffset>
<mouthShapeDef>open</mouthShapeDef>
</li>
<li>
<duration>4</duration>
<browShapeDef>flat</browShapeDef>
<lidShapeDef>close</lidShapeDef>
<mouthShapeDef>normal</mouthShapeDef>
</li>
<li>
<duration>30</duration>
<browShapeDef>normal</browShapeDef>
</li>
</animationFrames>
<targetJobs>
<li>Wait_Combat</li>
</targetJobs>
<priority>10301</priority>
<roopIntervalMin>1000</roopIntervalMin>
<roopIntervalMax>2000</roopIntervalMax>
</FacialAnimation.FaceAnimationDef>
</Defs>

View File

@@ -1,50 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Wait_Downed</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>30</duration>
<browOffset>(0,0,0.015)</browOffset>
<lidOffset>(0,0,0.01)</lidOffset>
<headOffset>(0,0,0.01)</headOffset>
<browShapeDef>flat</browShapeDef>
<mouthOffset>(0,0,0.0025)</mouthOffset>
<mouthShapeDef>open</mouthShapeDef>
</li>
<li>
<duration>3</duration>
<browOffset>(0,0,0.0075)</browOffset>
<lidOffset>(0,0,0.005)</lidOffset>
<headOffset>(0,0,0.005)</headOffset>
<browShapeDef>flat</browShapeDef>
<mouthShapeDef>normal</mouthShapeDef>
</li>
</animationFrames>
<roopIntervalMin>0</roopIntervalMin>
<roopIntervalMax>100</roopIntervalMax>
<targetJobs>
<li>Wait_Downed</li>
</targetJobs>
<priority>10000</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
</FacialAnimation.FaceAnimationDef>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>Wait_Downed2</defName>
<animationFrames>
<li>
<duration>3</duration>
<lidOffset>(0,0,0.005)</lidOffset>
<browShapeDef>flat</browShapeDef>
</li>
</animationFrames>
<targetJobs>
<li>Wait_Downed</li>
</targetJobs>
<priority>10001</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
</FacialAnimation.FaceAnimationDef>
</Defs>

View File

@@ -1,77 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Wear</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>10</duration>
<lidOffset>(0,0,0.0)</lidOffset>
<eyeballOffset>(-0.005,0,0.005)</eyeballOffset>
<mouthShapeDef>open</mouthShapeDef>
<headShapeDef>blush</headShapeDef>
</li>
<li>
<duration>10</duration>
<lidOffset>(0,0,0.0)</lidOffset>
<eyeballOffset>(0.005,0,0.005)</eyeballOffset>
<mouthShapeDef>open</mouthShapeDef>
<headShapeDef>blush</headShapeDef>
</li>
<li>
<duration>10</duration>
<lidOffset>(0,0,0.0)</lidOffset>
<eyeballOffset>(0,0,0.005)</eyeballOffset>
<mouthShapeDef>open</mouthShapeDef>
<headShapeDef>blush</headShapeDef>
</li>
</animationFrames>
<targetJobs>
<li>Wear</li>
</targetJobs>
<priority>105</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
<roopIntervalMin>30 </roopIntervalMin>
<roopIntervalMax>300</roopIntervalMax>
</FacialAnimation.FaceAnimationDef>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>ArachnaeNode_Wear2</defName>
<raceName>ArachnaeNode_Race_Myrmecocystus</raceName>
<animationFrames>
<li>
<duration>1</duration>
<browShapeDef>s-shaped</browShapeDef>
<lidShapeDef>normal</lidShapeDef>
<eyeballOffset>(0.0,0,0.005)</eyeballOffset>
<headShapeDef>blush</headShapeDef>
</li>
</animationFrames>
<targetJobs>
<li>Wear</li>
</targetJobs>
<priority>104</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
</FacialAnimation.FaceAnimationDef>
<FacialAnimation.FaceAnimationDef MayRequire="Nals.FacialAnimation">
<defName>Wear3</defName>
<animationFrames>
<li>
<duration>120</duration>
<browShapeDef>flat</browShapeDef>
<lidShapeDef>close</lidShapeDef>
<headOffset>(0.0,0,0.005)</headOffset>
<headShapeDef>blush</headShapeDef>
</li>
</animationFrames>
<targetJobs>
<li>Wear</li>
</targetJobs>
<priority>110</priority>
<applyWhenStandingOnly>true</applyWhenStandingOnly>
<roopIntervalMin>30 </roopIntervalMin>
<roopIntervalMax>300</roopIntervalMax>
</FacialAnimation.FaceAnimationDef>
</Defs>

View File

@@ -173,6 +173,37 @@
</spawnCategories>
</AlienRace.AlienBackstoryDef>
<AlienRace.AlienBackstoryDef ParentName="ARA_BaseBackStory">
<defName>Arachnae_Node_BS_Adult_Skyraider</defName>
<title>阿拉克涅空天种</title>
<titleShort>空天种</titleShort>
<description>[PAWN_nameDef]是一只阿拉克涅空天种督虫,空天种作为阿拉克涅督虫中的精锐,进化出了强大的飞行能力,是巢穴中无可争议的空中霸主。\n\n作为为数不多拥有飞行能力的虫族她可以从空中掠袭猎物并将其带至千米高空之上俯冲投下只留其余猎物在地面无助的挣扎。</description>
<slot>Adulthood</slot>
<workDisables>
<li>Cleaning</li>
<!-- <li>Hauling</li> -->
<li>Mining</li>
<li>PlantWork</li>
<!-- <li>Animals</li> -->
<!-- <li>Hunting</li> -->
<li>Crafting</li>
<li>Cooking</li>
<li>Constructing</li>
<li>Caring</li>
<li>Social</li>
<li>Artistic</li>
<li>Intellectual</li>
</workDisables>
<skillGains>
<Shooting>5</Shooting>
<Melee>5</Melee>
</skillGains>
<spawnCategories>
<li>ArachnaeNode_spawnCategories_Skyraider</li>
</spawnCategories>
</AlienRace.AlienBackstoryDef>
<AlienRace.AlienBackstoryDef ParentName="ARA_BaseBackStory">
<defName>Arachnae_Node_BS_Adult_Facehugger</defName>
<title>阿拉克涅原虫种</title>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<!-- North Frames -->
<GraphicStateDef><defName>ARA_FlyNorth_0</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_1_north</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlyNorth_1</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_2_north</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlyNorth_2</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_3_north</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlyNorth_3</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_4_north</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlyNorth_4</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_5_north</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlyNorth_5</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_6_north</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlyNorth_6</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_7_north</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlyNorth_7</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_8_north</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<!-- East Frames -->
<GraphicStateDef><defName>ARA_FlyEast_0</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_1_east</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlyEast_1</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_2_east</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlyEast_2</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_3_east</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlyEast_3</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_4_east</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlyEast_4</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_5_east</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlyEast_5</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_6_east</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlyEast_6</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_7_east</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlyEast_7</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_8_east</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<!-- South Frames -->
<GraphicStateDef><defName>ARA_FlySouth_0</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_1_south</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlySouth_1</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_2_south</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlySouth_2</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_3_south</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlySouth_3</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_4_south</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlySouth_4</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_5_south</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlySouth_5</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_6_south</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlySouth_6</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_7_south</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
<GraphicStateDef><defName>ARA_FlySouth_7</defName><defaultGraphicData><graphicClass>Graphic_Single</graphicClass><texPath>Things/Pawn/Animal/Goose/Goose_Flying_8_south</texPath><drawSize>1.35</drawSize></defaultGraphicData></GraphicStateDef>
</Defs>

View File

@@ -12,7 +12,7 @@
<HeadTypeDef ParentName="ARA_FemaleHeadtypeBase">
<defName>ARA_QUEEN_Female_AverageNormalA</defName>
<graphicPath>Textures/Pawns/General/Invisible/Inv</graphicPath>
<graphicPath>ArachnaeSwarm/Things/General/Invisible/Inv</graphicPath>
</HeadTypeDef>

View File

@@ -4,7 +4,21 @@
<JobDef>
<defName>ARA_StartInteractiveProduction</defName>
<driverClass>ArachnaeSwarm.JobDriver_StartProduction</driverClass>
<reportString>正在启动生产 TargetA.</reportString>
<reportString>正在启动孵化 TargetA.</reportString>
<allowOpportunisticPrefix>true</allowOpportunisticPrefix>
</JobDef>
<JobDef>
<defName>ARA_AddToQueueJob</defName>
<driverClass>ArachnaeSwarm.JobDriver_AddToQueue</driverClass>
<reportString>正在添加虫族孵化订单。</reportString>
<allowOpportunisticPrefix>true</allowOpportunisticPrefix>
</JobDef>
<JobDef>
<defName>ARA_AddProcessToQueueJob</defName>
<driverClass>ArachnaeSwarm.JobDriver_AddProcessToQueue</driverClass>
<reportString>正在添加物品孵化订单。</reportString>
<allowOpportunisticPrefix>true</allowOpportunisticPrefix>
</JobDef>

View File

@@ -169,7 +169,7 @@
</apparelTags>
<apparelMoney>0</apparelMoney>
</PawnKindDef>
<PawnKindDef ParentName="ArachnaeNodeABasePawnKind">
<PawnKindDef ParentName="ArachnaeNodeABasePawnKind">
<defName>ArachnaeNode_Race_Facehugger</defName>
<label>阿拉克涅原虫种</label>
<race>ArachnaeNode_Race_Facehugger</race>
@@ -213,6 +213,34 @@
</apparelTags>
<apparelMoney>0</apparelMoney>
</PawnKindDef>
<PawnKindDef ParentName="ArachnaeNodeABasePawnKind">
<defName>ArachnaeNode_Race_Skyraider</defName>
<label>阿拉克涅空天种</label>
<race>ArachnaeNode_Race_Skyraider</race>
<defaultFactionType>PlayerColony</defaultFactionType>
<invNutrition>0</invNutrition>
<flyingAnimationFramePathPrefix>Things/Pawn/Animal/Goose/Goose_Flying_</flyingAnimationFramePathPrefix>
<flyingAnimationDrawSize>1.35</flyingAnimationDrawSize>
<flyingAnimationFrameCount>2</flyingAnimationFrameCount>
<flyingAnimationTicksPerFrame>2</flyingAnimationTicksPerFrame>
<flyingAnimationInheritColors>false</flyingAnimationInheritColors>
<backstoryFiltersOverride>
<li>
<categories>
<li>ArachnaeNode_spawnCategoriesA</li>
<li>ArachnaeNode_spawnCategories_Fighter</li>
</categories>
</li>
</backstoryFiltersOverride>
<abilities>
<li>ARA_BaseRace_Acid_Launcher</li>
<li>ARA_AcidSprayBurst</li>
<li>ARA_Toxic_Needle_Fire</li>
</abilities>
<apparelTags>
</apparelTags>
<apparelMoney>0</apparelMoney>
</PawnKindDef>
<PawnKindDef Name="ARA_InsectKindBase" ParentName="AnimalKindBase" Abstract="True">
<defaultFactionType>PlayerColony</defaultFactionType>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<PawnRenderNodeTagDef>
<defName>ARA_Flight_Attachment</defName>
</PawnRenderNodeTagDef>
</Defs>

View File

@@ -0,0 +1,159 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<PawnRenderTreeDef>
<defName>ARA_ArachnaeRenderTree</defName>
<root Class="PawnRenderNodeProperties_Parent">
<debugLabel>Root</debugLabel>
<tagDef>Root</tagDef>
<children>
<li>
<debugLabel>Body</debugLabel>
<nodeClass>PawnRenderNode_Body</nodeClass>
<workerClass>PawnRenderNodeWorker_Body</workerClass>
<tagDef>Body</tagDef>
<skipFlag>Body</skipFlag>
<colorType>Skin</colorType>
<useRottenColor>true</useRottenColor>
<useSkinShader>true</useSkinShader>
<children>
<li Class="PawnRenderNodeProperties_Tattoo" MayRequire="Ludeon.RimWorld.Ideology">
<debugLabel>Body tattoo</debugLabel>
<nodeClass>PawnRenderNode_Tattoo_Body</nodeClass>
<workerClass>PawnRenderNodeWorker_Body_Tattoo</workerClass>
<colorType>Skin</colorType>
<useRottenColor>true</useRottenColor>
<baseLayer>2</baseLayer>
<rotDrawMode>Fresh, Rotting</rotDrawMode>
</li>
<li Class="PawnRenderNodeProperties_Overlay">
<debugLabel>Wounds - pre apparel</debugLabel>
<workerClass>PawnRenderNodeWorker_OverlayWounds</workerClass>
<overlayLayer>Body</overlayLayer>
<baseLayer>8</baseLayer>
</li>
<li Class="PawnRenderNodeProperties_Swaddle" MayRequire="Ludeon.RimWorld.Biotech">
<debugLabel>Baby swaddle</debugLabel>
<nodeClass>PawnRenderNode_Swaddle</nodeClass>
<workerClass>PawnRenderNodeWorker_Swaddle</workerClass>
<texPath>Things/Pawn/Humanlike/Apparel/SwaddledBaby/Swaddled_Child</texPath>
<swaddleColorOffset>0.1</swaddleColorOffset>
<brightnessRange>0.6~0.89</brightnessRange>
<baseLayer>10</baseLayer>
</li>
<!-- ===== OUR CUSTOM NODE INSERTION START ===== -->
<!-- Using Milira's exact structure for testing -->
<li>
<debugLabel>Arachnae Flight Attachment</debugLabel>
<tagDef>ARA_Flight_Attachment</tagDef>
<texPath>ArachnaeSwarm/Things/General/Invisible/Inv</texPath>
<baseLayer>60</baseLayer>
<drawData>
<dataSouth>
<layer>-10</layer>
</dataSouth>
</drawData>
</li>
<!-- ===== OUR CUSTOM NODE INSERTION END ===== -->
<li Class="PawnRenderNodeProperties_Parent">
<debugLabel>Apparel root</debugLabel>
<tagDef>ApparelBody</tagDef>
<baseLayer>20</baseLayer>
</li>
<li Class="PawnRenderNodeProperties_Overlay">
<debugLabel>Wounds - post apparel</debugLabel>
<workerClass>PawnRenderNodeWorker_OverlayWounds</workerClass>
<overlayOverApparel>true</overlayOverApparel>
<overlayLayer>Body</overlayLayer>
<baseLayer>30</baseLayer>
</li>
<li Class="PawnRenderNodeProperties_Overlay">
<debugLabel>Firefoam</debugLabel>
<workerClass>PawnRenderNodeWorker_OverlayFirefoam</workerClass>
<overlayLayer>Body</overlayLayer>
<baseLayer>40</baseLayer>
</li>
</children>
</li>
<li>
<debugLabel>Head stump</debugLabel>
<nodeClass>PawnRenderNode_Stump</nodeClass>
<workerClass>PawnRenderNodeWorker_Stump</workerClass>
<texPath>Things/Pawn/Humanlike/Heads/None_Average_Stump</texPath>
<baseLayer>50</baseLayer>
<colorType>Skin</colorType>
<skipFlag>Head</skipFlag>
<useSkinShader>true</useSkinShader>
<useRottenColor>true</useRottenColor>
<rotDrawMode>Fresh, Rotting</rotDrawMode>
</li>
<li>
<debugLabel>Head</debugLabel>
<nodeClass>PawnRenderNode_Head</nodeClass>
<workerClass>PawnRenderNodeWorker_Head</workerClass>
<tagDef>Head</tagDef>
<skipFlag>Head</skipFlag>
<baseLayer>50</baseLayer>
<colorType>Skin</colorType>
<useRottenColor>true</useRottenColor>
<useSkinShader>true</useSkinShader>
<children>
<li Class="PawnRenderNodeProperties_Tattoo" MayRequire="Ludeon.RimWorld.Ideology">
<debugLabel>Head tattoo</debugLabel>
<nodeClass>PawnRenderNode_Tattoo_Head</nodeClass>
<workerClass>PawnRenderNodeWorker_Tattoo_Head</workerClass>
<rotDrawMode>Fresh, Rotting</rotDrawMode>
<colorType>Skin</colorType>
<baseLayer>52</baseLayer>
</li>
<li>
<debugLabel>Beard</debugLabel>
<nodeClass>PawnRenderNode_Beard</nodeClass>
<workerClass>PawnRenderNodeWorker_Beard</workerClass>
<rotDrawMode>Fresh, Rotting</rotDrawMode>
<colorType>Hair</colorType>
<skipFlag>Beard</skipFlag>
<baseLayer>60</baseLayer>
</li>
<li>
<debugLabel>Hair</debugLabel>
<nodeClass>PawnRenderNode_Hair</nodeClass>
<workerClass>PawnRenderNodeWorker_FlipWhenCrawling</workerClass>
<rotDrawMode>Fresh, Rotting</rotDrawMode>
<colorType>Hair</colorType>
<skipFlag>Hair</skipFlag>
<baseLayer>62</baseLayer>
</li>
<li Class="PawnRenderNodeProperties_Overlay">
<debugLabel>Head wounds</debugLabel>
<workerClass>PawnRenderNodeWorker_OverlayWounds</workerClass>
<overlayLayer>Head</overlayLayer>
<baseLayer>65</baseLayer>
</li>
<li Class="PawnRenderNodeProperties_Parent">
<debugLabel>Apparel root</debugLabel>
<tagDef>ApparelHead</tagDef>
<baseLayer>70</baseLayer>
</li>
<li Class="PawnRenderNodeProperties_Overlay">
<debugLabel>Firefoam</debugLabel>
<workerClass>PawnRenderNodeWorker_OverlayFirefoam</workerClass>
<overlayLayer>Head</overlayLayer>
<baseLayer>85</baseLayer>
</li>
<li Class="PawnRenderNodeProperties_Overlay">
<debugLabel>Status overlay</debugLabel>
<workerClass>PawnRenderNodeWorker_OverlayStatus</workerClass>
<baseLayer>100</baseLayer>
</li>
</children>
</li>
<li Class="PawnRenderNodeProperties_Carried">
<debugLabel>Weapon/carried thing</debugLabel>
<workerClass>PawnRenderNodeWorker_Carried</workerClass>
</li>
</children>
</root>
</PawnRenderTreeDef>
</Defs>

View File

@@ -22,7 +22,6 @@
<li Class="HediffCompProperties_GiveAbility">
<abilityDefs>
<li>ARA_EggSpew</li>
<li>ARA_EggSpew_BaseFighter</li>
<li>ARA_BindDrone</li>
<li>ARA_Queen_Upgrade_1_Stage</li>
<li>ARA_AcidSprayBurst_Queen</li>
@@ -111,7 +110,6 @@
<li Class="HediffCompProperties_GiveAbility">
<abilityDefs>
<li>ARA_EggSpew</li>
<li>ARA_EggSpew_BaseFighter</li>
<li>ARA_BindDrone</li>
<li>ARA_AcidSprayBurst_Queen</li>
<li>ARA_Queen_Upgrade_2_Stage</li>
@@ -195,7 +193,6 @@
<li Class="HediffCompProperties_GiveAbility">
<abilityDefs>
<li>ARA_EggSpew</li>
<li>ARA_EggSpew_BaseFighter</li>
<li>ARA_BindDrone</li>
<li>ARA_AcidSprayBurst_Queen</li>
<!-- <li>ARA_Queen_Upgrade_2_Stage</li> -->

View File

@@ -60,9 +60,11 @@
<li>(0.0, 0, -0.12)</li>
<li>(-0.07, 0, 0.08)</li>
</headPosPerRotation>
<!-- <deathAction Class="DeathActionProperties_Vanish">
<deathAction Class="DeathActionProperties_Vanish">
<workerClass>DeathActionWorker_Vanish</workerClass>
</deathAction> -->
<filth>Filth_Slime</filth>
<filthCountRange>1~3</filthCountRange>
</deathAction>
</race>
<comps>
<li Class="ArachnaeSwarm.CompProperties_HediffGiver">

View File

@@ -672,7 +672,7 @@
<AlienRace.ThingDef_AlienRace ParentName="ARA_NodeBase">
<defName>ArachnaeNode_Race_Myrmecocystus</defName>
<label>阿拉克涅蜜罐种</label>
<description>阿拉克涅督虫之一,拥有非常广泛的食谱,可以吞下许多未经处理的生物并将其分解为阿拉克涅虫蜜,以滋养虫群。这种督虫除了生产虫蜜外也能执行烹饪工作。\n\n作为督虫她可以繁育并监管若干阿拉克涅苦役种辅虫,以协助巢穴进行搬运工作。</description>
<description>阿拉克涅督虫之一,拥有非常广泛的食谱,可以吞下许多未经处理的生物并将其分解为阿拉克涅虫蜜,以滋养虫群。这种督虫除了生产虫蜜外也能执行烹饪和种植工作。\n\n作为督虫她可以繁育并监管若干阿拉克涅食腐种辅虫,以协助巢穴进行收割和播种工作。</description>
<alienRace>
<generalSettings>
<!-- 各种零件定义 -->
@@ -774,7 +774,7 @@
<AlienRace.ThingDef_AlienRace ParentName="ARA_NodeBase">
<defName>ArachnaeNode_Race_ShieldHead</defName>
<label>阿拉克涅盾头种</label>
<description>阿拉克涅督虫之一,拥有过度生长而覆盖头部和腿部的甲壳,防御力超群的同时还可以定时剥落甲壳素供虫巢使用。坚韧的鳌刺挥舞起来非常缓慢但是可以破开岩壁,以完成虫群的采矿工作。\n\n作为督虫她可以繁育并监管若干阿拉克涅坚颚种辅虫以协助巢穴开采矿脉。</description>
<description>阿拉克涅督虫之一,拥有过度生长而覆盖头部和腿部的甲壳,防御力超群的同时还可以定时剥落甲壳素供虫巢使用。坚韧的鳌刺挥舞起来非常缓慢但是可以破开岩壁和固定结构,以完成虫群的采矿和建筑工作。\n\n作为督虫她可以繁育并监管若干阿拉克涅坚颚种辅虫以协助巢穴开采矿脉。</description>
<alienRace>
<generalSettings>
<!-- 各种零件定义 -->
@@ -807,7 +807,7 @@
</south>
<north>
<layerOffset>-0.275</layerOffset>
</north>
</north>
<east>
<layerOffset>-0.275</layerOffset>
</east>
@@ -898,7 +898,7 @@
<AlienRace.ThingDef_AlienRace ParentName="ARA_NodeBase">
<defName>ArachnaeNode_Race_WeaponSmith</defName>
<label>阿拉克涅工艺种</label>
<description>阿拉克涅督虫之一,是少数拥有结茧能力的非女皇种阿拉克涅虫族——她们可以排出一枚器官茧,这枚茧将按照其信息素所标定的方向定向演化出一个武装器官,以供虫群使用。除此之外,她们的辅肢比普通的虫族更加复杂灵活,这使得她们不仅可以执行手工、建造、艺术等复杂的工作,也可以操作武装器官——虽然她们本身极度脆弱。\n\n作为督虫她可以繁育并监管若干阿拉克涅家政种辅虫以协助巢穴进行清洁工作。</description>
<description>阿拉克涅督虫之一,是少数拥有结茧能力的非女皇种阿拉克涅虫族——她们可以排出一枚器官茧,这枚茧将按照其信息素所标定的方向定向演化出一个武装器官,以供虫群使用。除此之外,她们的辅肢比普通的虫族更加复杂灵活,这使得她们不仅可以执行手工、艺术等复杂的工作,也可以操作武装器官——虽然她们本身极度脆弱。\n\n作为督虫她可以繁育并监管若干阿拉克涅家政种辅虫以协助巢穴进行清洁和搬运工作。</description>
<alienRace>
<generalSettings>
<!-- 各种零件定义 -->
@@ -911,7 +911,7 @@
<offsets>
<north>
<layerOffset>-0.275</layerOffset>
</north>
</north>
</offsets>
</li>
</bodyAddons>
@@ -984,12 +984,10 @@
</lifeStageAges>
</race>
</AlienRace.ThingDef_AlienRace>
<AlienRace.ThingDef_AlienRace ParentName="ARA_NodeBase">
<defName>ArachnaeNode_Race_Fighter</defName>
<label>阿拉克涅战士种</label>
<description>阿拉克涅督虫之一,是巢穴中真正的战士,除了战斗外也可以进行狩猎和搬运。其拥有强大的可塑性基因,随着科技的解锁其将获得更多的能力。\n\n作为督虫她可以向敌人投射寿命有限但是非常恼人的阿拉克涅酸噬种辅虫以阻止敌人的远程火力开火。</description>
<description>阿拉克涅督虫之一,是巢穴中真正的战士,除了战斗外也可以进行狩猎和驯兽工作。其拥有强大的可塑性基因,随着科技的解锁其将获得更多的能力。\n\n作为督虫她可以向敌人投射寿命有限但是非常恼人的阿拉克涅酸噬种辅虫以阻止敌人的远程火力开火。</description>
<alienRace>
<generalSettings>
<!-- 各种零件定义 -->
@@ -1006,7 +1004,7 @@
<offsets>
<north>
<layerOffset>-0.275</layerOffset>
</north>
</north>
</offsets>
</li>
</bodyAddons>
@@ -1075,12 +1073,10 @@
</lifeStageAges>
</race>
</AlienRace.ThingDef_AlienRace>
<AlienRace.ThingDef_AlienRace ParentName="ARA_NodeBase">
<defName>ArachnaeNode_Race_Facehugger</defName>
<label>阿拉克涅原虫种</label>
<description>阿拉克涅督虫之一,呈现高度未分化状态的特殊督虫,可以通过独特的神经链接管控制受害者的身体,并释放灵能信号以使得周围的人忽略其存在。\n\n不同于普通阿拉克涅虫族高度未分化的身体决定了其无法孕育任何辅虫在完成寄生前也无法进行任何工作。</description>
<description>阿拉克涅督虫之一,呈现高度未分化状态的特殊督虫,可以通过独特的神经链接管控制受害者的身体,并释放灵能信号以使得周围的人忽略其存在。\n\n不同于普通阿拉克涅虫族高度未分化的身体决定了其无法孕育任何辅虫在完成寄生前也难以胜任任何工作。</description>
<alienRace>
<generalSettings>
<!-- 各种零件定义 -->
@@ -1142,4 +1138,112 @@
</li>
</comps>
</AlienRace.ThingDef_AlienRace>
<AlienRace.ThingDef_AlienRace ParentName="ARA_NodeBase">
<defName>ArachnaeNode_Race_Skyraider</defName>
<label>阿拉克涅空天种</label>
<description>阿拉克涅督虫中的精锐,进化出了强大的飞行能力,是巢穴中无可争议的空中霸主。\n\n作为为数不多拥有飞行能力的虫族她可以从空中掠袭猎物并将其带至千米高空之上俯冲投下只留其余猎物在地面无助的挣扎。</description>
<alienRace>
<generalSettings>
<!-- 各种零件定义 -->
<alienPartGenerator>
<!-- 额外身体部件 -->
<bodyAddons>
<li>
<path>ArachnaeSwarm/Things/ARA_HiveNode/Addons/ArachnaeNode_Race_Addons_Fighter_Claw</path>
<inFrontOfBody>true</inFrontOfBody>
</li>
<li>
<path>ArachnaeSwarm/Things/ARA_HiveNode/Addons/ArachnaeNode_Race_Addons_Fighter_Tail</path>
<inFrontOfBody>false</inFrontOfBody>
<offsets>
<north>
<layerOffset>-0.275</layerOffset>
</north>
</offsets>
</li>
</bodyAddons>
</alienPartGenerator>
</generalSettings>
<raceRestriction>
<onlyEatRaceRestrictedFood>true</onlyEatRaceRestrictedFood>
</raceRestriction>
</alienRace>
<comps>
<!-- Add our new flight component here -->
<li Class="ArachnaeSwarm.CompProperties_PawnFlight"> <!-- 2. 添加我们的飞行组件 -->
<!-- 飞行触发条件:仅在征召时飞行 -->
<flightCondition>Drafted</flightCondition>
<!-- 链接到我们刚刚创建的 AnimationDef -->
<flyingAnimationNorth>ARA_FlyNorth</flyingAnimationNorth>
<flyingAnimationEast>ARA_FlyEast</flyingAnimationEast>
<flyingAnimationSouth>ARA_FlySouth</flyingAnimationSouth>
</li>
</comps>
<!-- 基础属性设置 -->
<statBases>
<!-- 移动速度 -->
<MoveSpeed>4.5</MoveSpeed>
<MaxFlightTime>9999</MaxFlightTime>
<FlightCooldown>0</FlightCooldown>
<!-- <RestRateMultiplier>1</RestRateMultiplier> -->
<!-- <HungerRateMultiplier>1</HungerRateMultiplier> -->
<!-- <EatingSpeed>5</EatingSpeed> -->
<MaxNutrition>2</MaxNutrition>
<CarryingCapacity>100</CarryingCapacity>
<MeatAmount>60</MeatAmount>
<LeatherAmount>30</LeatherAmount>
<MeleeDodgeChance>1.25</MeleeDodgeChance>
<MeleeHitChance>1.25</MeleeHitChance>
<!-- <NegotiationAbility>1</NegotiationAbility> -->
<!-- <SellPriceFactor>1</SellPriceFactor> -->
<!-- <SocialImpact>1</SocialImpact> -->
<!-- <TradePriceImprovement>0.5</TradePriceImprovement> -->
<!-- 自带的甲壳可以防御外部攻击 -->
<ArmorRating_Blunt>0.4</ArmorRating_Blunt>
<ArmorRating_Sharp>0.4</ArmorRating_Sharp>
<ArmorRating_Heat>0.3</ArmorRating_Heat>
</statBases>
<tools>
<li>
<label>巨镰</label>
<capacities>
<li>Cut</li>
</capacities>
<power>20</power>
<cooldownTime>2.5</cooldownTime>
<linkedBodyPartsGroup>ARA_Sickles</linkedBodyPartsGroup>
<!-- <ensureLinkedBodyPartsGroupAlwaysUsable>true</ensureLinkedBodyPartsGroupAlwaysUsable> -->
<chanceFactor>0.5</chanceFactor>
</li>
</tools>
<race>
<!-- 身体类型 -->
<body>ArachnaeFighter_Body</body>
<renderTree>ARA_ArachnaeRenderTree</renderTree>
<flightStartChanceOnJobStart>1.0</flightStartChanceOnJobStart>
<baseBodySize>0.85</baseBodySize>
<baseHealthScale>2</baseHealthScale>
<lifeExpectancy>5</lifeExpectancy>
<lifeStageAges Inherit="False">
<li>
<def>ArachnaeNode_Myrmecocystus_Adult</def>
<minAge>0</minAge>
</li>
</lifeStageAges>
</race>
</AlienRace.ThingDef_AlienRace>
</Defs>

View File

@@ -309,6 +309,7 @@
<thingDef>ARA_RW_Basic_Fist_Needle_Gun</thingDef>
<productionTicks>40000</productionTicks>
<totalNutritionNeeded>10</totalNutritionNeeded>
<!--<requiredResearch>ARA_Technology_5PAV</requiredResearch>-->
</li>
</processes>
@@ -509,6 +510,7 @@
<thingDef>ARA_RW_Basic_Acid_Bladder_Gun</thingDef>
<productionTicks>80000</productionTicks>
<totalNutritionNeeded>30</totalNutritionNeeded>
<!--<requiredResearch>ARA_Technology_7VXI</requiredResearch>-->
</li>
</processes>

View File

@@ -23,7 +23,130 @@
</ThingDef>
<!-- 2. 主建筑 "生物孵化池" -->
<!-- 3. 主建筑 "生物孵化池" -->
<ThingDef ParentName="BuildingBase">
<defName>ARA_BioforgeIncubator_Thing</defName>
<label>生物质物品孵化池</label>
<description>一个大型的、需要消耗大量营养物质的孵化设施,可以同时孵化多个单位,并能通过链接外部设备来提高效率。</description>
<graphicData>
<texPath>Things/Building/AncientHeatVent</texPath>
<graphicClass>Graphic_Single</graphicClass>
<shaderType>CutoutComplex</shaderType>
<drawSize>(7,7)</drawSize>
</graphicData>
<size>(7,7)</size>
<tickerType>Normal</tickerType>
<stuffCategories Inherit="False"/>
<costStuffCount>0</costStuffCount>
<costList>
<ARA_Carapace>50</ARA_Carapace>
</costList>
<castEdgeShadows>false</castEdgeShadows>
<staticSunShadowHeight>0</staticSunShadowHeight>
<altitudeLayer>Building</altitudeLayer>
<passability>PassThroughOnly</passability>
<terrainAffordanceNeeded>ARA_Creep</terrainAffordanceNeeded>
<pathCost>50</pathCost>
<statBases>
<MaxHitPoints>250</MaxHitPoints>
<WorkToBuild>2800</WorkToBuild>
<Flammability>1.0</Flammability>
</statBases>
<placeWorkers>
<li>PlaceWorker_PreventInteractionSpotOverlap</li>
</placeWorkers>
<fillPercent>0.8</fillPercent>
<interactionCellOffset>(0,0,-1)</interactionCellOffset>
<hasInteractionCell>true</hasInteractionCell>
<designationCategory>ARA_Buildings</designationCategory>
<uiOrder>2600</uiOrder>
<surfaceType>Item</surfaceType>
<building>
<workTableRoomRole>Laboratory</workTableRoomRole>
<workTableNotInRoomRoleFactor>0.8</workTableNotInRoomRoleFactor>
</building>
<comps>
<!-- a. 我们新的队列物品生产组件 -->
<li Class="ArachnaeSwarm.CompProperties_QueuedInteractiveProducer">
<!-- 队列和交互设置 -->
<productionQueueLimit>3</productionQueueLimit>
<minNutritionToStart>1.0</minNutritionToStart>
<whitelist>
<li>ArachnaeNode_Race_WeaponSmith</li> <!-- 示例:允许普通殖民者操作 -->
</whitelist>
<!-- 质量系统设置 -->
<minSafeTemperature>10</minSafeTemperature>
<maxSafeTemperature>30</maxSafeTemperature>
<penaltyPerDegreePerTick>0.00001</penaltyPerDegreePerTick>
<qualityThresholds>
<li>
<quality>Legendary</quality>
<threshold>0.99</threshold>
</li>
<li>
<quality>Masterwork</quality>
<threshold>0.90</threshold>
</li>
<li>
<quality>Excellent</quality>
<threshold>0.70</threshold>
</li>
<li>
<quality>Good</quality>
<threshold>0.50</threshold>
</li>
<li>
<quality>Normal</quality>
<threshold>0.20</threshold>
</li>
<li>
<quality>Poor</quality>
<threshold>0.10</threshold>
</li>
</qualityThresholds>
<!-- 生产列表 -->
<processes>
<li>
<thingDef>ARA_RW_Basic_Acid_Bladder_Gun</thingDef>
<productionTicks>80000</productionTicks>
<totalNutritionNeeded>30</totalNutritionNeeded>
<requiredResearch>ARA_Technology_7VXI</requiredResearch>
</li>
<li>
<thingDef>ARA_RW_Basic_Fist_Needle_Gun</thingDef>
<productionTicks>40000</productionTicks>
<totalNutritionNeeded>10</totalNutritionNeeded>
<requiredResearch>ARA_Technology_5PAV</requiredResearch>
</li>
</processes>
</li>
<!-- b. 我们的营养燃料组件 -->
<li Class="ArachnaeSwarm.CompProperties_RefuelableNutrition">
<fuelCapacity>100.0</fuelCapacity>
<fuelFilter>
<categories>
<li>Foods</li>
</categories>
</fuelFilter>
<fuelGizmoLabel>生物质</fuelGizmoLabel>
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
<targetFuelLevelConfigurable>true</targetFuelLevelConfigurable>
</li>
<!-- c. 原版的设施链接接收组件 -->
<li Class="CompProperties_AffectedByFacilities">
<linkableFacilities>
<li>ARA_IncubationAccelerator</li>
</linkableFacilities>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="BuildingBase">
<defName>ARA_BioforgeIncubator</defName>
<label>生物质孵化池</label>
@@ -103,6 +226,8 @@
</categories>
</fuelFilter>
<fuelGizmoLabel>生物质</fuelGizmoLabel>
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
<targetFuelLevelConfigurable>true</targetFuelLevelConfigurable>
</li>
<!-- c. 原版的设施链接接收组件 -->

View File

@@ -52,49 +52,7 @@
</comps>
</ThingDef>
<ThingDef ParentName="ARA_EggSpew_Base_Proj">
<defName>ARA_Proj_EggSac_BaseFighter</defName>
<label>阿拉克涅虫卵</label>
<projectile>
<spawnsThingDef>ARA_InteractiveEggSac_Basic_Fighter</spawnsThingDef>
</projectile>
</ThingDef>
<ThingDef ParentName="ARA_InteractiveEggSac_Base">
<defName>ARA_InteractiveEggSac_Basic_Fighter</defName>
<label>阿拉克涅虫卵囊 战士虫</label>
<description>一个脆弱、易燃、黏滑的囊状物,是阿拉克涅女皇种所诞之卵,内含哺育一只新督虫所需的营养和遗传物质,可以通过阿拉克涅女皇种的交互完成激活进程——参阅虫卵的超链接,了解各个督虫的特点。\n\n卵囊对温度极度敏感该类型的卵适温为-10~22°C需要小心保护</description>
<descriptionHyperlinks>
<ThingDef>ArachnaeNode_Race_Fighter</ThingDef>
</descriptionHyperlinks>
<researchPrerequisites>
<li>ARA_Technology_1KYC</li>
</researchPrerequisites>
<comps>
<li Class="ArachnaeSwarm.CompProperties_SpawnPawnFromList">
<spawnablePawns>
<li>
<pawnKind>ArachnaeNode_Race_Fighter</pawnKind>
<delayTicks>12</delayTicks>
<requiredResearch>ARA_Technology_1KYC</requiredResearch>
</li>
</spawnablePawns>
<whitelist>
<li>ARA_ArachnaeQueen</li>
</whitelist>
<destroyOnSpawn>true</destroyOnSpawn>
</li>
<li Class="ArachnaeSwarm.CompProperties_TemperatureRuinableDamage">
<minSafeTemperature>-10</minSafeTemperature>
<maxSafeTemperature>22</maxSafeTemperature>
<progressPerDegreePerTick>0.00005</progressPerDegreePerTick>
<damagePerTick>0.005</damagePerTick>
<recoveryRate>0.001</recoveryRate>
</li>
</comps>
</ThingDef>
<!-- T1 -->
<ThingDef ParentName="ARA_EggSpew_Base_Proj">
<defName>ARA_Proj_EggSac</defName>
<label>阿拉克涅虫卵</label>
@@ -102,7 +60,6 @@
<spawnsThingDef>ARA_InteractiveEggSac</spawnsThingDef>
</projectile>
</ThingDef>
<ThingDef ParentName="ARA_InteractiveEggSac_Base">
<defName>ARA_InteractiveEggSac</defName>
<label>阿拉克涅虫卵囊</label>
@@ -111,6 +68,7 @@
<ThingDef>ArachnaeNode_Race_Myrmecocystus</ThingDef>
<ThingDef>ArachnaeNode_Race_ShieldHead</ThingDef>
<ThingDef>ArachnaeNode_Race_WeaponSmith</ThingDef>
<ThingDef>ArachnaeNode_Race_Fighter</ThingDef>
</descriptionHyperlinks>
<researchPrerequisites>
<li>ARA_Base_Technology</li>
@@ -121,16 +79,21 @@
<spawnablePawns>
<li>
<pawnKind>ArachnaeNode_Race_Myrmecocystus</pawnKind>
<delayTicks>180000</delayTicks>
<delayTicks>10000</delayTicks>
</li>
<li>
<pawnKind>ArachnaeNode_Race_ShieldHead</pawnKind>
<delayTicks>180000</delayTicks>
<delayTicks>120000</delayTicks>
</li>
<li>
<pawnKind>ArachnaeNode_Race_WeaponSmith</pawnKind>
<delayTicks>180000</delayTicks>
</li>
<li>
<pawnKind>ArachnaeNode_Race_Fighter</pawnKind>
<delayTicks>120000</delayTicks>
<requiredResearch>ARA_Technology_1KYC</requiredResearch>
</li>
</spawnablePawns>
<whitelist>
<li>ARA_ArachnaeQueen</li>
@@ -146,7 +109,6 @@
</li>
</comps>
</ThingDef>
<ThingDef ParentName="ARA_InteractiveEggSac_Base">
<defName>ARA_InteractiveEggSac_Start</defName>
<label>初诞阿拉克涅虫卵囊</label>
@@ -189,5 +151,4 @@
</li>
</comps>
</ThingDef>
</Defs>
</Defs>

View File

@@ -17,4 +17,8 @@
<NotProducing>未在生产</NotProducing>
<ARA_NeedArachnaeToStartIncubation>未孵化,需要阿拉克涅工艺种交互</ARA_NeedArachnaeToStartIncubation>
<!-- Added for CompQueuedPawnSpawner -->
<NutritionNeeded>所需营养</NutritionNeeded>
<ARA_Incubate>孵化 {0}</ARA_Incubate>
</LanguageData>

View File

@@ -112,12 +112,20 @@ namespace ArachnaeSwarm
foreach (var process in Props.processes)
{
yield return new FloatMenuOption("StartProduction".Translate(process.thingDef.label), () =>
if (process.requiredResearch != null && !process.requiredResearch.IsFinished)
{
this._selectedProcess = process;
Job job = JobMaker.MakeJob(DefDatabase<JobDef>.GetNamed("ARA_StartInteractiveProduction"), parent);
selPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
});
string disabledText = "StartProduction".Translate(process.thingDef.label) + " (" + "Requires".Translate() + ": " + process.requiredResearch.label + ")";
yield return new FloatMenuOption(disabledText, null);
}
else
{
yield return new FloatMenuOption("StartProduction".Translate(process.thingDef.label), () =>
{
this._selectedProcess = process;
Job job = JobMaker.MakeJob(DefDatabase<JobDef>.GetNamed("ARA_StartInteractiveProduction"), parent);
selPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
});
}
}
}

View File

@@ -0,0 +1,273 @@
using RimWorld;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Verse;
using Verse.AI;
using UnityEngine;
namespace ArachnaeSwarm
{
// Data contract for a single production order in the queue
public class QueuedProcessOrder : IExposable
{
public ProcessDef process; // Using the existing ProcessDef
public int productionUntilTick = -1;
// Quality-related fields
public int ticksUnderOptimalConditions;
public float temperaturePenaltyPercent;
public void ExposeData()
{
Scribe_Deep.Look(ref process, "process");
Scribe_Values.Look(ref productionUntilTick, "productionUntilTick", -1);
Scribe_Values.Look(ref ticksUnderOptimalConditions, "ticksUnderOptimalConditions", 0);
Scribe_Values.Look(ref temperaturePenaltyPercent, "temperaturePenaltyPercent", 0f);
}
}
// Properties for the new queued producer component
public class CompProperties_QueuedInteractiveProducer : CompProperties
{
public List<ProcessDef> processes;
public List<PawnKindDef> whitelist;
public int productionQueueLimit = 1;
public float minNutritionToStart = 0.1f;
// Quality-related properties from CompInteractiveProducer
public float minSafeTemperature = 7f;
public float maxSafeTemperature = 32f;
public float penaltyPerDegreePerTick = 0.00001f;
public List<QualityThreshold> qualityThresholds;
public IntRange spawnCount = new IntRange(1, 1);
public CompProperties_QueuedInteractiveProducer()
{
compClass = typeof(CompQueuedInteractiveProducer);
}
}
// The main component logic
public class CompQueuedInteractiveProducer : ThingComp
{
private List<QueuedProcessOrder> productionOrders = new List<QueuedProcessOrder>();
public ProcessDef selectedProcess; // For passing to the JobDriver
private CompRefuelableNutrition _fuelComp;
private CompAffectedByFacilities _facilitiesComp;
public CompProperties_QueuedInteractiveProducer Props => (CompProperties_QueuedInteractiveProducer)props;
private CompRefuelableNutrition FuelComp => _fuelComp ?? (_fuelComp = parent.GetComp<CompRefuelableNutrition>());
private CompAffectedByFacilities FacilitiesComp => _facilitiesComp ?? (_facilitiesComp = parent.GetComp<CompAffectedByFacilities>());
public override void Initialize(CompProperties props)
{
base.Initialize(props);
_fuelComp = parent.GetComp<CompRefuelableNutrition>();
_facilitiesComp = parent.GetComp<CompAffectedByFacilities>();
}
public override IEnumerable<FloatMenuOption> CompFloatMenuOptions(Pawn selPawn)
{
if (Props.whitelist == null || !Props.whitelist.Contains(selPawn.kindDef)) yield break;
if (FuelComp != null && (!FuelComp.HasFuel || FuelComp.NutritionStored < Props.minNutritionToStart))
{
yield return new FloatMenuOption("CannotStartProduction".Translate(), null);
yield break;
}
foreach (var process in Props.processes)
{
if (process.requiredResearch != null && !process.requiredResearch.IsFinished)
{
yield return new FloatMenuOption("StartProduction".Translate(process.thingDef.label) + " (" + "Requires".Translate() + ": " + process.requiredResearch.label + ")", null);
}
else
{
yield return new FloatMenuOption("StartProduction".Translate(process.thingDef.label), () =>
{
this.selectedProcess = process;
Job job = JobMaker.MakeJob(DefDatabase<JobDef>.GetNamed("ARA_AddProcessToQueueJob"), parent);
selPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
});
}
}
}
public void AddToQueue()
{
if (selectedProcess == null) return;
productionOrders.Add(new QueuedProcessOrder { process = selectedProcess });
selectedProcess = null;
}
public override void CompTick()
{
base.CompTick();
var producingOrders = productionOrders.Where(o => o.productionUntilTick > 0).ToList();
bool hasFuel = FuelComp?.HasFuel ?? true;
float ambientTemperature = parent.AmbientTemperature;
bool isTempSafe = ambientTemperature >= Props.minSafeTemperature && ambientTemperature <= Props.maxSafeTemperature;
// Update progress and penalties for active orders
foreach(var order in producingOrders)
{
if(hasFuel && isTempSafe)
{
order.ticksUnderOptimalConditions++;
}
if (!isTempSafe)
{
float tempDelta = (ambientTemperature > Props.maxSafeTemperature) ? ambientTemperature - Props.maxSafeTemperature : Props.minSafeTemperature - ambientTemperature;
order.temperaturePenaltyPercent = Mathf.Min(1f, order.temperaturePenaltyPercent + tempDelta * Props.penaltyPerDegreePerTick);
}
if (!hasFuel)
{
order.productionUntilTick++; // Pause production
}
}
// Update fuel consumption
if (FuelComp != null)
{
float totalConsumptionRatePerDay = 0f;
if(hasFuel)
{
foreach (var order in producingOrders)
{
if (order.process.totalNutritionNeeded > 0 && order.process.productionTicks > 0)
{
totalConsumptionRatePerDay += (order.process.totalNutritionNeeded / order.process.productionTicks) * 60000f;
}
}
}
FuelComp.currentConsumptionRate = totalConsumptionRatePerDay;
}
// Finish completed orders
productionOrders.RemoveAll(order =>
{
if (order.productionUntilTick > 0 && Find.TickManager.TicksGame >= order.productionUntilTick)
{
FinishProduction(order);
return true;
}
return false;
});
// Start new orders
int currentlyProducingCount = productionOrders.Count(o => o.productionUntilTick > 0);
if (currentlyProducingCount < Props.productionQueueLimit)
{
var waitingOrder = productionOrders.FirstOrDefault(o => o.productionUntilTick == -1);
if (waitingOrder != null)
{
float speedFactor = 1f + (FacilitiesComp?.GetStatOffset(StatDef.Named("ARA_IncubationSpeedFactor")) ?? 0f);
int modifiedDelay = (int)(waitingOrder.process.productionTicks / speedFactor);
waitingOrder.productionUntilTick = Find.TickManager.TicksGame + modifiedDelay;
}
}
}
private (QualityCategory quality, float baseScore, float penalty) GetEstimatedQualityDetails(QueuedProcessOrder order)
{
if (order == null || Props.qualityThresholds.NullOrEmpty())
{
return (QualityCategory.Normal, 0f, 0f);
}
float progress = (order.process.productionTicks > 0) ? (float)order.ticksUnderOptimalConditions / order.process.productionTicks : 1f;
float finalQualityPercent = Mathf.Clamp01(progress - order.temperaturePenaltyPercent);
QualityCategory finalQuality = QualityCategory.Awful;
foreach (var threshold in Props.qualityThresholds.OrderByDescending(q => q.threshold))
{
if (finalQualityPercent >= threshold.threshold)
{
finalQuality = threshold.quality;
break;
}
}
return (finalQuality, progress, order.temperaturePenaltyPercent);
}
private void FinishProduction(QueuedProcessOrder order)
{
var qualityDetails = GetEstimatedQualityDetails(order);
QualityCategory finalQuality = qualityDetails.quality;
for (int i = 0; i < Props.spawnCount.RandomInRange; i++)
{
Thing product = ThingMaker.MakeThing(order.process.thingDef);
product.TryGetComp<CompQuality>()?.SetQuality(finalQuality, ArtGenerationContext.Colony);
GenPlace.TryPlaceThing(product, parent.Position, parent.Map, ThingPlaceMode.Near);
}
}
public override string CompInspectStringExtra()
{
StringBuilder sb = new StringBuilder();
int producingCount = productionOrders.Count(o => o.productionUntilTick > 0);
int queuedCount = productionOrders.Count - producingCount;
sb.AppendLine($"生产槽位: {producingCount} / {Props.productionQueueLimit}");
if (queuedCount > 0) sb.AppendLine($"等待队列: {queuedCount}");
if (FacilitiesComp != null)
{
float speedFactor = 1f + FacilitiesComp.GetStatOffset(StatDef.Named("ARA_IncubationSpeedFactor"));
if(speedFactor != 1f) sb.AppendLine($"生产速度: {speedFactor.ToStringPercent()}");
}
var producingNow = productionOrders.Where(o => o.productionUntilTick > 0).OrderBy(o => o.productionUntilTick);
if (producingNow.Any())
{
sb.AppendLine("正在生产:");
foreach (var order in producingNow)
{
int remainingTicks = order.productionUntilTick - Find.TickManager.TicksGame;
var qualityDetails = GetEstimatedQualityDetails(order);
sb.AppendLine($" - {order.process.thingDef.LabelCap}: {remainingTicks.ToStringTicksToPeriod(true, false, true, true)} (品质: {qualityDetails.quality.GetLabel()})");
}
}
// 添加温度信息
string tempStr = "CurrentTemperature".Translate(parent.AmbientTemperature.ToStringTemperature("F0"));
tempStr += $" ({"SafeTemperatureRange".Translate()}: {Props.minSafeTemperature.ToStringTemperature("F0")} ~ {Props.maxSafeTemperature.ToStringTemperature("F0")})";
sb.AppendLine(tempStr);
return sb.ToString().TrimEnd();
}
public override void PostExposeData()
{
base.PostExposeData();
Scribe_Collections.Look(ref productionOrders, "productionOrders", LookMode.Deep);
Scribe_Deep.Look(ref selectedProcess, "selectedProcess");
}
public override IEnumerable<Gizmo> CompGetGizmosExtra()
{
foreach (Gizmo gizmo in base.CompGetGizmosExtra())
{
yield return gizmo;
}
if (productionOrders.Any())
{
var lastOrder = productionOrders.Last();
yield return new Command_Action
{
defaultLabel = "CommandCancelProduction".Translate() + ": " + lastOrder.process.thingDef.LabelCap,
defaultDesc = "CommandCancelProductionDesc".Translate(),
icon = ContentFinder<Texture2D>.Get("UI/Designators/Cancel"),
action = () =>
{
productionOrders.Remove(lastOrder);
}
};
}
}
}
}

View File

@@ -10,37 +10,32 @@ namespace ArachnaeSwarm
public CompProperties_RefuelableNutrition()
{
compClass = typeof(CompRefuelableNutrition);
// 默认启用这些Gizmo除非在XML中明确设置为false
this.targetFuelLevelConfigurable = true;
this.showAllowAutoRefuelToggle = true;
}
}
[StaticConstructorOnStartup]
public class CompRefuelableNutrition : CompRefuelable
{
private static readonly Texture2D FuelIcon = ContentFinder<Texture2D>.Get("UI/Icons/ThingCategories/FoodMeals");
// This rate is controlled externally, e.g., by a producer comp. Units: nutrition per day.
public float currentConsumptionRate = 0f;
public float NutritionStored => Fuel;
public new CompProperties_RefuelableNutrition Props => (CompProperties_RefuelableNutrition)props;
public override void CompTick()
{
// Call the base tick for things like vacuum logic, but we will handle fuel consumption ourselves.
// 调用基类的Tick让它处理真空等情况。
// 基类的燃料消耗逻辑将因为 fuelConsumptionRate 为0而无效。
base.CompTick();
// External consumption logic
if (currentConsumptionRate > 0)
// 我们自己的动态消耗逻辑
if (currentConsumptionRate > 0 && HasFuel)
{
// Convert per-day rate to per-tick rate and consume
float consumptionPerTick = currentConsumptionRate / 60000f;
ConsumeFuel(consumptionPerTick);
}
}
// Note: The base class's ConsumeFuel is sufficient.
// public void ConsumeFuel(float amount) { ... }
public new void Refuel(List<Thing> fuelThings)
{
@@ -48,49 +43,52 @@ namespace ArachnaeSwarm
if (fuelNeeded < 0.001f) return;
float totalNutritionGained = 0;
List<Thing> thingsToProcess = new List<Thing>(fuelThings);
var thingsToProcess = new List<Thing>(fuelThings);
foreach (var thing in thingsToProcess)
{
if (fuelNeeded <= 0) break;
float nutritionPerUnit = thing.GetStatValue(StatDefOf.Nutrition);
if (nutritionPerUnit <= 0) continue;
int numToTake = Mathf.CeilToInt(fuelNeeded / nutritionPerUnit);
numToTake = Mathf.Min(numToTake, thing.stackCount);
float nutritionFromThis = numToTake * nutritionPerUnit;
base.Refuel(nutritionFromThis);
totalNutritionGained += nutritionFromThis;
thing.SplitOff(numToTake).Destroy();
fuelNeeded = TargetFuelLevel - Fuel;
}
if (totalNutritionGained > 0 && Props.fuelGizmoLabel != null)
{
// Removed PawnUtility.ShouldSendNotificationAbout check as it requires a Pawn.
Messages.Message("MessageRefueled".Translate(parent.LabelShort, totalNutritionGained.ToString("0.##"), Props.fuelGizmoLabel), parent, MessageTypeDefOf.PositiveEvent);
}
}
public override string CompInspectStringExtra()
{
// Build the string from scratch to avoid the base class's incorrect time calculation.
string text = Props.FuelLabel + ": " + Fuel.ToStringDecimalIfSmall() + " / " + Props.fuelCapacity.ToStringDecimalIfSmall();
// If we have a custom consumption rate, calculate and display our own time estimate.
if (currentConsumptionRate > 0f && HasFuel)
{
int numTicks = (int)(Fuel / (currentConsumptionRate / 60000f));
text += " (" + numTicks.ToStringTicksToPeriod() + ")";
}
else if (!HasFuel && !Props.outOfFuelMessage.NullOrEmpty())
{
text += "\n" + Props.outOfFuelMessage;
}
if (Props.targetFuelLevelConfigurable)
{
text += "\n" + "ConfiguredTargetFuelLevel".Translate(TargetFuelLevel.ToStringDecimalIfSmall());
}
return text;
}
// Removed CompGetGizmosExtra override because Command_Refuel is a private class in CompRefuelable.
}
}

View File

@@ -10,11 +10,20 @@ namespace ArachnaeSwarm
public List<ThingDef> blacklist;
}
public class ProcessDef
public class ProcessDef : IExposable
{
public ThingDef thingDef;
public int productionTicks;
public float totalNutritionNeeded;
public ResearchProjectDef requiredResearch;
public void ExposeData()
{
Scribe_Defs.Look(ref thingDef, "thingDef");
Scribe_Values.Look(ref productionTicks, "productionTicks", 0);
Scribe_Values.Look(ref totalNutritionNeeded, "totalNutritionNeeded", 0f);
Scribe_Defs.Look(ref requiredResearch, "requiredResearch");
}
}
public class QualityThreshold

View File

@@ -0,0 +1,35 @@
using System.Collections.Generic;
using RimWorld;
using Verse;
using Verse.AI;
namespace ArachnaeSwarm
{
public class JobDriver_AddProcessToQueue : JobDriver
{
private const TargetIndex BuildingInd = TargetIndex.A;
protected Building Building => (Building)job.GetTarget(BuildingInd).Thing;
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
return pawn.Reserve(Building, job, 1, -1, null, errorOnFailed);
}
protected override IEnumerable<Toil> MakeNewToils()
{
this.FailOnDespawnedNullOrForbidden(BuildingInd);
yield return Toils_Goto.GotoThing(BuildingInd, PathEndMode.InteractionCell);
Toil work = ToilMaker.MakeToil("MakeNewToils");
work.initAction = delegate
{
// Call the new component's method
Building.GetComp<CompQueuedInteractiveProducer>().AddToQueue();
};
work.defaultCompleteMode = ToilCompleteMode.Instant;
yield return work;
}
}
}

View File

@@ -4,11 +4,10 @@ using System.Linq;
using System.Text;
using Verse;
using Verse.AI;
using UnityEngine;
namespace ArachnaeSwarm
{
// CompProperties: 在XML中配置组件的属性
public class CompProperties_QueuedPawnSpawner : CompProperties
{
public List<QueuedPawnSpawnEntry> spawnablePawns;
@@ -22,38 +21,22 @@ namespace ArachnaeSwarm
}
}
// 主组件类
public class CompQueuedPawnSpawner : ThingComp
{
private List<QueuedProductionOrder> productionOrders = new List<QueuedProductionOrder>();
// 缓存对其他组件的引用以提高性能
public QueuedPawnSpawnEntry selectedEntry;
private CompRefuelableNutrition _fuelComp;
private CompAffectedByFacilities _facilitiesComp;
public CompProperties_QueuedPawnSpawner Props => (CompProperties_QueuedPawnSpawner)props;
private CompRefuelableNutrition FuelComp
{
get
{
if (_fuelComp == null) _fuelComp = parent.GetComp<CompRefuelableNutrition>();
return _fuelComp;
}
}
private CompAffectedByFacilities FacilitiesComp
{
get
{
if (_facilitiesComp == null) _facilitiesComp = parent.GetComp<CompAffectedByFacilities>();
return _facilitiesComp;
}
}
private CompRefuelableNutrition FuelComp => _fuelComp ?? (_fuelComp = parent.GetComp<CompRefuelableNutrition>());
private CompAffectedByFacilities FacilitiesComp => _facilitiesComp ?? (_facilitiesComp = parent.GetComp<CompAffectedByFacilities>());
public override void Initialize(CompProperties props)
{
base.Initialize(props);
// 在初始化时获取一次避免在每次访问时都调用GetComp
_fuelComp = parent.GetComp<CompRefuelableNutrition>();
_facilitiesComp = parent.GetComp<CompAffectedByFacilities>();
}
@@ -64,39 +47,37 @@ namespace ArachnaeSwarm
if (FuelComp != null && (!FuelComp.HasFuel || FuelComp.NutritionStored < Props.minNutritionToStart))
{
yield return new FloatMenuOption("CannotStartProduction".Translate() + ": " + "NoFuel".Translate(), null);
yield return new FloatMenuOption("CannotStartProduction".Translate(), null);
yield break;
}
foreach (QueuedPawnSpawnEntry entry in Props.spawnablePawns)
foreach (var entry in Props.spawnablePawns)
{
if (entry.pawnKind == null) continue;
if (entry.requiredResearch != null && !entry.requiredResearch.IsFinished)
{
string disabledText = "ARA_Incubate".Translate(entry.pawnKind.label) + " (" + "Requires".Translate() + ": " + entry.requiredResearch.label + ")";
yield return new FloatMenuOption(disabledText, null);
yield return new FloatMenuOption("ARA_Incubate".Translate(entry.pawnKind.label) + " (" + "Requires".Translate() + ": " + entry.requiredResearch.label + ")", null);
}
else
{
string label = "ARA_Incubate".Translate(entry.pawnKind.label);
if (entry.totalNutritionNeeded > 0)
yield return new FloatMenuOption("ARA_Incubate".Translate(entry.pawnKind.label), () =>
{
label += $" ({"NutritionNeeded".Translate()}: {entry.totalNutritionNeeded.ToString("0.0")})";
}
yield return new FloatMenuOption(label, () => AddToQueue(entry, selPawn));
this.selectedEntry = entry;
Job job = JobMaker.MakeJob(DefDatabase<JobDef>.GetNamed("ARA_AddToQueueJob"), parent);
selPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
});
}
}
}
private void AddToQueue(QueuedPawnSpawnEntry entry, Pawn selPawn)
public void AddToQueue()
{
productionOrders.Add(new QueuedProductionOrder { entry = entry });
// 给交互的Pawn一个反馈表示订单已接受
if (selPawn.jobs?.curJob != null)
if (selectedEntry == null)
{
selPawn.jobs.EndCurrentJob(JobCondition.Succeeded);
Log.Error("Tried to add to queue but selectedEntry was null.");
return;
}
productionOrders.Add(new QueuedProductionOrder { entry = selectedEntry });
selectedEntry = null;
}
public override void CompTick()
@@ -106,7 +87,6 @@ namespace ArachnaeSwarm
var producingOrders = productionOrders.Where(o => o.spawnUntilTick > 0).ToList();
bool hasFuel = FuelComp?.HasFuel ?? true;
// 处理无燃料情况:仅暂停生产
if (!hasFuel && FuelComp != null && producingOrders.Any())
{
foreach (var order in producingOrders)
@@ -115,11 +95,9 @@ namespace ArachnaeSwarm
}
}
// 动态计算总燃料消耗速率
if (FuelComp != null)
{
float totalConsumptionRatePerDay = 0f;
// 只计算有燃料时正在生产的订单
if(hasFuel)
{
foreach (var order in producingOrders)
@@ -133,7 +111,6 @@ namespace ArachnaeSwarm
FuelComp.currentConsumptionRate = totalConsumptionRatePerDay;
}
// 检查并完成订单
productionOrders.RemoveAll(order =>
{
if (order.spawnUntilTick > 0 && Find.TickManager.TicksGame >= order.spawnUntilTick)
@@ -145,11 +122,10 @@ namespace ArachnaeSwarm
return false;
});
// 检查并启动新订单
int currentlyProducingCount = productionOrders.Count(o => o.spawnUntilTick > 0);
if (currentlyProducingCount < Props.productionQueueLimit)
{
QueuedProductionOrder waitingOrder = productionOrders.FirstOrDefault(o => o.spawnUntilTick == -1);
var waitingOrder = productionOrders.FirstOrDefault(o => o.spawnUntilTick == -1);
if (waitingOrder != null)
{
float speedFactor = 1f;
@@ -166,8 +142,7 @@ namespace ArachnaeSwarm
public override string CompInspectStringExtra()
{
StringBuilder sb = new StringBuilder();
if (FuelComp != null) sb.AppendLine(FuelComp.CompInspectStringExtra());
int producingCount = productionOrders.Count(o => o.spawnUntilTick > 0);
int queuedCount = productionOrders.Count - producingCount;
@@ -198,6 +173,31 @@ namespace ArachnaeSwarm
{
base.PostExposeData();
Scribe_Collections.Look(ref productionOrders, "productionOrders", LookMode.Deep, new object[0]);
Scribe_Deep.Look(ref selectedEntry, "selectedEntry");
}
public override IEnumerable<Gizmo> CompGetGizmosExtra()
{
foreach (Gizmo gizmo in base.CompGetGizmosExtra())
{
yield return gizmo;
}
if (productionOrders.Any())
{
var lastOrder = productionOrders.Last();
yield return new Command_Action
{
defaultLabel = "CommandCancelProduction".Translate() + ": " + lastOrder.entry.pawnKind.LabelCap,
defaultDesc = "CommandCancelProductionDesc".Translate(),
icon = ContentFinder<Texture2D>.Get("UI/Designators/Cancel"),
action = () =>
{
productionOrders.Remove(lastOrder);
}
};
}
}
}
}

View File

@@ -4,6 +4,7 @@ using Verse;
using RimWorld;
using Verse.AI;
using Verse.AI.Group;
using UnityEngine; // Add this for ContentFinder
namespace ArachnaeSwarm
{
@@ -13,7 +14,8 @@ namespace ArachnaeSwarm
private int spawnUntilTick = -1;
private PawnKindDef spawningPawnKind;
private PawnSpawnEntry selectedEntry;
// This component uses its own PawnSpawnEntry, separate from the Queued spawner
private PawnSpawnEntry selectedEntry;
public bool IsHatching => spawnUntilTick > 0;
public override IEnumerable<FloatMenuOption> CompFloatMenuOptions(Pawn selPawn)
@@ -34,20 +36,17 @@ namespace ArachnaeSwarm
{
if (entry.pawnKind == null) continue;
// 检查科技需求
if (entry.requiredResearch != null && !entry.requiredResearch.IsFinished)
{
// 科技未完成,显示灰色不可点击选项
string disabledText = "ARA_Incubate".Translate(entry.pawnKind.label) + " (" + "Requires".Translate() + ": " + entry.requiredResearch.label + ")";
yield return new FloatMenuOption(disabledText, null);
}
else
{
// 科技已完成或无需求,显示正常选项
yield return new FloatMenuOption("ARA_Incubate".Translate(entry.pawnKind.label), () =>
{
Job job = JobMaker.MakeJob(DefDatabase<JobDef>.GetNamed("ARA_IncubateJob"), parent);
this.selectedEntry = entry; // 保存整个入口信息
this.selectedEntry = entry;
selPawn.jobs.TryTakeOrderedJob(job);
});
}
@@ -55,7 +54,6 @@ namespace ArachnaeSwarm
}
}
public void StartIncubation()
{
if (this.selectedEntry == null) return;
@@ -73,8 +71,6 @@ namespace ArachnaeSwarm
}
}
private void SpawnPawn(PawnKindDef pawnKind)
{
try
@@ -138,7 +134,6 @@ namespace ArachnaeSwarm
}
}
public override string CompInspectStringExtra()
{
if (spawnUntilTick > 0)
@@ -161,7 +156,31 @@ namespace ArachnaeSwarm
base.PostExposeData();
Scribe_Values.Look(ref spawnUntilTick, "spawnUntilTick", -1);
Scribe_Defs.Look(ref spawningPawnKind, "spawningPawnKind");
// selectedEntry is transient and does not need to be saved.
// selectedEntry is not saved because the interaction is a one-off action.
}
// Moved to the correct position, at the class level.
public override IEnumerable<Gizmo> CompGetGizmosExtra()
{
foreach (var g in base.CompGetGizmosExtra())
{
yield return g;
}
if (IsHatching)
{
yield return new Command_Action
{
defaultLabel = "CommandCancelProduction".Translate(),
defaultDesc = "CommandCancelProductionDesc".Translate(),
icon = ContentFinder<Texture2D>.Get("UI/Designators/Cancel"),
action = () =>
{
spawnUntilTick = -1;
spawningPawnKind = null;
}
};
}
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Collections.Generic;
using Verse;
using Verse.AI;
namespace ArachnaeSwarm
{
public class JobDriver_AddToQueue : JobDriver
{
private const TargetIndex IncubatorInd = TargetIndex.A;
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
return pawn.Reserve(job.GetTarget(IncubatorInd), job, 1, -1, null, errorOnFailed);
}
protected override IEnumerable<Toil> MakeNewToils()
{
this.FailOnDespawnedNullOrForbidden(IncubatorInd);
yield return Toils_Goto.GotoThing(IncubatorInd, PathEndMode.Touch);
Toil addToQueue = new Toil();
addToQueue.initAction = () =>
{
CompQueuedPawnSpawner comp = job.GetTarget(IncubatorInd).Thing.TryGetComp<CompQueuedPawnSpawner>();
if (comp != null)
{
comp.AddToQueue();
}
};
addToQueue.defaultCompleteMode = ToilCompleteMode.Instant;
yield return addToQueue;
}
}
}

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="15.0"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -73,6 +74,7 @@
<Compile Include="ARA_SpawnPawnFromList\JobDriver_Incubate.cs" />
<Compile Include="ARA_SpawnPawnFromList\CompQueuedPawnSpawner.cs" />
<Compile Include="ARA_SpawnPawnFromList\ProductionContracts.cs" />
<Compile Include="ARA_SpawnPawnFromList\JobDriver_AddToQueue.cs" />
<Compile Include="ARA_QueenAbility\CompProperties_AbilitySprayLiquidMulti.cs" />
<Compile Include="ARA_QueenAbility\CompAbilityEffect_SprayLiquidMulti.cs" />
<Compile Include="DRM_HediffCurseFlame\Hediff_CurseFlame.cs" />
@@ -117,6 +119,8 @@
<Compile Include="ARA_CompInteractiveProducer\CompRefuelableNutrition.cs" />
<Compile Include="ARA_CompInteractiveProducer\DataContracts.cs" />
<Compile Include="ARA_CompInteractiveProducer\CompTemperatureRuinableDamage.cs" />
<Compile Include="ARA_CompInteractiveProducer\CompQueuedInteractiveProducer.cs" />
<Compile Include="ARA_CompInteractiveProducer\JobDriver_AddProcessToQueue.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="ARA_HuggingFace\Hediff_Possession.cs" />
@@ -134,6 +138,9 @@
</ItemGroup>
<ItemGroup>
<Compile Include="HediffComp_Temperature.cs" />
<Compile Include="CompPawnFlight.cs" />
<Compile Include="CompProperties_PawnFlight.cs" />
<Compile Include="HarmonyPatches.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="Abilities\CompAbilityEffect_TrackingCharge.cs" />

View File

@@ -0,0 +1,14 @@
using Verse;
namespace ArachnaeSwarm
{
/// <summary>
/// A marker component that holds custom flight properties.
/// The actual flight logic is handled by Harmony patches that check for this component
/// and use its properties to override or trigger vanilla flight behavior.
/// </summary>
public class CompPawnFlight : ThingComp
{
public CompProperties_PawnFlight Props => (CompProperties_PawnFlight)props;
}
}

View File

@@ -0,0 +1,49 @@
using Verse;
using RimWorld;
namespace ArachnaeSwarm
{
public enum FlightCondition
{
Drafted
}
public class CompProperties_PawnFlight : CompProperties
{
// --- Custom Flight Logic ---
public FlightCondition flightCondition = FlightCondition.Drafted;
// --- Vanilla PawnKindDef Flight Parameters ---
[NoTranslate]
public string flyingAnimationFramePathPrefix;
[NoTranslate]
public string flyingAnimationFramePathPrefixFemale;
public int flyingAnimationFrameCount;
public int flyingAnimationTicksPerFrame = -1;
public float flyingAnimationDrawSize = 1f;
public bool flyingAnimationDrawSizeIsMultiplier;
public bool flyingAnimationInheritColors;
// --- Vanilla PawnKindLifeStage Flight Parameters ---
// Note: These are normally defined per lifestage, we define them once here for simplicity.
// The harmony patch will need to inject these into the correct lifestage at runtime.
public AnimationDef flyingAnimationEast;
public AnimationDef flyingAnimationNorth;
public AnimationDef flyingAnimationSouth;
public AnimationDef flyingAnimationEastFemale;
public AnimationDef flyingAnimationNorthFemale;
public AnimationDef flyingAnimationSouthFemale;
public CompProperties_PawnFlight()
{
compClass = typeof(CompPawnFlight);
}
}
}

View File

@@ -0,0 +1,81 @@
using HarmonyLib;
using Verse;
using RimWorld;
using Verse.AI;
namespace ArachnaeSwarm
{
[HarmonyPatch]
public static class FlightHarmonyPatches
{
// Corrected Patch 1: The method signature now correctly matches the static target method.
[HarmonyPrefix]
[HarmonyPatch(typeof(Pawn_FlightTracker), "GetBestFlyAnimation")]
public static bool GetBestFlyAnimation_Prefix(Pawn pawn, ref AnimationDef __result) // Correct parameters: Pawn pawn, not __instance and ___pawn
{
var flightComp = pawn?.TryGetComp<CompPawnFlight>();
if (flightComp == null) // No props check needed, as the crash was due to wrong signature
{
return true;
}
var compProps = flightComp.Props;
AnimationDef selectedAnim = null;
if (pawn.gender == Gender.Female && compProps.flyingAnimationNorthFemale != null)
{
switch (pawn.Rotation.AsInt)
{
case 0: selectedAnim = compProps.flyingAnimationNorthFemale; break;
case 1: selectedAnim = compProps.flyingAnimationEastFemale; break;
case 2: selectedAnim = compProps.flyingAnimationSouthFemale; break;
case 3: selectedAnim = compProps.flyingAnimationEastFemale ?? compProps.flyingAnimationEast; break;
}
}
else
{
switch (pawn.Rotation.AsInt)
{
case 0: selectedAnim = compProps.flyingAnimationNorth; break;
case 1: selectedAnim = compProps.flyingAnimationEast; break;
case 2: selectedAnim = compProps.flyingAnimationSouth; break;
case 3: selectedAnim = compProps.flyingAnimationEast; break;
}
}
if (selectedAnim != null)
{
__result = selectedAnim;
return false;
}
return true;
}
// Patch 2 remains correct as Notify_JobStarted is a non-static method.
[HarmonyPrefix]
[HarmonyPatch(typeof(Pawn_FlightTracker), "Notify_JobStarted")]
public static bool Notify_JobStarted_Prefix(Job job, Pawn_FlightTracker __instance, Pawn ___pawn)
{
var flightComp = ___pawn?.TryGetComp<CompPawnFlight>();
if (flightComp == null || __instance == null || !__instance.CanEverFly || ___pawn == null || ___pawn.Dead)
{
return true;
}
var compProps = flightComp.Props;
bool shouldBeFlying = (compProps.flightCondition == FlightCondition.Drafted && ___pawn.Drafted);
if (shouldBeFlying)
{
if (!__instance.Flying) __instance.StartFlying();
job.flying = true;
}
else
{
if (__instance.Flying) __instance.ForceLand();
job.flying = false;
}
return false;
}
}
}