基因窃贼

This commit is contained in:
Tourswen
2025-10-22 01:02:33 +08:00
parent fc9bd81f88
commit 88000aa1ca
25 changed files with 1060 additions and 52 deletions

Binary file not shown.

View File

@@ -902,6 +902,104 @@
</comps>
</AbilityDef>
<AbilityDef>
<defName>ARA_Genestealer_ExtractGene</defName>
<label>基因窃取</label>
<description>畸变种从目标的基因库中抽取1-4个基因包括超凡基因加入自己的基因序列被抽取的目标虽然不会死亡但是将失去此基因并从此一蹶不振无法再从昏迷中醒来。</description>
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_Genestealer_ExtractGene</iconPath>
<cooldownTicksRange>50000</cooldownTicksRange>
<casterMustBeCapableOfViolence>false</casterMustBeCapableOfViolence>
<stunTargetWhileCasting>true</stunTargetWhileCasting>
<warmupMote>Mote_HoraxSmallSpellWarmup</warmupMote>
<warmupEffecter>HoraxianAbilityCasting</warmupEffecter>
<warmupSound>AnomalyAbilityWarmup</warmupSound>
<jobDef>CastAbilityOnThingMelee</jobDef>
<verbProperties>
<verbClass>Verb_CastAbilityTouch</verbClass>
<drawAimPie>false</drawAimPie>
<range>-1</range>
<warmupTime>5</warmupTime>
<targetParams>
<onlyTargetColonistsOrPrisonersOrSlaves>true</onlyTargetColonistsOrPrisonersOrSlaves>
<canTargetSelf>false</canTargetSelf>
<canTargetMechs>false</canTargetMechs>
<canTargetBuildings>false</canTargetBuildings>
</targetParams>
</verbProperties>
<comps>
<li Class="ArachnaeSwarm.CompProperties_AbilityNeedCost">
<customLabel>饮食</customLabel>
<showProgressBar>true</showProgressBar>
<needDef>Food</needDef>
<needCost>1</needCost>
<failMessage>营养值不足,需要进食</failMessage>
</li>
<li Class="CompProperties_AbilityGiveHediff">
<compClass>CompAbilityEffect_GiveHediff</compClass>
<hediffDef>ARA_Genestealer_ExtractGene_Hediff</hediffDef>
<replaceExisting>true</replaceExisting>
</li>
<li Class="ArachnaeSwarm.CompProperties_AbilityExtractGene">
<baseGeneCount>1</baseGeneCount>
<maxComplexity>5</maxComplexity>
<canExtractArchiteGenes>true</canExtractArchiteGenes>
<allowMelaninGenes>false</allowMelaninGenes>
<targetLosesGene>true</targetLosesGene>
<geneCountChanceCurve>
<points>
<li>(1, 0.7)</li>
<li>(2, 0.2)</li>
<li>(3, 0.08)</li>
<li>(4, 0.02)</li>
<li>(5, 0)</li>
</points>
</geneCountChanceCurve>
</li>
</comps>
</AbilityDef>
<AbilityDef>
<defName>ARA_Genestealer_InjectGenes</defName>
<label>基因注入</label>
<description>畸变种尝试将自身的基因全部注入到目标体内。</description>
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_Genestealer_InjectGenes</iconPath>
<cooldownTicksRange>1</cooldownTicksRange>
<casterMustBeCapableOfViolence>false</casterMustBeCapableOfViolence>
<stunTargetWhileCasting>true</stunTargetWhileCasting>
<warmupMote>Mote_HoraxSmallSpellWarmup</warmupMote>
<warmupEffecter>HoraxianAbilityCasting</warmupEffecter>
<warmupSound>AnomalyAbilityWarmup</warmupSound>
<jobDef>CastAbilityOnThingMelee</jobDef>
<verbProperties>
<verbClass>Verb_CastAbilityTouch</verbClass>
<drawAimPie>false</drawAimPie>
<range>-1</range>
<warmupTime>3</warmupTime>
<targetParams>
<onlyTargetColonistsOrPrisonersOrSlaves>true</onlyTargetColonistsOrPrisonersOrSlaves>
<canTargetSelf>false</canTargetSelf>
<canTargetMechs>false</canTargetMechs>
<canTargetBuildings>false</canTargetBuildings>
</targetParams>
</verbProperties>
<comps>
<li Class="ArachnaeSwarm.CompProperties_AbilityNeedCost">
<customLabel>饮食</customLabel>
<showProgressBar>true</showProgressBar>
<needDef>Food</needDef>
<needCost>1</needCost>
<failMessage>营养值不足,需要进食</failMessage>
</li>
<li Class="ArachnaeSwarm.CompProperties_AbilityInjectGenes">
<includeArchiteGenes>true</includeArchiteGenes>
<includeMelaninGenes>false</includeMelaninGenes>
<casterGetsNegativeEffect>true</casterGetsNegativeEffect>
<targetGetsPositiveEffect>true</targetGetsPositiveEffect>
<allowDuplicateGenes>false</allowDuplicateGenes>
<maxComplexity>10</maxComplexity>
</li>
</comps>
</AbilityDef>
<AbilityDef>
<defName>ARA_TerrainHeal_Ability</defName>
<label>护士装疗愈</label>

View File

@@ -133,6 +133,63 @@
<positionRadius>0.1</positionRadius>
</EffecterDef>
<FleckDef ParentName="FleckBase_RandomGraphic_Thrown">
<defName>ARA_Mote_Melee_Attack_Main</defName>
<growthRate>1.0</growthRate>
<altitudeLayer>MoteOverheadLow</altitudeLayer>
<fadeInTime>0</fadeInTime>
<solidTime>0</solidTime>
<fadeOutTime>0.6</fadeOutTime>
<rotateTowardsMoveDirection>true</rotateTowardsMoveDirection>
<randomGraphics>
<li>
<texPath>ArachnaeSwarm/Mote/ARA_Melee_Attack</texPath>
<shaderType>MoteGlow</shaderType>
<renderInstanced>true</renderInstanced>
<graphicClass>Graphic_Fleck</graphicClass>
</li>
<!-- <li>
<texPath>SRA/Effect/SRA_FlashSlash_Big_B</texPath>
<shaderType>MoteGlow</shaderType>
<renderInstanced>true</renderInstanced>
<graphicClass>Graphic_Fleck</graphicClass>
</li> -->
</randomGraphics>
</FleckDef>
<EffecterDef>
<defName>ARA_Melee_Attack_Hit</defName>
<children>
<li>
<subEffecterClass>SubEffecter_Random</subEffecterClass>
<children>
<li>
<subEffecterClass>SubEffecter_SprayerTriggered</subEffecterClass>
<fleckDef>ARA_Mote_Melee_Attack_Main</fleckDef>
<burstCount>1</burstCount>
<color>(170,74,68)</color>
<scale>3.5~4.5</scale>
<speed>0.5</speed>
<angle>-35~35</angle>
<spawnLocType>OnSource</spawnLocType>
<fleckUsesAngleForVelocity>true</fleckUsesAngleForVelocity>
</li>
<li>
<subEffecterClass>SubEffecter_SprayerTriggered</subEffecterClass>
<fleckDef>ARA_Mote_Melee_Attack_Main</fleckDef>
<burstCount>1</burstCount>
<color>(147,50,28)</color>
<scale>2.5~3.5</scale>
<speed>0.5</speed>
<angle>-15~15</angle>
<spawnLocType>OnSource</spawnLocType>
<fleckUsesAngleForVelocity>true</fleckUsesAngleForVelocity>
</li>
</children>
</li>
</children>
<positionRadius>0.1</positionRadius>
</EffecterDef>
<FleckDef ParentName="FleckBase">
<defName>ARA_Fleck_Icez_Cloud</defName>
<graphicData>

