This commit is contained in:
2026-02-15 11:53:08 +08:00
parent 98fb8d89c3
commit c7a520b2f3
18 changed files with 445 additions and 761 deletions

Binary file not shown.

View File

@@ -1031,7 +1031,7 @@
<defName>ARA_Dissolver_Touch</defName>
<label>溶脂强酸</label>
<description>在极近的范围内向目标泼洒溶脂强酸,目标的器官会快速分解,变成大量的虫蜜。因为准头很差,无法用于战场上,只能对不反抗的目标使用。</description>
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_Fighter_Invisibility_jump</iconPath>
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_Dissolver_Touch</iconPath>
<cooldownTicksRange>1000</cooldownTicksRange>
<charges>3</charges>
<cooldownPerCharge>true</cooldownPerCharge>
@@ -1062,6 +1062,14 @@
<needCost>0.1</needCost>
<failMessage>营养值不足,需要进食</failMessage>
</li>
<li Class="ArachnaeSwarm.CompProperties_AbilityHediffBlacklist">
<blacklistedHediffs>
<li>ARA_HiveMindMaster</li>
<li>ARA_HiveMindDrone</li>
<li>ARA_HiveMindWorker</li>
</blacklistedHediffs>
<blockedMessage>ARA_BlacklistedHediff_Blocked</blockedMessage>
</li>
<li Class="CompProperties_AbilityGiveHediff">
<compClass>CompAbilityEffect_GiveHediff</compClass>
<hediffDef>ARA_Dissolver_Touch_Damage</hediffDef>

View File

@@ -455,6 +455,7 @@
<comps>
<li Class="HediffCompProperties_GiveAbility">
<abilityDefs>
<li>ARA_AcidSprayBurst</li>
<li>ARA_Dissolver_Touch</li>
</abilityDefs>
</li>

View File

@@ -3,7 +3,7 @@
<HediffDef>
<defName>ARA_HiveMindMaster</defName>
<label>阿拉克涅女皇种</label>
<description>阿拉克涅女皇种是虫群意识的中心节点, 作为主脑统御整个阿拉克涅虫群。其体内拥有大量未分化的修复细胞,可以以常人无法想象的速度自行治愈所有的创伤</description>
<description>阿拉克涅女皇种是虫的中心节点, 作为族群主脑统御阿拉克涅虫</description>
<!-- <hediffClass>ArachnaeSwarm.Hediff_HiveMindMaster</hediffClass> -->
<hediffClass>HediffWithComps</hediffClass>
<defaultLabelColor>(0.8, 0.3, 0.8)</defaultLabelColor>
@@ -21,6 +21,7 @@
<li>Beauty</li>
<li>Comfort</li>
<li>Outdoors</li>
<li>Rest</li>
</disablesNeeds>
<enablesNeeds>
<li>ARA_ChitinArmor</li>
@@ -64,7 +65,7 @@
<capMods>
<li>
<capacity>Consciousness</capacity>
<setMax>0.3</setMax>
<setMax>0.2</setMax>
</li>
</capMods>
<minSeverity>0</minSeverity>

View File

@@ -14,7 +14,7 @@
<label>节点SLA-8"暴戮之兽"</label>
<description>&lt;color=#915A30>&lt;i>阿拉克涅虫群-泰坦触须\n泰坦触须是阿拉克涅虫群的主力军团包含阿拉克涅虫群中最坚韧、最具有适应力的族群承担在战场上维持战线的任务。这个分支下的虫群拥有均衡的攻防能力擅长以硬碰硬的模式消灭对手。&lt;/i>&lt;/color>\n\n允许女皇种孵化新的兽虫——暴屠种。\n\n阿拉克涅虫群 泰坦触须所有需要蓝图的科技,其研究只能通过基因试验卵进行。</description>
<baseCost>3000</baseCost>
<researchViewX>10.00</researchViewX>
<researchViewX>17.00</researchViewX>
<researchViewY>5.80</researchViewY>
<hiddenPrerequisites>
<li>ARA_Technology_2HAG</li>
@@ -29,8 +29,8 @@
<label>节点ACD-7"溶脂强酸"</label>
<description>&lt;color=#915A30>&lt;i>阿拉克涅虫群-泰坦触须\n泰坦触须是阿拉克涅虫群的主力军团包含阿拉克涅虫群中最坚韧、最具有适应力的族群承担在战场上维持战线的任务。这个分支下的虫群拥有均衡的攻防能力擅长以硬碰硬的模式消灭对手。&lt;/i>&lt;/color>\n\n允许蜜罐种进行定向进化抛弃孵化辅虫的能力换取溶解囚犯和俘虏以快速换取虫蜜的溶脂强酸。\n\n阿拉克涅虫群 泰坦触须所有需要蓝图的科技,其研究只能通过基因试验卵进行。</description>
<baseCost>500</baseCost>
<researchViewX>10.00</researchViewX>
<researchViewY>5.80</researchViewY>
<researchViewX>17.00</researchViewX>
<researchViewY>0.30</researchViewY>
<hiddenPrerequisites>
<li>ARA_Technology_7VXI</li>
</hiddenPrerequisites>

View File

