补暂存
This commit is contained in:
Binary file not shown.
@@ -30,7 +30,6 @@
|
|||||||
<li>Wula_Apparel_Init</li>
|
<li>Wula_Apparel_Init</li>
|
||||||
</apparelTags>
|
</apparelTags>
|
||||||
<abilities>
|
<abilities>
|
||||||
<li>WULA_EmergencyEnergyRestore</li>
|
|
||||||
</abilities>
|
</abilities>
|
||||||
<weaponMoney>0</weaponMoney>
|
<weaponMoney>0</weaponMoney>
|
||||||
<apparelAllowHeadgearChance>0</apparelAllowHeadgearChance>
|
<apparelAllowHeadgearChance>0</apparelAllowHeadgearChance>
|
||||||
@@ -74,7 +73,6 @@
|
|||||||
<li>Wula_Apparel_Init</li>
|
<li>Wula_Apparel_Init</li>
|
||||||
</apparelTags>
|
</apparelTags>
|
||||||
<abilities>
|
<abilities>
|
||||||
<li>WULA_EmergencyEnergyRestore</li>
|
|
||||||
</abilities>
|
</abilities>
|
||||||
<apparelRequired Inherit="False" />
|
<apparelRequired Inherit="False" />
|
||||||
|
|
||||||
|
|||||||
@@ -1,247 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Defs>
|
|
||||||
|
|
||||||
<ThingDef ParentName="ApparelMakeableBase">
|
|
||||||
<defName>WULA_ShieldBelt</defName>
|
|
||||||
<label>乌拉护盾腰带</label>
|
|
||||||
<description>乌拉帝国的个人护盾装置,可以产生动量排斥场来阻挡来袭的投射物。护盾可以通过能力按钮开关,并且具有可配置的护盾值和范围。</description>
|
|
||||||
<techLevel>Ultra</techLevel>
|
|
||||||
<recipeMaker>
|
|
||||||
<researchPrerequisite>WULA_Synth_Weapon_2_Stun_Technology</researchPrerequisite>
|
|
||||||
<unfinishedThingDef>UnfinishedBelt</unfinishedThingDef>
|
|
||||||
<recipeUsers Inherit="False">
|
|
||||||
<li>WULA_Cube_Productor_Energy</li>
|
|
||||||
</recipeUsers>
|
|
||||||
<skillRequirements>
|
|
||||||
<Crafting>8</Crafting>
|
|
||||||
</skillRequirements>
|
|
||||||
</recipeMaker>
|
|
||||||
<graphicData>
|
|
||||||
<texPath>Things/Item/Equipment/WeaponMelee/Knife</texPath>
|
|
||||||
<graphicClass>Graphic_Single</graphicClass>
|
|
||||||
</graphicData>
|
|
||||||
<costList>
|
|
||||||
<Steel>50</Steel>
|
|
||||||
<Plasteel>25</Plasteel>
|
|
||||||
<ComponentSpacer>3</ComponentSpacer>
|
|
||||||
<BroadshieldCore>1</BroadshieldCore>
|
|
||||||
</costList>
|
|
||||||
<statBases>
|
|
||||||
<WorkToMake>12000</WorkToMake>
|
|
||||||
<Mass>1.2</Mass>
|
|
||||||
<Flammability>0.4</Flammability>
|
|
||||||
</statBases>
|
|
||||||
<thingCategories>
|
|
||||||
<li>Apparel</li>
|
|
||||||
</thingCategories>
|
|
||||||
<apparel>
|
|
||||||
<bodyPartGroups>
|
|
||||||
<li>Waist</li>
|
|
||||||
</bodyPartGroups>
|
|
||||||
<wornGraphicPath>Things/Pawn/Humanlike/Apparel/ShieldBelt/ShieldBelt</wornGraphicPath>
|
|
||||||
<layers>
|
|
||||||
<li>Belt</li>
|
|
||||||
</layers>
|
|
||||||
<tags>
|
|
||||||
<li>BeltDefensePop</li>
|
|
||||||
</tags>
|
|
||||||
<defaultOutfitTags>
|
|
||||||
<li>Soldier</li>
|
|
||||||
</defaultOutfitTags>
|
|
||||||
</apparel>
|
|
||||||
<comps>
|
|
||||||
<li Class="WulaFallenEmpire.CompProperties_WulaShieldBelt">
|
|
||||||
<!-- 护盾最大生命值 - 护盾能承受的总伤害量 -->
|
|
||||||
<maxShieldHitPoints>200</maxShieldHitPoints>
|
|
||||||
<!-- 护盾半径 - 护盾保护范围的半径(以格子为单位) -->
|
|
||||||
<shieldRadius>3.0</shieldRadius>
|
|
||||||
<!-- 拦截地面投射物 - 是否拦截子弹、箭矢等地面投射物 -->
|
|
||||||
<interceptGroundProjectiles>true</interceptGroundProjectiles>
|
|
||||||
<!-- 拦截空中投射物 - 是否拦截迫击炮弹等空中投射物 -->
|
|
||||||
<interceptAirProjectiles>false</interceptAirProjectiles>
|
|
||||||
<!-- 拦截近战攻击 - 是否能够阻挡近战攻击 -->
|
|
||||||
<interceptMeleeAttacks>false</interceptMeleeAttacks>
|
|
||||||
<!-- EMP免疫 - 是否免疫电磁脉冲攻击 -->
|
|
||||||
<empImmune>false</empImmune>
|
|
||||||
<!-- 护盾颜色 - 护盾显示的颜色 (R, G, B) 值范围0-1 -->
|
|
||||||
<shieldColor>(0.2, 0.6, 1.0)</shieldColor>
|
|
||||||
<!-- 充能速率 - 护盾每秒恢复的生命值 -->
|
|
||||||
<rechargeRate>5.0</rechargeRate>
|
|
||||||
<!-- 充能冷却时间 - 护盾被破坏后开始充能前的等待时间(游戏刻数,60刻=1秒) -->
|
|
||||||
<rechargeCooldownTicks>300</rechargeCooldownTicks>
|
|
||||||
<!-- 激活音效 - 护盾运行时播放的环境音效 -->
|
|
||||||
<activeSound>BulletShield_Ambience</activeSound>
|
|
||||||
<!-- 重新激活特效 - 护盾重新启动时播放的视觉特效 -->
|
|
||||||
<reactivateEffect>BulletShieldGenerator_Reactivate</reactivateEffect>
|
|
||||||
<!-- 初始启用状态 - 护盾腰带装备后是否默认开启 -->
|
|
||||||
<startEnabled>false</startEnabled>
|
|
||||||
<!-- 护盾模式 - true=有生命值模式(可被破坏),false=无生命值模式(类似低角护盾,只偏转) -->
|
|
||||||
<useHitPointsMode>true</useHitPointsMode>
|
|
||||||
</li>
|
|
||||||
</comps>
|
|
||||||
</ThingDef>
|
|
||||||
|
|
||||||
<!-- 高级版本 -->
|
|
||||||
<ThingDef ParentName="ApparelMakeableBase">
|
|
||||||
<defName>WULA_ShieldBelt_Advanced</defName>
|
|
||||||
<label>乌拉高级护盾腰带</label>
|
|
||||||
<description>乌拉帝国的高级个人护盾装置,具有更强的护盾值、更大的范围,并且可以抵抗近战攻击和EMP伤害。</description>
|
|
||||||
<techLevel>Ultra</techLevel>
|
|
||||||
<recipeMaker>
|
|
||||||
<researchPrerequisite>WULA_Synth_Weapon_2_Stun_Technology</researchPrerequisite>
|
|
||||||
<unfinishedThingDef>UnfinishedBelt</unfinishedThingDef>
|
|
||||||
<recipeUsers Inherit="False">
|
|
||||||
<li>WULA_Cube_Productor_Energy</li>
|
|
||||||
</recipeUsers>
|
|
||||||
<skillRequirements>
|
|
||||||
<Crafting>10</Crafting>
|
|
||||||
</skillRequirements>
|
|
||||||
</recipeMaker>
|
|
||||||
<graphicData>
|
|
||||||
<texPath>Things/Item/Equipment/WeaponMelee/Knife</texPath>
|
|
||||||
<graphicClass>Graphic_Single</graphicClass>
|
|
||||||
</graphicData>
|
|
||||||
<costList>
|
|
||||||
<Steel>100</Steel>
|
|
||||||
<Plasteel>50</Plasteel>
|
|
||||||
<ComponentSpacer>6</ComponentSpacer>
|
|
||||||
<BroadshieldCore>2</BroadshieldCore>
|
|
||||||
<Uranium>10</Uranium>
|
|
||||||
</costList>
|
|
||||||
<statBases>
|
|
||||||
<WorkToMake>20000</WorkToMake>
|
|
||||||
<Mass>2.0</Mass>
|
|
||||||
<Flammability>0.2</Flammability>
|
|
||||||
</statBases>
|
|
||||||
<thingCategories>
|
|
||||||
<li>Apparel</li>
|
|
||||||
</thingCategories>
|
|
||||||
<apparel>
|
|
||||||
<bodyPartGroups>
|
|
||||||
<li>Waist</li>
|
|
||||||
</bodyPartGroups>
|
|
||||||
<wornGraphicPath>Things/Pawn/Humanlike/Apparel/ShieldBelt/ShieldBelt</wornGraphicPath>
|
|
||||||
<layers>
|
|
||||||
<li>Belt</li>
|
|
||||||
</layers>
|
|
||||||
<tags>
|
|
||||||
<li>BeltDefensePop</li>
|
|
||||||
</tags>
|
|
||||||
<defaultOutfitTags>
|
|
||||||
<li>Soldier</li>
|
|
||||||
</defaultOutfitTags>
|
|
||||||
</apparel>
|
|
||||||
<comps>
|
|
||||||
<li Class="WulaFallenEmpire.CompProperties_WulaShieldBelt">
|
|
||||||
<!-- 护盾最大生命值 - 护盾能承受的总伤害量 -->
|
|
||||||
<maxShieldHitPoints>400</maxShieldHitPoints>
|
|
||||||
<!-- 护盾半径 - 护盾保护范围的半径(以格子为单位) -->
|
|
||||||
<shieldRadius>4.5</shieldRadius>
|
|
||||||
<!-- 拦截地面投射物 - 是否拦截子弹、箭矢等地面投射物 -->
|
|
||||||
<interceptGroundProjectiles>true</interceptGroundProjectiles>
|
|
||||||
<!-- 拦截空中投射物 - 是否拦截迫击炮弹等空中投射物 -->
|
|
||||||
<interceptAirProjectiles>true</interceptAirProjectiles>
|
|
||||||
<!-- 拦截近战攻击 - 是否能够阻挡近战攻击 -->
|
|
||||||
<interceptMeleeAttacks>true</interceptMeleeAttacks>
|
|
||||||
<!-- EMP免疫 - 是否免疫电磁脉冲攻击 -->
|
|
||||||
<empImmune>true</empImmune>
|
|
||||||
<!-- 护盾颜色 - 护盾显示的颜色 (R, G, B) 值范围0-1 -->
|
|
||||||
<shieldColor>(1.0, 0.6, 0.2)</shieldColor>
|
|
||||||
<!-- 充能速率 - 护盾每秒恢复的生命值 -->
|
|
||||||
<rechargeRate>8.0</rechargeRate>
|
|
||||||
<!-- 充能冷却时间 - 护盾被破坏后开始充能前的等待时间(游戏刻数,60刻=1秒) -->
|
|
||||||
<rechargeCooldownTicks>180</rechargeCooldownTicks>
|
|
||||||
<!-- 激活音效 - 护盾运行时播放的环境音效 -->
|
|
||||||
<activeSound>BulletShield_Ambience</activeSound>
|
|
||||||
<!-- 重新激活特效 - 护盾重新启动时播放的视觉特效 -->
|
|
||||||
<reactivateEffect>BulletShieldGenerator_Reactivate</reactivateEffect>
|
|
||||||
<!-- 初始启用状态 - 护盾腰带装备后是否默认开启 -->
|
|
||||||
<startEnabled>false</startEnabled>
|
|
||||||
<!-- 护盾模式 - true=有生命值模式(可被破坏),false=无生命值模式(类似低角护盾,只偏转) -->
|
|
||||||
<useHitPointsMode>true</useHitPointsMode>
|
|
||||||
</li>
|
|
||||||
</comps>
|
|
||||||
</ThingDef>
|
|
||||||
|
|
||||||
<!-- 偏转型护盾腰带 - 无生命值模式示例 -->
|
|
||||||
<ThingDef ParentName="ApparelMakeableBase">
|
|
||||||
<defName>WULA_ShieldBelt_Deflector</defName>
|
|
||||||
<label>乌拉偏转护盾腰带</label>
|
|
||||||
<description>乌拉帝国的偏转型个人护盾装置,采用低角护盾技术,不会被破坏但只能偏转投射物。这种护盾永远不会过载,但也无法完全阻挡攻击。</description>
|
|
||||||
<techLevel>Ultra</techLevel>
|
|
||||||
<recipeMaker>
|
|
||||||
<researchPrerequisite>WULA_Synth_Weapon_2_Stun_Technology</researchPrerequisite>
|
|
||||||
<unfinishedThingDef>UnfinishedBelt</unfinishedThingDef>
|
|
||||||
<recipeUsers Inherit="False">
|
|
||||||
<li>WULA_Cube_Productor_Energy</li>
|
|
||||||
</recipeUsers>
|
|
||||||
<skillRequirements>
|
|
||||||
<Crafting>6</Crafting>
|
|
||||||
</skillRequirements>
|
|
||||||
</recipeMaker>
|
|
||||||
<graphicData>
|
|
||||||
<texPath>Things/Item/Equipment/WeaponMelee/Knife</texPath>
|
|
||||||
<graphicClass>Graphic_Single</graphicClass>
|
|
||||||
</graphicData>
|
|
||||||
<costList>
|
|
||||||
<Steel>30</Steel>
|
|
||||||
<Plasteel>15</Plasteel>
|
|
||||||
<ComponentSpacer>2</ComponentSpacer>
|
|
||||||
<BroadshieldCore>1</BroadshieldCore>
|
|
||||||
</costList>
|
|
||||||
<statBases>
|
|
||||||
<WorkToMake>8000</WorkToMake>
|
|
||||||
<Mass>0.8</Mass>
|
|
||||||
<Flammability>0.4</Flammability>
|
|
||||||
</statBases>
|
|
||||||
<thingCategories>
|
|
||||||
<li>Apparel</li>
|
|
||||||
</thingCategories>
|
|
||||||
<apparel>
|
|
||||||
<bodyPartGroups>
|
|
||||||
<li>Waist</li>
|
|
||||||
</bodyPartGroups>
|
|
||||||
<wornGraphicPath>Things/Pawn/Humanlike/Apparel/ShieldBelt/ShieldBelt</wornGraphicPath>
|
|
||||||
<layers>
|
|
||||||
<li>Belt</li>
|
|
||||||
</layers>
|
|
||||||
<tags>
|
|
||||||
<li>BeltDefensePop</li>
|
|
||||||
</tags>
|
|
||||||
<defaultOutfitTags>
|
|
||||||
<li>Soldier</li>
|
|
||||||
</defaultOutfitTags>
|
|
||||||
</apparel>
|
|
||||||
<comps>
|
|
||||||
<li Class="WulaFallenEmpire.CompProperties_WulaShieldBelt">
|
|
||||||
<!-- 护盾最大生命值 - 在偏转模式下此值不重要,但仍需设置 -->
|
|
||||||
<maxShieldHitPoints>100</maxShieldHitPoints>
|
|
||||||
<!-- 护盾半径 - 护盾保护范围的半径(以格子为单位) -->
|
|
||||||
<shieldRadius>2.5</shieldRadius>
|
|
||||||
<!-- 拦截地面投射物 - 是否拦截子弹、箭矢等地面投射物 -->
|
|
||||||
<interceptGroundProjectiles>true</interceptGroundProjectiles>
|
|
||||||
<!-- 拦截空中投射物 - 是否拦截迫击炮弹等空中投射物 -->
|
|
||||||
<interceptAirProjectiles>false</interceptAirProjectiles>
|
|
||||||
<!-- 拦截近战攻击 - 是否能够阻挡近战攻击 -->
|
|
||||||
<interceptMeleeAttacks>false</interceptMeleeAttacks>
|
|
||||||
<!-- EMP免疫 - 是否免疫电磁脉冲攻击 -->
|
|
||||||
<empImmune>false</empImmune>
|
|
||||||
<!-- 护盾颜色 - 护盾显示的颜色 (R, G, B) 值范围0-1 -->
|
|
||||||
<shieldColor>(0.6, 1.0, 0.6)</shieldColor>
|
|
||||||
<!-- 充能速率 - 在偏转模式下此值不重要 -->
|
|
||||||
<rechargeRate>0</rechargeRate>
|
|
||||||
<!-- 充能冷却时间 - 在偏转模式下此值不重要 -->
|
|
||||||
<rechargeCooldownTicks>0</rechargeCooldownTicks>
|
|
||||||
<!-- 激活音效 - 护盾运行时播放的环境音效 -->
|
|
||||||
<activeSound>BulletShield_Ambience</activeSound>
|
|
||||||
<!-- 重新激活特效 - 护盾重新启动时播放的视觉特效 -->
|
|
||||||
<reactivateEffect>BulletShieldGenerator_Reactivate</reactivateEffect>
|
|
||||||
<!-- 初始启用状态 - 护盾腰带装备后是否默认开启 -->
|
|
||||||
<startEnabled>true</startEnabled>
|
|
||||||
<!-- 护盾模式 - false=无生命值模式(类似低角护盾,只偏转,永不破坏) -->
|
|
||||||
<useHitPointsMode>false</useHitPointsMode>
|
|
||||||
</li>
|
|
||||||
</comps>
|
|
||||||
</ThingDef>
|
|
||||||
|
|
||||||
</Defs>
|
|
||||||
@@ -1,24 +1,492 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<Defs>
|
<Defs>
|
||||||
<ThinkTreeDef>
|
<ThinkTreeDef>
|
||||||
<defName>WULA_Humanlike</defName>
|
<defName>WULA_Humanlike</defName>
|
||||||
<thinkRoot Class="ThinkNode_Priority">
|
<thinkRoot Class="ThinkNode_Priority">
|
||||||
<subNodes>
|
<subNodes>
|
||||||
<!-- Add our custom JobGiver for Wula energy here -->
|
|
||||||
<li Class="WulaFallenEmpire.JobGiver_WulaGetEnergy">
|
<!-- Do lovin' -->
|
||||||
<minEnergyLevelPercentage>0.5</minEnergyLevelPercentage> <!-- 能量低于50%时开始寻找 -->
|
<li Class="ThinkNode_ConditionalLyingDown">
|
||||||
<emergencyThreshold>0.1</emergencyThreshold> <!-- 能量低于10%时非常紧急 -->
|
<subNodes>
|
||||||
<normalPriority>5.0</normalPriority>
|
<li Class="ThinkNode_ChancePerHour_Lovin">
|
||||||
<emergencyPriority>9.5</emergencyPriority>
|
<subNodes>
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>SatisfyingNeeds</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_DoLovin" />
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
</li>
|
</li>
|
||||||
<!-- Include original Humanlike think tree -->
|
|
||||||
|
<!-- If we HAVE to keep lying down... -->
|
||||||
|
<li Class="ThinkNode_ConditionalMustKeepLyingDown">
|
||||||
|
<subNodes>
|
||||||
|
<!-- Do a queued job if possible (e.g. watch tv in bed) -->
|
||||||
|
<li Class="ThinkNode_QueuedJob">
|
||||||
|
<inBedOnly>true</inBedOnly>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Get joy -->
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>SatisfyingNeeds</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ThinkNode_PrioritySorter">
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ThinkNode_Priority_GetJoy">
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_GetJoyInBed" />
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
<li Class="JobGiver_MeditateInBed"/>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Keep lying down -->
|
||||||
|
<li Class="JobGiver_KeepLyingDown" />
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li Class="ThinkNode_Subtree">
|
<li Class="ThinkNode_Subtree">
|
||||||
<treeDef>Humanlike</treeDef>
|
<treeDef>Downed</treeDef>
|
||||||
</li>
|
</li>
|
||||||
<!-- Include original HumanlikeConstant think tree -->
|
|
||||||
<li Class="ThinkNode_Subtree">
|
<li Class="ThinkNode_Subtree">
|
||||||
<treeDef>HumanlikeConstant</treeDef>
|
<treeDef>BurningResponse</treeDef>
|
||||||
</li>
|
</li>
|
||||||
|
<li Class="ThinkNode_Subtree">
|
||||||
|
<treeDef>MentalStateCritical</treeDef>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Escaping threats -->
|
||||||
|
<li Class="ThinkNode_Subtree" MayRequire="Ludeon.RimWorld.Biotech">
|
||||||
|
<treeDef>Abilities_Escape</treeDef>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- React to close melee threat -->
|
||||||
|
<li Class="JobGiver_ReactToCloseMeleeThreat" />
|
||||||
|
|
||||||
|
<!-- Mental state non critical -->
|
||||||
|
<li Class="ThinkNode_Subtree">
|
||||||
|
<treeDef>MentalStateNonCritical</treeDef>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Behavior when roped -->
|
||||||
|
<li Class="ThinkNode_Subtree">
|
||||||
|
<treeDef>RopedPawn</treeDef>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Insertion hook for modders -->
|
||||||
|
<li Class="ThinkNode_SubtreesByTag">
|
||||||
|
<insertTag>Humanlike_PostMentalState</insertTag>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Do a queued job -->
|
||||||
|
<li Class="ThinkNode_QueuedJob" />
|
||||||
|
|
||||||
|
<!-- Wait if drafted -->
|
||||||
|
<li Class="ThinkNode_ConditionalColonist">
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>DraftedOrder</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_MoveToStandable" />
|
||||||
|
<li Class="JobGiver_Orders" />
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Self-tend if you're an NPC -->
|
||||||
|
<li Class="ThinkNode_ConditionalNPCCanSelfTendNow">
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_SelfTend" />
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Lord directives (high priority) -->
|
||||||
|
<li Class="ThinkNode_JoinVoluntarilyJoinableLord">
|
||||||
|
<dutyHook>HighPriority</dutyHook>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ThinkNode_Subtree">
|
||||||
|
<treeDef>LordDuty</treeDef>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Insertion hook for modders -->
|
||||||
|
<li Class="ThinkNode_SubtreesByTag">
|
||||||
|
<insertTag>Humanlike_PostDuty</insertTag>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Prisoner -->
|
||||||
|
<li Class="ThinkNode_ConditionalPrisoner">
|
||||||
|
<leaveJoinableLordIfIssuesJob>true</leaveJoinableLordIfIssuesJob>
|
||||||
|
<subNodes>
|
||||||
|
<!-- If it's the player home map... -->
|
||||||
|
<li Class="ThinkNode_ConditionalInNonPlayerHomeMap">
|
||||||
|
<invert>true</invert>
|
||||||
|
<subNodes>
|
||||||
|
<!-- Wait instead of escaping if should -->
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>Idle</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_PrisonerWaitInsteadOfEscaping">
|
||||||
|
<maxDanger>Deadly</maxDanger>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Escape -->
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>Escaping</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_PrisonerEscape" />
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Exit map if released -->
|
||||||
|
<li Class="ThinkNode_ConditionalReleased">
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>Misc</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_ExitMapBest">
|
||||||
|
<defaultLocomotion>Walk</defaultLocomotion>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>RestingForMedicalReasons</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_PatientGoToBed" />
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>ChangingApparel</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_PrisonerGetDressed" />
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>SatisfyingNeeds</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ThinkNode_PrioritySorter">
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_Autofeed" MayRequire="Ludeon.RimWorld.Biotech" />
|
||||||
|
<li Class="WulaFallenEmpire.JobGiver_WulaGetEnergy"/>
|
||||||
|
<li Class="JobGiver_GetRest"/>
|
||||||
|
<li Class="JobGiver_SatisfyChemicalNeed"/>
|
||||||
|
<li Class="JobGiver_SatifyChemicalDependency" MayRequire="Ludeon.RimWorld.Biotech" />
|
||||||
|
<li Class="JobGiver_GetHemogen" MayRequire="Ludeon.RimWorld.Biotech" />
|
||||||
|
<li Class="JobGiver_GetDeathrest" MayRequire="Ludeon.RimWorld.Biotech" />
|
||||||
|
<li Class="ThinkNode_Priority_GetJoy">
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_GetJoy"/>
|
||||||
|
<li Class="JobGiver_GetJoyInBed"/>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
<li Class="JobGiver_Meditate"/>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- If in non-PlayerHomeMap -->
|
||||||
|
<li Class="ThinkNode_ConditionalInNonPlayerHomeMap">
|
||||||
|
<subNodes>
|
||||||
|
<!-- No colonist spawned in the map -->
|
||||||
|
<li Class="ThinkNode_ConditionalAnyUndownedColonistSpawnedNearby">
|
||||||
|
<invert>true</invert>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>Escaping</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_PrisonerEscape" />
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
<!-- Wander -->
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>Idle</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_WanderColony">
|
||||||
|
<maxDanger>Deadly</maxDanger>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>Idle</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_WanderCurrentRoom">
|
||||||
|
<maxDanger>Deadly</maxDanger>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li Class="JobGiver_IdleError" />
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- If on colonist team, do forced and emergency work -->
|
||||||
|
<li Class="ThinkNode_ConditionalColonist">
|
||||||
|
<subNodes>
|
||||||
|
<!-- Seek allowed area -->
|
||||||
|
<li Class="JobGiver_SeekAllowedArea" />
|
||||||
|
|
||||||
|
<!-- Seek safe temperatures -->
|
||||||
|
<li Class="JobGiver_BringBabyToSafety" />
|
||||||
|
<li Class="JobGiver_SeekSafeTemperature" />
|
||||||
|
|
||||||
|
<!-- Drop unnused inventory -->
|
||||||
|
<li Class="JobGiver_DropUnusedInventory" />
|
||||||
|
|
||||||
|
<!-- Emergency work -->
|
||||||
|
<li Class="JobGiver_Work">
|
||||||
|
<leaveJoinableLordIfIssuesJob>true</leaveJoinableLordIfIssuesJob>
|
||||||
|
<emergency>true</emergency>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Get Wula energy (only if starving) -->
|
||||||
|
<li Class="ThinkNode_ConditionalNeedPercentageAbove">
|
||||||
|
<need>WULA_Energy</need>
|
||||||
|
<threshold>0.5</threshold> <!-- 能量低于10%时触发 -->
|
||||||
|
<invert>true</invert>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>SatisfyingNeeds</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="WulaFallenEmpire.JobGiver_WulaGetEnergy">
|
||||||
|
<leaveJoinableLordIfIssuesJob>true</leaveJoinableLordIfIssuesJob>
|
||||||
|
<minEnergyLevelPercentage>0.5</minEnergyLevelPercentage>
|
||||||
|
<emergencyThreshold>0.1</emergencyThreshold>
|
||||||
|
<normalPriority>5</normalPriority>
|
||||||
|
<emergencyPriority>9.5</emergencyPriority>
|
||||||
|
<searchRadius>30</searchRadius> <!-- 搜索半径调整为30 -->
|
||||||
|
<ingestCount>1</ingestCount> <!-- 每次摄取1个能量核心 -->
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Breastfeed -->
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>Misc</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_Autofeed" MayRequire="Ludeon.RimWorld.Biotech" />
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
<!-- Lord directives (medium priority) -->
|
||||||
|
<li Class="ThinkNode_JoinVoluntarilyJoinableLord">
|
||||||
|
<dutyHook>MediumPriority</dutyHook>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ThinkNode_Subtree">
|
||||||
|
<treeDef>LordDuty</treeDef>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Pick up a weapon dropped while previously downed -->
|
||||||
|
<li Class="JobGiver_PickupDroppedWeapon">
|
||||||
|
<ignoreForbidden>true</ignoreForbidden>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Optimize apparel -->
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>ChangingApparel</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_OptimizeApparel">
|
||||||
|
<leaveJoinableLordIfIssuesJob>true</leaveJoinableLordIfIssuesJob>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Look change -->
|
||||||
|
<li MayRequire="Ludeon.RimWorld.Ideology" Class="ThinkNode_ConditionalWantsLookChange">
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_UseStylingStationAutomatic" />
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Dye hair -->
|
||||||
|
<li MayRequire="Ludeon.RimWorld.Ideology" Class="JobGiver_DyeHair" />
|
||||||
|
|
||||||
|
<!-- Take for inventory stock -->
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>TakeForInventoryStock</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_TakeForInventoryStock">
|
||||||
|
<leaveJoinableLordIfIssuesJob>true</leaveJoinableLordIfIssuesJob>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Unload your inventory -->
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>UnloadingOwnInventory</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_UnloadYourInventory" />
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Pack Wula energy if not enough -->
|
||||||
|
<li Class="ThinkNode_ConditionalNeedPercentageAbove">
|
||||||
|
<need>WULA_Energy</need> <!-- 能量NeedDef的defName -->
|
||||||
|
<threshold>0.6</threshold> <!-- 能量低于packEnergyThreshold时考虑打包 -->
|
||||||
|
<invert>true</invert> <!-- 当能量低于阈值时触发 -->
|
||||||
|
<subNodes>
|
||||||
|
<li Class="WulaFallenEmpire.JobGiver_WulaPackEnergy">
|
||||||
|
<leaveJoinableLordIfIssuesJob>true</leaveJoinableLordIfIssuesJob>
|
||||||
|
<packEnergyThreshold>0.6</packEnergyThreshold> <!-- 能量低于50%时考虑打包 -->
|
||||||
|
<packEnergyCount>2</packEnergyCount> <!-- 每次打包2个能量核心 -->
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Behavior from traits -->
|
||||||
|
<li Class="ThinkNode_TraitBehaviors" />
|
||||||
|
|
||||||
|
<!-- Insertion hook for modders -->
|
||||||
|
<li Class="ThinkNode_SubtreesByTag">
|
||||||
|
<insertTag>Humanlike_PreMain</insertTag>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Main colonist behavior core -->
|
||||||
|
<li Class="ThinkNode_ConditionalColonist">
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ThinkNode_Subtree">
|
||||||
|
<treeDef>MainColonistBehaviorCore</treeDef>
|
||||||
|
<leaveJoinableLordIfIssuesJob>true</leaveJoinableLordIfIssuesJob>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
<!-- Main wild man behavior core -->
|
||||||
|
<li Class="ThinkNode_ConditionalPawnKind">
|
||||||
|
<pawnKind>WildMan</pawnKind>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ThinkNode_Subtree">
|
||||||
|
<treeDef>MainWildManBehaviorCore</treeDef>
|
||||||
|
<leaveJoinableLordIfIssuesJob>true</leaveJoinableLordIfIssuesJob>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Insertion hook for modders -->
|
||||||
|
<li Class="ThinkNode_SubtreesByTag">
|
||||||
|
<insertTag>Humanlike_PostMain</insertTag>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Idle colonist -->
|
||||||
|
<li Class="ThinkNode_ConditionalColonist">
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>Idle</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<!-- Do random joy activity -->
|
||||||
|
<li Class="ThinkNode_ConditionalNeedPercentageAbove">
|
||||||
|
<need>Joy</need>
|
||||||
|
<threshold>0.9</threshold>
|
||||||
|
<invert>true</invert>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_IdleJoy" />
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Wander -->
|
||||||
|
<li Class="JobGiver_WanderColony">
|
||||||
|
<maxDanger>None</maxDanger>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Idle wild man -->
|
||||||
|
<li Class="ThinkNode_ConditionalPawnKind">
|
||||||
|
<pawnKind>WildMan</pawnKind>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>Idle</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<!-- Wander -->
|
||||||
|
<li Class="JobGiver_WanderAnywhere">
|
||||||
|
<maxDanger>Deadly</maxDanger>
|
||||||
|
<ticksBetweenWandersRange>120~240</ticksBetweenWandersRange>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- If you're a neutral guest, if you're not hurt exit the map, otherwise use a medical bed -->
|
||||||
|
<li Class="ThinkNode_ConditionalGuest">
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ThinkNode_ConditionalNonPlayerNonHostileFactionOrFactionless">
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>RestingForMedicalReasons</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_PatientGoToBed" />
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>Misc</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_ExitMapBest">
|
||||||
|
<defaultLocomotion>Walk</defaultLocomotion>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Final backup: If you're just here for no apparent reason, and not a colonist, leave the map
|
||||||
|
e.g. This happens for pawns who are downed during combat, then later self-heal -->
|
||||||
|
<li Class="ThinkNode_ConditionalColonist">
|
||||||
|
<invert>true</invert>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>Misc</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_ExitMapBest">
|
||||||
|
<defaultLocomotion>Walk</defaultLocomotion>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- If you can't leave, just wander -->
|
||||||
|
<li Class="ThinkNode_Tagger">
|
||||||
|
<tagToGive>Idle</tagToGive>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="JobGiver_WanderAnywhere">
|
||||||
|
<maxDanger>Deadly</maxDanger>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li Class="JobGiver_IdleError" />
|
||||||
</subNodes>
|
</subNodes>
|
||||||
</thinkRoot>
|
</thinkRoot>
|
||||||
</ThinkTreeDef>
|
</ThinkTreeDef>
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LanguageData>
|
||||||
|
|
||||||
|
<WULA_SkillTrainer_TargetSkillGained>{0}的{1}技能获得了经验。</WULA_SkillTrainer_TargetSkillGained>
|
||||||
|
<WULA_SkillTrainer_SkillLoss>{0}的{1}技能经验减少了。</WULA_SkillTrainer_SkillLoss>
|
||||||
|
|
||||||
|
</LanguageData>
|
||||||
Binary file not shown.
@@ -2,12 +2,28 @@
|
|||||||
"Version": 1,
|
"Version": 1,
|
||||||
"WorkspaceRootPath": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\",
|
"WorkspaceRootPath": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\",
|
||||||
"Documents": [
|
"Documents": [
|
||||||
|
{
|
||||||
|
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|c:\\steam\\steamapps\\common\\rimworld\\mods\\3516260226\\source\\wulafallenempire\\jobgiver_wulapackenergy.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||||
|
"RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:jobgiver_wulapackenergy.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\jobgiver_wulagetenergy.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||||
|
"RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:jobgiver_wulagetenergy.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|c:\\steam\\steamapps\\common\\rimworld\\mods\\3516260226\\source\\wulafallenempire\\compuseeffect_wulaskilltrainer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||||
|
"RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:compuseeffect_wulaskilltrainer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\wulafallenempiremod.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||||
|
"RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:wulafallenempiremod.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\building_wula_darkenergy_engine.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\building_wula_darkenergy_engine.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||||
"RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:building_wula_darkenergy_engine.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
"RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:building_wula_darkenergy_engine.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|c:\\steam\\steamapps\\common\\rimworld\\mods\\3516260226\\source\\wulafallenempire\\ingestpatch.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\ingestpatch.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||||
"RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:ingestpatch.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
"RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:ingestpatch.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -17,10 +33,6 @@
|
|||||||
{
|
{
|
||||||
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\mechanitorpatch.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\mechanitorpatch.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||||
"RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:mechanitorpatch.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
"RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:mechanitorpatch.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||||
},
|
|
||||||
{
|
|
||||||
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\wulafallenempiremod.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
|
||||||
"RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:wulafallenempiremod.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"DocumentGroupContainers": [
|
"DocumentGroupContainers": [
|
||||||
@@ -30,15 +42,66 @@
|
|||||||
"DocumentGroups": [
|
"DocumentGroups": [
|
||||||
{
|
{
|
||||||
"DockedWidth": 200,
|
"DockedWidth": 200,
|
||||||
"SelectedChildIndex": 6,
|
"SelectedChildIndex": 2,
|
||||||
"Children": [
|
"Children": [
|
||||||
{
|
{
|
||||||
"$type": "Bookmark",
|
"$type": "Bookmark",
|
||||||
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
|
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"$type": "Document",
|
||||||
|
"DocumentIndex": 2,
|
||||||
|
"Title": "CompUseEffect_WulaSkillTrainer.cs",
|
||||||
|
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\CompUseEffect_WulaSkillTrainer.cs",
|
||||||
|
"RelativeDocumentMoniker": "CompUseEffect_WulaSkillTrainer.cs",
|
||||||
|
"ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\CompUseEffect_WulaSkillTrainer.cs",
|
||||||
|
"RelativeToolTip": "CompUseEffect_WulaSkillTrainer.cs",
|
||||||
|
"ViewState": "AQIAAEAAAAAAAAAAAAAUwFMAAAABAAAA",
|
||||||
|
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||||
|
"WhenOpened": "2025-07-22T07:52:56.407Z",
|
||||||
|
"EditorCaption": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$type": "Document",
|
||||||
|
"DocumentIndex": 0,
|
||||||
|
"Title": "JobGiver_WulaPackEnergy.cs",
|
||||||
|
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\JobGiver_WulaPackEnergy.cs",
|
||||||
|
"RelativeDocumentMoniker": "JobGiver_WulaPackEnergy.cs",
|
||||||
|
"ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\JobGiver_WulaPackEnergy.cs",
|
||||||
|
"RelativeToolTip": "JobGiver_WulaPackEnergy.cs",
|
||||||
|
"ViewState": "AQIAAAAAAAAAAAAAAAAAAAgAAAAoAAAA",
|
||||||
|
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||||
|
"WhenOpened": "2025-07-22T07:19:52.552Z",
|
||||||
|
"EditorCaption": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
"DocumentIndex": 1,
|
"DocumentIndex": 1,
|
||||||
|
"Title": "JobGiver_WulaGetEnergy.cs",
|
||||||
|
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\JobGiver_WulaGetEnergy.cs",
|
||||||
|
"RelativeDocumentMoniker": "JobGiver_WulaGetEnergy.cs",
|
||||||
|
"ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\JobGiver_WulaGetEnergy.cs",
|
||||||
|
"RelativeToolTip": "JobGiver_WulaGetEnergy.cs",
|
||||||
|
"ViewState": "AQIAADsAAAAAAAAAAAAUwGEAAAAlAAAA",
|
||||||
|
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||||
|
"WhenOpened": "2025-07-22T07:19:46.094Z",
|
||||||
|
"EditorCaption": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$type": "Document",
|
||||||
|
"DocumentIndex": 4,
|
||||||
|
"Title": "Building_Wula_DarkEnergy_Engine.cs",
|
||||||
|
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\Building_Wula_DarkEnergy_Engine.cs",
|
||||||
|
"RelativeDocumentMoniker": "Building_Wula_DarkEnergy_Engine.cs",
|
||||||
|
"ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\Building_Wula_DarkEnergy_Engine.cs",
|
||||||
|
"RelativeToolTip": "Building_Wula_DarkEnergy_Engine.cs",
|
||||||
|
"ViewState": "AQIAABUAAAAAAAAAAAAIwAAAAAAAAAAA",
|
||||||
|
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||||
|
"WhenOpened": "2025-07-14T12:24:18.86Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$type": "Document",
|
||||||
|
"DocumentIndex": 5,
|
||||||
"Title": "IngestPatch.cs",
|
"Title": "IngestPatch.cs",
|
||||||
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\IngestPatch.cs",
|
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\IngestPatch.cs",
|
||||||
"RelativeDocumentMoniker": "IngestPatch.cs",
|
"RelativeDocumentMoniker": "IngestPatch.cs",
|
||||||
@@ -46,12 +109,11 @@
|
|||||||
"RelativeToolTip": "IngestPatch.cs",
|
"RelativeToolTip": "IngestPatch.cs",
|
||||||
"ViewState": "AQIAACEAAAAAAAAAAAAowEwAAAAAAAAA",
|
"ViewState": "AQIAACEAAAAAAAAAAAAowEwAAAAAAAAA",
|
||||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||||
"WhenOpened": "2025-07-20T17:09:27.916Z",
|
"WhenOpened": "2025-07-20T17:09:27.916Z"
|
||||||
"EditorCaption": ""
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
"DocumentIndex": 2,
|
"DocumentIndex": 6,
|
||||||
"Title": "HediffComp_RegenerateBackstory.cs",
|
"Title": "HediffComp_RegenerateBackstory.cs",
|
||||||
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\HediffComp_RegenerateBackstory.cs",
|
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\HediffComp_RegenerateBackstory.cs",
|
||||||
"RelativeDocumentMoniker": "HediffComp_RegenerateBackstory.cs",
|
"RelativeDocumentMoniker": "HediffComp_RegenerateBackstory.cs",
|
||||||
@@ -63,15 +125,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
"DocumentIndex": 4,
|
"DocumentIndex": 3,
|
||||||
"Title": "WulaFallenEmpireMod.cs",
|
"Title": "WulaFallenEmpireMod.cs",
|
||||||
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\WulaFallenEmpireMod.cs",
|
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\WulaFallenEmpireMod.cs",
|
||||||
"RelativeDocumentMoniker": "WulaFallenEmpireMod.cs",
|
"RelativeDocumentMoniker": "WulaFallenEmpireMod.cs",
|
||||||
"ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\WulaFallenEmpireMod.cs",
|
"ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\WulaFallenEmpireMod.cs",
|
||||||
"RelativeToolTip": "WulaFallenEmpireMod.cs",
|
"RelativeToolTip": "WulaFallenEmpireMod.cs",
|
||||||
"ViewState": "AQIAAAAAAAAAAAAAAAAAABQAAAAAAAAA",
|
"ViewState": "AQIAAAAAAAAAAAAAAAAAAA4AAAA+AAAA",
|
||||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||||
"WhenOpened": "2025-07-18T10:23:17.898Z"
|
"WhenOpened": "2025-07-18T10:23:17.898Z",
|
||||||
|
"EditorCaption": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Bookmark",
|
"$type": "Bookmark",
|
||||||
@@ -79,7 +142,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
"DocumentIndex": 3,
|
"DocumentIndex": 7,
|
||||||
"Title": "MechanitorPatch.cs",
|
"Title": "MechanitorPatch.cs",
|
||||||
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\MechanitorPatch.cs",
|
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\MechanitorPatch.cs",
|
||||||
"RelativeDocumentMoniker": "MechanitorPatch.cs",
|
"RelativeDocumentMoniker": "MechanitorPatch.cs",
|
||||||
@@ -88,19 +151,6 @@
|
|||||||
"ViewState": "AQIAAAAAAAAAAAAAAAAAACEAAAAJAAAA",
|
"ViewState": "AQIAAAAAAAAAAAAAAAAAACEAAAAJAAAA",
|
||||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||||
"WhenOpened": "2025-07-18T10:20:31.368Z"
|
"WhenOpened": "2025-07-18T10:20:31.368Z"
|
||||||
},
|
|
||||||
{
|
|
||||||
"$type": "Document",
|
|
||||||
"DocumentIndex": 0,
|
|
||||||
"Title": "Building_Wula_DarkEnergy_Engine.cs",
|
|
||||||
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\Building_Wula_DarkEnergy_Engine.cs",
|
|
||||||
"RelativeDocumentMoniker": "Building_Wula_DarkEnergy_Engine.cs",
|
|
||||||
"ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\Building_Wula_DarkEnergy_Engine.cs",
|
|
||||||
"RelativeToolTip": "Building_Wula_DarkEnergy_Engine.cs",
|
|
||||||
"ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
|
||||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
|
||||||
"WhenOpened": "2025-07-14T12:24:18.86Z",
|
|
||||||
"EditorCaption": ""
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
using RimWorld;
|
|
||||||
using UnityEngine;
|
|
||||||
using Verse;
|
|
||||||
using Verse.Sound;
|
|
||||||
|
|
||||||
namespace WulaFallenEmpire
|
|
||||||
{
|
|
||||||
public class CompProperties_WulaShieldBelt : CompProperties
|
|
||||||
{
|
|
||||||
public int maxShieldHitPoints = 200;
|
|
||||||
public float shieldRadius = 3.0f;
|
|
||||||
public bool interceptGroundProjectiles = true;
|
|
||||||
public bool interceptAirProjectiles = false;
|
|
||||||
public bool interceptMeleeAttacks = false;
|
|
||||||
public bool empImmune = false;
|
|
||||||
public Color shieldColor = new Color(0.2f, 0.6f, 1.0f);
|
|
||||||
public float rechargeRate = 5.0f;
|
|
||||||
public int rechargeCooldownTicks = 300;
|
|
||||||
public SoundDef activeSound;
|
|
||||||
public EffecterDef reactivateEffect;
|
|
||||||
public bool startEnabled = false;
|
|
||||||
|
|
||||||
// 护盾模式:true = 有生命值模式(可被破坏),false = 无生命值模式(类似低角护盾,只是偏转)
|
|
||||||
public bool useHitPointsMode = true;
|
|
||||||
|
|
||||||
public CompProperties_WulaShieldBelt()
|
|
||||||
{
|
|
||||||
compClass = typeof(CompWulaShieldBelt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -58,7 +58,7 @@ namespace WulaFallenEmpire
|
|||||||
// 大火的技能掉得最少,保持默认值
|
// 大火的技能掉得最少,保持默认值
|
||||||
|
|
||||||
skillRecord.Learn(-experienceLoss, true); // 减少经验
|
skillRecord.Learn(-experienceLoss, true); // 减少经验
|
||||||
Messages.Message("WULA_SkillTrainer_OtherSkillLost".Translate(usedBy.LabelShort, skillRecord.def.label), usedBy, MessageTypeDefOf.NegativeEvent);
|
Messages.Message("WULA_SkillTrainer_SkillLoss".Translate(usedBy.LabelShort, skillRecord.def.label), usedBy, MessageTypeDefOf.NegativeEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,308 +0,0 @@
|
|||||||
using RimWorld;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
using Verse;
|
|
||||||
using Verse.Sound;
|
|
||||||
|
|
||||||
namespace WulaFallenEmpire
|
|
||||||
{
|
|
||||||
[StaticConstructorOnStartup]
|
|
||||||
public class CompWulaShieldBelt : ThingComp
|
|
||||||
{
|
|
||||||
private float shieldHitPoints;
|
|
||||||
private int ticksToReset = -1;
|
|
||||||
private int lastKeepDisplayTick = -9999;
|
|
||||||
private Vector3 impactAngleVect;
|
|
||||||
private int lastAbsorbDamageTick = -9999;
|
|
||||||
private Sustainer sustainer;
|
|
||||||
// 静态构造函数加载材质
|
|
||||||
private static readonly Material BubbleMat = MaterialPool.MatFrom("Other/ShieldBubble", ShaderDatabase.Transparent, Color.white);
|
|
||||||
|
|
||||||
public CompProperties_WulaShieldBelt Props => (CompProperties_WulaShieldBelt)props;
|
|
||||||
|
|
||||||
public float ShieldHitPoints => shieldHitPoints;
|
|
||||||
public float ShieldMaxHitPoints => Props.maxShieldHitPoints;
|
|
||||||
|
|
||||||
private bool ShouldDisplay
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
Pawn wearer = GetWearer();
|
|
||||||
return wearer != null && wearer.Spawned && (wearer.Drafted || (wearer.Faction != null && wearer.Faction.IsPlayer) || Find.TickManager.TicksGame < lastKeepDisplayTick + 50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostExposeData()
|
|
||||||
{
|
|
||||||
base.PostExposeData();
|
|
||||||
Scribe_Values.Look(ref shieldHitPoints, "shieldHitPoints", 0f);
|
|
||||||
Scribe_Values.Look(ref ticksToReset, "ticksToReset", -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostSpawnSetup(bool respawningAfterLoad)
|
|
||||||
{
|
|
||||||
base.PostSpawnSetup(respawningAfterLoad);
|
|
||||||
if (!respawningAfterLoad)
|
|
||||||
{
|
|
||||||
shieldHitPoints = Props.maxShieldHitPoints;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void CompTick()
|
|
||||||
{
|
|
||||||
base.CompTick();
|
|
||||||
|
|
||||||
Pawn wearer = GetWearer();
|
|
||||||
if (wearer == null) return;
|
|
||||||
|
|
||||||
if (sustainer == null && Props.activeSound != null)
|
|
||||||
{
|
|
||||||
sustainer = Props.activeSound.TrySpawnSustainer(SoundInfo.InMap(wearer, MaintenanceType.PerTick));
|
|
||||||
}
|
|
||||||
sustainer?.Maintain();
|
|
||||||
|
|
||||||
if (ticksToReset > 0)
|
|
||||||
{
|
|
||||||
ticksToReset--;
|
|
||||||
if (ticksToReset <= 0)
|
|
||||||
{
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Props.useHitPointsMode && shieldHitPoints < Props.maxShieldHitPoints)
|
|
||||||
{
|
|
||||||
shieldHitPoints += Props.rechargeRate / 60f; // 每秒恢复
|
|
||||||
if (shieldHitPoints > Props.maxShieldHitPoints)
|
|
||||||
{
|
|
||||||
shieldHitPoints = Props.maxShieldHitPoints;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostDraw()
|
|
||||||
{
|
|
||||||
base.PostDraw();
|
|
||||||
if (ShouldDisplay)
|
|
||||||
{
|
|
||||||
float num = Mathf.Lerp(1.2f, 1.55f, shieldHitPoints / Props.maxShieldHitPoints);
|
|
||||||
Vector3 drawPos = GetWearer().Drawer.DrawPos;
|
|
||||||
drawPos.y = AltitudeLayer.MoteOverhead.AltitudeFor();
|
|
||||||
int num2 = Find.TickManager.TicksGame - lastAbsorbDamageTick;
|
|
||||||
if (num2 < 8)
|
|
||||||
{
|
|
||||||
float num3 = (8 - num2) / 8f * 0.05f;
|
|
||||||
drawPos += impactAngleVect * num3;
|
|
||||||
num -= num3;
|
|
||||||
}
|
|
||||||
|
|
||||||
float alpha;
|
|
||||||
if (Props.useHitPointsMode)
|
|
||||||
{
|
|
||||||
// 生命值模式:透明度根据护盾生命值变化
|
|
||||||
alpha = Mathf.Lerp(0.2f, 0.7f, shieldHitPoints / Props.maxShieldHitPoints);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 偏转模式:固定透明度,稍微闪烁效果
|
|
||||||
alpha = 0.4f + Mathf.Sin(Time.time * 2f) * 0.1f;
|
|
||||||
}
|
|
||||||
Color color = Props.shieldColor;
|
|
||||||
color.a = alpha;
|
|
||||||
|
|
||||||
Matrix4x4 matrix = default(Matrix4x4);
|
|
||||||
matrix.SetTRS(drawPos, Quaternion.identity, Vector3.one * num * Props.shieldRadius);
|
|
||||||
Graphics.DrawMesh(MeshPool.plane10, matrix, BubbleMat, 0, null, 0, MaterialPropertyBlock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private MaterialPropertyBlock materialPropertyBlock;
|
|
||||||
private MaterialPropertyBlock MaterialPropertyBlock
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (materialPropertyBlock == null)
|
|
||||||
{
|
|
||||||
materialPropertyBlock = new MaterialPropertyBlock();
|
|
||||||
}
|
|
||||||
materialPropertyBlock.SetColor(ShaderPropertyIDs.Color, Props.shieldColor);
|
|
||||||
return materialPropertyBlock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CheckIntercept(Projectile projectile, Vector3 lastExactPos, Vector3 newExactPos)
|
|
||||||
{
|
|
||||||
// 如果使用生命值模式且护盾已破坏,则不拦截
|
|
||||||
if (Props.useHitPointsMode && shieldHitPoints <= 0f)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Pawn wearer = GetWearer();
|
|
||||||
if (wearer == null || !wearer.Spawned)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!Props.interceptGroundProjectiles && !projectile.def.projectile.flyOverhead)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!Props.interceptAirProjectiles && projectile.def.projectile.flyOverhead)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Vector3 center = wearer.TrueCenter();
|
|
||||||
float radius = Props.shieldRadius;
|
|
||||||
|
|
||||||
// 简单检查:如果射线起点和终点都在圆外,且连线不穿过圆,则不相交
|
|
||||||
float distanceFromLastPos = Vector3.Distance(lastExactPos, center);
|
|
||||||
float distanceFromNewPos = Vector3.Distance(newExactPos, center);
|
|
||||||
|
|
||||||
if (distanceFromLastPos > radius && distanceFromNewPos > radius)
|
|
||||||
{
|
|
||||||
// 计算点到线段的最短距离
|
|
||||||
Vector3 line = newExactPos - lastExactPos;
|
|
||||||
float lineLength = line.magnitude;
|
|
||||||
Vector3 lineDirection = line / lineLength;
|
|
||||||
float projection = Mathf.Clamp(Vector3.Dot(center - lastExactPos, lineDirection), 0f, lineLength);
|
|
||||||
Vector3 closestPoint = lastExactPos + lineDirection * projection;
|
|
||||||
float distanceToLine = Vector3.Distance(center, closestPoint);
|
|
||||||
|
|
||||||
if (distanceToLine > radius)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastKeepDisplayTick = Find.TickManager.TicksGame + 40;
|
|
||||||
|
|
||||||
// 根据模式处理伤害
|
|
||||||
if (Props.useHitPointsMode)
|
|
||||||
{
|
|
||||||
// 生命值模式:吸收伤害并可能破坏护盾
|
|
||||||
AbsorbDamage(projectile.DamageAmount, projectile.ExactPosition);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 偏转模式:只是偏转,不消耗护盾生命值
|
|
||||||
DeflectProjectile(projectile.ExactPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CheckMeleeIntercept(DamageInfo dinfo, Pawn attacker)
|
|
||||||
{
|
|
||||||
if (!Props.interceptMeleeAttacks || shieldHitPoints <= 0f)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Pawn wearer = GetWearer();
|
|
||||||
if (wearer == null || !wearer.Spawned)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
lastKeepDisplayTick = Find.TickManager.TicksGame + 40;
|
|
||||||
AbsorbDamage(dinfo.Amount, attacker.Position.ToVector3());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AbsorbDamage(float damage, Vector3 impactPos)
|
|
||||||
{
|
|
||||||
if (Props.empImmune && damage > 0f)
|
|
||||||
{
|
|
||||||
// EMP免疫时减少EMP伤害
|
|
||||||
damage *= 0.1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 只有在生命值模式下才扣除护盾生命值
|
|
||||||
if (Props.useHitPointsMode)
|
|
||||||
{
|
|
||||||
shieldHitPoints -= damage;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastAbsorbDamageTick = Find.TickManager.TicksGame;
|
|
||||||
|
|
||||||
Pawn wearer = GetWearer();
|
|
||||||
if (wearer != null)
|
|
||||||
{
|
|
||||||
impactAngleVect = Vector3Utility.HorizontalVectorFromAngle((impactPos - wearer.TrueCenter()).AngleFlat() + 180f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 只有在生命值模式下才会破坏护盾
|
|
||||||
if (Props.useHitPointsMode && shieldHitPoints <= 0f)
|
|
||||||
{
|
|
||||||
Break();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DeflectProjectile(Vector3 impactPos)
|
|
||||||
{
|
|
||||||
// 偏转模式:只显示视觉效果,不消耗护盾生命值
|
|
||||||
lastAbsorbDamageTick = Find.TickManager.TicksGame;
|
|
||||||
|
|
||||||
Pawn wearer = GetWearer();
|
|
||||||
if (wearer != null)
|
|
||||||
{
|
|
||||||
impactAngleVect = Vector3Utility.HorizontalVectorFromAngle((impactPos - wearer.TrueCenter()).AngleFlat() + 180f);
|
|
||||||
|
|
||||||
// 播放偏转特效
|
|
||||||
FleckMaker.ThrowLightningGlow(impactPos, wearer.Map, 0.5f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Break()
|
|
||||||
{
|
|
||||||
shieldHitPoints = 0f;
|
|
||||||
ticksToReset = Props.rechargeCooldownTicks;
|
|
||||||
sustainer?.End();
|
|
||||||
sustainer = null;
|
|
||||||
|
|
||||||
Pawn wearer = GetWearer();
|
|
||||||
if (wearer != null && wearer.Map != null)
|
|
||||||
{
|
|
||||||
FleckMaker.Static(wearer.TrueCenter(), wearer.Map, FleckDefOf.ExplosionFlash, 12f);
|
|
||||||
for (int i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
FleckMaker.ThrowDustPuff(wearer.TrueCenter() + Vector3Utility.HorizontalVectorFromAngle(Rand.Range(0, 360)) * Rand.Range(0.3f, 0.6f), wearer.Map, Rand.Range(0.8f, 1.2f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Reset()
|
|
||||||
{
|
|
||||||
if (parent.Spawned)
|
|
||||||
{
|
|
||||||
SoundDefOf.EnergyShield_Reset.PlayOneShot(new TargetInfo(parent.Position, parent.Map));
|
|
||||||
FleckMaker.ThrowLightningGlow(GetWearer().TrueCenter(), parent.Map, 3f);
|
|
||||||
|
|
||||||
if (Props.reactivateEffect != null)
|
|
||||||
{
|
|
||||||
Effecter effecter = Props.reactivateEffect.Spawn(parent.Position, parent.Map);
|
|
||||||
effecter.Trigger(new TargetInfo(parent.Position, parent.Map), TargetInfo.Invalid);
|
|
||||||
effecter.Cleanup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
shieldHitPoints = Props.maxShieldHitPoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Pawn GetWearer()
|
|
||||||
{
|
|
||||||
if (parent is Apparel apparel)
|
|
||||||
{
|
|
||||||
return apparel.Wearer;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加初始化方法,确保护盾值正确设置
|
|
||||||
public override void Initialize(CompProperties props)
|
|
||||||
{
|
|
||||||
base.Initialize(props);
|
|
||||||
shieldHitPoints = ((CompProperties_WulaShieldBelt)props).maxShieldHitPoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string CompInspectStringExtra()
|
|
||||||
{
|
|
||||||
if (Props.useHitPointsMode)
|
|
||||||
{
|
|
||||||
return $"护盾: {shieldHitPoints:F0} / {Props.maxShieldHitPoints} (生命值模式)";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return "护盾: 激活 (偏转模式)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -30,16 +30,41 @@ namespace WulaFallenEmpire
|
|||||||
|
|
||||||
protected override IEnumerable<Toil> MakeNewToils()
|
protected override IEnumerable<Toil> MakeNewToils()
|
||||||
{
|
{
|
||||||
// 失败条件:如果食物来源或病患被摧毁、为空或被禁止
|
// 失败条件:如果病患被摧毁、为空或不在床上
|
||||||
this.FailOn(() => FoodSource.DestroyedOrNull() || !FoodSource.IngestibleNow);
|
|
||||||
this.FailOn(() => Patient.DestroyedOrNull());
|
this.FailOn(() => Patient.DestroyedOrNull());
|
||||||
this.FailOn(() => !Patient.InBed()); // 确保病患在床上
|
this.FailOn(() => !Patient.InBed());
|
||||||
|
|
||||||
// Toil 1: 前往食物来源
|
// Toil 0: 检查医生库存中是否有能量核心
|
||||||
|
Toil checkInventoryToil = ToilMaker.MakeToil("CheckInventory");
|
||||||
|
checkInventoryToil.initAction = delegate
|
||||||
|
{
|
||||||
|
Thing inventoryFood = null;
|
||||||
|
foreach (Thing t in pawn.inventory.innerContainer)
|
||||||
|
{
|
||||||
|
ThingDefExtension_EnergySource energySourceExt = t.def.GetModExtension<ThingDefExtension_EnergySource>();
|
||||||
|
if (energySourceExt != null && t.IngestibleNow)
|
||||||
|
{
|
||||||
|
inventoryFood = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inventoryFood != null)
|
||||||
|
{
|
||||||
|
// 如果库存中有食物,则将Job的目标设置为库存食物,并跳过拾取步骤,直接前往病患
|
||||||
|
job.SetTarget(FoodSourceInd, inventoryFood);
|
||||||
|
pawn.jobs.curDriver.JumpToToil(Toils_Goto.GotoThing(PatientInd, PathEndMode.Touch)); // 跳转到前往病患的Toil
|
||||||
|
}
|
||||||
|
// 如果库存中没有,则继续执行下一个Toil(前往地图上的食物来源)
|
||||||
|
};
|
||||||
|
yield return checkInventoryToil;
|
||||||
|
|
||||||
|
// Toil 1: 前往食物来源 (如果库存中没有,则执行此Toil)
|
||||||
yield return Toils_Goto.GotoThing(FoodSourceInd, PathEndMode.ClosestTouch)
|
yield return Toils_Goto.GotoThing(FoodSourceInd, PathEndMode.ClosestTouch)
|
||||||
.FailOnDespawnedNullOrForbidden(FoodSourceInd);
|
.FailOnDespawnedNullOrForbidden(FoodSourceInd)
|
||||||
|
.FailOn(() => !pawn.CanReserve(FoodSource, 1, -1, null, false)); // 在这里预留食物来源
|
||||||
|
|
||||||
// Toil 2: 拾取食物来源
|
// Toil 2: 拾取食物来源 (如果库存中没有,则执行此Toil)
|
||||||
yield return Toils_Haul.StartCarryThing(FoodSourceInd); // 使用 StartCarryThing 拾取物品
|
yield return Toils_Haul.StartCarryThing(FoodSourceInd); // 使用 StartCarryThing 拾取物品
|
||||||
|
|
||||||
// Toil 3: 前往病患
|
// Toil 3: 前往病患
|
||||||
@@ -51,12 +76,17 @@ namespace WulaFallenEmpire
|
|||||||
feedToil.initAction = delegate
|
feedToil.initAction = delegate
|
||||||
{
|
{
|
||||||
Pawn actor = feedToil.actor;
|
Pawn actor = feedToil.actor;
|
||||||
Thing food = actor.carryTracker.CarriedThing; // 医生携带的食物
|
Thing food = actor.carryTracker.CarriedThing; // 医生携带的食物 (从地图拾取)
|
||||||
|
|
||||||
|
// 如果医生没有携带食物,检查是否在库存中 (从库存获取)
|
||||||
if (food == null)
|
if (food == null)
|
||||||
{
|
{
|
||||||
actor.jobs.EndCurrentJob(JobCondition.Incompletable);
|
food = job.GetTarget(FoodSourceInd).Thing; // 此时FoodSourceInd应该指向库存中的物品
|
||||||
return;
|
if (food == null || !actor.inventory.innerContainer.Contains(food))
|
||||||
|
{
|
||||||
|
actor.jobs.EndCurrentJob(JobCondition.Incompletable);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取乌拉能量需求
|
// 获取乌拉能量需求
|
||||||
@@ -79,10 +109,25 @@ namespace WulaFallenEmpire
|
|||||||
energyNeed.CurLevel += ext.energyAmount;
|
energyNeed.CurLevel += ext.energyAmount;
|
||||||
|
|
||||||
// 消耗物品
|
// 消耗物品
|
||||||
food.Destroy(DestroyMode.Vanish); // 销毁医生携带的物品
|
if (actor.carryTracker.CarriedThing == food) // 如果是携带的物品
|
||||||
|
{
|
||||||
// 移除医生携带的物品
|
food.Destroy(DestroyMode.Vanish); // 销毁医生携带的物品
|
||||||
actor.carryTracker.innerContainer.ClearAndDestroyContents();
|
actor.carryTracker.innerContainer.ClearAndDestroyContents(); // 移除医生携带的物品
|
||||||
|
}
|
||||||
|
else if (actor.inventory.innerContainer.Contains(food)) // 如果是库存中的物品
|
||||||
|
{
|
||||||
|
food.stackCount--; // 减少库存物品数量
|
||||||
|
if (food.stackCount <= 0)
|
||||||
|
{
|
||||||
|
food.Destroy(DestroyMode.Vanish); // 如果数量为0,销毁物品
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 理论上不应该发生
|
||||||
|
actor.jobs.EndCurrentJob(JobCondition.Errored);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 记录能量摄入 (可选)
|
// 记录能量摄入 (可选)
|
||||||
// Patient.records.AddTo(RecordDefOf.NutritionEaten, ext.energyAmount);
|
// Patient.records.AddTo(RecordDefOf.NutritionEaten, ext.energyAmount);
|
||||||
|
|||||||
@@ -10,21 +10,41 @@ namespace WulaFallenEmpire
|
|||||||
public class JobDriver_IngestWulaEnergy : JobDriver
|
public class JobDriver_IngestWulaEnergy : JobDriver
|
||||||
{
|
{
|
||||||
private const TargetIndex IngestibleSourceInd = TargetIndex.A;
|
private const TargetIndex IngestibleSourceInd = TargetIndex.A;
|
||||||
|
private bool eatingFromInventory; // 新增字段
|
||||||
|
|
||||||
|
private Toil chewing; // 新增咀嚼Toil字段
|
||||||
|
|
||||||
private Thing IngestibleSource => job.GetTarget(IngestibleSourceInd).Thing;
|
private Thing IngestibleSource => job.GetTarget(IngestibleSourceInd).Thing;
|
||||||
|
|
||||||
|
// 新增咀嚼时间乘数属性
|
||||||
|
private float ChewDurationMultiplier
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
Thing ingestibleSource = IngestibleSource;
|
||||||
|
// 假设乌拉能量核心也有EatingSpeed属性影响咀嚼速度,或者固定为1f
|
||||||
|
return 1f / pawn.GetStatValue(StatDefOf.EatingSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ExposeData()
|
||||||
|
{
|
||||||
|
base.ExposeData();
|
||||||
|
Scribe_Values.Look(ref eatingFromInventory, "eatingFromInventory", defaultValue: false);
|
||||||
|
}
|
||||||
|
|
||||||
public override bool TryMakePreToilReservations(bool errorOnFailed)
|
public override bool TryMakePreToilReservations(bool errorOnFailed)
|
||||||
{
|
{
|
||||||
// 尝试预留能量核心
|
|
||||||
if (pawn.Faction != null)
|
if (pawn.Faction != null)
|
||||||
{
|
{
|
||||||
Thing ingestibleSource = IngestibleSource;
|
Thing ingestibleSource = IngestibleSource;
|
||||||
|
// 使用FoodUtility.GetMaxAmountToPickup
|
||||||
int maxAmountToPickup = FoodUtility.GetMaxAmountToPickup(ingestibleSource, pawn, job.count);
|
int maxAmountToPickup = FoodUtility.GetMaxAmountToPickup(ingestibleSource, pawn, job.count);
|
||||||
if (!pawn.Reserve(ingestibleSource, job, 10, maxAmountToPickup, null, errorOnFailed))
|
if (!pawn.Reserve(ingestibleSource, job, 10, maxAmountToPickup, null, errorOnFailed))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
job.count = maxAmountToPickup; // 更新job.count以匹配实际预留数量
|
job.count = maxAmountToPickup;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -34,30 +54,28 @@ namespace WulaFallenEmpire
|
|||||||
// 失败条件:如果能量核心被摧毁、为空或被禁止
|
// 失败条件:如果能量核心被摧毁、为空或被禁止
|
||||||
this.FailOn(() => IngestibleSource.DestroyedOrNull() || !IngestibleSource.IngestibleNow);
|
this.FailOn(() => IngestibleSource.DestroyedOrNull() || !IngestibleSource.IngestibleNow);
|
||||||
|
|
||||||
// Toil 1: 前往能量核心
|
// 初始化 eatingFromInventory
|
||||||
yield return Toils_Goto.GotoThing(IngestibleSourceInd, PathEndMode.ClosestTouch)
|
eatingFromInventory = pawn.inventory != null && pawn.inventory.Contains(IngestibleSource);
|
||||||
.FailOnDespawnedNullOrForbidden(IngestibleSourceInd);
|
|
||||||
|
|
||||||
// Toil 2: 拾取能量核心并放入carryTracker
|
// 定义咀嚼Toil
|
||||||
yield return Toils_Haul.StartCarryThing(IngestibleSourceInd);
|
chewing = Toils_Ingest.ChewIngestible(pawn, ChewDurationMultiplier, IngestibleSourceInd, TargetIndex.None)
|
||||||
|
.FailOn((Toil x) => !IngestibleSource.Spawned && (pawn.carryTracker == null || pawn.carryTracker.CarriedThing != IngestibleSource))
|
||||||
|
.FailOnCannotTouch(IngestibleSourceInd, PathEndMode.Touch);
|
||||||
|
|
||||||
// Toil 3: “摄取”能量核心 (模拟咀嚼过程,可以是一个简单的延迟)
|
// 根据是否从背包摄入,选择不同的Toil序列
|
||||||
Toil chewToil = ToilMaker.MakeToil("ChewWulaEnergy");
|
foreach (Toil item in PrepareToIngestToils(chewing))
|
||||||
chewToil.initAction = delegate
|
|
||||||
{
|
{
|
||||||
// 设定一个短暂的“咀嚼”时间
|
yield return item;
|
||||||
pawn.jobs.curDriver.ticksLeftThisToil = 60; // 1秒
|
}
|
||||||
};
|
|
||||||
chewToil.defaultCompleteMode = ToilCompleteMode.Delay;
|
|
||||||
yield return chewToil;
|
|
||||||
|
|
||||||
// Toil 4: 最终处理能量摄取
|
yield return chewing;
|
||||||
|
|
||||||
|
// 最终处理能量摄取
|
||||||
Toil finalizeToil = ToilMaker.MakeToil("FinalizeWulaEnergyIngest");
|
Toil finalizeToil = ToilMaker.MakeToil("FinalizeWulaEnergyIngest");
|
||||||
finalizeToil.initAction = delegate
|
finalizeToil.initAction = delegate
|
||||||
{
|
{
|
||||||
Pawn actor = finalizeToil.actor;
|
Pawn actor = finalizeToil.actor;
|
||||||
// 从Pawn的carryTracker中获取能量核心
|
Thing thing = actor.carryTracker.CarriedThing; // 从carryTracker获取,因为Toils_Ingest.ChewIngestible会处理携带
|
||||||
Thing thing = actor.carryTracker.CarriedThing;
|
|
||||||
|
|
||||||
if (thing == null)
|
if (thing == null)
|
||||||
{
|
{
|
||||||
@@ -65,7 +83,6 @@ namespace WulaFallenEmpire
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取乌拉能量需求
|
|
||||||
Need_WulaEnergy energyNeed = actor.needs.TryGetNeed<Need_WulaEnergy>();
|
Need_WulaEnergy energyNeed = actor.needs.TryGetNeed<Need_WulaEnergy>();
|
||||||
if (energyNeed == null)
|
if (energyNeed == null)
|
||||||
{
|
{
|
||||||
@@ -73,7 +90,6 @@ namespace WulaFallenEmpire
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查食物来源是否有自定义能量扩展
|
|
||||||
ThingDefExtension_EnergySource ext = thing.def.GetModExtension<ThingDefExtension_EnergySource>();
|
ThingDefExtension_EnergySource ext = thing.def.GetModExtension<ThingDefExtension_EnergySource>();
|
||||||
if (ext == null)
|
if (ext == null)
|
||||||
{
|
{
|
||||||
@@ -81,17 +97,30 @@ namespace WulaFallenEmpire
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 补充乌拉的能量
|
|
||||||
energyNeed.CurLevel += ext.energyAmount;
|
energyNeed.CurLevel += ext.energyAmount;
|
||||||
|
|
||||||
// 消耗物品
|
|
||||||
thing.Destroy(DestroyMode.Vanish);
|
thing.Destroy(DestroyMode.Vanish);
|
||||||
|
|
||||||
// 记录能量摄入 (可选,如果需要类似 NutritionEaten 的记录)
|
|
||||||
// actor.records.AddTo(RecordDefOf.NutritionEaten, ext.energyAmount);
|
|
||||||
};
|
};
|
||||||
finalizeToil.defaultCompleteMode = ToilCompleteMode.Instant;
|
finalizeToil.defaultCompleteMode = ToilCompleteMode.Instant;
|
||||||
yield return finalizeToil;
|
yield return finalizeToil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 辅助方法,根据情况返回不同的Toil序列
|
||||||
|
private IEnumerable<Toil> PrepareToIngestToils(Toil chewToil)
|
||||||
|
{
|
||||||
|
if (eatingFromInventory)
|
||||||
|
{
|
||||||
|
yield return Toils_Misc.TakeItemFromInventoryToCarrier(pawn, IngestibleSourceInd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 类似原版JobDriver_Ingest的ToolUser逻辑
|
||||||
|
yield return Toils_Goto.GotoThing(IngestibleSourceInd, PathEndMode.ClosestTouch)
|
||||||
|
.FailOnDespawnedNullOrForbidden(IngestibleSourceInd);
|
||||||
|
yield return Toils_Ingest.PickupIngestible(IngestibleSourceInd, pawn);
|
||||||
|
}
|
||||||
|
// 不处理FindAdjacentEatSurface,因为乌拉能量核心可能不需要“吃表面”
|
||||||
|
// 也不处理takeExtraIngestibles,因为乌拉能量核心通常是单次消耗
|
||||||
|
yield break; // 确保迭代器结束
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
using Verse;
|
||||||
|
|
||||||
|
namespace WulaFallenEmpire
|
||||||
|
{
|
||||||
|
public class JobGiverDefExtension_WulaPackEnergy : DefModExtension
|
||||||
|
{
|
||||||
|
public float packEnergyThreshold = 0.5f; // 默认打包能量阈值
|
||||||
|
public int packEnergyCount = 10; // 默认打包数量
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,8 @@ namespace WulaFallenEmpire
|
|||||||
public float emergencyThreshold = 0.1f;
|
public float emergencyThreshold = 0.1f;
|
||||||
public float normalPriority = 5f;
|
public float normalPriority = 5f;
|
||||||
public float emergencyPriority = 9.5f;
|
public float emergencyPriority = 9.5f;
|
||||||
|
public float searchRadius = 20f; // 添加 searchRadius
|
||||||
|
public int ingestCount = 1; // 添加 ingestCount
|
||||||
|
|
||||||
public override ThinkNode DeepCopy(bool resolve = true)
|
public override ThinkNode DeepCopy(bool resolve = true)
|
||||||
{
|
{
|
||||||
@@ -19,6 +21,8 @@ namespace WulaFallenEmpire
|
|||||||
obj.emergencyThreshold = emergencyThreshold;
|
obj.emergencyThreshold = emergencyThreshold;
|
||||||
obj.normalPriority = normalPriority;
|
obj.normalPriority = normalPriority;
|
||||||
obj.emergencyPriority = emergencyPriority;
|
obj.emergencyPriority = emergencyPriority;
|
||||||
|
obj.searchRadius = searchRadius;
|
||||||
|
obj.ingestCount = ingestCount;
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,14 +62,26 @@ namespace WulaFallenEmpire
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 寻找最佳能量核心
|
// 优先检查小人背包中的能量核心
|
||||||
|
foreach (Thing t in pawn.inventory.innerContainer)
|
||||||
|
{
|
||||||
|
ThingDefExtension_EnergySource energySourceExt = t.def.GetModExtension<ThingDefExtension_EnergySource>();
|
||||||
|
if (energySourceExt != null && t.IngestibleNow)
|
||||||
|
{
|
||||||
|
Job job = JobMaker.MakeJob(DefDatabase<JobDef>.GetNamed("WULA_IngestWulaEnergy"), t);
|
||||||
|
job.count = ingestCount;
|
||||||
|
return job;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果背包中没有,则寻找最佳能量核心
|
||||||
Thing bestEnergySource = GenClosest.ClosestThingReachable(
|
Thing bestEnergySource = GenClosest.ClosestThingReachable(
|
||||||
pawn.Position,
|
pawn.Position,
|
||||||
pawn.Map,
|
pawn.Map,
|
||||||
ThingRequest.ForGroup(ThingRequestGroup.HaulableEver), // 扫描所有可搬运的物品
|
ThingRequest.ForGroup(ThingRequestGroup.HaulableEver), // 扫描所有可搬运的物品
|
||||||
PathEndMode.ClosestTouch,
|
PathEndMode.ClosestTouch,
|
||||||
TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false),
|
TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false),
|
||||||
9999f,
|
searchRadius, // 使用类中的 searchRadius
|
||||||
(Thing t) =>
|
(Thing t) =>
|
||||||
{
|
{
|
||||||
// 检查物品是否是能量核心
|
// 检查物品是否是能量核心
|
||||||
@@ -92,7 +108,7 @@ namespace WulaFallenEmpire
|
|||||||
{
|
{
|
||||||
// 创建摄取能量核心的Job
|
// 创建摄取能量核心的Job
|
||||||
Job job = JobMaker.MakeJob(DefDatabase<JobDef>.GetNamed("WULA_IngestWulaEnergy"), bestEnergySource);
|
Job job = JobMaker.MakeJob(DefDatabase<JobDef>.GetNamed("WULA_IngestWulaEnergy"), bestEnergySource);
|
||||||
job.count = 1; // 每次摄取一个
|
job.count = ingestCount; // 使用类中的 ingestCount
|
||||||
return job;
|
return job;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
86
Source/WulaFallenEmpire/JobGiver_WulaPackEnergy.cs
Normal file
86
Source/WulaFallenEmpire/JobGiver_WulaPackEnergy.cs
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using Verse;
|
||||||
|
using Verse.AI;
|
||||||
|
using RimWorld; // For JobDefOf, ThingDefOf, StatDefOf
|
||||||
|
|
||||||
|
namespace WulaFallenEmpire
|
||||||
|
{
|
||||||
|
public class JobGiver_WulaPackEnergy : ThinkNode_JobGiver
|
||||||
|
{
|
||||||
|
public float packEnergyThreshold = 0.5f; // 默认打包能量阈值
|
||||||
|
public int packEnergyCount = 2; // 默认打包数量
|
||||||
|
|
||||||
|
// 定义乌拉能量核心的ThingDef
|
||||||
|
private static ThingDef WULA_Charge_Cube_Def => ThingDef.Named("WULA_Charge_Cube");
|
||||||
|
|
||||||
|
public override ThinkNode DeepCopy(bool resolve = true)
|
||||||
|
{
|
||||||
|
JobGiver_WulaPackEnergy obj = (JobGiver_WulaPackEnergy)base.DeepCopy(resolve);
|
||||||
|
obj.packEnergyThreshold = packEnergyThreshold;
|
||||||
|
obj.packEnergyCount = packEnergyCount;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Job TryGiveJob(Pawn pawn)
|
||||||
|
{
|
||||||
|
if (pawn.inventory == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查背包中是否有足够的能量核心,这里可以根据Need_WulaEnergy的当前值来判断是否需要打包
|
||||||
|
// 简化逻辑:如果能量低于某个阈值,并且背包中没有能量核心,则尝试打包
|
||||||
|
Need_WulaEnergy energyNeed = pawn.needs.TryGetNeed<Need_WulaEnergy>();
|
||||||
|
if (energyNeed == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 只有当能量低于阈值,并且背包中能量核心数量少于2个时,才尝试打包
|
||||||
|
if (energyNeed.CurLevelPercentage > packEnergyThreshold || pawn.inventory.innerContainer.TotalStackCountOfDef(WULA_Charge_Cube_Def) >= 2)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否超重
|
||||||
|
if (MassUtility.IsOverEncumbered(pawn))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 寻找地图上可触及的WULA_Charge_Cube
|
||||||
|
Thing thing = GenClosest.ClosestThing_Regionwise_ReachablePrioritized(
|
||||||
|
pawn.Position,
|
||||||
|
pawn.Map,
|
||||||
|
ThingRequest.ForDef(WULA_Charge_Cube_Def), // 只寻找WULA_Charge_Cube
|
||||||
|
PathEndMode.ClosestTouch,
|
||||||
|
TraverseParms.For(pawn),
|
||||||
|
20f, // 搜索距离
|
||||||
|
delegate(Thing t)
|
||||||
|
{
|
||||||
|
// 检查物品是否被禁止,是否可预留,是否社交得体
|
||||||
|
return !t.IsForbidden(pawn) && pawn.CanReserve(t) && t.IsSociallyProper(pawn);
|
||||||
|
},
|
||||||
|
(Thing x) => 0f // 优先级,这里可以根据距离或其他因素调整
|
||||||
|
);
|
||||||
|
|
||||||
|
if (thing == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算需要打包的数量,限制在1到2个
|
||||||
|
int countToTake = Mathf.Min(thing.stackCount, 2); // 限制为最多2个
|
||||||
|
if (WULA_Charge_Cube_Def != null)
|
||||||
|
{
|
||||||
|
countToTake = Mathf.Min(countToTake, WULA_Charge_Cube_Def.stackLimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建TakeInventory Job
|
||||||
|
Job job = JobMaker.MakeJob(JobDefOf.TakeInventory, thing);
|
||||||
|
job.count = countToTake;
|
||||||
|
return job;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -82,13 +82,12 @@
|
|||||||
<Compile Include="Hediff_EmergencyEnergyRestore.cs" />
|
<Compile Include="Hediff_EmergencyEnergyRestore.cs" />
|
||||||
<Compile Include="CompProperties_AbilityEmergencyEnergyRestore.cs" />
|
<Compile Include="CompProperties_AbilityEmergencyEnergyRestore.cs" />
|
||||||
<Compile Include="CompAbilityEffect_EmergencyEnergyRestore.cs" />
|
<Compile Include="CompAbilityEffect_EmergencyEnergyRestore.cs" />
|
||||||
<Compile Include="CompProperties_WulaShieldBelt.cs" />
|
|
||||||
<Compile Include="CompWulaShieldBelt.cs" />
|
|
||||||
<Compile Include="WulaShieldBeltPatches.cs" />
|
|
||||||
<Compile Include="EmergencyAbilityPatches.cs" />
|
<Compile Include="EmergencyAbilityPatches.cs" />
|
||||||
<Compile Include="JobGiver_WulaGetEnergy.cs" />
|
<Compile Include="JobGiver_WulaGetEnergy.cs" />
|
||||||
<Compile Include="JobGiverDefExtension_WulaGetEnergy.cs" />
|
<Compile Include="JobGiverDefExtension_WulaGetEnergy.cs" />
|
||||||
<Compile Include="JobDriver_CastEmergencyEnergyRestore.cs" />
|
<Compile Include="JobDriver_CastEmergencyEnergyRestore.cs" />
|
||||||
|
<Compile Include="JobGiver_WulaPackEnergy.cs" />
|
||||||
|
<Compile Include="JobGiverDefExtension_WulaPackEnergy.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
|
||||||
|
|||||||
@@ -14,9 +14,6 @@ namespace WulaFallenEmpire
|
|||||||
var harmony = new Harmony("tourswen.wulafallenempire"); // 替换为您的唯一Mod ID
|
var harmony = new Harmony("tourswen.wulafallenempire"); // 替换为您的唯一Mod ID
|
||||||
harmony.PatchAll(Assembly.GetExecutingAssembly());
|
harmony.PatchAll(Assembly.GetExecutingAssembly());
|
||||||
|
|
||||||
// 手动应用护盾腰带的近战拦截补丁
|
|
||||||
WulaShieldBeltPatches.ApplyMeleePatch(harmony);
|
|
||||||
|
|
||||||
Log.Message("[WulaFallenEmpire] Harmony patches applied.");
|
Log.Message("[WulaFallenEmpire] Harmony patches applied.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,97 +0,0 @@
|
|||||||
using HarmonyLib;
|
|
||||||
using RimWorld;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using UnityEngine;
|
|
||||||
using Verse;
|
|
||||||
|
|
||||||
namespace WulaFallenEmpire
|
|
||||||
{
|
|
||||||
public static class WulaShieldBeltPatches
|
|
||||||
{
|
|
||||||
// 拦截投射物
|
|
||||||
[HarmonyPatch(typeof(Projectile), "CheckForFreeInterceptBetween")]
|
|
||||||
[HarmonyPrefix]
|
|
||||||
public static bool CheckForFreeInterceptBetween_Prefix(Projectile __instance, Vector3 lastExactPos, Vector3 newExactPos, ref bool __result)
|
|
||||||
{
|
|
||||||
var map = __instance.Map;
|
|
||||||
if (map == null) return true;
|
|
||||||
|
|
||||||
// 检查所有穿戴护盾腰带的pawn
|
|
||||||
var pawns = map.mapPawns.AllPawnsSpawned;
|
|
||||||
foreach (var pawn in pawns)
|
|
||||||
{
|
|
||||||
if (pawn.apparel?.WornApparel == null) continue;
|
|
||||||
|
|
||||||
foreach (var apparel in pawn.apparel.WornApparel)
|
|
||||||
{
|
|
||||||
var shieldComp = apparel.GetComp<CompWulaShieldBelt>();
|
|
||||||
if (shieldComp != null && shieldComp.CheckIntercept(__instance, lastExactPos, newExactPos))
|
|
||||||
{
|
|
||||||
// 使用反射调用protected方法
|
|
||||||
typeof(Projectile).GetMethod("Impact", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)
|
|
||||||
.Invoke(__instance, new object[] { null, true });
|
|
||||||
__result = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 拦截近战攻击 - 使用Harmony的手动补丁方式
|
|
||||||
public static void ApplyMeleePatch(Harmony harmony)
|
|
||||||
{
|
|
||||||
// 获取Thing.TakeDamage方法
|
|
||||||
var originalMethod = typeof(Thing).GetMethod("TakeDamage",
|
|
||||||
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
|
|
||||||
|
|
||||||
if (originalMethod != null)
|
|
||||||
{
|
|
||||||
// 获取我们的前缀方法
|
|
||||||
var prefixMethod = typeof(WulaShieldBeltPatches).GetMethod("TakeDamage_Manual_Prefix",
|
|
||||||
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
|
|
||||||
|
|
||||||
// 应用补丁
|
|
||||||
harmony.Patch(originalMethod, new HarmonyMethod(prefixMethod));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 手动补丁方法
|
|
||||||
public static bool TakeDamage_Manual_Prefix(Thing __instance, DamageInfo dinfo, ref DamageWorker.DamageResult __result)
|
|
||||||
{
|
|
||||||
// 只有当实例是Pawn时才执行护盾腰带的逻辑
|
|
||||||
if (__instance is Pawn pawn)
|
|
||||||
{
|
|
||||||
if (pawn.apparel?.WornApparel == null) return true;
|
|
||||||
|
|
||||||
// 检查是否有护盾腰带可以拦截这次攻击
|
|
||||||
foreach (var apparel in pawn.apparel.WornApparel)
|
|
||||||
{
|
|
||||||
var shieldComp = apparel.GetComp<CompWulaShieldBelt>();
|
|
||||||
if (shieldComp != null && dinfo.Instigator is Pawn attacker)
|
|
||||||
{
|
|
||||||
if (shieldComp.CheckMeleeIntercept(dinfo, attacker))
|
|
||||||
{
|
|
||||||
__result = new DamageWorker.DamageResult();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 为护盾腰带添加投射物拦截器接口支持
|
|
||||||
[HarmonyPatch(typeof(CompProjectileInterceptor), "CheckIntercept")]
|
|
||||||
[HarmonyPostfix]
|
|
||||||
public static void CheckIntercept_Postfix(CompProjectileInterceptor __instance, Projectile projectile, Vector3 lastExactPos, Vector3 newExactPos, ref bool __result)
|
|
||||||
{
|
|
||||||
if (__result) return; // 如果已经被拦截了就不需要再检查
|
|
||||||
|
|
||||||
// 这个补丁确保我们的护盾系统与原版的投射物拦截系统兼容
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user