View File

@@ -721,11 +721,13 @@
<li>ARA_AcidSprayBurst</li>
<li>ARA_Toxic_Needle_Fire</li>
<li>ARA_Fighter_Invisibility</li>
<li>ARA_Fighter_Genestealer</li>
</abilityDefs>
</li>
<li Class="HediffCompProperties_RemoveIfOtherHediff">
<hediffs>
<li>ARA_Fighter_Invisibility</li>
<li>ARA_Fighter_Genestealer</li>
</hediffs>
</li>
</comps>
@@ -815,6 +817,77 @@
<li Class="HediffCompProperties_DisappearsOnDeath" />
</comps>
</HediffDef>
<AbilityDef>
<defName>ARA_Fighter_Genestealer</defName>
<label>战士种转换——基因窃贼</label>
<description>使战士种发生内驱性进化,损害其战斗能力和使用技能的能力,以换取从敌人身上窃取基因、向己方殖民者注入基因和诱发非虫族殖民者虫族化的能力。\n\n该进化过程不可逆</description>
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_Fighter_Genestealer</iconPath>
<cooldownTicksRange>1800</cooldownTicksRange>
<hostile>false</hostile>
<groupAbility>true</groupAbility>
<displayGizmoWhileUndrafted>true</displayGizmoWhileUndrafted>
<disableGizmoWhileUndrafted>false</disableGizmoWhileUndrafted>
<aiCanUse>false</aiCanUse>
<ai_IsOffensive>true</ai_IsOffensive>
<targetRequired>false</targetRequired>
<jobDef>CastAbilityOnThing</jobDef>
<verbProperties>
<verbClass>Verb_CastAbility</verbClass>
<range>1</range>
<warmupTime>12</warmupTime>
<soundCast>AcidSpray_Resolve</soundCast>
<violent>false</violent>
<targetable>false</targetable>
<targetParams>
<canTargetSelf>True</canTargetSelf>
</targetParams>
</verbProperties>
<comps>
<li Class="CompProperties_AbilityGiveHediff">
<compClass>CompAbilityEffect_GiveHediff</compClass>
<hediffDef>ARA_Fighter_Genestealer</hediffDef>
<onlyApplyToSelf>True</onlyApplyToSelf>
<replaceExisting>true</replaceExisting>
<severity>1</severity>
</li>
<li Class="ArachnaeSwarm.CompProperties_AbilityAddExtraExp">
<skillChanges>
<li>
<skill>Melee</skill>
<passionGained>None</passionGained>
<xpGainAmount>-350000</xpGainAmount>
</li>
<li>
<skill>Shooting</skill>
<passionGained>None</passionGained>
<xpGainAmount>-350000</xpGainAmount>
</li>
</skillChanges>
</li>
<li Class="ArachnaeSwarm.CompProperties_AbilityResearchPrereq">
<requiredResearch>ARA_Technology_4CLO</requiredResearch>
<failMessage>需要科技 节点CLO-4"追猎种" 以解锁进化</failMessage>
</li>
</comps>
</AbilityDef>
<HediffDef>
<defName>ARA_Fighter_Genestealer</defName>
<hediffClass>HediffWithComps</hediffClass>
<label>亚种-畸变种</label>
<description>畸变种是移动的基因库,她们在虫群中不再担任刀剑舔血的工作,而是专注于提纯囚犯和奴隶的优质基因,并将其赋予虫族中的高质量个体。她们也拥有引发非虫族殖民者器官虫族化的能力,以使得那些没有用处的异族能那么稍微对虫巢做出一些贡献。</description>
<isBad>false</isBad>
<stages>
</stages>
<comps>
<li Class="HediffCompProperties_GiveAbility">
<abilityDefs>
<li>ARA_Genestealer_ExtractGene</li>
<li>ARA_Genestealer_InjectGenes</li>
</abilityDefs>
</li>
<li Class="HediffCompProperties_DisappearsOnDeath" />
</comps>
</HediffDef>
<!-- 迷雾种 -->
<HediffDef>

View File

@@ -610,4 +610,27 @@
</li>
</stages>
</HediffDef>
<HediffDef>
<defName>ARA_Genestealer_ExtractGene_Hediff</defName>
<label>强制剥离</label>
<description>阿拉克涅畸变种从该殖民者身上强制抽离了一部分基因序列,这导致该殖民者无法再维持基本生理活动。该伤害是不可逆的,即使这些基因被塞回去亦是如此。</description>
<defaultLabelColor>(1, 1, 0.8)</defaultLabelColor>
<hediffClass>HediffWithComps</hediffClass>
<comps>
<li Class="HediffCompProperties_DisappearsOnDeath"/>
</comps>
<stages>
<li>
<label>minor</label>
<becomeVisible>true</becomeVisible>
<capMods>
<li>
<capacity>Consciousness</capacity>
<setMax>0.1</setMax>
</li>
</capMods>
</li>
</stages>
</HediffDef>
</Defs>

View File