@@ -1752,19 +1752,19 @@
<li>ARA_Psi_Master</li>
</hediffs>
<!-- 自定义部位映射 -->
<customBodyPartMapping>
<li>
<hediff>PsychicAmplifier</hediff>
<bodyPart>Brain</bodyPart>
<priority>1</priority>
<chooseRandomPart>false</chooseRandomPart>
<fallbackToDefault>true</fallbackToDefault>
</li>
</customBodyPartMapping>
<addChance>1.0</addChance>
<allowDuplicates>false</allowDuplicates>
</li>
<li Class="ArachnaeSwarm.CompProperties_HediffGiver">
<hediffs>
<li>PsychicAmplifier</li>
</hediffs>
<bodyPart>Brain</bodyPart>
<addChance>1.0</addChance>
<allowDuplicates>false</allowDuplicates>
<partSelectionMode>First</partSelectionMode>
<skipIfPartMissing>true</skipIfPartMissing>
</li>
<li Class="ArachnaeSwarm.CompProperties_SkillExperienceGiver">
<addChance>1.0</addChance>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -3,80 +3,12 @@
"WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\compabilityeffect_researchprereq.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\compabilityeffect_researchprereq.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\pawn_comps\\ara_comphediffgiver\\compproperties_hediffgiver.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_comphediffgiver\\compproperties_hediffgiver.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_spawner\\hediffcompproperties_spawner.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_spawner\\hediffcompproperties_spawner.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_productionqueue\\hediffcompproperties_productionqueue.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_productionqueue\\hediffcompproperties_productionqueue.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_spawner\\hediffcomp_spawner.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_spawner\\hediffcomp_spawner.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_productionqueue\\hediffcomp_productionqueue.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_productionqueue\\hediffcomp_productionqueue.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_gestaltnode\\hediffcomp_gestaltnode.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_gestaltnode\\hediffcomp_gestaltnode.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\pawn_comps\\ara_nodeswarmlifetime\\compnodeswarmlifetime.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_nodeswarmlifetime\\compnodeswarmlifetime.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\abilities\\ara_launchmultiprojectile\\compproperties_abilitylaunchmultiprojectile.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_launchmultiprojectile\\compproperties_abilitylaunchmultiprojectile.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\abilities\\ara_launchmultiprojectile\\compabilityeffect_launchmultiprojectile.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_launchmultiprojectile\\compabilityeffect_launchmultiprojectile.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ara_defof.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:ara_defof.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\abilities\\ara_launchmultiprojectile\\jobdriver_castabilitymaintainmultiprojectile.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_launchmultiprojectile\\jobdriver_castabilitymaintainmultiprojectile.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\abilities\\ara_morphable\\compabilityeffect_transform.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_morphable\\compabilityeffect_transform.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\abilities\\ara_psychicloadcost\\compabilityeffect_psychicloadcost.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_psychicloadcost\\compabilityeffect_psychicloadcost.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\abilities\\ara_psychicloadcost\\compproperties_abilitypsychicloadcost.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_psychicloadcost\\compproperties_abilitypsychicloadcost.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\pawn_comps\\ara_pawnresearchblueprintreader\\gizmo_pawnresearchprogress.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_pawnresearchblueprintreader\\gizmo_pawnresearchprogress.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\pawn_comps\\ara_pawnresearchblueprintreader\\comp_pawnresearchblueprintreader.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_pawnresearchblueprintreader\\comp_pawnresearchblueprintreader.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\buildings\\building_researchblueprintreader\\gizmo_researchprogress.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_researchblueprintreader\\gizmo_researchprogress.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\abilities\\psychicbrainburn\\compabilityeffect_psychicbrainburn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\psychicbrainburn\\compabilityeffect_psychicbrainburn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\buildings\\building_researchblueprintreader\\researchblueprintdata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_researchblueprintreader\\researchblueprintdata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\pawn_comps\\ara_comphediffgiver\\comphediffgiver.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_comphediffgiver\\comphediffgiver.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
"DocumentGroupContainers": [
@@ -86,245 +18,36 @@
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 0,
"SelectedChildIndex": 2,
"Children": [
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "CompAbilityEffect_ResearchPrereq.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\CompAbilityEffect_ResearchPrereq.cs",
"RelativeDocumentMoniker": "Abilities\\CompAbilityEffect_ResearchPrereq.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\CompAbilityEffect_ResearchPrereq.cs",
"RelativeToolTip": "Abilities\\CompAbilityEffect_ResearchPrereq.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAwAAABBAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-14T07:44:51.729Z",
"EditorCaption": ""
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "HediffCompProperties_ProductionQueue.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_ProductionQueue\\HediffCompProperties_ProductionQueue.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_ProductionQueue\\HediffCompProperties_ProductionQueue.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_ProductionQueue\\HediffCompProperties_ProductionQueue.cs",
"RelativeToolTip": "Hediffs\\ARA_ProductionQueue\\HediffCompProperties_ProductionQueue.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAwAAAARAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-14T07:21:19.792Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 4,
"Title": "HediffComp_ProductionQueue.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_ProductionQueue\\HediffComp_ProductionQueue.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_ProductionQueue\\HediffComp_ProductionQueue.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_ProductionQueue\\HediffComp_ProductionQueue.cs",
"RelativeToolTip": "Hediffs\\ARA_ProductionQueue\\HediffComp_ProductionQueue.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAoAAAArAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-14T07:19:42.058Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "HediffCompProperties_Spawner.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_Spawner\\HediffCompProperties_Spawner.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_Spawner\\HediffCompProperties_Spawner.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_Spawner\\HediffCompProperties_Spawner.cs",
"RelativeToolTip": "Hediffs\\ARA_Spawner\\HediffCompProperties_Spawner.cs",
"ViewState": "AgIAAFcAAAAAAAAAAADgv3gAAAApAAAAAAAAAA==",
"Title": "CompHediffGiver.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_CompHediffGiver\\CompHediffGiver.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_CompHediffGiver\\CompHediffGiver.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_CompHediffGiver\\CompHediffGiver.cs",
"RelativeToolTip": "Pawn_Comps\\ARA_CompHediffGiver\\CompHediffGiver.cs",
"ViewState": "AgIAAFAAAAAAAAAAAAAQwBEAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-14T07:09:01.203Z",
"WhenOpened": "2026-02-15T01:45:35.176Z"
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "CompProperties_HediffGiver.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_CompHediffGiver\\CompProperties_HediffGiver.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_CompHediffGiver\\CompProperties_HediffGiver.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_CompHediffGiver\\CompProperties_HediffGiver.cs",
"RelativeToolTip": "Pawn_Comps\\ARA_CompHediffGiver\\CompProperties_HediffGiver.cs",
"ViewState": "AgIAAAgAAAAAAAAAAAAAAC8AAAAWAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-15T01:43:54.125Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "HediffComp_Spawner.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_Spawner\\HediffComp_Spawner.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_Spawner\\HediffComp_Spawner.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_Spawner\\HediffComp_Spawner.cs",
"RelativeToolTip": "Hediffs\\ARA_Spawner\\HediffComp_Spawner.cs",
"ViewState": "AgIAAFwAAAAAAAAAAAAvwHEAAAAoAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-14T07:08:13.475Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 6,
"Title": "CompNodeSwarmLifetime.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_NodeSwarmLifetime\\CompNodeSwarmLifetime.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_NodeSwarmLifetime\\CompNodeSwarmLifetime.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_NodeSwarmLifetime\\CompNodeSwarmLifetime.cs",
"RelativeToolTip": "Pawn_Comps\\ARA_NodeSwarmLifetime\\CompNodeSwarmLifetime.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAANAAAAARAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-14T04:41:09.997Z"
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "HediffComp_GestaltNode.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\HediffComp_GestaltNode.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_GestaltNode\\HediffComp_GestaltNode.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\HediffComp_GestaltNode.cs",
"RelativeToolTip": "Hediffs\\ARA_GestaltNode\\HediffComp_GestaltNode.cs",
"ViewState": "AgIAABMAAAAAAAAAAAAAwBUAAAAVAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-14T02:36:39.249Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 9,
"Title": "ARA_DefOf.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_DefOf.cs",
"RelativeDocumentMoniker": "ARA_DefOf.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_DefOf.cs",
"RelativeToolTip": "ARA_DefOf.cs",
"ViewState": "AgIAAAYAAAAAAAAAAAAAACAAAAAkAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-13T08:26:42.851Z"
},
{
"$type": "Document",
"DocumentIndex": 10,
"Title": "JobDriver_CastAbilityMaintainMultiProjectile.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_LaunchMultiProjectile\\JobDriver_CastAbilityMaintainMultiProjectile.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_LaunchMultiProjectile\\JobDriver_CastAbilityMaintainMultiProjectile.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_LaunchMultiProjectile\\JobDriver_CastAbilityMaintainMultiProjectile.cs",
"RelativeToolTip": "Abilities\\ARA_LaunchMultiProjectile\\JobDriver_CastAbilityMaintainMultiProjectile.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAYAAAA9AAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-13T08:25:54.467Z"
},
{
"$type": "Document",
"DocumentIndex": 7,
"Title": "CompProperties_AbilityLaunchMultiProjectile.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_LaunchMultiProjectile\\CompProperties_AbilityLaunchMultiProjectile.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_LaunchMultiProjectile\\CompProperties_AbilityLaunchMultiProjectile.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_LaunchMultiProjectile\\CompProperties_AbilityLaunchMultiProjectile.cs",
"RelativeToolTip": "Abilities\\ARA_LaunchMultiProjectile\\CompProperties_AbilityLaunchMultiProjectile.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABQAAAAsAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-13T08:25:52.233Z"
},
{
"$type": "Document",
"DocumentIndex": 11,
"Title": "CompAbilityEffect_Transform.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_Morphable\\CompAbilityEffect_Transform.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_Morphable\\CompAbilityEffect_Transform.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_Morphable\\CompAbilityEffect_Transform.cs",
"RelativeToolTip": "Abilities\\ARA_Morphable\\CompAbilityEffect_Transform.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAMAAAAXAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-13T08:25:48.115Z"
},
{
"$type": "Document",
"DocumentIndex": 8,
"Title": "CompAbilityEffect_LaunchMultiProjectile.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_LaunchMultiProjectile\\CompAbilityEffect_LaunchMultiProjectile.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_LaunchMultiProjectile\\CompAbilityEffect_LaunchMultiProjectile.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_LaunchMultiProjectile\\CompAbilityEffect_LaunchMultiProjectile.cs",
"RelativeToolTip": "Abilities\\ARA_LaunchMultiProjectile\\CompAbilityEffect_LaunchMultiProjectile.cs",
"ViewState": "AgIAADEAAAAAAAAAAAASwKgAAAAWAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-13T08:25:25.05Z"
},
{
"$type": "Document",
"DocumentIndex": 13,
"Title": "CompProperties_AbilityPsychicLoadCost.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicLoadCost\\CompProperties_AbilityPsychicLoadCost.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_PsychicLoadCost\\CompProperties_AbilityPsychicLoadCost.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicLoadCost\\CompProperties_AbilityPsychicLoadCost.cs",
"RelativeToolTip": "Abilities\\ARA_PsychicLoadCost\\CompProperties_AbilityPsychicLoadCost.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-13T07:48:29.02Z"
},
{
"$type": "Document",
"DocumentIndex": 14,
"Title": "Gizmo_PawnResearchProgress.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_PawnResearchBlueprintReader\\Gizmo_PawnResearchProgress.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_PawnResearchBlueprintReader\\Gizmo_PawnResearchProgress.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_PawnResearchBlueprintReader\\Gizmo_PawnResearchProgress.cs",
"RelativeToolTip": "Pawn_Comps\\ARA_PawnResearchBlueprintReader\\Gizmo_PawnResearchProgress.cs",
"ViewState": "AgIAAOoAAAAAAAAAAAAAAP8AAAAzAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-13T07:41:00.755Z"
},
{
"$type": "Document",
"DocumentIndex": 12,
"Title": "CompAbilityEffect_PsychicLoadCost.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicLoadCost\\CompAbilityEffect_PsychicLoadCost.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_PsychicLoadCost\\CompAbilityEffect_PsychicLoadCost.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicLoadCost\\CompAbilityEffect_PsychicLoadCost.cs",
"RelativeToolTip": "Abilities\\ARA_PsychicLoadCost\\CompAbilityEffect_PsychicLoadCost.cs",
"ViewState": "AgIAAFYAAAAAAAAAAAAcwGQAAAAJAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-13T07:04:17.954Z"
},
{
"$type": "Document",
"DocumentIndex": 17,
"Title": "CompAbilityEffect_PsychicBrainburn.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\PsychicBrainburn\\CompAbilityEffect_PsychicBrainburn.cs",
"RelativeDocumentMoniker": "Abilities\\PsychicBrainburn\\CompAbilityEffect_PsychicBrainburn.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\PsychicBrainburn\\CompAbilityEffect_PsychicBrainburn.cs",
"RelativeToolTip": "Abilities\\PsychicBrainburn\\CompAbilityEffect_PsychicBrainburn.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAgAAABTAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-13T07:04:16.513Z"
},
{
"$type": "Document",
"DocumentIndex": 16,
"Title": "Gizmo_ResearchProgress.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ResearchBlueprintReader\\Gizmo_ResearchProgress.cs",
"RelativeDocumentMoniker": "Buildings\\Building_ResearchBlueprintReader\\Gizmo_ResearchProgress.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ResearchBlueprintReader\\Gizmo_ResearchProgress.cs",
"RelativeToolTip": "Buildings\\Building_ResearchBlueprintReader\\Gizmo_ResearchProgress.cs",
"ViewState": "AgIAACIAAAAAAAAAAAAswDAAAAAwAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-13T07:03:24.516Z"
},
{
"$type": "Document",
"DocumentIndex": 18,
"Title": "ResearchBlueprintData.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ResearchBlueprintReader\\ResearchBlueprintData.cs",
"RelativeDocumentMoniker": "Buildings\\Building_ResearchBlueprintReader\\ResearchBlueprintData.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ResearchBlueprintReader\\ResearchBlueprintData.cs",
"RelativeToolTip": "Buildings\\Building_ResearchBlueprintReader\\ResearchBlueprintData.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-13T07:03:24.054Z"
},
{
"$type": "Document",
"DocumentIndex": 15,
"Title": "Comp_PawnResearchBlueprintReader.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_PawnResearchBlueprintReader\\Comp_PawnResearchBlueprintReader.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_PawnResearchBlueprintReader\\Comp_PawnResearchBlueprintReader.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_PawnResearchBlueprintReader\\Comp_PawnResearchBlueprintReader.cs",
"RelativeToolTip": "Pawn_Comps\\ARA_PawnResearchBlueprintReader\\Comp_PawnResearchBlueprintReader.cs",
"ViewState": "AgIAADEDAAAAAAAAAAAEwAIDAAB4AAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-02-13T03:53:59.347Z"
}
]
}

