diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index b704dc5..66aeeb5 100644 Binary files a/1.6/1.6/Assemblies/ArachnaeSwarm.dll and b/1.6/1.6/Assemblies/ArachnaeSwarm.dll differ diff --git a/1.6/1.6/Defs/AbilityDefs/ARA_Abilities.xml b/1.6/1.6/Defs/AbilityDefs/ARA_Abilities.xml index 499156f..7873e2a 100644 --- a/1.6/1.6/Defs/AbilityDefs/ARA_Abilities.xml +++ b/1.6/1.6/Defs/AbilityDefs/ARA_Abilities.xml @@ -902,6 +902,104 @@ + + ARA_Genestealer_ExtractGene + + 畸变种从目标的基因库中抽取1-4个基因(包括超凡基因)加入自己的基因序列,被抽取的目标虽然不会死亡,但是将失去此基因,并从此一蹶不振,无法再从昏迷中醒来。 + ArachnaeSwarm/UI/Abilities/ARA_Genestealer_ExtractGene + 50000 + false + true + Mote_HoraxSmallSpellWarmup + HoraxianAbilityCasting + AnomalyAbilityWarmup + CastAbilityOnThingMelee + + Verb_CastAbilityTouch + false + -1 + 5 + + true + false + false + false + + + +
  • + 饮食 + true + Food + 1 + 营养值不足,需要进食 +
  • +
  • + CompAbilityEffect_GiveHediff + ARA_Genestealer_ExtractGene_Hediff + true +
  • +
  • + 1 + 5 + true + false + true + + +
  • (1, 0.7)
  • +
  • (2, 0.2)
  • +
  • (3, 0.08)
  • +
  • (4, 0.02)
  • +
  • (5, 0)
  • + + + +
    +
    + + ARA_Genestealer_InjectGenes + + 畸变种尝试将自身的基因全部注入到目标体内。 + ArachnaeSwarm/UI/Abilities/ARA_Genestealer_InjectGenes + 1 + false + true + Mote_HoraxSmallSpellWarmup + HoraxianAbilityCasting + AnomalyAbilityWarmup + CastAbilityOnThingMelee + + Verb_CastAbilityTouch + false + -1 + 3 + + true + false + false + false + + + +
  • + 饮食 + true + Food + 1 + 营养值不足,需要进食 +
  • +
  • + true + false + true + true + false + 10 +
  • +
    +
    + ARA_TerrainHeal_Ability diff --git a/1.6/1.6/Defs/Effects/ARA_Flecks.xml b/1.6/1.6/Defs/Effects/ARA_Flecks.xml index c022d9d..c8ff334 100644 --- a/1.6/1.6/Defs/Effects/ARA_Flecks.xml +++ b/1.6/1.6/Defs/Effects/ARA_Flecks.xml @@ -133,6 +133,63 @@ 0.1 + + ARA_Mote_Melee_Attack_Main + 1.0 + MoteOverheadLow + 0 + 0 + 0.6 + true + +
  • + ArachnaeSwarm/Mote/ARA_Melee_Attack + MoteGlow + true + Graphic_Fleck +
  • + +
    +
    + + ARA_Melee_Attack_Hit + +
  • + SubEffecter_Random + +
  • + SubEffecter_SprayerTriggered + ARA_Mote_Melee_Attack_Main + 1 + (170,74,68) + 3.5~4.5 + 0.5 + -35~35 + OnSource + true +
  • +
  • + SubEffecter_SprayerTriggered + ARA_Mote_Melee_Attack_Main + 1 + (147,50,28) + 2.5~3.5 + 0.5 + -15~15 + OnSource + true +
  • +
    + + + 0.1 +
    + ARA_Fleck_Icez_Cloud diff --git a/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml b/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml index c91a685..a79ea2d 100644 --- a/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml +++ b/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml @@ -721,11 +721,13 @@
  • ARA_AcidSprayBurst
  • ARA_Toxic_Needle_Fire
  • ARA_Fighter_Invisibility
  • +
  • ARA_Fighter_Genestealer
  • ARA_Fighter_Invisibility
  • +
  • ARA_Fighter_Genestealer
  • @@ -815,6 +817,77 @@
  • + + ARA_Fighter_Genestealer + + 使战士种发生内驱性进化,损害其战斗能力和使用技能的能力,以换取从敌人身上窃取基因、向己方殖民者注入基因和诱发非虫族殖民者虫族化的能力。\n\n该进化过程不可逆! + ArachnaeSwarm/UI/Abilities/ARA_Fighter_Genestealer + 1800 + false + true + true + false + false + true + false + CastAbilityOnThing + + Verb_CastAbility + 1 + 12 + AcidSpray_Resolve + false + false + + True + + + +
  • + CompAbilityEffect_GiveHediff + ARA_Fighter_Genestealer + True + true + 1 +
  • +
  • + +
  • + Melee + None + -350000 +
  • +
  • + Shooting + None + -350000 +
  • + + +
  • + ARA_Technology_4CLO + 需要科技 节点CLO-4"追猎种" 以解锁进化 +
  • + +
    + + ARA_Fighter_Genestealer + HediffWithComps + + 畸变种是移动的基因库,她们在虫群中不再担任刀剑舔血的工作,而是专注于提纯囚犯和奴隶的优质基因,并将其赋予虫族中的高质量个体。她们也拥有引发非虫族殖民者器官虫族化的能力,以使得那些没有用处的异族能那么稍微对虫巢做出一些贡献。 + false + + + +
  • + +
  • ARA_Genestealer_ExtractGene
  • +
  • ARA_Genestealer_InjectGenes
  • + + +
  • + + diff --git a/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Damage.xml b/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Damage.xml index 7ef3f81..9f817c4 100644 --- a/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Damage.xml +++ b/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Damage.xml @@ -610,4 +610,27 @@
  • + + + ARA_Genestealer_ExtractGene_Hediff + + 阿拉克涅畸变种从该殖民者身上强制抽离了一部分基因序列,这导致该殖民者无法再维持基本生理活动。该伤害是不可逆的,即使这些基因被塞回去亦是如此。 + (1, 1, 0.8) + HediffWithComps + +
  • + + +
  • + + true + +
  • + Consciousness + 0.1 +
  • + + + +
    \ No newline at end of file diff --git a/1.6/1.6/Defs/ResearchProjectDefs/ARA_ResearchProjects.xml b/1.6/1.6/Defs/ResearchProjectDefs/ARA_ResearchProjects.xml index 66e737b..ad60d21 100644 --- a/1.6/1.6/Defs/ResearchProjectDefs/ARA_ResearchProjects.xml +++ b/1.6/1.6/Defs/ResearchProjectDefs/ARA_ResearchProjects.xml @@ -590,6 +590,18 @@ + + ARA_Technology_5STL + + 允许战士种进行定向进化,抛弃其战斗技能以换取其从殖民者、囚犯和奴隶身上抽取和注入基因的能力,并且可以主动诱发非虫族殖民者的虫化变异。\n\n阿拉克涅虫群所有需要蓝图的科技,其蓝图只能通过女皇种的基因试验卵获取。 + 500 + 2.00 + 5.40 + ARA_ResearchBench + +
  • ARA_Technology_1KYC
  • +
    +
    ARA_Technology_1VTE diff --git a/1.6/1.6/Defs/StoryTellers/ARA_Storytellers.xml b/1.6/1.6/Defs/StoryTellers/ARA_Storytellers.xml index 26545dd..c644ba4 100644 --- a/1.6/1.6/Defs/StoryTellers/ARA_Storytellers.xml +++ b/1.6/1.6/Defs/StoryTellers/ARA_Storytellers.xml @@ -19,9 +19,9 @@
  • ThreatBig - 15.0 - 2 - 9 + 0 + 1 + 2 0.25 2~3 @@ -32,8 +32,8 @@
  • ThreatSmall 11.0 - 4.6 - 6.0 + 2 + 2.0 0.2~1 diff --git a/1.6/1.6/Defs/Thing_Misc/Weapons/ARA_Weapon.xml b/1.6/1.6/Defs/Thing_Misc/Weapons/ARA_Weapon.xml index 2ac1fef..467f862 100644 --- a/1.6/1.6/Defs/Thing_Misc/Weapons/ARA_Weapon.xml +++ b/1.6/1.6/Defs/Thing_Misc/Weapons/ARA_Weapon.xml @@ -235,6 +235,8 @@ 0.5 false Cut + ARA_Melee_Attack_Hit + ARA_Melee_Attack_Hit
  • diff --git a/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/ArachnaeSwarm_Keys.xml b/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/ArachnaeSwarm_Keys.xml index 4de987c..31fea5f 100644 --- a/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/ArachnaeSwarm_Keys.xml +++ b/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/ArachnaeSwarm_Keys.xml @@ -98,4 +98,21 @@ 没有来自更高级节点的允许,{0} 将从基因层面拒绝任何复活。 孵化期间无法重新安装 + + {CASTER} 已经从 {TARGET} 的身上窃取基因 + 基因提取失败 + 必须瞄准类人种族 + 目标必须拥有可提取的基因 + 目标拥有特殊基因,但是没有提取价值 + {CASTER} 的基因序列容量达到上限 + 可窃取的基因数量:{0} + + {CASTER}将基因注入了{TARGET} + 基因注入失败 + {CASTER}没有可注入的基因 + {CASTER}没有符合要求的可转移基因 + {TARGET}无法接受这些基因 + {CASTER}没有可转移的基因 + 可转移基因数: {0} + 目标已有: {0} \ No newline at end of file diff --git a/Content/Textures/ArachnaeSwarm/Mote/ARA_Melee_Attack.png b/Content/Textures/ArachnaeSwarm/Mote/ARA_Melee_Attack.png new file mode 100644 index 0000000..79aab89 Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Mote/ARA_Melee_Attack.png differ diff --git a/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Fighter_Genestealer.png b/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Fighter_Genestealer.png new file mode 100644 index 0000000..502be7b Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Fighter_Genestealer.png differ diff --git a/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Genestealer_ExtractGene.png b/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Genestealer_ExtractGene.png new file mode 100644 index 0000000..e8c2cf6 Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Genestealer_ExtractGene.png differ diff --git a/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Genestealer_InjectGenes.png b/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Genestealer_InjectGenes.png new file mode 100644 index 0000000..43886f3 Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Genestealer_InjectGenes.png differ diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo index 90299ff..e1e38a5 100644 Binary files a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo and b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo differ diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json index 0a85c73..e30551f 100644 --- a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json +++ b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json @@ -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", diff --git a/Source/ArachnaeSwarm/Abilities/ARA_Genestealer/CompAbilityEffect_ExtractGene.cs b/Source/ArachnaeSwarm/Abilities/ARA_Genestealer/CompAbilityEffect_ExtractGene.cs new file mode 100644 index 0000000..8f9fbaf --- /dev/null +++ b/Source/ArachnaeSwarm/Abilities/ARA_Genestealer/CompAbilityEffect_ExtractGene.cs @@ -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 availableGenes = GetExtractableGenes(targetPawn); + + if (!availableGenes.Any()) + { + Messages.Message("NoExtractableGenes".Translate(targetPawn.Named("TARGET")), targetPawn, MessageTypeDefOf.RejectInput); + return; + } + + // 确定要提取的基因数量 + int geneCount = DetermineGeneCount(availableGenes.Count); + + // 选择基因 + List genesToAdd = SelectGenesToExtract(availableGenes, geneCount, caster); + + if (!genesToAdd.Any()) + { + Messages.Message("FailedToExtractGenes".Translate(), caster, MessageTypeDefOf.NegativeEvent); + return; + } + + // 应用基因效果 + ApplyGeneExtraction(caster, targetPawn, genesToAdd); + + // 显示消息 + ShowExtractionMessage(caster, targetPawn, genesToAdd); + } + + /// + /// 获取可提取的基因列表 + /// + private List 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(); + } + + /// + /// 确定要提取的基因数量 + /// + 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); + } + + /// + /// 选择要提取的基因 + /// + private List SelectGenesToExtract(List availableGenes, int geneCount, Pawn caster) + { + List selectedGenes = new List(); + List remainingGenes = new List(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; + } + + /// + /// 获取基因选择权重 + /// + private float GetGeneSelectionWeight(Gene gene, List 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; + } + + /// + /// 应用基因提取效果 + /// + private void ApplyGeneExtraction(Pawn caster, Pawn target, List 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); + } + } + } + } + + /// + /// 显示提取消息 + /// + private void ShowExtractionMessage(Pawn caster, Pawn target, List 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); + } + + /// + /// 检查施法者是否可以接受更多基因 + /// + 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); + } + } +} diff --git a/Source/ArachnaeSwarm/Abilities/ARA_Genestealer/CompAbilityEffect_InjectGenes.cs b/Source/ArachnaeSwarm/Abilities/ARA_Genestealer/CompAbilityEffect_InjectGenes.cs new file mode 100644 index 0000000..3933bc6 --- /dev/null +++ b/Source/ArachnaeSwarm/Abilities/ARA_Genestealer/CompAbilityEffect_InjectGenes.cs @@ -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 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); + } + + /// + /// 获取可转移的基因列表(施法者的原生基因) + /// + private List 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(); + } + + /// + /// 检查目标是否可以接受这些基因 + /// + private bool CanTargetAcceptGenes(Pawn target, List genesToTransfer) + { + if (target.genes == null) + return false; + + // 检查每个基因是否可以被目标接受 + foreach (var gene in genesToTransfer) + { + // 如果目标已经有这个基因且不允许重复,则不能接受 + if (!Props.allowDuplicateGenes && target.genes.HasActiveGene(gene.def)) + return false; + + // 检查生物统计值限制 + // 这里可以添加更复杂的容量检查 + } + + return true; + } + + /// + /// 执行基因转移 + /// + private void PerformGeneTransfer(Pawn caster, Pawn target, List genesToTransfer) + { + List transferredGenes = new List(); + + // 按特定顺序处理基因(先添加后移除,避免出现问题) + 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}"); + } + } + } + + /// + /// 显示转移消息 + /// + private void ShowTransferMessage(Pawn caster, Pawn target, List 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 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); + } + } +} diff --git a/Source/ArachnaeSwarm/Abilities/ARA_Genestealer/CompProperties_AbilityInjectGenes.cs b/Source/ArachnaeSwarm/Abilities/ARA_Genestealer/CompProperties_AbilityInjectGenes.cs new file mode 100644 index 0000000..a162d78 --- /dev/null +++ b/Source/ArachnaeSwarm/Abilities/ARA_Genestealer/CompProperties_AbilityInjectGenes.cs @@ -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); + } + } +} diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj index eb193b7..d0c1ed4 100644 --- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj +++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj @@ -75,6 +75,9 @@ + + + diff --git a/Source/ArachnaeSwarm/Pawn_Comps/ARA_UniquePawn/Patch_UniquePawn.cs b/Source/ArachnaeSwarm/Pawn_Comps/ARA_UniquePawn/Patch_UniquePawn.cs index 0501f32..dace18f 100644 --- a/Source/ArachnaeSwarm/Pawn_Comps/ARA_UniquePawn/Patch_UniquePawn.cs +++ b/Source/ArachnaeSwarm/Pawn_Comps/ARA_UniquePawn/Patch_UniquePawn.cs @@ -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 _globalVariables; private static bool _initialized = false; - private static void EnsureInitialized() + public static void Initialize() { if (!_initialized) { _globalVariables = new HashSet(); _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 variablesList = new List(_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(variablesList); + if (Prefs.DevMode) + { + Log.Message($"GlobalVariableManager: Loaded {_globalVariables.Count} variables"); + } } else { _globalVariables = new HashSet(); + 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 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"); + } } } } diff --git a/Source/ArachnaeSwarm/Verbs/Cleave/CompCleave.cs b/Source/ArachnaeSwarm/Verbs/Cleave/CompCleave.cs index e969134..5966211 100644 --- a/Source/ArachnaeSwarm/Verbs/Cleave/CompCleave.cs +++ b/Source/ArachnaeSwarm/Verbs/Cleave/CompCleave.cs @@ -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; } -} \ No newline at end of file +} diff --git a/Source/ArachnaeSwarm/Verbs/Cleave/Verb_MeleeAttack_Cleave.cs b/Source/ArachnaeSwarm/Verbs/Cleave/Verb_MeleeAttack_Cleave.cs index a4a7bfa..d33c45d 100644 --- a/Source/ArachnaeSwarm/Verbs/Cleave/Verb_MeleeAttack_Cleave.cs +++ b/Source/ArachnaeSwarm/Verbs/Cleave/Verb_MeleeAttack_Cleave.cs @@ -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; } + /// + /// 播放攻击特效 + /// + 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); + } + } + + /// + /// 播放溅射特效 + /// + 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(); } } -} \ No newline at end of file +} diff --git a/非公开资源/Content/Textures/Mote/ARA_Melee_Attack.sai2 b/非公开资源/Content/Textures/Mote/ARA_Melee_Attack.sai2 new file mode 100644 index 0000000..1ab8f9b Binary files /dev/null and b/非公开资源/Content/Textures/Mote/ARA_Melee_Attack.sai2 differ diff --git a/非公开资源/Content/Textures/UI/Abilities/ARA_Genestealer_ExtractGene.sai2 b/非公开资源/Content/Textures/UI/Abilities/ARA_Genestealer_ExtractGene.sai2 new file mode 100644 index 0000000..1fdcf9a Binary files /dev/null and b/非公开资源/Content/Textures/UI/Abilities/ARA_Genestealer_ExtractGene.sai2 differ diff --git a/非公开资源/Content/Textures/UI/Abilities/ARA_Queen_Upgrade_1_Stage.sai2 b/非公开资源/Content/Textures/UI/Abilities/ARA_Queen_Upgrade_1_Stage.sai2 index ee59077..c6cb690 100644 Binary files a/非公开资源/Content/Textures/UI/Abilities/ARA_Queen_Upgrade_1_Stage.sai2 and b/非公开资源/Content/Textures/UI/Abilities/ARA_Queen_Upgrade_1_Stage.sai2 differ