diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index f6f3ec5..b45d123 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/EvolutionDefs/ARA_Evolution.xml b/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml index 4ce4245..c91a685 100644 --- a/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml +++ b/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml @@ -1469,8 +1469,29 @@ 0 true +
  • + ARA_Mote_Hivelord_Turret_Range + true +
  • + + ARA_Mote_Hivelord_Turret_Range + MoteAttached + LightingOverlay + true + + 9999999 + true + + + Graphic_Mote + Things/Mote/CombatCommandMask + MoteGlow + (32, 17, 0, 255) + 66 + + ARA_Skyraider_Empthrower @@ -1559,8 +1580,29 @@ 0 true +
  • + ARA_Mote_Empthrower_Turret_Range + true +
  • + + ARA_Mote_Empthrower_Turret_Range + MoteAttached + LightingOverlay + true + + 9999999 + true + + + Graphic_Mote + Things/Mote/CombatCommandMask + MoteGlow + (13, 191, 200, 25) + 51 + + diff --git a/1.6/1.6/Defs/FactionDefs/ARA_Factions_Hostile_Hive.xml b/1.6/1.6/Defs/FactionDefs/ARA_Factions_Hostile_Hive.xml index f0cc427..86befdc 100644 --- a/1.6/1.6/Defs/FactionDefs/ARA_Factions_Hostile_Hive.xml +++ b/1.6/1.6/Defs/FactionDefs/ARA_Factions_Hostile_Hive.xml @@ -39,10 +39,10 @@
  • (300, 0)
  • -
  • (700, 0)
  • -
  • (1400, 0)
  • -
  • (2800, 0)
  • -
  • (4000, 0)
  • +
  • (700, 1)
  • +
  • (1400, 1.8)
  • +
  • (2800, 2.2)
  • +
  • (4000, 2.6)
  • @@ -77,7 +77,7 @@ - + ARA_Hostile_Hive_RaidLootMaker
  • (35, 8)
  • @@ -85,6 +85,7 @@
  • (1000, 250)
  • (2000, 400)
  • (4000, 500)
  • +
  • (10000, 1500)
  • true @@ -96,7 +97,7 @@
  • Cloth
  • - 0 + 45 true true @@ -116,4 +117,17 @@
  • Children
  • + + ARA_Hostile_Hive_RaidLootMaker + + + + +
  • ARA_InsectJelly
  • +
  • ARA_Carapace
  • +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/1.6/1.6/Defs/ThingDef_Races/ARA_RaceQueen.xml b/1.6/1.6/Defs/ThingDef_Races/ARA_RaceQueen.xml index b61550d..db4e05a 100644 --- a/1.6/1.6/Defs/ThingDef_Races/ARA_RaceQueen.xml +++ b/1.6/1.6/Defs/ThingDef_Races/ARA_RaceQueen.xml @@ -718,6 +718,12 @@ +
  • + Unique_Arachnae_Queen + true + ARA_QueenAlreadyExists + +
  • ARA_Queen_0_Stage
  • 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 2f60ccf..2ac1fef 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 @@ -411,8 +411,8 @@ 0.5 Bullet_ARA_RW_Toxic_Needle_MG 25.9 - 36 - 2 + 28 + 4 SpitterSpit true @@ -2131,13 +2131,13 @@ None -
  • +
  • ARA_Weapon_Damage_Icez
  • diff --git a/1.6/1.6/Defs/Thing_building/ARA_Building.xml b/1.6/1.6/Defs/Thing_building/ARA_Building.xml index e520e7e..b52344f 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_Building.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_Building.xml @@ -120,10 +120,6 @@ 0.6 2 - - 2 - 1 - 10 ConstructMetal 6 diff --git a/1.6/1.6/Defs/Thing_building/ARA_InteractiveEggSac.xml b/1.6/1.6/Defs/Thing_building/ARA_InteractiveEggSac.xml index 255179a..fc9144c 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_InteractiveEggSac.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_InteractiveEggSac.xml @@ -1,7 +1,7 @@ - Building + ArachnaeSwarm.Building_Incubatable Building (1,1) @@ -21,6 +21,7 @@ false Normal Light + MinifiedThing 10 20 @@ -498,71 +499,39 @@
    - - - - ARA_Proj_EggSac_Techprint - - ArachnaeSwarm/Building/ARA_InteractiveEggSac_Techprint - Graphic_Single - - - ARA_InteractiveEggSac_Techprint - - - - ARA_InteractiveEggSac_Techprint - - 一个脆弱、易燃、黏滑的囊状物,它无法孵化任何督虫,而是可以孵化一些特定的科技蓝图,阿拉克涅女皇种可以通过与其交互将其激活。\n\n该虫卵需要使用大量精华素维持工作,并且能研究的项目以其落地时的研究完成度为准,那些尚未解锁的科技将无法孵化其蓝图。 - - 2000 - + + + ARA_InteractiveEggSac_Queen + + 用于孵化阿拉克涅女皇种的超巨型卵囊,表皮坚硬地堪比堡垒,内部蕴含的遗传物质和营养足以孵化出这个星球闻所未闻的庞然大物。 - ARA_Gene_Essence + ArachnaeQueen_Race - ArachnaeSwarm/Building/ARA_InteractiveEggSac_Techprint - Graphic_Single - (1.1,1.1) - - (0.7, 0.4, 0.7) - (0,0,-0.1) - + (0.9, 0.9 ,0.5) + (3,3) + + 1200 + + (3,3) - -
  • - 100 - 精华素 - - -
  • ARA_Gene_Essence
  • - - - 0 - false - 0.02 - 1 - 0 +
  • + 12 + (230, 230, 128, 0)
  • - -
  • - +
  • + +
  • + ARA_ArachnaeQueen + 180000 +
  • + + true - 0.2 - 1.0 - 0.06 - 30 - -
  • - -30 - 55 - 0.00005 - 0.005 - 0.001
  • @@ -1440,4 +1409,72 @@
    + + + + ARA_Proj_EggSac_Techprint + + ArachnaeSwarm/Building/ARA_InteractiveEggSac_Techprint + Graphic_Single + + + ARA_InteractiveEggSac_Techprint + + + + ARA_InteractiveEggSac_Techprint + + 一个脆弱、易燃、黏滑的囊状物,它无法孵化任何督虫,而是可以孵化一些特定的科技蓝图,阿拉克涅女皇种可以通过与其交互将其激活。\n\n该虫卵需要使用大量精华素维持工作,并且能研究的项目以其落地时的研究完成度为准,那些尚未解锁的科技将无法孵化其蓝图。 + + 2000 + + + ARA_Gene_Essence + + + ArachnaeSwarm/Building/ARA_InteractiveEggSac_Techprint + Graphic_Single + (1.1,1.1) + + (0.7, 0.4, 0.7) + (0,0,-0.1) + + + + + +
  • + 100 + 精华素 + + +
  • ARA_Gene_Essence
  • + + + 0 + false + 0.02 + 1 + 0 + + +
  • + +
  • ARA_ArachnaeQueen
  • + + true + 0.2 + 1.0 + 0.06 + 30 + +
  • + -30 + 55 + 0.00005 + 0.005 + 0.001 +
  • +
    +
    \ No newline at end of file diff --git a/1.6/1.6/Defs/Thing_building/ARA_SwarmTurret.xml b/1.6/1.6/Defs/Thing_building/ARA_SwarmTurret.xml index 0d1df17..45791ba 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_SwarmTurret.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_SwarmTurret.xml @@ -221,9 +221,6 @@ EatVegetarian Filth_Slime - - 20 - 10 4 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 82f1be2..4de987c 100644 --- a/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/ArachnaeSwarm_Keys.xml +++ b/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/ArachnaeSwarm_Keys.xml @@ -93,4 +93,9 @@ 需要{0}才能开始研究生产 可用的研究项目 生产完成:{0}个{1}({2}研究所需) + + 新诞生女皇种被基因性痉挛杀死了——由于阿拉克涅虫群在蜂巢意识层面上的结构性保护,一个虫巢只能有一只女皇种。 + 没有来自更高级节点的允许,{0} 将从基因层面拒绝任何复活。 + + 孵化期间无法重新安装 \ No newline at end of file diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo index 4562b0e..1cf9b08 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 bf1f7ba..7d553bf 100644 --- a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json +++ b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json @@ -3,11 +3,63 @@ "WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\", "Documents": [ { - "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_drawmoteinrange\\hediffcomp_drawmoteinrange.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_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}" + }, + { + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_incubatable.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_incubatable.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\building_comps\\ara_spawnpawnfromlist\\compspawnpawnfromlist.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_spawnpawnfromlist\\compspawnpawnfromlist.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\building_comps\\ara_spawnpawnfromlist\\compproperties_spawnpawnfromlist.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_spawnpawnfromlist\\compproperties_spawnpawnfromlist.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\ara_showspawnablepawnslist\\compabilityeffect_abilityshowspawnablepawns.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_showspawnablepawnslist\\compabilityeffect_abilityshowspawnablepawns.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\pawn_comps\\ara_uniquepawn\\patch_uniquepawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_uniquepawn\\patch_uniquepawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\pawn_comps\\ara_uniquepawn\\compuniquepawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_uniquepawn\\compuniquepawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\pawn_comps\\ara_uniquepawn\\compproperties_uniquepawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_uniquepawn\\compproperties_uniquepawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\buildings\\building_turretgunhasspeed.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_turretgunhasspeed.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\building_comps\\ara_building_refuelingvat\\building_refuelingvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_building_refuelingvat\\building_refuelingvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\building_comps\\ara_nutrientvat\\building_nutrientvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_nutrientvat\\building_nutrientvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\buildings\\building_catastrophemissilesilo\\building_catastrophemissilesilo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_catastrophemissilesilo\\building_catastrophemissilesilo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\buildings\\building_aranutrientdispenser\\building_aranutrientdispenser.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_aranutrientdispenser\\building_aranutrientdispenser.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\hediffs\\ara_drawmoteinrange\\hediffcomp_drawmoteinrange.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_drawmoteinrange\\hediffcomp_drawmoteinrange.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, { - "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_hivemind\\hediff_hivemindmaster.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\hediffs\\ara_hivemind\\hediff_hivemindmaster.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_hivemind\\hediff_hivemindmaster.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, { @@ -34,28 +86,189 @@ "DocumentGroups": [ { "DockedWidth": 200, - "SelectedChildIndex": 1, + "SelectedChildIndex": 0, "Children": [ + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "Building_ArachnidGravEngine.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ArachnidGravEngine.cs", + "RelativeDocumentMoniker": "Buildings\\Building_ArachnidGravEngine.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ArachnidGravEngine.cs", + "RelativeToolTip": "Buildings\\Building_ArachnidGravEngine.cs", + "ViewState": "AgIAAAMAAAAAAAAAAAAkwBUAAAAJAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-21T09:12:42.006Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "Building_Incubatable.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Incubatable.cs", + "RelativeDocumentMoniker": "Buildings\\Building_Incubatable.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Incubatable.cs", + "RelativeToolTip": "Buildings\\Building_Incubatable.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABAAAAARAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-21T08:39:15.745Z", + "EditorCaption": "" + }, { "$type": "Bookmark", "Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}" }, { "$type": "Document", - "DocumentIndex": 0, + "DocumentIndex": 2, + "Title": "CompSpawnPawnFromList.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SpawnPawnFromList\\CompSpawnPawnFromList.cs", + "RelativeDocumentMoniker": "Building_Comps\\ARA_SpawnPawnFromList\\CompSpawnPawnFromList.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SpawnPawnFromList\\CompSpawnPawnFromList.cs", + "RelativeToolTip": "Building_Comps\\ARA_SpawnPawnFromList\\CompSpawnPawnFromList.cs", + "ViewState": "AgIAAAsAAAAAAAAAAAAIwBkAAAANAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-21T08:29:44.344Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "CompProperties_SpawnPawnFromList.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SpawnPawnFromList\\CompProperties_SpawnPawnFromList.cs", + "RelativeDocumentMoniker": "Building_Comps\\ARA_SpawnPawnFromList\\CompProperties_SpawnPawnFromList.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SpawnPawnFromList\\CompProperties_SpawnPawnFromList.cs", + "RelativeToolTip": "Building_Comps\\ARA_SpawnPawnFromList\\CompProperties_SpawnPawnFromList.cs", + "ViewState": "AgIAAA8AAAAAAAAAAAAuwBoAAAAvAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-21T08:29:42.187Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 4, + "Title": "CompAbilityEffect_AbilityShowSpawnablePawns.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs", + "RelativeDocumentMoniker": "Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs", + "RelativeToolTip": "Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs", + "ViewState": "AgIAADgAAAAAAAAAAAAuwEwAAAA8AAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-21T08:29:37.669Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 5, + "Title": "Patch_UniquePawn.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\Patch_UniquePawn.cs", + "RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\Patch_UniquePawn.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\Patch_UniquePawn.cs", + "RelativeToolTip": "Pawn_Comps\\ARA_UniquePawn\\Patch_UniquePawn.cs", + "ViewState": "AgIAACUAAAAAAAAAAAAkwDEAAAAlAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-21T07:20:36.341Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 8, + "Title": "Building_TurretGunHasSpeed.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_TurretGunHasSpeed.cs", + "RelativeDocumentMoniker": "Buildings\\Building_TurretGunHasSpeed.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_TurretGunHasSpeed.cs", + "RelativeToolTip": "Buildings\\Building_TurretGunHasSpeed.cs", + "ViewState": "AgIAAL4CAAAAAAAAAAAAAL4CAABZAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-21T07:00:48.984Z" + }, + { + "$type": "Document", + "DocumentIndex": 7, + "Title": "CompProperties_UniquePawn.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\CompProperties_UniquePawn.cs", + "RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\CompProperties_UniquePawn.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\CompProperties_UniquePawn.cs", + "RelativeToolTip": "Pawn_Comps\\ARA_UniquePawn\\CompProperties_UniquePawn.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-21T07:00:00.021Z" + }, + { + "$type": "Document", + "DocumentIndex": 6, + "Title": "CompUniquePawn.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs", + "RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs", + "RelativeToolTip": "Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs", + "ViewState": "AgIAADQAAAAAAAAAAAAkwEYAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-21T07:00:02.43Z" + }, + { + "$type": "Document", + "DocumentIndex": 9, + "Title": "Building_RefuelingVat.cs", + "DocumentMoniker": "D:\\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", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs", + "RelativeToolTip": "Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs", + "ViewState": "AgIAAPUAAAAAAAAAAAAAAPUAAAA2AAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-21T07:00:47.792Z" + }, + { + "$type": "Document", + "DocumentIndex": 10, + "Title": "Building_NutrientVat.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_NutrientVat\\Building_NutrientVat.cs", + "RelativeDocumentMoniker": "Building_Comps\\ARA_NutrientVat\\Building_NutrientVat.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_NutrientVat\\Building_NutrientVat.cs", + "RelativeToolTip": "Building_Comps\\ARA_NutrientVat\\Building_NutrientVat.cs", + "ViewState": "AgIAAJUBAAAAAAAAAAAmwKgBAABmAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-21T07:00:43.042Z" + }, + { + "$type": "Document", + "DocumentIndex": 11, + "Title": "Building_CatastropheMissileSilo.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CatastropheMissileSilo\\Building_CatastropheMissileSilo.cs", + "RelativeDocumentMoniker": "Buildings\\Building_CatastropheMissileSilo\\Building_CatastropheMissileSilo.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CatastropheMissileSilo\\Building_CatastropheMissileSilo.cs", + "RelativeToolTip": "Buildings\\Building_CatastropheMissileSilo\\Building_CatastropheMissileSilo.cs", + "ViewState": "AgIAALAAAAAAAAAAAAAAAL8AAABMAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-21T07:00:24.191Z" + }, + { + "$type": "Document", + "DocumentIndex": 12, + "Title": "Building_ARANutrientDispenser.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ARANutrientDispenser\\Building_ARANutrientDispenser.cs", + "RelativeDocumentMoniker": "Buildings\\Building_ARANutrientDispenser\\Building_ARANutrientDispenser.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ARANutrientDispenser\\Building_ARANutrientDispenser.cs", + "RelativeToolTip": "Buildings\\Building_ARANutrientDispenser\\Building_ARANutrientDispenser.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAgAAACMAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-21T07:00:20.274Z" + }, + { + "$type": "Document", + "DocumentIndex": 13, "Title": "HediffComp_DrawMoteInRange.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_DrawMoteInRange\\HediffComp_DrawMoteInRange.cs", "RelativeDocumentMoniker": "Hediffs\\ARA_DrawMoteInRange\\HediffComp_DrawMoteInRange.cs", "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_DrawMoteInRange\\HediffComp_DrawMoteInRange.cs", "RelativeToolTip": "Hediffs\\ARA_DrawMoteInRange\\HediffComp_DrawMoteInRange.cs", - "ViewState": "AgIAABUAAAAAAAAAAAAIwBcAAABHAAAAAAAAAA==", + "ViewState": "AgIAAAgAAAAAAAAAAADwvw4AAAAJAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-21T03:59:47.61Z", - "EditorCaption": "" + "WhenOpened": "2025-10-21T03:59:47.61Z" }, { "$type": "Document", - "DocumentIndex": 2, + "DocumentIndex": 15, "Title": "Hediff_HiveMindDrone.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\Hediff_HiveMindDrone.cs", "RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\Hediff_HiveMindDrone.cs", @@ -67,7 +280,7 @@ }, { "$type": "Document", - "DocumentIndex": 1, + "DocumentIndex": 14, "Title": "Hediff_HiveMindMaster.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs", "RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs", @@ -75,12 +288,11 @@ "RelativeToolTip": "Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs", "ViewState": "AgIAADkAAAAAAAAAAAAgwI0AAAAAAAAAAAAAAA==", "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": 3, + "DocumentIndex": 16, "Title": "CompAbilityEffect_BindDrone.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\CompAbilityEffect_BindDrone.cs", "RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\CompAbilityEffect_BindDrone.cs", @@ -92,7 +304,7 @@ }, { "$type": "Document", - "DocumentIndex": 4, + "DocumentIndex": 17, "Title": "CompProperties_AbilityBindDrone.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\CompProperties_AbilityBindDrone.cs", "RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\CompProperties_AbilityBindDrone.cs", @@ -104,7 +316,7 @@ }, { "$type": "Document", - "DocumentIndex": 5, + "DocumentIndex": 18, "Title": "Verb_ShootArc.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Verbs\\Verb_ShootArc.cs", "RelativeDocumentMoniker": "Verbs\\Verb_ShootArc.cs", diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj index 91bee2b..b90767e 100644 --- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj +++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj @@ -100,6 +100,8 @@ + + @@ -125,6 +127,9 @@ + + + diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_SpawnPawnFromList/CompSpawnPawnFromList.cs b/Source/ArachnaeSwarm/Building_Comps/ARA_SpawnPawnFromList/CompSpawnPawnFromList.cs index 5ffb744..a4b5b1c 100644 --- a/Source/ArachnaeSwarm/Building_Comps/ARA_SpawnPawnFromList/CompSpawnPawnFromList.cs +++ b/Source/ArachnaeSwarm/Building_Comps/ARA_SpawnPawnFromList/CompSpawnPawnFromList.cs @@ -24,18 +24,16 @@ namespace ArachnaeSwarm { yield break; } - - if (Props.whitelist == null || !Props.whitelist.Contains(selPawn.kindDef)) + // ޸ֻе whitelist Ϊʱż + if (Props.whitelist != null && Props.whitelist.Count > 0 && !Props.whitelist.Contains(selPawn.kindDef)) { yield break; } - if (Props.spawnablePawns != null) { foreach (PawnSpawnEntry entry in Props.spawnablePawns) { if (entry.pawnKind == null) continue; - if (entry.requiredResearch != null && !entry.requiredResearch.IsFinished) { string disabledText = "ARA_Incubate".Translate(entry.pawnKind.label) + " (" + "Requires".Translate() + ": " + entry.requiredResearch.label + ")"; diff --git a/Source/ArachnaeSwarm/Buildings/Building_ArachnidGravEngine.cs b/Source/ArachnaeSwarm/Buildings/Building_ArachnidGravEngine.cs new file mode 100644 index 0000000..9dc455d --- /dev/null +++ b/Source/ArachnaeSwarm/Buildings/Building_ArachnidGravEngine.cs @@ -0,0 +1,222 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using RimWorld; +using RimWorld.Planet; +using UnityEngine; +using Verse; + +namespace ArachnaeSwarm +{ + public class Building_ArachnidGravEngine : Building_GravEngine + { + // 通过 ModExtension 暴露的纹理路径 + private ArachnidGravEngineExtension modExtension; + + // 覆盖的纹理资源 + private Texture2D customInspectCommandTex; + private CachedMaterial customOrbMat; + private Graphic customOnCooldownGraphic; + + public ArachnidGravEngineExtension ModExtension + { + get + { + if (modExtension == null) + { + modExtension = def.GetModExtension(); + } + return modExtension; + } + } + + // 重写 Graphic 属性以使用自定义纹理 + public override Graphic Graphic + { + get + { + if (Find.TickManager.TicksGame >= cooldownCompleteTick) + { + return base.Graphic; + } + return CustomOnCooldownGraphic; + } + } + + private Texture2D CustomInspectCommandTex + { + get + { + if (customInspectCommandTex == null && ModExtension?.inspectCommandTexPath != null) + { + customInspectCommandTex = ContentFinder.Get(ModExtension.inspectCommandTexPath); + } + return customInspectCommandTex ?? ContentFinder.Get("UI/Commands/Inspect"); + } + } + + private CachedMaterial CustomOrbMat + { + get + { + if (customOrbMat == null && ModExtension?.orbTexPath != null) + { + customOrbMat = new CachedMaterial(ModExtension.orbTexPath, ShaderDatabase.Cutout); + } + return customOrbMat ?? new CachedMaterial("Things/Building/GravEngine/GravEngine_Orb", ShaderDatabase.Cutout); + } + } + + private Graphic CustomOnCooldownGraphic + { + get + { + if (customOnCooldownGraphic == null && ModExtension?.cooldownTexPath != null) + { + customOnCooldownGraphic = GraphicDatabase.Get( + ModExtension.cooldownTexPath, + ShaderDatabase.Cutout, + Vector2.one * 3f, + Color.white); + } + return customOnCooldownGraphic ?? GraphicDatabase.Get("Things/Building/GravEngine/GravEngine_Cooldown", ShaderDatabase.Cutout, Vector2.one * 3f, Color.white); + } + } + + // 禁用检查系统 - 重写 Inspect 方法为空 + public new void Inspect(bool silent = false) + { + // 完全禁用检查系统,不执行任何操作 + // 虫群建筑不需要人类的研究检查流程 + } + + // 重写 GetGizmos 方法,移除检查相关的 gizmo + public override IEnumerable GetGizmos() + { + foreach (Gizmo gizmo in base.GetGizmos()) + { + // 过滤掉检查相关的 gizmo + if (gizmo is Command_Action command && + command.defaultLabel?.Contains("CommandInspectGravEngine") == true) + { + continue; + } + yield return gizmo; + } + + // 可以添加虫群特有的 gizmo + if (DebugSettings.ShowDevGizmos) + { + yield return new Command_Action + { + defaultLabel = "DEV: Spawn Arachnid Swarm", + action = delegate + { + // 虫群特有的调试功能 + SpawnArachnidSwarm(); + } + }; + } + } + + // 重写 GetFloatMenuOptions 方法,移除检查选项 + public override IEnumerable GetFloatMenuOptions(Pawn selPawn) + { + foreach (FloatMenuOption floatMenuOption in base.GetFloatMenuOptions(selPawn)) + { + // 过滤掉检查相关的选项 + if (floatMenuOption.Label.Contains("CommandInspectGravEngine")) + { + continue; + } + yield return floatMenuOption; + } + } + + // 重写 ClaimableBy 方法,移除检查限制 + public override AcceptanceReport ClaimableBy(Faction by) + { + // 虫群建筑不需要检查就可以被认领 + AcceptanceReport result = base.ClaimableBy(by); + if (!result.Accepted) + { + return result; + } + return true; // 总是返回 true,忽略检查限制 + } + + // 重写 GetInspectString 方法,移除检查相关的文本 + public override string GetInspectString() + { + string text = base.GetInspectString(); + + // 移除关于未检查的文本 + if (text.Contains("GravEngineNotInspected")) + { + text = text.Replace("GravEngineNotInspected".Translate() + "\n", ""); + } + + // 添加虫群特有的信息 + if (!string.IsNullOrEmpty(text)) + { + text += "\n"; + } + text += "ArachnidSwarmControl".Translate(); + + return text; + } + + // 虫群特有的方法 + private void SpawnArachnidSwarm() + { + // 虫群特有的生成逻辑 + // 这里可以添加生成虫群单位的代码 + Messages.Message("ArachnidSwarmActivated".Translate(), this, MessageTypeDefOf.PositiveEvent); + } + + // 重写 DrawAt 方法以使用自定义材质 + protected override void DrawAt(Vector3 drawLoc, bool flip = false) + { + base.DrawAt(drawLoc, flip); + if (base.Spawned) + { + if (Find.TickManager.TicksGame >= cooldownCompleteTick) + { + // 使用 Mathf 替代 MathF + drawLoc.z += 0.5f * (1f + Mathf.Sin(Mathf.PI * 2f * (float)GenTicks.TicksGame / 500f)) * 0.3f; + } + drawLoc.y += 0.03658537f; + Vector3 s = new Vector3(def.graphicData.drawSize.x, 1f, def.graphicData.drawSize.y); + + // 使用自定义的球体材质 + Graphics.DrawMesh(MeshPool.plane10Back, Matrix4x4.TRS(drawLoc, base.Rotation.AsQuat, s), CustomOrbMat.Material, 0, null, 0); + } + } + + public override void SpawnSetup(Map map, bool respawningAfterLoad) + { + base.SpawnSetup(map, respawningAfterLoad); + + // 虫群建筑自动属于玩家,不需要检查 + if (base.Faction != Faction.OfPlayer) + { + SetFaction(Faction.OfPlayer); + } + + // 标记为已检查,避免父类的检查逻辑 + Find.ResearchManager.gravEngineInspected = true; + } + + // 由于父类的私有字段无法访问,我们移除 UpdateSubstructureIfNeeded 的重写 + // 如果需要修改子结构逻辑,可能需要通过其他方式 + } + + // ModExtension 定义,用于在 XML 中配置纹理路径 + public class ArachnidGravEngineExtension : DefModExtension + { + public string inspectCommandTexPath; + public string orbTexPath; + public string cooldownTexPath; + public string swarmIconPath; + } +} diff --git a/Source/ArachnaeSwarm/Buildings/Building_Incubatable.cs b/Source/ArachnaeSwarm/Buildings/Building_Incubatable.cs new file mode 100644 index 0000000..acb3976 --- /dev/null +++ b/Source/ArachnaeSwarm/Buildings/Building_Incubatable.cs @@ -0,0 +1,93 @@ +using System.Collections.Generic; +using System.Linq; +using Verse; +using RimWorld; + +namespace ArachnaeSwarm +{ + public class Building_Incubatable : Building + { + private CompSpawnPawnFromList spawnComp; + + public CompSpawnPawnFromList SpawnComp + { + get + { + if (spawnComp == null) + { + spawnComp = this.GetComp(); + } + return spawnComp; + } + } + + public bool IsHatching => SpawnComp?.IsHatching == true; + + public override IEnumerable GetGizmos() + { + foreach (Gizmo gizmo in base.GetGizmos()) + { + // 如果正在孵化,过滤掉卸载相关的 gizmo + if (IsHatching && IsUninstallGizmo(gizmo)) + { + continue; + } + + yield return gizmo; + } + + // 确保组件的 gizmo 也能正常显示 + if (SpawnComp != null) + { + foreach (Gizmo compGizmo in SpawnComp.CompGetGizmosExtra()) + { + yield return compGizmo; + } + } + } + + private bool IsUninstallGizmo(Gizmo gizmo) + { + // 检查是否是卸载/重新安装相关的 gizmo + if (gizmo is Command_Action commandAction) + { + string label = commandAction.defaultLabel?.ToLower() ?? ""; + string desc = commandAction.defaultDesc?.ToLower() ?? ""; + + return label.Contains("uninstall") || + label.Contains("reinstall") || + desc.Contains("uninstall") || + desc.Contains("reinstall"); + } + + if (gizmo is Designator designator) + { + string label = designator.defaultLabel?.ToLower() ?? ""; + string desc = designator.defaultDesc?.ToLower() ?? ""; + + return label.Contains("uninstall") || + label.Contains("reinstall") || + desc.Contains("uninstall") || + desc.Contains("reinstall"); + } + + return false; + } + + public override string GetInspectString() + { + string baseString = base.GetInspectString(); + + if (IsHatching) + { + if (!string.IsNullOrEmpty(baseString)) + { + baseString += "\n"; + } + baseString += "CannotBeUninstalled".Translate(); + } + + return baseString; + } + } +} diff --git a/Source/ArachnaeSwarm/MentalState/MentalState_HiveMindCascade.cs b/Source/ArachnaeSwarm/MentalState/MentalState_HiveMindCascade.cs new file mode 100644 index 0000000..db49d3b --- /dev/null +++ b/Source/ArachnaeSwarm/MentalState/MentalState_HiveMindCascade.cs @@ -0,0 +1,208 @@ +using System.Collections.Generic; +using System.Linq; +using RimWorld; +using Verse; + +namespace ArachnaeSwarm +{ + public class MentalState_HiveMindCascade : MentalState + { + private bool hasCascaded = false; + + public override void PostStart(string reason) + { + base.PostStart(reason); + + // 发送通知 + if (PawnUtility.ShouldSendNotificationAbout(pawn)) + { + string labelText = def.beginLetterLabel.NullOrEmpty() ? def.label : def.beginLetterLabel; + TaggedString letterLabel = labelText.Formatted(pawn.LabelShort, pawn.Named("PAWN")).CapitalizeFirst(); + TaggedString letterText = def.beginLetter.Formatted(pawn.LabelShort, pawn.Named("PAWN")).CapitalizeFirst(); + if (reason != null) + { + letterText += "\n\n" + reason; + } + Find.LetterStack.ReceiveLetter(letterLabel, letterText, LetterDefOf.NegativeEvent, pawn); + } + + // 立即执行级联传播 + ExecuteCascadeBreakdown(); + } + + public override void MentalStateTick(int delta) + { + base.MentalStateTick(delta); + + // 确保级联只执行一次 + if (!hasCascaded) + { + ExecuteCascadeBreakdown(); + } + + // 设置强制恢复时间 + if (this.forceRecoverAfterTicks <= 0) + { + this.forceRecoverAfterTicks = 300; // 5秒后恢复 + } + + // 如果级联已完成且超过恢复时间,则恢复 + if (hasCascaded && age > forceRecoverAfterTicks) + { + RecoverFromState(); + } + } + + private void ExecuteCascadeBreakdown() + { + if (hasCascaded) return; + + var extension = def.GetModExtension(); + if (extension?.mentalStatesToSpread == null || extension.mentalStatesToSpread.Count == 0) + { + Log.Error($"[ArachnaeSwarm] MentalState_HiveMindCascade: No mentalStatesToSpread defined for {def.defName}"); + hasCascaded = true; + return; + } + + // 获取主节点的HiveMindMaster hediff + var masterHediff = pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("ARA_HiveMindMaster")) as Hediff_HiveMindMaster; + if (masterHediff == null) + { + Log.Warning($"[ArachnaeSwarm] MentalState_HiveMindCascade: Pawn {pawn.LabelShort} does not have ARA_HiveMindMaster hediff"); + hasCascaded = true; + return; + } + + // 通过反射或其他方式获取无人机列表 + var drones = GetDronesFromMaster(masterHediff); + if (drones == null || drones.Count == 0) + { + Log.Message($"[ArachnaeSwarm] MentalState_HiveMindCascade: No drones found for master {pawn.LabelShort}"); + hasCascaded = true; + return; + } + + int spreadCount = 0; + foreach (var drone in drones) + { + if (drone == null || drone.Dead || !drone.Spawned || drone.Destroyed) + continue; + + // 随机选择一个精神崩溃状态 + var randomMentalState = extension.mentalStatesToSpread.RandomElement(); + if (randomMentalState == null) + continue; + + // 强制无人机进入选定的精神崩溃状态 + if (drone.mindState.mentalStateHandler.TryStartMentalState(randomMentalState, "HiveMindCascade", force: true)) + { + spreadCount++; + Log.Message($"[ArachnaeSwarm] Cascaded {randomMentalState.defName} to drone {drone.LabelShort}"); + } + else + { + Log.Warning($"[ArachnaeSwarm] Failed to cascade {randomMentalState.defName} to drone {drone.LabelShort}"); + } + } + + Log.Message($"[ArachnaeSwarm] HiveMindCascade: Successfully spread {spreadCount} mental breaks to drones"); + hasCascaded = true; + + // 显示级联完成的消息 + if (spreadCount > 0 && PawnUtility.ShouldSendNotificationAbout(pawn)) + { + Messages.Message("ARA_HiveMindCascadeComplete".Translate(pawn.LabelShort, spreadCount), pawn, MessageTypeDefOf.NegativeEvent); + } + } + + /// + /// 通过反射获取HiveMindMaster中的无人机列表 + /// + private List GetDronesFromMaster(Hediff_HiveMindMaster masterHediff) + { + // 方法1: 如果HiveMindMaster有公共属性暴露无人机列表 + // return masterHediff.Drones; // 如果存在这样的属性 + + // 方法2: 通过反射访问私有字段 + try + { + var dronesField = typeof(Hediff_HiveMindMaster).GetField("drones", + System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + + if (dronesField != null) + { + return dronesField.GetValue(masterHediff) as List; + } + } + catch (System.Exception ex) + { + Log.Error($"[ArachnaeSwarm] Failed to access drones field via reflection: {ex.Message}"); + } + + // 方法3: 如果以上都失败,尝试通过其他方式 + Log.Error($"[ArachnaeSwarm] Could not access drones list from HiveMindMaster"); + return new List(); + } + + public override bool ForceRecoverFromState() + { + // 确保级联已经执行 + if (!hasCascaded) + { + ExecuteCascadeBreakdown(); + } + return base.ForceRecoverFromState(); + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Values.Look(ref hasCascaded, "hasCascaded", false); + } + } + + public class MentalStateDefExtension_HiveMindCascade : DefModExtension + { + public List mentalStatesToSpread; + + // 可选:可以添加传播概率或其他参数 + public float spreadChance = 1.0f; + public bool includeMasterInSpread = false; + } + + public class MentalBreakWorker_HiveMindCascade : MentalBreakWorker + { + public override bool TryStart(Pawn pawn, string reason, bool causedByMood) + { + // 检查pawn是否有HiveMindMaster hediff + var hasHiveMindMaster = pawn.health.hediffSet.HasHediff(HediffDef.Named("ARA_HiveMindMaster")); + + if (!hasHiveMindMaster) + { + Log.Message($"[ArachnaeSwarm] MentalBreakWorker_HiveMindCascade: Pawn {pawn.LabelShort} does not have ARA_HiveMindMaster, cannot start cascade"); + return false; + } + + // 调用基类方法启动精神状态 + if (base.TryStart(pawn, reason, causedByMood)) + { + Log.Message($"[ArachnaeSwarm] Started HiveMindCascade mental state on {pawn.LabelShort}"); + return true; + } + + return false; + } + + public override float CommonalityFor(Pawn pawn, bool moodInduced = false) + { + // 只有拥有HiveMindMaster的pawn才能触发这种崩溃 + var hasHiveMindMaster = pawn.health.hediffSet.HasHediff(HediffDef.Named("ARA_HiveMindMaster")); + + if (!hasHiveMindMaster) + return 0f; + + return base.CommonalityFor(pawn, moodInduced); + } + } +} diff --git a/Source/ArachnaeSwarm/Pawn_Comps/ARA_UniquePawn/CompProperties_UniquePawn.cs b/Source/ArachnaeSwarm/Pawn_Comps/ARA_UniquePawn/CompProperties_UniquePawn.cs new file mode 100644 index 0000000..1d3afeb --- /dev/null +++ b/Source/ArachnaeSwarm/Pawn_Comps/ARA_UniquePawn/CompProperties_UniquePawn.cs @@ -0,0 +1,24 @@ +using Verse; + +namespace ArachnaeSwarm +{ + public class CompProperties_UniquePawn : CompProperties + { + // 全局变量的唯一标识符 + public string globalVariable; + + // 可选:杀死pawn时是否显示消息 + public bool showDeathMessage = true; + + // 可选:死亡消息的翻译键 + public string deathMessageKey = "ARA_UniquePawnDeathMessage"; + + // 可选:杀死pawn的方式 + public DamageDef killDamageDef = null; + + public CompProperties_UniquePawn() + { + this.compClass = typeof(CompUniquePawn); + } + } +} diff --git a/Source/ArachnaeSwarm/Pawn_Comps/ARA_UniquePawn/CompUniquePawn.cs b/Source/ArachnaeSwarm/Pawn_Comps/ARA_UniquePawn/CompUniquePawn.cs new file mode 100644 index 0000000..fa5f62c --- /dev/null +++ b/Source/ArachnaeSwarm/Pawn_Comps/ARA_UniquePawn/CompUniquePawn.cs @@ -0,0 +1,151 @@ +using System; +using RimWorld; +using Verse; + +namespace ArachnaeSwarm +{ + public class CompUniquePawn : ThingComp + { + private bool _checked = false; + private bool _scheduledForCheck = false; + + public CompProperties_UniquePawn Props => (CompProperties_UniquePawn)this.props; + + public override void PostSpawnSetup(bool respawningAfterLoad) + { + base.PostSpawnSetup(respawningAfterLoad); + + // 基本安全检查 + if (this.parent == null || !(this.parent is Pawn pawn) || !pawn.Spawned) + return; + + // 只在首次生成时检查,不是加载存档时 + if (respawningAfterLoad || _checked || _scheduledForCheck) + return; + + // 确保属性有效 + if (this.props == null || string.IsNullOrEmpty(Props?.globalVariable)) + return; + + try + { + // 延迟整个检查过程到下一帧 + _scheduledForCheck = true; + + LongEventHandler.QueueLongEvent(() => + { + try + { + if (this.parent is Pawn delayedPawn && delayedPawn.Spawned && !_checked) + { + CheckAndHandleUniquePawn(delayedPawn); + _checked = true; + } + _scheduledForCheck = false; + } + catch (Exception ex) + { + Log.Error($"Error in delayed unique pawn check: {ex}"); + _scheduledForCheck = false; + } + }, "ArachnaeSwarm_UniquePawnCheck", false, null); + } + catch (Exception ex) + { + Log.Error($"Error in CompUniquePawn.PostSpawnSetup: {ex}"); + _scheduledForCheck = false; + } + } + + private void CheckAndHandleUniquePawn(Pawn pawn) + { + try + { + string variable = Props.globalVariable; + + if (string.IsNullOrEmpty(variable)) + { + Log.Error("CompUniquePawn: globalVariable is null or empty"); + return; + } + + // 检查变量是否已存在 + if (GlobalVariableManager.HasVariable(variable)) + { + // 变量已存在,杀死pawn + KillPawn(pawn, variable); + } + else + { + // 变量不存在,添加变量 + GlobalVariableManager.SetVariable(variable); + + if (Prefs.DevMode) + { + Log.Message($"Added global variable '{variable}' for pawn {pawn.Label}"); + } + } + } + catch (Exception ex) + { + Log.Error($"Error in CheckAndHandleUniquePawn: {ex}"); + } + } + + private void KillPawn(Pawn pawn, string variable) + { + try + { + // 显示死亡消息 + if (Props.showDeathMessage && !string.IsNullOrEmpty(Props.deathMessageKey)) + { + string deathMessage = Props.deathMessageKey.Translate(pawn.Label, variable); + if (!string.IsNullOrEmpty(deathMessage)) + { + Messages.Message(deathMessage, MessageTypeDefOf.NegativeEvent); + } + } + + if (Prefs.DevMode) + { + Log.Message($"Killing pawn {pawn.Label} because global variable '{variable}' already exists"); + } + + // 使用更安全的延迟执行 + LongEventHandler.QueueLongEvent(() => + { + try + { + if (pawn != null && pawn.Spawned && !pawn.Destroyed) + { + if (Props.killDamageDef != null) + { + var damageInfo = new DamageInfo(Props.killDamageDef, 99999f, -1f, -1f); + pawn.TakeDamage(damageInfo); + } + else + { + pawn.Kill(null); + } + } + } + catch (Exception ex) + { + Log.Error($"Error in delayed pawn kill: {ex}"); + } + }, "ArachnaeSwarm_KillDuplicatePawn", false, null); + } + catch (Exception ex) + { + Log.Error($"Error in KillPawn: {ex}"); + } + } + + public override void PostExposeData() + { + base.PostExposeData(); + Scribe_Values.Look(ref _checked, "checked", false); + Scribe_Values.Look(ref _scheduledForCheck, "scheduledForCheck", false); + } + } +} diff --git a/Source/ArachnaeSwarm/Pawn_Comps/ARA_UniquePawn/Patch_UniquePawn.cs b/Source/ArachnaeSwarm/Pawn_Comps/ARA_UniquePawn/Patch_UniquePawn.cs new file mode 100644 index 0000000..0501f32 --- /dev/null +++ b/Source/ArachnaeSwarm/Pawn_Comps/ARA_UniquePawn/Patch_UniquePawn.cs @@ -0,0 +1,217 @@ +using System.Collections.Generic; +using System.Reflection; +using HarmonyLib; +using RimWorld; +using Verse; + +namespace ArachnaeSwarm +{ + [StaticConstructorOnStartup] + public static class ModInit + { + static ModInit() + { + var harmony = new Harmony("ArachnaeSwarm.Mod"); + harmony.PatchAll(); + } + } + + [HarmonyPatch(typeof(Game), "ExposeData")] + public static class Game_ExposeData_Patch + { + public static void Postfix() + { + GlobalVariableManager.ExposeData(); + } + } + + // 复活拦截补丁 + [HarmonyPatch] + public static class ResurrectionUtility_Patch + { + private static MethodInfo TargetMethod() + { + // 尝试找到复活方法 + return AccessTools.Method("ResurrectionUtility:TryResurrect") ?? + AccessTools.Method("RimWorld.ResurrectionUtility:TryResurrect"); + } + + [HarmonyPrefix] + public static bool Prefix(Pawn pawn, ref bool __result) + { + try + { + // 检查 pawn 是否有 CompUniquePawn 组件 + var comp = pawn?.GetComp(); + if (comp != null && !string.IsNullOrEmpty(comp.Props?.globalVariable)) + { + string variable = comp.Props.globalVariable; + + // 如果全局变量已存在,阻止复活 + if (GlobalVariableManager.HasVariable(variable)) + { + // 显示阻止复活的消息 + if (comp.Props.showDeathMessage && !string.IsNullOrEmpty(comp.Props.deathMessageKey)) + { + string preventMessage = "ARA_ResurrectionPrevented".Translate(pawn.Label, variable); + if (string.IsNullOrEmpty(preventMessage) || preventMessage == "ARA_ResurrectionPrevented") + { + preventMessage = "无法复活 {0},因为 {1} 已经存在。".Translate(pawn.Label, variable); + } + Messages.Message(preventMessage, MessageTypeDefOf.NegativeEvent); + } + + if (Prefs.DevMode) + { + Log.Message($"阻止复活 {pawn.Label},因为全局变量 '{variable}' 已存在"); + } + + __result = false; // 返回 false 表示复活失败 + return false; // 跳过原始方法 + } + } + } + catch (System.Exception ex) + { + Log.Error($"Error in resurrection prevention: {ex}"); + } + + return true; // 继续执行原始方法 + } + } + + // 带副作用的复活拦截补丁 + [HarmonyPatch] + public static class ResurrectionUtility_Patch2 + { + private static MethodInfo TargetMethod() + { + // 尝试找到带副作用的复活方法 + return AccessTools.Method("ResurrectionUtility:TryResurrectWithSideEffects") ?? + AccessTools.Method("RimWorld.ResurrectionUtility:TryResurrectWithSideEffects"); + } + + [HarmonyPrefix] + public static bool Prefix(Pawn pawn, ref bool __result) + { + try + { + // 检查 pawn 是否有 CompUniquePawn 组件 + var comp = pawn?.GetComp(); + if (comp != null && !string.IsNullOrEmpty(comp.Props?.globalVariable)) + { + string variable = comp.Props.globalVariable; + + // 如果全局变量已存在,阻止复活 + if (GlobalVariableManager.HasVariable(variable)) + { + // 显示阻止复活的消息 + if (comp.Props.showDeathMessage && !string.IsNullOrEmpty(comp.Props.deathMessageKey)) + { + string preventMessage = "ARA_ResurrectionPrevented".Translate(pawn.Label, variable); + if (string.IsNullOrEmpty(preventMessage) || preventMessage == "ARA_ResurrectionPrevented") + { + preventMessage = "无法复活 {0},因为 {1} 已经存在。".Translate(pawn.Label, variable); + } + Messages.Message(preventMessage, MessageTypeDefOf.NegativeEvent); + } + + if (Prefs.DevMode) + { + Log.Message($"阻止复活 {pawn.Label},因为全局变量 '{variable}' 已存在"); + } + + __result = false; // 返回 false 表示复活失败 + return false; // 跳过原始方法 + } + } + } + catch (System.Exception ex) + { + Log.Error($"Error in resurrection prevention: {ex}"); + } + + return true; // 继续执行原始方法 + } + } + + public static class GlobalVariableManager + { + private static HashSet _globalVariables; + private static bool _initialized = false; + + private static void EnsureInitialized() + { + if (!_initialized) + { + _globalVariables = new HashSet(); + _initialized = true; + } + } + + public static void ExposeData() + { + try + { + if (Scribe.mode == LoadSaveMode.Saving) + { + EnsureInitialized(); + if (_globalVariables.Count > 0) + { + List variablesList = new List(_globalVariables); + Scribe_Collections.Look(ref variablesList, "ArachnaeSwarm_GlobalVariables", LookMode.Value); + } + } + else if (Scribe.mode == LoadSaveMode.LoadingVars) + { + List variablesList = null; + Scribe_Collections.Look(ref variablesList, "ArachnaeSwarm_GlobalVariables", LookMode.Value); + + if (variablesList != null) + { + _globalVariables = new HashSet(variablesList); + } + else + { + _globalVariables = new HashSet(); + } + _initialized = true; + } + } + catch (System.Exception ex) + { + Log.Error($"Error in GlobalVariableManager.ExposeData: {ex}"); + } + } + + public static bool HasVariable(string variable) + { + EnsureInitialized(); + return _globalVariables.Contains(variable); + } + + public static void SetVariable(string variable) + { + EnsureInitialized(); + _globalVariables.Add(variable); + } + + public static bool RemoveVariable(string variable) + { + EnsureInitialized(); + return _globalVariables.Remove(variable); + } + + public static IEnumerable GetAllVariables() + { + EnsureInitialized(); + return _globalVariables; + } + + public static void ClearAllVariables() + { + EnsureInitialized(); + _globalVariables.Clear(); + } + } +}