View File

@@ -34,6 +34,8 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Compile Include="Abilities\ARA_HediffBlacklist\CompAbilityEffect_HediffBlacklist.cs" />
<Compile Include="Abilities\ARA_HediffBlacklist\CompProperties_AbilityHediffBlacklist.cs" />
<Compile Include="Abilities\ARA_HediffGacha\CompAbilityEffect_HediffGacha.cs" />
<Compile Include="Abilities\ARA_HediffGacha\Window_HediffSelection.cs" />
<Compile Include="Abilities\ARA_PsychicLoadCost\CompAbilityEffect_PsychicLoadCost.cs" />

View File

@@ -0,0 +1,19 @@
using HarmonyLib;
using RimWorld;
using Verse;
namespace ArachnaeSwarm
{
[HarmonyPatch(typeof(Faction), "get_ShouldHaveLeader")]
public static class Faction_ShouldHaveLeader_Patch
{
[HarmonyPostfix]
public static void Postfix(Faction __instance, ref bool __result)
{
if (__instance.def?.defName == "ARA_Hostile_Hive")
{
__result = false;
}
}
}
}

View File

@@ -18,7 +18,7 @@ namespace ArachnaeSwarm
private Pawn_GestaltTracker tracker;
private bool wasConnected = false; // 缓存连接状态,避免每帧都调整严重性
// === 新增字段 ===
// === 延迟初始化字段 ===
/// <summary>
/// 生成时间戳ticks用于延迟计算
/// </summary>
@@ -34,6 +34,7 @@ namespace ArachnaeSwarm
/// </summary>
private const int DELAY_TICKS = 60;
// === 动态过渡系统字段 ===
/// <summary>
/// 过渡开始时间ticks
/// </summary>
@@ -45,7 +46,12 @@ namespace ArachnaeSwarm
private const int TRANSITION_DURATION = 300; // 5秒
/// <summary>
/// 过渡后的目标严重性
/// 过渡开始时的严重性
/// </summary>
private float transitionStartSeverity = 0.5f;
/// <summary>
/// 过渡结束时的目标严重性
/// </summary>
private float targetSeverityAfterTransition = 1.0f;
@@ -54,6 +60,11 @@ namespace ArachnaeSwarm
/// </summary>
private bool isTransitioning = false;
/// <summary>
/// 上一次更新严重性的时间ticks
/// </summary>
private int lastSeverityUpdateTick = -1;
// === 属性 ===
/// <summary>
@@ -125,6 +136,27 @@ namespace ArachnaeSwarm
}
}
/// <summary>
/// 获取每秒变化速率
/// </summary>
public float SeverityChangePerSecond
{
get
{
// 根据过渡类型计算不同的变化速率
if (targetSeverityAfterTransition > transitionStartSeverity)
{
// 连接状态从0.5到1.5总共1.0的变化量5秒内完成
return 0.2f; // 1.0 / 5.0 = 0.2
}
else
{
// 断开状态从1.5到0.5,总共-1.0的变化量5秒内完成
return -0.2f; // -1.0 / 5.0 = -0.2
}
}
}
/// <summary>
/// 获取 GestaltTracker
/// </summary>
@@ -161,13 +193,11 @@ namespace ArachnaeSwarm
// 记录生成时间戳
spawnTimestamp = Find.TickManager.TicksGame;
// 如果是HiveNode初始化时设置较低的严重性延迟后再计算
if (NodeType == GestaltNodeType.HiveNode)
{
// 设置初始严重性为0.5(未连接状态)
if (parent != null)
{
parent.Severity = 0.5f;
parent.Severity = 1.5f;
}
}
else
@@ -200,13 +230,13 @@ namespace ArachnaeSwarm
InitializeAfterDelay();
}
// 检查过渡状态
UpdateTransitionState();
// 检查过渡状态,并更新严重性变化
UpdateTransitionStateWithRate();
// 正常的Tick逻辑
if (NodeType == GestaltNodeType.HiveNode)
{
// 定期更新严重性(如果不在过渡中)
// 定期检查连接状态(如果不在过渡中)
if (!IsInTransition && Find.TickManager.TicksGame % 60 == 0) // 每60tick检查一次
{
UpdateSeverityBasedOnConnection();
@@ -252,9 +282,9 @@ namespace ArachnaeSwarm
}
/// <summary>
/// 更新过渡状态
/// 带速率变化的过渡状态更新
/// </summary>
private void UpdateTransitionState()
private void UpdateTransitionStateWithRate()
{
// 检查Pawn是否死亡或无效
var pawn = Pawn;
@@ -262,69 +292,152 @@ namespace ArachnaeSwarm
{
isTransitioning = false;
transitionStartTick = -1;
lastSeverityUpdateTick = -1;
return;
}
// 如果不在过渡中,重置并返回
if (!isTransitioning || transitionStartTick < 0)
{
lastSeverityUpdateTick = -1;
return;
// 检查是否过渡完成
}
// 检查过渡是否已经完成
if (!IsInTransition)
{
// 过渡完成,设置目标严重性
if (parent != null && Mathf.Abs(parent.Severity - targetSeverityAfterTransition) > 0.01f)
{
parent.Severity = targetSeverityAfterTransition;
// 通知Pawn状态改变使用方法开头声明的pawn变量
if (pawn?.health != null)
{
pawn.health.Notify_HediffChanged(parent);
}
ArachnaeLog.Debug($"[GestaltNode] {pawn?.LabelShort} 过渡完成,严重性: {targetSeverityAfterTransition}");
}
// 过渡完成,确保设置目标严重性
CompleteTransition();
return;
}
// 检查是否应该更新严重性(每秒更新一次
int currentTick = Find.TickManager.TicksGame;
if (lastSeverityUpdateTick < 0 || currentTick - lastSeverityUpdateTick >= 60) // 60ticks = 1秒
{
UpdateSeverityWithRate(currentTick);
lastSeverityUpdateTick = currentTick;
}
}
/// <summary>
/// 使用速率更新严重性
/// </summary>
private void UpdateSeverityWithRate(int currentTick)
{
var pawn = Pawn;
if (pawn == null || parent == null)
return;
// 重置过渡状态
transitionStartTick = -1;
isTransitioning = false;
// 计算经过的时间(秒)
float elapsedSeconds = (currentTick - transitionStartTick) / 60f;
// 计算新的严重性
float newSeverity;
// 方法1线性插值
// newSeverity = Mathf.Lerp(transitionStartSeverity, targetSeverityAfterTransition,
// Mathf.Clamp01(elapsedSeconds / (TRANSITION_DURATION / 60f)));
// 方法2使用速率计算更符合要求
float changeAmount = SeverityChangePerSecond * (currentTick - transitionStartTick) / 60f;
newSeverity = transitionStartSeverity + changeAmount;
// 确保严重性在合理范围内
if (targetSeverityAfterTransition > transitionStartSeverity)
{
// 连接过程,严重性增加
newSeverity = Mathf.Clamp(newSeverity, transitionStartSeverity, targetSeverityAfterTransition);
}
else
{
// 在过渡中,保持中间态严重性1
if (parent != null && Mathf.Abs(parent.Severity - 1.0f) > 0.01f)
// 断开过程,严重性减少
newSeverity = Mathf.Clamp(newSeverity, targetSeverityAfterTransition, transitionStartSeverity);
}
// 应用新的严重性
if (Mathf.Abs(parent.Severity - newSeverity) > 0.001f)
{
parent.Severity = newSeverity;
// 通知Pawn状态改变
if (pawn?.health != null)
{
parent.Severity = 1.0f;
pawn.health.Notify_HediffChanged(parent);
}
// 调试信息
if (Find.TickManager.TicksGame % 120 == 0) // 每2秒记录一次
{
ArachnaeLog.Debug($"[GestaltNode] {pawn.LabelShort} 过渡中: {parent.Severity:F2} -> {targetSeverityAfterTransition:F2} " +
$"(进度: {TransitionProgress:P0}, 速率: {SeverityChangePerSecond:F2}/秒)");
}
}
}
/// <summary>
/// 开始过渡
/// 完成过渡
/// </summary>
private void StartTransition(bool isConnecting)
private void CompleteTransition()
{
// 设置目标严重性
targetSeverityAfterTransition = isConnecting ? 1.5f : 0.5f;
// 记录过渡开始时间
transitionStartTick = Find.TickManager.TicksGame;
isTransitioning = true;
// 立即设置到中间态严重性1
if (parent != null)
var pawn = Pawn;
if (pawn == null || parent == null)
{
parent.Severity = 1.0f;
ResetTransition();
return;
}
// 确保最终严重性准确
if (Mathf.Abs(parent.Severity - targetSeverityAfterTransition) > 0.01f)
{
parent.Severity = targetSeverityAfterTransition;
// 通知Pawn状态改变
var pawn = Pawn;
if (pawn?.health != null)
{
pawn.health.Notify_HediffChanged(parent);
}
}
ArachnaeLog.Debug($"[GestaltNode] {Pawn?.LabelShort} 开始过渡,目标: {(isConnecting ? "" : "")} ({targetSeverityAfterTransition})");
ArachnaeLog.Debug($"[GestaltNode] {pawn.LabelShort} 过渡完成: {targetSeverityAfterTransition:F2}");
// 重置过渡状态
ResetTransition();
}
/// <summary>
/// 重置过渡状态
/// </summary>
private void ResetTransition()
{
transitionStartTick = -1;
isTransitioning = false;
lastSeverityUpdateTick = -1;
transitionStartSeverity = 0.5f;
targetSeverityAfterTransition = 1.0f;
}
/// <summary>
/// 开始带速率变化的过渡
/// </summary>
private void StartRateBasedTransition(bool isConnecting)
{
var pawn = Pawn;
if (pawn == null || parent == null)
return;
// 设置目标严重性
targetSeverityAfterTransition = isConnecting ? 1.5f : 0.5f;
// 记录过渡开始时的严重性
transitionStartSeverity = parent.Severity;
// 记录过渡开始时间
transitionStartTick = Find.TickManager.TicksGame;
isTransitioning = true;
lastSeverityUpdateTick = transitionStartTick;
ArachnaeLog.Debug($"[GestaltNode] {pawn.LabelShort} 开始速率过渡: {transitionStartSeverity:F2} -> {targetSeverityAfterTransition:F2} " +
$"({(isConnecting ? "" : "")}, 速率: {SeverityChangePerSecond:F2}/秒)");
}
/// <summary>
@@ -346,8 +459,8 @@ namespace ArachnaeSwarm
// 检查连接状态是否改变
if (isConnected != wasConnected)
{
// 连接状态改变,开始过渡
StartTransition(isConnected);
// 连接状态改变,开始带速率变化的过渡
StartRateBasedTransition(isConnected);
wasConnected = isConnected;
}
@@ -475,8 +588,7 @@ namespace ArachnaeSwarm
base.CompPostPostRemoved();
// 清理过渡状态
isTransitioning = false;
transitionStartTick = -1;
ResetTransition();
// 当Hediff被移除时如果连接到Overlord需要断开连接
if (NodeType == GestaltNodeType.HiveNode && IsConnectedToOverlord())
@@ -503,8 +615,7 @@ namespace ArachnaeSwarm
base.Notify_PawnDied(dinfo, culprit);
// 清理过渡状态
isTransitioning = false;
transitionStartTick = -1;
ResetTransition();
ArachnaeLog.Debug($"[GestaltNode] {Pawn?.LabelShort} 死亡,清理过渡状态");
}
@@ -519,8 +630,10 @@ namespace ArachnaeSwarm
Scribe_Values.Look(ref spawnTimestamp, "spawnTimestamp", -1);
Scribe_Values.Look(ref isInitialized, "isInitialized", false);
Scribe_Values.Look(ref transitionStartTick, "transitionStartTick", -1);
Scribe_Values.Look(ref transitionStartSeverity, "transitionStartSeverity", 0.5f);
Scribe_Values.Look(ref targetSeverityAfterTransition, "targetSeverityAfterTransition", 1.0f);
Scribe_Values.Look(ref isTransitioning, "isTransitioning", false);
Scribe_Values.Look(ref lastSeverityUpdateTick, "lastSeverityUpdateTick", -1);
// 加载后,如果已经过了延迟期,标记为已初始化
if (Scribe.mode == LoadSaveMode.PostLoadInit && spawnTimestamp >= 0)
@@ -542,8 +655,12 @@ namespace ArachnaeSwarm
{
parent.Severity = targetSeverityAfterTransition;
}
transitionStartTick = -1;
isTransitioning = false;
ResetTransition();
}
else
{
// 过渡未完成,恢复过渡
ArachnaeLog.Debug($"[GestaltNode] 恢复未完成的过渡: {transitionStartSeverity:F2} -> {targetSeverityAfterTransition:F2}");
}
}
}
@@ -561,11 +678,16 @@ namespace ArachnaeSwarm
string transitionInfo = "无";
if (IsInTransition)
{
transitionInfo = $"过渡中,进度: {TransitionProgress:P0},目标: {targetSeverityAfterTransition}";
float rate = SeverityChangePerSecond;
string direction = rate > 0 ? "增加" : "减少";
transitionInfo = $"过渡中,进度: {TransitionProgress:P0}\n" +
$"从: {transitionStartSeverity:F2} 到: {targetSeverityAfterTransition:F2}\n" +
$"速率: {Mathf.Abs(rate):F2}/秒 ({direction})\n" +
$"当前: {parent?.Severity:F2}";
}
else if (isTransitioning)
{
transitionInfo = $"过渡完成,目标: {targetSeverityAfterTransition}";
transitionInfo = $"过渡完成,目标: {targetSeverityAfterTransition:F2}";
}
return $"NodeType: {NodeType}\n" +
@@ -575,7 +697,7 @@ namespace ArachnaeSwarm
$"WasConnected: {wasConnected}\n" +
$"IsConnected: {IsConnectedToOverlord()}\n" +
$"Transition: {transitionInfo}\n" +
$"CurrentSeverity: {parent?.Severity ?? 0f}";
$"CurrentSeverity: {parent?.Severity ?? 0f:F2}";
}
}