@@ -590,6 +590,18 @@
</prerequisites>
</ResearchProjectDef>
<!-- 进化发展 -->
<ResearchProjectDef ParentName="ARA_techBase_Needtechprint">
<defName>ARA_Technology_5STL</defName>
<label>节点STL-5"基因窃取"</label>
<description>允许战士种进行定向进化,抛弃其战斗技能以换取其从殖民者、囚犯和奴隶身上抽取和注入基因的能力,并且可以主动诱发非虫族殖民者的虫化变异。\n\n阿拉克涅虫群所有需要蓝图的科技其蓝图只能通过女皇种的基因试验卵获取。</description>
<baseCost>500</baseCost>
<researchViewX>2.00</researchViewX>
<researchViewY>5.40</researchViewY>
<requiredResearchBuilding>ARA_ResearchBench</requiredResearchBuilding>
<prerequisites>
<li>ARA_Technology_1KYC</li>
</prerequisites>
</ResearchProjectDef>
<ResearchProjectDef ParentName="ARA_techBase_Needtechprint">
<defName>ARA_Technology_1VTE</defName>
<label>节点VTE-1"护卫者"</label>

View File

@@ -19,9 +19,9 @@
<!-- <li Class="StorytellerCompProperties_ClassicIntro"/> -->
<li Class="StorytellerCompProperties_OnOffCycle">
<category>ThreatBig</category> <!-- 大型袭击 -->
<minDaysPassed>15.0</minDaysPassed> <!-- 最低在15日后开始生成 -->
<onDays>2</onDays> <!-- 每个周期(12天)有多少天允许生成袭击 -->
<offDays>9</offDays> <!-- 每个周期(12天)有多少天不生成袭击 -->
<minDaysPassed>0</minDaysPassed> <!-- 最低在15日后开始生成 -->
<onDays>1</onDays> <!-- 每个周期(12天)有多少天允许生成袭击 -->
<offDays>2</offDays> <!-- 每个周期(2天)有多少天不生成袭击 -->
<minSpacingDays>0.25</minSpacingDays> <!-- 事件最小间隔 -->
<numIncidentsRange>2~3</numIncidentsRange> <!-- 事件点数 -->
<!-- <forceRaidEnemyBeforeDaysPassed>20</forceRaidEnemyBeforeDaysPassed> -->
@@ -32,8 +32,8 @@
<li Class="StorytellerCompProperties_OnOffCycle">
<category>ThreatSmall</category>
<minDaysPassed>11.0</minDaysPassed>
<onDays>4.6</onDays>
<offDays>6.0</offDays>
<onDays>2</onDays>
<offDays>2.0</offDays>
<numIncidentsRange>0.2~1</numIncidentsRange>
<acceptPercentFactorPerThreatPointsCurve>
<points>

View File

@@ -235,6 +235,8 @@
<cleaveDamageFactor>0.5</cleaveDamageFactor>
<damageDowned>false</damageDowned>
<explosionDamageDef>Cut</explosionDamageDef>
<attackEffecter>ARA_Melee_Attack_Hit</attackEffecter>
<cleaveEffecter>ARA_Melee_Attack_Hit</cleaveEffecter>
</li>
</comps>
</ThingDef>

View File

@@ -98,4 +98,21 @@
<ARA_ResurrectionPrevented>没有来自更高级节点的允许,{0} 将从基因层面拒绝任何复活。</ARA_ResurrectionPrevented>
<CannotBeUninstalled>孵化期间无法重新安装</CannotBeUninstalled>
<ARAGeneExtractionComplete>{CASTER} 已经从 {TARGET} 的身上窃取基因</ARAGeneExtractionComplete>
<ARAGeneExtractionFailed>基因提取失败</ARAGeneExtractionFailed>
<TargetMustBeHumanlike>必须瞄准类人种族</TargetMustBeHumanlike>
<TargetHasNoGenes>目标必须拥有可提取的基因</TargetHasNoGenes>
<NoExtractableGenes>目标拥有特殊基因,但是没有提取价值</NoExtractableGenes>
<CasterAtGeneCapacity>{CASTER} 的基因序列容量达到上限</CasterAtGeneCapacity>
<ExtractableGenesCount>可窃取的基因数量:{0}</ExtractableGenesCount>
<ARA_GeneInjectionComplete>{CASTER}将基因注入了{TARGET}</ARA_GeneInjectionComplete>
<ARA_GeneInjectionFailed>基因注入失败</ARA_GeneInjectionFailed>
<CasterHasNoGenes>{CASTER}没有可注入的基因</CasterHasNoGenes>
<NoTransferableGenes>{CASTER}没有符合要求的可转移基因</NoTransferableGenes>
<TargetCannotAcceptGenes>{TARGET}无法接受这些基因</TargetCannotAcceptGenes>
<CasterHasNoTransferableGenes>{CASTER}没有可转移的基因</CasterHasNoTransferableGenes>
<TransferableGenesCount>可转移基因数: {0}</TransferableGenesCount>
<TargetHasGenesCount>目标已有: {0}</TargetHasGenesCount>
</LanguageData>

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -2,12 +2,28 @@
"Version": 1,
"WorkspaceRootPath": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\ara_genestealer\\compabilityeffect_injectgenes.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_genestealer\\compabilityeffect_injectgenes.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\ara_genestealer\\compabilityeffect_extractgene.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_genestealer\\compabilityeffect_extractgene.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\ara_genestealer\\compproperties_abilityinjectgenes.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_genestealer\\compproperties_abilityinjectgenes.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\verbs\\cleave\\verb_meleeattack_cleave.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:verbs\\cleave\\verb_meleeattack_cleave.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\hediffs\\ara_hivemind\\hediff_hiveminddrone.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_hivemind\\hediff_hiveminddrone.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_hivemind\\hediffcomp_hiveminddrone.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\hediffs\\ara_hivemind\\hediffcomp_hiveminddrone.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_hivemind\\hediffcomp_hiveminddrone.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
@@ -15,11 +31,11 @@
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_hivemind\\hediff_hivemindmaster.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\mentalstate\\mentalstate_hivemindcascade.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\mentalstate\\mentalstate_hivemindcascade.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:mentalstate\\mentalstate_hivemindcascade.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_arachnidgravengine.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\buildings\\building_arachnidgravengine.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_arachnidgravengine.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
@@ -94,15 +110,67 @@
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 8,
"SelectedChildIndex": 3,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "CompProperties_AbilityInjectGenes.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_Genestealer\\CompProperties_AbilityInjectGenes.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_Genestealer\\CompProperties_AbilityInjectGenes.cs",
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_Genestealer\\CompProperties_AbilityInjectGenes.cs",
"RelativeToolTip": "Abilities\\ARA_Genestealer\\CompProperties_AbilityInjectGenes.cs",
"ViewState": "AgIAAAAAAAAAAAAAAADwvwAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T16:09:51.937Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "CompAbilityEffect_ExtractGene.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_Genestealer\\CompAbilityEffect_ExtractGene.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_Genestealer\\CompAbilityEffect_ExtractGene.cs",
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_Genestealer\\CompAbilityEffect_ExtractGene.cs",
"RelativeToolTip": "Abilities\\ARA_Genestealer\\CompAbilityEffect_ExtractGene.cs",
"ViewState": "AgIAADUAAAAAAAAAAAAewFwAAABVAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T16:09:29.065Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "CompAbilityEffect_InjectGenes.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_Genestealer\\CompAbilityEffect_InjectGenes.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_Genestealer\\CompAbilityEffect_InjectGenes.cs",
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_Genestealer\\CompAbilityEffect_InjectGenes.cs",
"RelativeToolTip": "Abilities\\ARA_Genestealer\\CompAbilityEffect_InjectGenes.cs",
"ViewState": "AgIAAC0AAAAAAAAAAAAtwD4AAAAQAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T16:08:53.903Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "Verb_MeleeAttack_Cleave.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Verbs\\Cleave\\Verb_MeleeAttack_Cleave.cs",
"RelativeDocumentMoniker": "Verbs\\Cleave\\Verb_MeleeAttack_Cleave.cs",
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Verbs\\Cleave\\Verb_MeleeAttack_Cleave.cs",
"RelativeToolTip": "Verbs\\Cleave\\Verb_MeleeAttack_Cleave.cs",
"ViewState": "AgIAAG8AAAAAAAAAAAAhwI8AAABCAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T12:52:47.558Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "HediffComp_HiveMindDrone.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\HediffComp_HiveMindDrone.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\HediffComp_HiveMindDrone.cs",
@@ -110,12 +178,11 @@
"RelativeToolTip": "Hediffs\\ARA_HiveMind\\HediffComp_HiveMindDrone.cs",
"ViewState": "AgIAAAAAAAAAAAAAAADwvxAAAAAJAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T11:18:08.124Z",
"EditorCaption": ""
"WhenOpened": "2025-10-21T11:18:08.124Z"
},
{
"$type": "Document",
"DocumentIndex": 3,
"DocumentIndex": 7,
"Title": "MentalState_HiveMindCascade.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\MentalState\\MentalState_HiveMindCascade.cs",
"RelativeDocumentMoniker": "MentalState\\MentalState_HiveMindCascade.cs",
@@ -123,12 +190,11 @@
"RelativeToolTip": "MentalState\\MentalState_HiveMindCascade.cs",
"ViewState": "AgIAAI8AAAAAAAAAAAAkwJQAAAA2AAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T10:30:11.696Z",
"EditorCaption": ""
"WhenOpened": "2025-10-21T10:30:11.696Z"
},
{
"$type": "Document",
"DocumentIndex": 4,
"DocumentIndex": 8,
"Title": "Building_ArachnidGravEngine.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ArachnidGravEngine.cs",
"RelativeDocumentMoniker": "Buildings\\Building_ArachnidGravEngine.cs",
@@ -136,12 +202,11 @@
"RelativeToolTip": "Buildings\\Building_ArachnidGravEngine.cs",
"ViewState": "AgIAAAMAAAAAAAAAAAAkwBUAAAAJAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T09:12:42.006Z",
"EditorCaption": ""
"WhenOpened": "2025-10-21T09:12:42.006Z"
},
{
"$type": "Document",
"DocumentIndex": 8,
"DocumentIndex": 12,
"Title": "CompAbilityEffect_AbilityShowSpawnablePawns.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs",
@@ -153,7 +218,7 @@
},
{
"$type": "Document",
"DocumentIndex": 9,
"DocumentIndex": 13,
"Title": "Patch_UniquePawn.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\Patch_UniquePawn.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\Patch_UniquePawn.cs",
@@ -165,7 +230,7 @@
},
{
"$type": "Document",
"DocumentIndex": 12,
"DocumentIndex": 16,
"Title": "Building_TurretGunHasSpeed.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_TurretGunHasSpeed.cs",
"RelativeDocumentMoniker": "Buildings\\Building_TurretGunHasSpeed.cs",
@@ -177,7 +242,7 @@
},
{
"$type": "Document",
"DocumentIndex": 2,
"DocumentIndex": 6,
"Title": "Hediff_HiveMindMaster.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs",
@@ -185,25 +250,23 @@
"RelativeToolTip": "Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs",
"ViewState": "AgIAACIAAAAAAAAAAAAAADkAAACXAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-20T17:25:29.183Z",
"EditorCaption": ""
"WhenOpened": "2025-10-20T17:25:29.183Z"
},
{
"$type": "Document",
"DocumentIndex": 0,
"DocumentIndex": 4,
"Title": "Hediff_HiveMindDrone.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\Hediff_HiveMindDrone.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\Hediff_HiveMindDrone.cs",
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\Hediff_HiveMindDrone.cs",
"RelativeToolTip": "Hediffs\\ARA_HiveMind\\Hediff_HiveMindDrone.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAFcAAAAWAAAAAAAAAA==",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABYAAAAVAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-20T17:26:14.842Z",
"EditorCaption": ""
"WhenOpened": "2025-10-20T17:26:14.842Z"
},
{
"$type": "Document",
"DocumentIndex": 7,
"DocumentIndex": 11,
"Title": "CompProperties_SpawnPawnFromList.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SpawnPawnFromList\\CompProperties_SpawnPawnFromList.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_SpawnPawnFromList\\CompProperties_SpawnPawnFromList.cs",
@@ -215,7 +278,7 @@
},
{
"$type": "Document",
"DocumentIndex": 6,
"DocumentIndex": 10,
"Title": "CompSpawnPawnFromList.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SpawnPawnFromList\\CompSpawnPawnFromList.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_SpawnPawnFromList\\CompSpawnPawnFromList.cs",
@@ -227,7 +290,7 @@
},
{
"$type": "Document",
"DocumentIndex": 5,
"DocumentIndex": 9,
"Title": "Building_Incubatable.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Incubatable.cs",
"RelativeDocumentMoniker": "Buildings\\Building_Incubatable.cs",
@@ -239,7 +302,7 @@
},
{
"$type": "Document",
"DocumentIndex": 11,
"DocumentIndex": 15,
"Title": "CompProperties_UniquePawn.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\CompProperties_UniquePawn.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\CompProperties_UniquePawn.cs",
@@ -251,7 +314,7 @@
},
{
"$type": "Document",
"DocumentIndex": 10,
"DocumentIndex": 14,
"Title": "CompUniquePawn.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs",
@@ -263,7 +326,7 @@
},
{
"$type": "Document",
"DocumentIndex": 13,
"DocumentIndex": 17,
"Title": "Building_RefuelingVat.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
@@ -275,7 +338,7 @@
},
{
"$type": "Document",
"DocumentIndex": 14,
"DocumentIndex": 18,
"Title": "Building_NutrientVat.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_NutrientVat\\Building_NutrientVat.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_NutrientVat\\Building_NutrientVat.cs",
@@ -287,7 +350,7 @@
},
{
"$type": "Document",
"DocumentIndex": 15,
"DocumentIndex": 19,
"Title": "Building_CatastropheMissileSilo.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CatastropheMissileSilo\\Building_CatastropheMissileSilo.cs",
"RelativeDocumentMoniker": "Buildings\\Building_CatastropheMissileSilo\\Building_CatastropheMissileSilo.cs",
@@ -299,7 +362,7 @@
},
{
"$type": "Document",
"DocumentIndex": 16,
"DocumentIndex": 20,
"Title": "Building_ARANutrientDispenser.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ARANutrientDispenser\\Building_ARANutrientDispenser.cs",
"RelativeDocumentMoniker": "Buildings\\Building_ARANutrientDispenser\\Building_ARANutrientDispenser.cs",
@@ -311,7 +374,7 @@
},
{
"$type": "Document",
"DocumentIndex": 17,
"DocumentIndex": 21,
"Title": "HediffComp_DrawMoteInRange.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_DrawMoteInRange\\HediffComp_DrawMoteInRange.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_DrawMoteInRange\\HediffComp_DrawMoteInRange.cs",
@@ -323,7 +386,7 @@
},
{
"$type": "Document",
"DocumentIndex": 18,
"DocumentIndex": 22,
"Title": "CompAbilityEffect_BindDrone.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\CompAbilityEffect_BindDrone.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\CompAbilityEffect_BindDrone.cs",
@@ -335,7 +398,7 @@
},
{
"$type": "Document",
"DocumentIndex": 19,
"DocumentIndex": 23,
"Title": "CompProperties_AbilityBindDrone.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\CompProperties_AbilityBindDrone.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\CompProperties_AbilityBindDrone.cs",
@@ -347,7 +410,7 @@
},
{
"$type": "Document",
"DocumentIndex": 20,
"DocumentIndex": 24,
"Title": "Verb_ShootArc.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Verbs\\Verb_ShootArc.cs",
"RelativeDocumentMoniker": "Verbs\\Verb_ShootArc.cs",

View File

@@ -0,0 +1,271 @@
using RimWorld;
using Verse;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace ArachnaeSwarm
{
public class CompProperties_AbilityExtractGene : CompProperties_AbilityEffect
{
public int baseGeneCount = 1;
public float maxComplexity = 5f;
public bool canExtractArchiteGenes = false;
public bool allowMelaninGenes = false;
public bool targetLosesGene = false; // 是否从目标身上移除基因
// 基因数量概率曲线
public SimpleCurve geneCountChanceCurve = new SimpleCurve
{
new CurvePoint(1f, 0.7f),
new CurvePoint(2f, 0.2f),
new CurvePoint(3f, 0.08f),
new CurvePoint(4f, 0.02f)
};
public CompProperties_AbilityExtractGene()
{
this.compClass = typeof(CompAbilityEffect_ExtractGene);
}
}
public class CompAbilityEffect_ExtractGene : CompAbilityEffect
{
public new CompProperties_AbilityExtractGene Props => (CompProperties_AbilityExtractGene)this.props;
public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
{
base.Apply(target, dest);
Pawn caster = parent.pawn;
Pawn targetPawn = target.Pawn;
if (caster == null || targetPawn == null)
return;
// 检查目标是否有基因
if (targetPawn.genes == null || !targetPawn.genes.GenesListForReading.Any())
{
Messages.Message("TargetHasNoGenes".Translate(targetPawn.Named("TARGET")), targetPawn, MessageTypeDefOf.RejectInput);
return;
}
// 获取可提取的基因列表
List<Gene> availableGenes = GetExtractableGenes(targetPawn);
if (!availableGenes.Any())
{
Messages.Message("NoExtractableGenes".Translate(targetPawn.Named("TARGET")), targetPawn, MessageTypeDefOf.RejectInput);
return;
}
// 确定要提取的基因数量
int geneCount = DetermineGeneCount(availableGenes.Count);
// 选择基因
List<GeneDef> genesToAdd = SelectGenesToExtract(availableGenes, geneCount, caster);
if (!genesToAdd.Any())
{
Messages.Message("FailedToExtractGenes".Translate(), caster, MessageTypeDefOf.NegativeEvent);
return;
}
// 应用基因效果
ApplyGeneExtraction(caster, targetPawn, genesToAdd);
// 显示消息
ShowExtractionMessage(caster, targetPawn, genesToAdd);
}
/// <summary>
/// 获取可提取的基因列表
/// </summary>
private List<Gene> GetExtractableGenes(Pawn target)
{
return target.genes.GenesListForReading.Where(gene =>
{
// 检查是否可以提取Archite基因
if (!Props.canExtractArchiteGenes && gene.def.biostatArc > 0)
return false;
// 检查是否允许提取黑色素基因
if (!Props.allowMelaninGenes && gene.def.endogeneCategory == EndogeneCategory.Melanin)
return false;
// 检查复杂度限制
if (gene.def.biostatCpx > Props.maxComplexity)
return false;
return true;
}).ToList();
}
/// <summary>
/// 确定要提取的基因数量
/// </summary>
private int DetermineGeneCount(int availableGeneCount)
{
int maxPossible = Mathf.Min(availableGeneCount, 4); // 最多4个基因
// 使用概率曲线确定数量
int count = (int)Props.geneCountChanceCurve.RandomElementByWeight(point => point.y).x;
return Mathf.Min(count, maxPossible);
}
/// <summary>
/// 选择要提取的基因
/// </summary>
private List<GeneDef> SelectGenesToExtract(List<Gene> availableGenes, int geneCount, Pawn caster)
{
List<GeneDef> selectedGenes = new List<GeneDef>();
List<Gene> remainingGenes = new List<Gene>(availableGenes);
for (int i = 0; i < geneCount && remainingGenes.Count > 0; i++)
{
// 使用权重选择基因
if (remainingGenes.TryRandomElementByWeight(gene => GetGeneSelectionWeight(gene, selectedGenes, caster), out Gene selectedGene))
{
selectedGenes.Add(selectedGene.def);
remainingGenes.Remove(selectedGene);
}
}
return selectedGenes;
}
/// <summary>
/// 获取基因选择权重
/// </summary>
private float GetGeneSelectionWeight(Gene gene, List<GeneDef> alreadySelected, Pawn caster)
{
// 如果已经选择了这个基因权重为0
if (alreadySelected.Contains(gene.def))
return 0f;
// 检查施法者是否已经有这个基因
if (caster.genes.HasActiveGene(gene.def))
return 0f;
// 复杂基因有更高权重
if (gene.def.biostatCpx > 0)
return 3f;
return 1f;
}
/// <summary>
/// 应用基因提取效果
/// </summary>
private void ApplyGeneExtraction(Pawn caster, Pawn target, List<GeneDef> genesToAdd)
{
// 给施法者添加基因(作为内源基因)
foreach (GeneDef geneDef in genesToAdd)
{
if (!caster.genes.HasActiveGene(geneDef))
{
caster.genes.AddGene(geneDef, xenogene: false);
}
}
// 如果配置为从目标身上移除基因
if (Props.targetLosesGene)
{
foreach (GeneDef geneDef in genesToAdd)
{
Gene geneToRemove = target.genes.GetGene(geneDef);
if (geneToRemove != null)
{
target.genes.RemoveGene(geneToRemove);
}
}
}
}
/// <summary>
/// 显示提取消息
/// </summary>
private void ShowExtractionMessage(Pawn caster, Pawn target, List<GeneDef> genesAdded)
{
if (genesAdded.Count > 0)
{
string geneList = genesAdded.Select(g => g.label).ToCommaList().CapitalizeFirst();
string message = "ARAGeneExtractionComplete".Translate(caster.Named("CASTER"), target.Named("TARGET")) + ": " + geneList;
Messages.Message(message, new LookTargets(caster, target), MessageTypeDefOf.PositiveEvent);
}
else
{
Messages.Message("ARAGeneExtractionFailed".Translate(), caster, MessageTypeDefOf.NegativeEvent);
}
}
public override bool Valid(LocalTargetInfo target, bool throwMessages = false)
{
Pawn targetPawn = target.Pawn;
if (targetPawn == null)
{
if (throwMessages)
Messages.Message("AbilityMustTargetPawn".Translate(), target.ToTargetInfo(parent.pawn.Map), MessageTypeDefOf.RejectInput);
return false;
}
// 检查目标是否有人类基因
if (!targetPawn.RaceProps.Humanlike)
{
if (throwMessages)
Messages.Message("TargetMustBeHumanlike".Translate(), targetPawn, MessageTypeDefOf.RejectInput);
return false;
}
// 检查目标是否有基因
if (targetPawn.genes == null || !targetPawn.genes.GenesListForReading.Any())
{
if (throwMessages)
Messages.Message("TargetHasNoGenes".Translate(targetPawn.Named("TARGET")), targetPawn, MessageTypeDefOf.RejectInput);
return false;
}
// 检查是否有可提取的基因
if (!GetExtractableGenes(targetPawn).Any())
{
if (throwMessages)
Messages.Message("NoExtractableGenes".Translate(targetPawn.Named("TARGET")), targetPawn, MessageTypeDefOf.RejectInput);
return false;
}
// 检查施法者基因容量
if (!CanCasterAcceptMoreGenes())
{
if (throwMessages)
Messages.Message("CasterAtGeneCapacity".Translate(parent.pawn.Named("CASTER")), parent.pawn, MessageTypeDefOf.RejectInput);
return false;
}
return base.Valid(target, throwMessages);
}
/// <summary>
/// 检查施法者是否可以接受更多基因
/// </summary>
private bool CanCasterAcceptMoreGenes()
{
// 这里可以添加基因容量检查逻辑
// 暂时返回true可以根据需要修改
return true;
}
public override string ExtraLabelMouseAttachment(LocalTargetInfo target)
{
Pawn targetPawn = target.Pawn;
if (targetPawn != null && targetPawn.genes != null)
{
int extractableCount = GetExtractableGenes(targetPawn).Count;
return "ExtractableGenesCount".Translate(extractableCount);
}
return base.ExtraLabelMouseAttachment(target);
}
}
}

View File

@@ -0,0 +1,230 @@
using RimWorld;
using Verse;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace ArachnaeSwarm
{
public class CompAbilityEffect_InjectGenes : CompAbilityEffect
{
public new CompProperties_AbilityInjectGenes Props => (CompProperties_AbilityInjectGenes)this.props;
public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
{
base.Apply(target, dest);
Pawn caster = parent.pawn;
Pawn targetPawn = target.Pawn;
if (caster == null || targetPawn == null)
return;
// 检查施法者是否有基因
if (caster.genes == null || !caster.genes.GenesListForReading.Any())
{
Messages.Message("CasterHasNoGenes".Translate(caster.Named("CASTER")), caster, MessageTypeDefOf.RejectInput);
return;
}
// 获取施法者可注入的基因列表(原生基因)
List<Gene> genesToTransfer = GetTransferableGenes(caster);
if (!genesToTransfer.Any())
{
Messages.Message("NoTransferableGenes".Translate(caster.Named("CASTER")), caster, MessageTypeDefOf.RejectInput);
return;
}
// 检查目标是否可以接受这些基因
if (!CanTargetAcceptGenes(targetPawn, genesToTransfer))
{
Messages.Message("TargetCannotAcceptGenes".Translate(targetPawn.Named("TARGET")), targetPawn, MessageTypeDefOf.RejectInput);
return;
}
// 执行基因转移
PerformGeneTransfer(caster, targetPawn, genesToTransfer);
// 显示消息
ShowTransferMessage(caster, targetPawn, genesToTransfer);
}
/// <summary>
/// 获取可转移的基因列表(施法者的原生基因)
/// </summary>
private List<Gene> GetTransferableGenes(Pawn caster)
{
return caster.genes.GenesListForReading.Where(gene =>
{
// 检查是否包括Archite基因
if (!Props.includeArchiteGenes && gene.def.biostatArc > 0)
return false;
// 检查是否包括黑色素基因
if (!Props.includeMelaninGenes && gene.def.endogeneCategory == EndogeneCategory.Melanin)
return false;
// 检查复杂度限制
if (gene.def.biostatCpx > Props.maxComplexity)
return false;
return true;
}).ToList();
}
/// <summary>
/// 检查目标是否可以接受这些基因
/// </summary>
private bool CanTargetAcceptGenes(Pawn target, List<Gene> genesToTransfer)
{
if (target.genes == null)
return false;
// 检查每个基因是否可以被目标接受
foreach (var gene in genesToTransfer)
{
// 如果目标已经有这个基因且不允许重复,则不能接受
if (!Props.allowDuplicateGenes && target.genes.HasActiveGene(gene.def))
return false;
// 检查生物统计值限制
// 这里可以添加更复杂的容量检查
}
return true;
}
/// <summary>
/// 执行基因转移
/// </summary>
private void PerformGeneTransfer(Pawn caster, Pawn target, List<Gene> genesToTransfer)
{
List<GeneDef> transferredGenes = new List<GeneDef>();
// 按特定顺序处理基因(先添加后移除,避免出现问题)
foreach (Gene gene in genesToTransfer)
{
GeneDef geneDef = gene.def;
try
{
// 给目标添加基因(作为原生基因)
if (!target.genes.HasActiveGene(geneDef))
{
target.genes.AddGene(geneDef, xenogene: false);
transferredGenes.Add(geneDef);
}
else if (Props.allowDuplicateGenes)
{
// 如果允许重复,仍然记录但可能不重复添加
transferredGenes.Add(geneDef);
}
// 从施法者移除基因
if (caster.genes.HasActiveGene(geneDef))
{
Gene geneToRemove = caster.genes.GetGene(geneDef);
if (geneToRemove != null)
{
caster.genes.RemoveGene(geneToRemove);
}
}
}
catch (System.Exception ex)
{
Log.Error($"Error transferring gene {geneDef.defName}: {ex}");
}
}
}
/// <summary>
/// 显示转移消息
/// </summary>
private void ShowTransferMessage(Pawn caster, Pawn target, List<Gene> transferredGenes)
{
if (transferredGenes.Count > 0)
{
string geneList = transferredGenes.Select(g => g.def.label).ToCommaList().CapitalizeFirst();
string message = "ARA_GeneInjectionComplete".Translate(caster.Named("CASTER"), target.Named("TARGET")) + ": " + geneList;
Messages.Message(message, new LookTargets(caster, target), MessageTypeDefOf.PositiveEvent);
if (Prefs.DevMode)
{
Log.Message($"Gene injection: {caster.Label} transferred {transferredGenes.Count} genes to {target.Label}");
}
}
else
{
Messages.Message("ARA_GeneInjectionFailed".Translate(), caster, MessageTypeDefOf.NegativeEvent);
}
}
public override bool Valid(LocalTargetInfo target, bool throwMessages = false)
{
Pawn targetPawn = target.Pawn;
if (targetPawn == null)
{
if (throwMessages)
Messages.Message("AbilityMustTargetPawn".Translate(), target.ToTargetInfo(parent.pawn.Map), MessageTypeDefOf.RejectInput);
return false;
}
// 检查目标是否有人类基因
if (!targetPawn.RaceProps.Humanlike)
{
if (throwMessages)
Messages.Message("TargetMustBeHumanlike".Translate(), targetPawn, MessageTypeDefOf.RejectInput);
return false;
}
// 检查施法者是否有可转移的基因
if (parent.pawn.genes == null || !GetTransferableGenes(parent.pawn).Any())
{
if (throwMessages)
Messages.Message("CasterHasNoTransferableGenes".Translate(parent.pawn.Named("CASTER")), parent.pawn, MessageTypeDefOf.RejectInput);
return false;
}
// 检查目标是否可以接受基因
List<Gene> transferableGenes = GetTransferableGenes(parent.pawn);
if (!CanTargetAcceptGenes(targetPawn, transferableGenes))
{
if (throwMessages)
Messages.Message("TargetCannotAcceptGenes".Translate(targetPawn.Named("TARGET")), targetPawn, MessageTypeDefOf.RejectInput);
return false;
}
return base.Valid(target, throwMessages);
}
public override string ExtraLabelMouseAttachment(LocalTargetInfo target)
{
Pawn targetPawn = target.Pawn;
Pawn caster = parent.pawn;
if (targetPawn != null && caster != null && caster.genes != null)
{
int transferableCount = GetTransferableGenes(caster).Count;
int targetHasCount = 0;
if (!Props.allowDuplicateGenes && targetPawn.genes != null)
{
var transferableGenes = GetTransferableGenes(caster);
targetHasCount = transferableGenes.Count(g => targetPawn.genes.HasActiveGene(g.def));
}
string baseText = "TransferableGenesCount".Translate(transferableCount);
if (targetHasCount > 0)
{
baseText += " (" + "TargetHasGenesCount".Translate(targetHasCount) + ")";
}
return baseText;
}
return base.ExtraLabelMouseAttachment(target);
}
}
}

View File

@@ -0,0 +1,31 @@
using RimWorld;
using Verse;
namespace ArachnaeSwarm
{
public class CompProperties_AbilityInjectGenes : CompProperties_AbilityEffect
{
// 是否包括Archite基因
public bool includeArchiteGenes = false;
// 是否包括黑色素基因
public bool includeMelaninGenes = false;
// 施法者失去基因后是否获得负面效果
public bool casterGetsNegativeEffect = true;
// 目标获得基因后是否获得正面效果
public bool targetGetsPositiveEffect = true;
// 是否允许向已有相同基因的目标注入
public bool allowDuplicateGenes = false;
// 最大复杂度限制
public float maxComplexity = 10f;
public CompProperties_AbilityInjectGenes()
{
this.compClass = typeof(CompAbilityEffect_InjectGenes);
}
}
}

View File

@@ -75,6 +75,9 @@
<Compile Include="Abilities\ARA_AddExtraExp\CompProperties_AddExtraExp.cs" />
<Compile Include="Abilities\ARA_DestroyOwnBodyPart\CompAbilityEffect_DestroyOwnBodyPart.cs" />
<Compile Include="Abilities\ARA_DestroyOwnBodyPart\CompProperties_AbilityDestroyOwnBodyPart.cs" />
<Compile Include="Abilities\ARA_Genestealer\CompAbilityEffect_ExtractGene.cs" />
<Compile Include="Abilities\ARA_Genestealer\CompAbilityEffect_InjectGenes.cs" />
<Compile Include="Abilities\ARA_Genestealer\CompProperties_AbilityInjectGenes.cs" />
<Compile Include="Abilities\ARA_GiveHediffWithSkillDuration\CompAbilityEffect_GiveHediffWithSkillDuration.cs" />
<Compile Include="Abilities\ARA_GiveHediffWithSkillDuration\CompProperties_GiveHediffWithSkillDuration.cs" />
<Compile Include="Abilities\ARA_HediffRestriction\CompAbilityEffect_HediffRestriction.cs" />

View File

@@ -13,18 +13,62 @@ namespace ArachnaeSwarm
{
var harmony = new Harmony("ArachnaeSwarm.Mod");
harmony.PatchAll();
// 初始化全局变量管理器
GlobalVariableManager.Initialize();
}
}
[HarmonyPatch(typeof(Game), "ExposeData")]
public static class Game_ExposeData_Patch
{
public static void Postfix()
public static void Postfix(Game __instance)
{
GlobalVariableManager.ExposeData();
}
}
// 新增:在游戏开始或结束时清理变量
[HarmonyPatch(typeof(Game), "InitNewGame")]
public static class Game_InitNewGame_Patch
{
public static void Postfix()
{
// 新游戏开始时清理所有变量
GlobalVariableManager.ClearAllVariables();
if (Prefs.DevMode)
{
Log.Message("GlobalVariableManager: Cleared all variables for new game");
}
}
}
// 新增:在游戏加载时确保变量正确
[HarmonyPatch(typeof(Game), "LoadGame")]
public static class Game_LoadGame_Patch
{
public static void Postfix()
{
// 确保变量管理器已初始化
GlobalVariableManager.Initialize();
if (Prefs.DevMode)
{
Log.Message("GlobalVariableManager: Initialized for loaded game");
}
}
}
// 新增:在返回主菜单时清理变量
[HarmonyPatch(typeof(Game), "FinalizeInit")]
public static class Game_FinalizeInit_Patch
{
public static void Postfix()
{
// 确保变量管理器已初始化
GlobalVariableManager.Initialize();
}
}
// 复活拦截补丁
[HarmonyPatch]
public static class ResurrectionUtility_Patch
@@ -140,12 +184,17 @@ namespace ArachnaeSwarm
private static HashSet<string> _globalVariables;
private static bool _initialized = false;
private static void EnsureInitialized()
public static void Initialize()
{
if (!_initialized)
{
_globalVariables = new HashSet<string>();
_initialized = true;
if (Prefs.DevMode)
{
Log.Message("GlobalVariableManager: Initialized");
}
}
}
@@ -153,13 +202,20 @@ namespace ArachnaeSwarm
{
try
{
// 确保在保存或加载前已初始化
Initialize();
if (Scribe.mode == LoadSaveMode.Saving)
{
EnsureInitialized();
if (_globalVariables.Count > 0)
{
List<string> variablesList = new List<string>(_globalVariables);
Scribe_Collections.Look(ref variablesList, "ArachnaeSwarm_GlobalVariables", LookMode.Value);
if (Prefs.DevMode)
{
Log.Message($"GlobalVariableManager: Saved {_globalVariables.Count} variables");
}
}
}
else if (Scribe.mode == LoadSaveMode.LoadingVars)
@@ -170,12 +226,19 @@ namespace ArachnaeSwarm
if (variablesList != null)
{
_globalVariables = new HashSet<string>(variablesList);
if (Prefs.DevMode)
{
Log.Message($"GlobalVariableManager: Loaded {_globalVariables.Count} variables");
}
}
else
{
_globalVariables = new HashSet<string>();
if (Prefs.DevMode)
{
Log.Message("GlobalVariableManager: No variables found in save, initializing empty set");
}
}
_initialized = true;
}
}
catch (System.Exception ex)
@@ -186,32 +249,50 @@ namespace ArachnaeSwarm
public static bool HasVariable(string variable)
{
EnsureInitialized();
Initialize();
return _globalVariables.Contains(variable);
}
public static void SetVariable(string variable)
{
EnsureInitialized();
Initialize();
_globalVariables.Add(variable);
if (Prefs.DevMode)
{
Log.Message($"GlobalVariableManager: Added variable '{variable}'");
}
}
public static bool RemoveVariable(string variable)
{
EnsureInitialized();
return _globalVariables.Remove(variable);
Initialize();
bool removed = _globalVariables.Remove(variable);
if (removed && Prefs.DevMode)
{
Log.Message($"GlobalVariableManager: Removed variable '{variable}'");
}
return removed;
}
public static IEnumerable<string> GetAllVariables()
{
EnsureInitialized();
Initialize();
return _globalVariables;
}
public static void ClearAllVariables()
{
EnsureInitialized();
Initialize();
int count = _globalVariables.Count;
_globalVariables.Clear();
if (Prefs.DevMode)
{
Log.Message($"GlobalVariableManager: Cleared {count} variables");
}
}
}
}