View File

@@ -59,31 +59,31 @@ namespace ArachnaeSwarm
if (!Props.allowDuplicates && pawn.health.hediffSet.HasHediff(hediffDef))
continue;
// === 新增:获取应应用的部位 ===
BodyPartDef bodyPartDef = Props.GetBodyPartForHediff(hediffDef);
List<BodyPartRecord> bodyParts = GetBodyPartsForHediff(pawn, hediffDef, bodyPartDef);
// === 简化的身体部位处理 ===
// 参考CompUseEffect_InstallImplant的实现方式
BodyPartRecord bodyPartRecord = GetBodyPartRecordForHediff(pawn, hediffDef);
// 如果没有指定部位,或者没有找到匹配部位,则添加到全身
if (bodyParts == null || bodyParts.Count == 0)
// 如果指定部位但找不到,根据配置决定是否跳过
if (Props.bodyPart != null && bodyPartRecord == null)
{
AddHediffToPawn(pawn, hediffDef, null);
continue;
if (Props.skipIfPartMissing)
{
ArachnaeLog.Debug($"Skipping hediff {hediffDef.defName} for {pawn.Label} - body part {Props.bodyPart.defName} not found");
continue;
}
// 如果不跳过则添加到全身null表示不指定部位
}
// 根据选择规则添加hediff到相应部位
foreach (var bodyPart in bodyParts)
{
AddHediffToPawn(pawn, hediffDef, bodyPart);
}
AddHediffToPawn(pawn, hediffDef, bodyPartRecord);
// 记录应用到的部位
if (bodyParts.Count > 0)
if (bodyPartRecord != null)
{
if (!appliedHediffParts.ContainsKey(hediffDef))
{
appliedHediffParts[hediffDef] = new List<BodyPartRecord>();
}
appliedHediffParts[hediffDef].AddRange(bodyParts);
appliedHediffParts[hediffDef].Add(bodyPartRecord);
}
}
@@ -96,6 +96,30 @@ namespace ArachnaeSwarm
}
}
/// <summary>
/// 简化的身体部位获取方法参考CompUseEffect_InstallImplant
/// </summary>
private BodyPartRecord GetBodyPartRecordForHediff(Pawn pawn, HediffDef hediffDef)
{
if (pawn?.RaceProps?.body == null)
return null;
// 使用指定的身体部位(如果有)
if (Props.bodyPart != null)
{
return pawn.RaceProps.body.GetPartsWithDef(Props.bodyPart).FirstOrFallback();
}
// 否则使用hediff的默认安装部位如果有
if (hediffDef?.defaultInstallPart != null)
{
return pawn.RaceProps.body.GetPartsWithDef(hediffDef.defaultInstallPart).FirstOrFallback();
}
// 都没有则返回null添加到全身
return null;
}
/// <summary>
/// 添加hediff到pawn的指定部位
/// </summary>
@@ -103,19 +127,43 @@ namespace ArachnaeSwarm
{
try
{
Hediff hediff = HediffMaker.MakeHediff(hediffDef, pawn, bodyPart);
// 参考CompUseEffect_InstallImplant的实现
Hediff existingHediff = GetExistingHediffOnPart(pawn, hediffDef, bodyPart);
// 设置严重度(如果有指定)
if (Props.initialSeverity >= 0f)
if (existingHediff == null || Props.canUpgrade)
{
hediff.Severity = Props.initialSeverity;
Hediff hediff = HediffMaker.MakeHediff(hediffDef, pawn, bodyPart);
// 设置严重度(如果有指定)
if (Props.initialSeverity >= 0f)
{
hediff.Severity = Props.initialSeverity;
}
else if (Props.minSeverity > 0f && Props.maxSeverity > 0f)
{
// 如果有min/max严重度则随机一个值
hediff.Severity = Rand.Range(Props.minSeverity, Props.maxSeverity);
}
// 添加hediff
pawn.health.AddHediff(hediff, bodyPart);
// 如果是可升级的hediff设置等级
if (Props.canUpgrade && existingHediff != null && existingHediff is Hediff_Level existingLevel)
{
// 注意这里实际上会创建新的hediff所以升级逻辑在CompProperties_HediffGiver中处理
// 如果是升级应该使用existingHediff的ChangeLevel方法
// 这里简化处理直接添加新hediff因为旧hediff会被覆盖
}
ArachnaeLog.Debug($"Added hediff {hediffDef.defName} to {pawn.Label} " +
$"{(bodyPart != null ? $"on {bodyPart.def.defName}" : "to whole body")} " +
$"with severity {hediff.Severity:F2}");
}
else
{
ArachnaeLog.Debug($"Hediff {hediffDef.defName} already exists on {pawn.Label}, skipping");
}
// 添加hediff
pawn.health.AddHediff(hediff);
ArachnaeLog.Debug($"Added hediff {hediffDef.defName} to {pawn.Label} " +
$"{(bodyPart != null ? $"on {bodyPart.def.defName}" : "to whole body")}");
}
catch (Exception ex)
{
@@ -124,231 +172,99 @@ namespace ArachnaeSwarm
}
/// <summary>
/// 获取hediff应应用的身体部位列表
/// 检查指定部位是否已有相同的hediff参考CompUseEffect_InstallImplant.GetExistingImplant
/// </summary>
private List<BodyPartRecord> GetBodyPartsForHediff(Pawn pawn, HediffDef hediffDef, BodyPartDef bodyPartDef)
private Hediff GetExistingHediffOnPart(Pawn pawn, HediffDef hediffDef, BodyPartRecord bodyPart)
{
if (pawn == null || pawn.RaceProps?.body == null)
if (pawn?.health?.hediffSet?.hediffs == null)
return null;
// 如果没有指定身体部位,返回空列表
if (bodyPartDef == null)
return null;
try
// 如果bodyPart为null检查全身
if (bodyPart == null)
{
// 获取所有匹配的身体部位
List<BodyPartRecord> allMatchingParts = pawn.RaceProps.body.GetPartsWithDef(bodyPartDef);
if (allMatchingParts == null || allMatchingParts.Count == 0)
return pawn.health.hediffSet.GetFirstHediffOfDef(hediffDef);
}
// 检查指定部位
foreach (Hediff hediff in pawn.health.hediffSet.hediffs)
{
if (hediff.def == hediffDef && hediff.Part == bodyPart)
{
// 如果没有找到匹配部位,检查是否有备用部位
var mapping = Props.GetMappingForHediff(hediffDef);
if (mapping != null && mapping.fallbackToDefault)
return hediff;
}
}
return null;
}
/// <summary>
/// 检查是否可以为指定Pawn添加hediff参考CompUseEffect_InstallImplant.CanBeUsedBy
/// </summary>
public AcceptanceReport CanAddHediffToPawn(Pawn pawn)
{
if (pawn == null || Props.hediffs == null)
return false;
// 检查是否需要特定身体部位
if (Props.bodyPart != null)
{
var bodyPartRecord = pawn.RaceProps.body.GetPartsWithDef(Props.bodyPart).FirstOrFallback();
if (bodyPartRecord == null)
{
return "InstallImplantNoBodyPart".Translate() + ": " + Props.bodyPart.LabelShort;
}
}
// 检查是否已有hediff如果不允许重复
if (!Props.allowDuplicates)
{
foreach (HediffDef hediffDef in Props.hediffs)
{
if (pawn.health.hediffSet.HasHediff(hediffDef))
{
// 使用默认方式添加(全身)
return null;
return "InstallImplantAlreadyInstalled".Translate();
}
return new List<BodyPartRecord>();
}
// 检查部位有效性
if (Props.checkPartValidity)
}
// 检查是否需要现有hediff才能升级
if (Props.requiresExistingHediff)
{
foreach (HediffDef hediffDef in Props.hediffs)
{
allMatchingParts = allMatchingParts.Where(part => IsBodyPartValid(pawn, part)).ToList();
}
if (allMatchingParts.Count == 0)
{
return new List<BodyPartRecord>();
}
// 获取选择规则
BodyPartSelectionRule rule = Props.GetPartSelectionRuleForHediff(hediffDef);
var mappingConfig = Props.GetMappingForHediff(hediffDef);
// 根据规则选择部位
List<BodyPartRecord> selectedParts = new List<BodyPartRecord>();
if (rule == null)
{
// 默认规则:使用第一个匹配的部位
selectedParts.Add(allMatchingParts[0]);
}
else
{
// 根据规则选择部位
switch (rule.mode)
var existingHediff = GetExistingHediffOnPart(pawn, hediffDef,
Props.bodyPart != null ?
pawn.RaceProps.body.GetPartsWithDef(Props.bodyPart).FirstOrFallback() :
null);
if (existingHediff == null)
{
case BodyPartSelectionMode.First:
selectedParts.Add(allMatchingParts[0]);
break;
case BodyPartSelectionMode.Random:
int count = Math.Min(rule.maxParts, allMatchingParts.Count);
selectedParts = allMatchingParts.InRandomOrder().Take(count).ToList();
break;
case BodyPartSelectionMode.All:
selectedParts = allMatchingParts;
break;
case BodyPartSelectionMode.MostDamaged:
var mostDamaged = allMatchingParts.OrderByDescending(p => GetPartDamage(pawn, p)).FirstOrDefault();
if (mostDamaged != null) selectedParts.Add(mostDamaged);
break;
case BodyPartSelectionMode.LeastDamaged:
var leastDamaged = allMatchingParts.OrderBy(p => GetPartDamage(pawn, p)).FirstOrDefault();
if (leastDamaged != null) selectedParts.Add(leastDamaged);
break;
return "InstallImplantHediffRequired".Translate(hediffDef.label);
}
// 如果配置了随机选择部位
if (mappingConfig != null && mappingConfig.chooseRandomPart)
// 检查是否可以升级
if (Props.canUpgrade && existingHediff is Hediff_Level existingLevel)
{
selectedParts = allMatchingParts.InRandomOrder().Take(1).ToList();
}
// 处理对称性
if (rule.symmetrical && selectedParts.Count > 0)
{
selectedParts = GetSymmetricalParts(pawn, selectedParts[0], allMatchingParts);
}
}
return selectedParts;
}
catch (Exception)
{
return null;
}
}
/// <summary>
/// 获取对称的身体部位
/// </summary>
private List<BodyPartRecord> GetSymmetricalParts(Pawn pawn, BodyPartRecord referencePart, List<BodyPartRecord> allParts)
{
List<BodyPartRecord> symmetricalParts = new List<BodyPartRecord> { referencePart };
// 查找对称部位(如左臂对应的右臂)
foreach (var part in allParts)
{
if (part != referencePart && part.def == referencePart.def)
{
// 简单的对称检测:检查部位标签或名称
if (IsSymmetricalPart(referencePart, part))
{
symmetricalParts.Add(part);
if ((float)existingLevel.level >= existingLevel.def.maxSeverity)
{
return "InstallImplantAlreadyMaxLevel".Translate();
}
if (Props.maxSeverity <= (float)existingLevel.level)
{
return "InstallImplantAlreadyMaxLevel".Translate() + " " + Props.maxSeverity.ToString();
}
if (Props.minSeverity > (float)existingLevel.level)
{
return "InstallImplantMinLevel".Translate(Props.minSeverity);
}
}
}
}
return symmetricalParts;
}
/// <summary>
/// 检查两个部位是否对称
/// 使用 MCP 验证的 RimWorld 1.6 API
/// </summary>
private bool IsSymmetricalPart(BodyPartRecord part1, BodyPartRecord part2)
{
if (part1 == null || part2 == null || part1 == part2)
return false;
// 方法1使用 BodyPartDef.IsMirroredPartMCP验证tags.Contains(BodyPartTagDefOf.Mirrored)
// 镜像部位通常有左右之分
if (part1.def.IsMirroredPart && part2.def.IsMirroredPart && part1.def == part2.def)
{
// 同类型的镜像部位,检查是否是相反侧
if (AreOppositeMirroredParts(part1, part2))
return true;
}
// 方法2通过 customLabel 检测(如 "left arm", "right arm"
string label1 = part1.customLabel ?? part1.def.label;
string label2 = part2.customLabel ?? part2.def.label;
if (!string.IsNullOrEmpty(label1) && !string.IsNullOrEmpty(label2))
{
// 检查左右对称(使用翻译键支持本地化)
bool part1Left = label1.Contains("Left") || label1.Contains("left");
bool part1Right = label1.Contains("Right") || label1.Contains("right");
bool part2Left = label2.Contains("Left") || label2.Contains("left");
bool part2Right = label2.Contains("Right") || label2.Contains("right");
if ((part1Left && part2Right) || (part1Right && part2Left))
return true;
// 检查前后对称
bool part1Front = label1.Contains("Front") || label1.Contains("front");
bool part1Back = label1.Contains("Back") || label1.Contains("back");
bool part2Front = label2.Contains("Front") || label2.Contains("front");
bool part2Back = label2.Contains("Back") || label2.Contains("back");
if ((part1Front && part2Back) || (part1Back && part2Front))
return true;
}
return false;
}
/// <summary>
/// 检查两个镜像部位是否是相反侧
/// </summary>
private bool AreOppositeMirroredParts(BodyPartRecord part1, BodyPartRecord part2)
{
// 检查是否在同一层级(相同的父部位)
if (part1.parent != part2.parent)
return false;
// 检查索引是否不同(左右部位通常是相邻的)
if (part1.Index == part2.Index)
return false;
// 对于镜像部位,如果它们有相同的 BodyPartDef 但不同的 Index通常是对称的
// 这是一个合理的假设,因为 RimWorld 的身体定义中镜像部位通常是成对出现的
return true;
}
/// <summary>
/// 检查身体部位是否有效
/// </summary>
private bool IsBodyPartValid(Pawn pawn, BodyPartRecord part)
{
if (part == null)
return false;
// 检查部位是否已完全损坏
if (pawn.health.hediffSet.PartIsMissing(part))
return false;
// 检查部位是否被覆盖(如被装备遮挡)
// 这里可以添加更多有效性检查
return true;
}
/// <summary>
/// 获取部位的伤害值
/// </summary>
private float GetPartDamage(Pawn pawn, BodyPartRecord part)
{
if (part == null)
return 0f;
float totalDamage = 0f;
foreach (var hediff in pawn.health.hediffSet.hediffs)
{
if (hediff.Part == part && hediff is Hediff_Injury injury)
{
totalDamage += injury.Severity;
}
}
return totalDamage;
}
// 序列化hediffsApplied标记
public override void PostExposeData()

View File

@@ -5,50 +5,8 @@ using Verse;
namespace ArachnaeSwarm
{
/// <summary>
/// Hediff与身体部位的映射关系用于XML序列化
/// 简化的身体部位选择模式
/// </summary>
public class HediffBodyPartMapping
{
public HediffDef hediff;
public BodyPartDef bodyPart;
/// <summary>
/// 可选优先级数值越大优先级越高默认1
/// </summary>
public int priority = 1;
/// <summary>
/// 可选是否随机选择多个部位如果pawn有多个相同部位
/// </summary>
public bool chooseRandomPart = false;
/// <summary>
/// 可选:如果找不到指定部位,是否使用默认添加方式
/// </summary>
public bool fallbackToDefault = true;
}
/// <summary>
/// 身体部位选择规则
/// </summary>
public class BodyPartSelectionRule
{
/// <summary>
/// 选择模式First第一个匹配的、Random随机一个、All所有匹配的
/// </summary>
public BodyPartSelectionMode mode = BodyPartSelectionMode.First;
/// <summary>
/// 仅当mode为Random时有效最多选择多少个部位
/// </summary>
public int maxParts = 1;
/// <summary>
/// 是否对称如果pawn有左右对称的相同部位
/// </summary>
public bool symmetrical = false;
}
public enum BodyPartSelectionMode
{
First, // 第一个匹配的部位
@@ -69,140 +27,74 @@ namespace ArachnaeSwarm
// 是否允许重复添加相同的hediff
public bool allowDuplicates = false;
// === 新增:优先应用部位设置 ===
public bool useDefaultInstallPart = true;
// === 简化的身体部位设置 ===
/// <summary>
/// 要安装到的身体部位参考CompUseEffect_InstallImplant
/// </summary>
public BodyPartDef bodyPart = null;
// === 新增自定义部位映射使用List替代Dictionary ===
public List<HediffBodyPartMapping> customBodyPartMapping = null;
/// <summary>
/// 如果指定部位不存在,是否跳过添加
/// </summary>
public bool skipIfPartMissing = false;
// === 新增:全局身体部位选择规则 ===
public BodyPartSelectionRule globalPartSelectionRule = null;
/// <summary>
/// 身体部位选择模式
/// </summary>
public BodyPartSelectionMode partSelectionMode = BodyPartSelectionMode.First;
// === 新增按hediff分类的身体部位选择规则 ===
public List<HediffPartSelectionRule> hediffPartSelectionRules = null;
/// <summary>
/// 仅当partSelectionMode为Random时有效最多选择多少个部位
/// </summary>
public int maxParts = 1;
// === 新增添加hediff时的严重度设置 ===
/// <summary>
/// 是否对称如果pawn有左右对称的相同部位
/// </summary>
public bool symmetrical = false;
// === Hediff升级相关设置参考CompUseEffect_InstallImplant===
/// <summary>
/// 是否可以升级已有的hediff
/// </summary>
public bool canUpgrade = false;
/// <summary>
/// 是否需要已有的hediff才能安装
/// </summary>
public bool requiresExistingHediff = false;
/// <summary>
/// 最小严重度(用于升级检查)
/// </summary>
public float minSeverity = 0f;
/// <summary>
/// 最大严重度(用于升级检查)
/// </summary>
public float maxSeverity = 1f;
// === 添加hediff时的严重度设置 ===
public float initialSeverity = -1f; // 负数表示使用hediff默认值
// === 新增:是否检查部位有效性(是否存在、是否已损坏等) ===
// === 是否检查部位有效性(是否存在、是否已损坏等)===
public bool checkPartValidity = true;
// === 新增:如果指定部位不存在时的备用部位 ===
public BodyPartDef fallbackBodyPart = null;
// === 新增添加hediff时的效果 ===
// === 添加hediff时的效果 ===
public EffecterDef applicationEffect = null;
// === 新增:是否在添加时显示消息 ===
// === 是否在添加时显示消息 ===
public bool showApplicationMessage = false;
// === 新增:添加消息的翻译键 ===
// === 添加消息的翻译键 ===
public string applicationMessageKey = null;
// === 新增:添加hediff时的声音 ===
// === 添加hediff时的声音 ===
public SoundDef applicationSound = null;
public CompProperties_HediffGiver()
{
this.compClass = typeof(CompHediffGiver);
}
/// <summary>
/// 根据hediff获取对应的身体部位定义
/// </summary>
public BodyPartDef GetBodyPartForHediff(HediffDef hediffDef)
{
if (hediffDef == null)
return null;
// 1. 首先检查自定义映射
if (customBodyPartMapping != null)
{
// 查找优先级最高的映射
HediffBodyPartMapping bestMapping = null;
int highestPriority = int.MinValue;
foreach (var mapping in customBodyPartMapping)
{
if (mapping.hediff == hediffDef)
{
if (mapping.priority > highestPriority)
{
bestMapping = mapping;
highestPriority = mapping.priority;
}
}
}
if (bestMapping != null)
{
return bestMapping.bodyPart;
}
}
// 2. 然后检查默认安装部位
if (useDefaultInstallPart && hediffDef.defaultInstallPart != null)
{
return hediffDef.defaultInstallPart;
}
// 3. 最后检查备用部位
return fallbackBodyPart;
}
/// <summary>
/// 获取hediff对应的身体部位选择规则
/// </summary>
public BodyPartSelectionRule GetPartSelectionRuleForHediff(HediffDef hediffDef)
{
if (hediffDef == null)
return globalPartSelectionRule;
// 1. 首先检查hediff特定的规则
if (hediffPartSelectionRules != null)
{
var rule = hediffPartSelectionRules.FirstOrDefault(r => r.hediff == hediffDef);
if (rule != null)
{
return rule.selectionRule;
}
}
// 2. 返回全局规则
return globalPartSelectionRule;
}
/// <summary>
/// 获取hediff对应的映射配置
/// </summary>
public HediffBodyPartMapping GetMappingForHediff(HediffDef hediffDef)
{
if (hediffDef == null || customBodyPartMapping == null)
return null;
// 查找优先级最高的映射
HediffBodyPartMapping bestMapping = null;
int highestPriority = int.MinValue;
foreach (var mapping in customBodyPartMapping)
{
if (mapping.hediff == hediffDef && mapping.priority > highestPriority)
{
bestMapping = mapping;
highestPriority = mapping.priority;
}
}
return bestMapping;
}
}
/// <summary>
/// Hediff与部位选择规则的映射
/// </summary>
public class HediffPartSelectionRule
{
public HediffDef hediff;
public BodyPartSelectionRule selectionRule;
}
}