View File

@@ -9,6 +9,11 @@ namespace ArachnaeSwarm
public float cleaveDamageFactor = 0.7f;
public bool damageDowned = false;
public DamageDef explosionDamageDef = null;
// 新增:攻击特效
public EffecterDef attackEffecter = null;
public EffecterDef cleaveEffecter = null;
public SoundDef attackSound = null;
public CompProperties_Cleave()
{
@@ -20,4 +25,4 @@ namespace ArachnaeSwarm
{
public CompProperties_Cleave Props => (CompProperties_Cleave)this.props;
}
}
}

View File

@@ -26,6 +26,9 @@ namespace ArachnaeSwarm
DamageWorker.DamageResult result = new DamageWorker.DamageResult();
// 播放攻击特效
PlayAttackEffecter(target);
// 1. 对主目标造成伤害
DamageInfo dinfo = new DamageInfo(
this.verbProps.meleeDamageDef,
@@ -104,6 +107,45 @@ namespace ArachnaeSwarm
return result;
}
/// <summary>
/// 播放攻击特效
/// </summary>
private void PlayAttackEffecter(LocalTargetInfo target)
{
if (this.CasterPawn == null || this.CasterPawn.Map == null)
return;
// 播放攻击特效
if (this.Comp.Props.attackEffecter != null)
{
Effecter attackEffect = this.Comp.Props.attackEffecter.Spawn();
attackEffect.Trigger(new TargetInfo(this.CasterPawn.Position, this.CasterPawn.Map), target.ToTargetInfo(this.CasterPawn.Map));
attackEffect.Cleanup();
}
// 播放溅射特效
if (this.Comp.Props.cleaveEffecter != null && target.HasThing)
{
PlayCleaveEffecter(target.Thing);
}
}
/// <summary>
/// 播放溅射特效
/// </summary>
private void PlayCleaveEffecter(Thing mainTarget)
{
if (this.CasterPawn == null || this.CasterPawn.Map == null || mainTarget == null)
return;
Pawn casterPawn = this.CasterPawn;
// 播放主要的溅射特效
Effecter cleaveEffect = this.Comp.Props.cleaveEffecter.Spawn();
cleaveEffect.Trigger(new TargetInfo(casterPawn.Position, casterPawn.Map), new TargetInfo(mainTarget.Position, casterPawn.Map));
cleaveEffect.Cleanup();
}
private void CreateCleaveExplosion(Pawn caster, Thing target, float radius, float angle)
{
if (caster.Map == null || this.Comp.Props.explosionDamageDef == null) return;
@@ -177,4 +219,4 @@ namespace ArachnaeSwarm
}).ToList();
}
}
}
}