diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index f1fb7c0..5c6fd68 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/NeedDefs/ARA_Needs.xml b/1.6/1.6/Defs/NeedDefs/ARA_Needs.xml index 797c71c..a1ddc69 100644 --- a/1.6/1.6/Defs/NeedDefs/ARA_Needs.xml +++ b/1.6/1.6/Defs/NeedDefs/ARA_Needs.xml @@ -18,8 +18,8 @@
  • - - 0.8 + + 1.25 1 diff --git a/1.6/1.6/Defs/ResearchProjectDefs/ARA_ResearchProjects.xml b/1.6/1.6/Defs/ResearchProjectDefs/ARA_ResearchProjects.xml index c1b62ec..0fffede 100644 --- a/1.6/1.6/Defs/ResearchProjectDefs/ARA_ResearchProjects.xml +++ b/1.6/1.6/Defs/ResearchProjectDefs/ARA_ResearchProjects.xml @@ -8,15 +8,15 @@ Medieval ARA_ResearchTab - + 2500
  • ARA_Technology_5ESS
  • - + 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 0930b44..cd7c06e 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_Building.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_Building.xml @@ -1013,6 +1013,98 @@ + + ARA_Research_Vat + + 阿拉克涅虫群中由触手长成的活体组织,可以支撑屋顶不至于倒塌,发出较大范围的光亮,并且比普通的支撑柱结实很多。 + ARA_Creep + ArachnaeSwarm.Building_ResearchBlueprintReader + ARA_Buildings + Normal + 2040 + Building + PassThroughOnly + 0.25 + 0 + 0.8 + + (1.25,1.25) + (0,0,0.2) + ArachnaeSwarm/Building/ARA_Column + Graphic_Single + CutoutComplex + + (0.3, 0.5, 0.3) + (0,0,-0.23) + + + (0.2,0.2,0.6,0.6) + + + + 1000 + 750 + 10 + 1.0 + 1 + 10 + + +
  • ARA_Base_Technology
  • +
    + + 10 + +
  • Woody
  • +
  • Stony
  • +
  • Metallic
  • +
    + + + +
  • + 1 +
  • +
    + + + 2 + + true + false + false + 0 + 6.9 + + true + false + true + +
  • ARA_InsectCreep
  • +
    +
    + +
  • PlaceWorker_GlowRadius
  • +
    + +
  • + 100 + 85 + 2 + 0.2 + 1800 + 0.5 + +
  • ArachnaeNode_Race_WeaponSmith
  • + + +
  • + 7 + (220,210,171,0) +
  • +
    +
    + ARA_Shelf diff --git a/1.6/1.6/Defs/Thing_building/ARA_Ootheca.xml b/1.6/1.6/Defs/Thing_building/ARA_Ootheca.xml index 6554f2e..72d1a6a 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_Ootheca.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_Ootheca.xml @@ -56,7 +56,7 @@ - 3 + 10 diff --git a/1.6/1.6/Defs/ThinkTreeDefs/ARA_ThinkTrees.xml b/1.6/1.6/Defs/ThinkTreeDefs/ARA_ThinkTrees.xml index 8f09aee..303ebaf 100644 --- a/1.6/1.6/Defs/ThinkTreeDefs/ARA_ThinkTrees.xml +++ b/1.6/1.6/Defs/ThinkTreeDefs/ARA_ThinkTrees.xml @@ -929,6 +929,16 @@
  • Humanlike_PreMain
  • + + +
  • + +
  • + MainColonistBehaviorCore + true +
  • + +
  • @@ -944,6 +954,7 @@
  • +
  • ARA_HiveMindMaster 0~5 @@ -958,16 +969,7 @@
  • - - -
  • - -
  • - MainColonistBehaviorCore - true -
  • - - +
  • WildMan diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo index 9cae529..8ecad50 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 cb49570..b05fd31 100644 --- a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json +++ b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json @@ -1,81 +1,109 @@ { "Version": 1, - "WorkspaceRootPath": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\", + "WorkspaceRootPath": "D:\\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\\jobs\\jobdriver_stripchitin\\jobdriver_stripchitin.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_researchblueprintreader\\researchblueprintreaderextension.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_researchblueprintreader\\researchblueprintreaderextension.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_researchblueprintreader\\researchblueprintreadermanager.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_researchblueprintreader\\researchblueprintreadermanager.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_researchblueprintreader\\building_researchblueprintreader.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_researchblueprintreader\\building_researchblueprintreader.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\\harmonypatches\\destroyremovesresearch\\compproperties_destroyremovesresearch.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:harmonypatches\\destroyremovesresearch\\compproperties_destroyremovesresearch.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\\harmonypatches\\patch_researchmanager_addremovemethod.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:harmonypatches\\patch_researchmanager_addremovemethod.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\\building_comps\\ara_nutrientvat\\defmodextension_nutrientvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_nutrientvat\\defmodextension_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\\harmonypatches\\destroyremovesresearch\\compdestroyremovesresearch.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:harmonypatches\\destroyremovesresearch\\compdestroyremovesresearch.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\\jobs\\jobdriver_stripchitin\\jobdriver_stripchitin.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_stripchitin\\jobdriver_stripchitin.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\\jobs\\jobdriver_stripchitin\\compproperties_chitinstripping.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\\jobs\\jobdriver_stripchitin\\compproperties_chitinstripping.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_stripchitin\\compproperties_chitinstripping.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\\jobs\\jobdriver_stripchitin\\comp_chitinstripping.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\\jobs\\jobdriver_stripchitin\\comp_chitinstripping.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_stripchitin\\comp_chitinstripping.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\\verb_shootselfunderfoot.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\\verbs\\verb_shootselfunderfoot.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:verbs\\verb_shootselfunderfoot.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_hediffcomp_topturret\\hediffcomp_topturret.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_hediffcomp_topturret\\hediffcomp_topturret.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_hediffcomp_topturret\\hediffcomp_topturret.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\\roomrole\\roomroleworker_incubator.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\\roomrole\\roomroleworker_incubator.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:roomrole\\roomroleworker_incubator.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\\building_comps\\ara_compinteractiveproducer\\compresearchproducer.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_compinteractiveproducer\\compresearchproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_compinteractiveproducer\\compresearchproducer.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\\ara_hediffdefof.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ara_hediffdefof.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:ara_hediffdefof.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\\building_comps\\ara_corpseconverter\\compcorpseconverter.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_corpseconverter\\compcorpseconverter.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_corpseconverter\\compcorpseconverter.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\\building_comps\\ara_corpseconverter\\compproperties_corpseconverter.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_corpseconverter\\compproperties_corpseconverter.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_corpseconverter\\compproperties_corpseconverter.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\\building_comps\\ara_terrainchanger\\compterrainchanger.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_terrainchanger\\compterrainchanger.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_terrainchanger\\compterrainchanger.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\\building_comps\\ara_terrainchanger\\compproperties_terrainchanger.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_terrainchanger\\compproperties_terrainchanger.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_terrainchanger\\compproperties_terrainchanger.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\\building_comps\\wula_mutifuelspawner\\comprefuelablenutrition_withkey.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\\wula_mutifuelspawner\\comprefuelablenutrition_withkey.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\wula_mutifuelspawner\\comprefuelablenutrition_withkey.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\\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_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|E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\buildings\\building_ootheca\\compproperties_incubatordata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_ootheca\\compproperties_incubatordata.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_ootheca\\oothecaincubatorextension.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_ootheca\\oothecaincubatorextension.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_ootheca\\oothecaincubatorextension.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_ootheca\\building_ootheca.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_ootheca\\building_ootheca.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_ootheca\\building_ootheca.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_equipmentootheca\\compproperties_equipmentincubatordata.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_equipmentootheca\\compproperties_equipmentincubatordata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_equipmentootheca\\compproperties_equipmentincubatordata.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_equipmentootheca\\building_equipmentootheca.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_equipmentootheca\\building_equipmentootheca.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_equipmentootheca\\building_equipmentootheca.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" } ], @@ -88,95 +116,193 @@ "DockedWidth": 200, "SelectedChildIndex": 1, "Children": [ - { - "$type": "Bookmark", - "Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}" - }, { "$type": "Document", - "DocumentIndex": 0, - "Title": "JobDriver_StripChitin.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_StripChitin\\JobDriver_StripChitin.cs", - "RelativeDocumentMoniker": "Jobs\\JobDriver_StripChitin\\JobDriver_StripChitin.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_StripChitin\\JobDriver_StripChitin.cs*", - "RelativeToolTip": "Jobs\\JobDriver_StripChitin\\JobDriver_StripChitin.cs*", - "ViewState": "AgIAAFcAAAAAAAAAAAAAAHMAAAAoAAAAAAAAAA==", + "DocumentIndex": 1, + "Title": "ResearchBlueprintReaderManager.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ResearchBlueprintReader\\ResearchBlueprintReaderManager.cs", + "RelativeDocumentMoniker": "Buildings\\Building_ResearchBlueprintReader\\ResearchBlueprintReaderManager.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ResearchBlueprintReader\\ResearchBlueprintReaderManager.cs", + "RelativeToolTip": "Buildings\\Building_ResearchBlueprintReader\\ResearchBlueprintReaderManager.cs", + "ViewState": "AgIAADwBAAAAAAAAAAArwEsBAAAIAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-12-16T15:50:38.09Z", + "WhenOpened": "2025-12-17T03:27:44.163Z", "EditorCaption": "" }, { "$type": "Document", - "DocumentIndex": 1, - "Title": "CompProperties_ChitinStripping.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_StripChitin\\CompProperties_ChitinStripping.cs", - "RelativeDocumentMoniker": "Jobs\\JobDriver_StripChitin\\CompProperties_ChitinStripping.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_StripChitin\\CompProperties_ChitinStripping.cs", - "RelativeToolTip": "Jobs\\JobDriver_StripChitin\\CompProperties_ChitinStripping.cs", - "ViewState": "AgIAAAAAAAAAAAAAAAAAABcAAAAtAAAAAAAAAA==", + "DocumentIndex": 0, + "Title": "ResearchBlueprintReaderExtension.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ResearchBlueprintReader\\ResearchBlueprintReaderExtension.cs", + "RelativeDocumentMoniker": "Buildings\\Building_ResearchBlueprintReader\\ResearchBlueprintReaderExtension.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ResearchBlueprintReader\\ResearchBlueprintReaderExtension.cs*", + "RelativeToolTip": "Buildings\\Building_ResearchBlueprintReader\\ResearchBlueprintReaderExtension.cs*", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-12-16T15:50:04.277Z", + "WhenOpened": "2025-12-17T03:27:11.518Z", "EditorCaption": "" }, { "$type": "Document", "DocumentIndex": 2, - "Title": "Comp_ChitinStripping.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_StripChitin\\Comp_ChitinStripping.cs", - "RelativeDocumentMoniker": "Jobs\\JobDriver_StripChitin\\Comp_ChitinStripping.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_StripChitin\\Comp_ChitinStripping.cs", - "RelativeToolTip": "Jobs\\JobDriver_StripChitin\\Comp_ChitinStripping.cs", - "ViewState": "AgIAAAAAAAAAAAAAAAAAAAoAAABWAAAAAAAAAA==", + "Title": "Building_ResearchBlueprintReader.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ResearchBlueprintReader\\Building_ResearchBlueprintReader.cs", + "RelativeDocumentMoniker": "Buildings\\Building_ResearchBlueprintReader\\Building_ResearchBlueprintReader.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ResearchBlueprintReader\\Building_ResearchBlueprintReader.cs", + "RelativeToolTip": "Buildings\\Building_ResearchBlueprintReader\\Building_ResearchBlueprintReader.cs", + "ViewState": "AgIAAE8BAAAAAAAAAAAswGIBAAAhAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-12-16T15:49:51.675Z", - "EditorCaption": "" - }, - { - "$type": "Document", - "DocumentIndex": 3, - "Title": "Verb_ShootSelfUnderfoot.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Verbs\\Verb_ShootSelfUnderfoot.cs", - "RelativeDocumentMoniker": "Verbs\\Verb_ShootSelfUnderfoot.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Verbs\\Verb_ShootSelfUnderfoot.cs", - "RelativeToolTip": "Verbs\\Verb_ShootSelfUnderfoot.cs", - "ViewState": "AgIAAJAAAAAAAAAAAAAcwJwAAAAoAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-12-16T15:07:22.127Z", - "EditorCaption": "" - }, - { - "$type": "Document", - "DocumentIndex": 4, - "Title": "HediffComp_TopTurret.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HediffComp_TopTurret\\HediffComp_TopTurret.cs", - "RelativeDocumentMoniker": "Hediffs\\ARA_HediffComp_TopTurret\\HediffComp_TopTurret.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HediffComp_TopTurret\\HediffComp_TopTurret.cs", - "RelativeToolTip": "Hediffs\\ARA_HediffComp_TopTurret\\HediffComp_TopTurret.cs", - "ViewState": "AgIAACcBAAAAAAAAAAAkwD0BAAAjAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-12-16T14:52:46.325Z", + "WhenOpened": "2025-12-17T01:51:43.528Z", "EditorCaption": "" }, { "$type": "Document", "DocumentIndex": 5, - "Title": "RoomRoleWorker_Incubator.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\RoomRole\\RoomRoleWorker_Incubator.cs", - "RelativeDocumentMoniker": "RoomRole\\RoomRoleWorker_Incubator.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\RoomRole\\RoomRoleWorker_Incubator.cs", - "RelativeToolTip": "RoomRole\\RoomRoleWorker_Incubator.cs", - "ViewState": "AgIAAAAAAAAAAAAAAAAAABsAAAARAAAAAAAAAA==", + "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": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-12-16T14:32:31.389Z", + "WhenOpened": "2025-12-17T01:33:36.723Z", "EditorCaption": "" }, { "$type": "Document", "DocumentIndex": 6, + "Title": "DefModExtension_NutrientVat.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_NutrientVat\\DefModExtension_NutrientVat.cs", + "RelativeDocumentMoniker": "Building_Comps\\ARA_NutrientVat\\DefModExtension_NutrientVat.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_NutrientVat\\DefModExtension_NutrientVat.cs", + "RelativeToolTip": "Building_Comps\\ARA_NutrientVat\\DefModExtension_NutrientVat.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-17T01:33:35.122Z", + "EditorCaption": "" + }, + { + "$type": "Bookmark", + "Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}" + }, + { + "$type": "Document", + "DocumentIndex": 4, + "Title": "Patch_ResearchManager_AddRemoveMethod.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\HarmonyPatches\\Patch_ResearchManager_AddRemoveMethod.cs", + "RelativeDocumentMoniker": "HarmonyPatches\\Patch_ResearchManager_AddRemoveMethod.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\HarmonyPatches\\Patch_ResearchManager_AddRemoveMethod.cs", + "RelativeToolTip": "HarmonyPatches\\Patch_ResearchManager_AddRemoveMethod.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAkAAAABAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-17T00:42:29.927Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "CompProperties_DestroyRemovesResearch.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\HarmonyPatches\\DestroyRemovesResearch\\CompProperties_DestroyRemovesResearch.cs", + "RelativeDocumentMoniker": "HarmonyPatches\\DestroyRemovesResearch\\CompProperties_DestroyRemovesResearch.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\HarmonyPatches\\DestroyRemovesResearch\\CompProperties_DestroyRemovesResearch.cs", + "RelativeToolTip": "HarmonyPatches\\DestroyRemovesResearch\\CompProperties_DestroyRemovesResearch.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-17T01:03:30.347Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 7, + "Title": "CompDestroyRemovesResearch.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\HarmonyPatches\\DestroyRemovesResearch\\CompDestroyRemovesResearch.cs", + "RelativeDocumentMoniker": "HarmonyPatches\\DestroyRemovesResearch\\CompDestroyRemovesResearch.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\HarmonyPatches\\DestroyRemovesResearch\\CompDestroyRemovesResearch.cs", + "RelativeToolTip": "HarmonyPatches\\DestroyRemovesResearch\\CompDestroyRemovesResearch.cs", + "ViewState": "AgIAADAAAAAAAAAAAAAswD8AAAAsAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-17T01:03:29.291Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 8, + "Title": "JobDriver_StripChitin.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_StripChitin\\JobDriver_StripChitin.cs", + "RelativeDocumentMoniker": "Jobs\\JobDriver_StripChitin\\JobDriver_StripChitin.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_StripChitin\\JobDriver_StripChitin.cs", + "RelativeToolTip": "Jobs\\JobDriver_StripChitin\\JobDriver_StripChitin.cs", + "ViewState": "AgIAAFcAAAAAAAAAAAAAAG0AAAAZAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-16T15:50:38.09Z" + }, + { + "$type": "Document", + "DocumentIndex": 9, + "Title": "CompProperties_ChitinStripping.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_StripChitin\\CompProperties_ChitinStripping.cs", + "RelativeDocumentMoniker": "Jobs\\JobDriver_StripChitin\\CompProperties_ChitinStripping.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_StripChitin\\CompProperties_ChitinStripping.cs", + "RelativeToolTip": "Jobs\\JobDriver_StripChitin\\CompProperties_ChitinStripping.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABcAAAAtAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-16T15:50:04.277Z" + }, + { + "$type": "Document", + "DocumentIndex": 10, + "Title": "Comp_ChitinStripping.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_StripChitin\\Comp_ChitinStripping.cs", + "RelativeDocumentMoniker": "Jobs\\JobDriver_StripChitin\\Comp_ChitinStripping.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_StripChitin\\Comp_ChitinStripping.cs", + "RelativeToolTip": "Jobs\\JobDriver_StripChitin\\Comp_ChitinStripping.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAoAAABWAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-16T15:49:51.675Z" + }, + { + "$type": "Document", + "DocumentIndex": 11, + "Title": "Verb_ShootSelfUnderfoot.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Verbs\\Verb_ShootSelfUnderfoot.cs", + "RelativeDocumentMoniker": "Verbs\\Verb_ShootSelfUnderfoot.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Verbs\\Verb_ShootSelfUnderfoot.cs", + "RelativeToolTip": "Verbs\\Verb_ShootSelfUnderfoot.cs", + "ViewState": "AgIAAJAAAAAAAAAAAAAcwJwAAAAoAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-16T15:07:22.127Z" + }, + { + "$type": "Document", + "DocumentIndex": 12, + "Title": "HediffComp_TopTurret.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HediffComp_TopTurret\\HediffComp_TopTurret.cs", + "RelativeDocumentMoniker": "Hediffs\\ARA_HediffComp_TopTurret\\HediffComp_TopTurret.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HediffComp_TopTurret\\HediffComp_TopTurret.cs", + "RelativeToolTip": "Hediffs\\ARA_HediffComp_TopTurret\\HediffComp_TopTurret.cs", + "ViewState": "AgIAACcBAAAAAAAAAAAkwD0BAAAjAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-16T14:52:46.325Z" + }, + { + "$type": "Document", + "DocumentIndex": 13, + "Title": "RoomRoleWorker_Incubator.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\RoomRole\\RoomRoleWorker_Incubator.cs", + "RelativeDocumentMoniker": "RoomRole\\RoomRoleWorker_Incubator.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\RoomRole\\RoomRoleWorker_Incubator.cs", + "RelativeToolTip": "RoomRole\\RoomRoleWorker_Incubator.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABsAAAARAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-16T14:32:31.389Z" + }, + { + "$type": "Document", + "DocumentIndex": 14, "Title": "CompResearchProducer.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CompInteractiveProducer\\CompResearchProducer.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CompInteractiveProducer\\CompResearchProducer.cs", "RelativeDocumentMoniker": "Building_Comps\\ARA_CompInteractiveProducer\\CompResearchProducer.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CompInteractiveProducer\\CompResearchProducer.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CompInteractiveProducer\\CompResearchProducer.cs", "RelativeToolTip": "Building_Comps\\ARA_CompInteractiveProducer\\CompResearchProducer.cs", "ViewState": "AgIAAAAAAAAAAAAAAADwvy0AAAAAAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", @@ -184,11 +310,11 @@ }, { "$type": "Document", - "DocumentIndex": 8, + "DocumentIndex": 16, "Title": "CompCorpseConverter.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CorpseConverter\\CompCorpseConverter.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CorpseConverter\\CompCorpseConverter.cs", "RelativeDocumentMoniker": "Building_Comps\\ARA_CorpseConverter\\CompCorpseConverter.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CorpseConverter\\CompCorpseConverter.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CorpseConverter\\CompCorpseConverter.cs", "RelativeToolTip": "Building_Comps\\ARA_CorpseConverter\\CompCorpseConverter.cs", "ViewState": "AgIAABwDAAAAAAAAAAAIwCoDAAARAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", @@ -196,11 +322,11 @@ }, { "$type": "Document", - "DocumentIndex": 7, + "DocumentIndex": 15, "Title": "ARA_HediffDefOf.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_HediffDefOf.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_HediffDefOf.cs", "RelativeDocumentMoniker": "ARA_HediffDefOf.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_HediffDefOf.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_HediffDefOf.cs", "RelativeToolTip": "ARA_HediffDefOf.cs", "ViewState": "AgIAAAAAAAAAAAAAAADwvy0AAAAJAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", @@ -208,11 +334,11 @@ }, { "$type": "Document", - "DocumentIndex": 9, + "DocumentIndex": 17, "Title": "CompProperties_CorpseConverter.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CorpseConverter\\CompProperties_CorpseConverter.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CorpseConverter\\CompProperties_CorpseConverter.cs", "RelativeDocumentMoniker": "Building_Comps\\ARA_CorpseConverter\\CompProperties_CorpseConverter.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CorpseConverter\\CompProperties_CorpseConverter.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CorpseConverter\\CompProperties_CorpseConverter.cs", "RelativeToolTip": "Building_Comps\\ARA_CorpseConverter\\CompProperties_CorpseConverter.cs", "ViewState": "AgIAAAAAAAAAAAAAAADwvwAAAAAAAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", @@ -220,11 +346,11 @@ }, { "$type": "Document", - "DocumentIndex": 12, + "DocumentIndex": 20, "Title": "CompRefuelableNutrition_WithKey.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\WULA_MutiFuelSpawner\\CompRefuelableNutrition_WithKey.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\WULA_MutiFuelSpawner\\CompRefuelableNutrition_WithKey.cs", "RelativeDocumentMoniker": "Building_Comps\\WULA_MutiFuelSpawner\\CompRefuelableNutrition_WithKey.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\WULA_MutiFuelSpawner\\CompRefuelableNutrition_WithKey.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\WULA_MutiFuelSpawner\\CompRefuelableNutrition_WithKey.cs", "RelativeToolTip": "Building_Comps\\WULA_MutiFuelSpawner\\CompRefuelableNutrition_WithKey.cs", "ViewState": "AgIAAAAAAAAAAAAAAAAAACUAAABAAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", @@ -232,11 +358,11 @@ }, { "$type": "Document", - "DocumentIndex": 10, + "DocumentIndex": 18, "Title": "CompTerrainChanger.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_TerrainChanger\\CompTerrainChanger.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_TerrainChanger\\CompTerrainChanger.cs", "RelativeDocumentMoniker": "Building_Comps\\ARA_TerrainChanger\\CompTerrainChanger.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_TerrainChanger\\CompTerrainChanger.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_TerrainChanger\\CompTerrainChanger.cs", "RelativeToolTip": "Building_Comps\\ARA_TerrainChanger\\CompTerrainChanger.cs", "ViewState": "AgIAAK0CAAAAAAAAAAAcwPYCAAAMAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", @@ -244,11 +370,11 @@ }, { "$type": "Document", - "DocumentIndex": 11, + "DocumentIndex": 19, "Title": "CompProperties_TerrainChanger.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_TerrainChanger\\CompProperties_TerrainChanger.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_TerrainChanger\\CompProperties_TerrainChanger.cs", "RelativeDocumentMoniker": "Building_Comps\\ARA_TerrainChanger\\CompProperties_TerrainChanger.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_TerrainChanger\\CompProperties_TerrainChanger.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_TerrainChanger\\CompProperties_TerrainChanger.cs", "RelativeToolTip": "Building_Comps\\ARA_TerrainChanger\\CompProperties_TerrainChanger.cs", "ViewState": "AgIAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", @@ -256,11 +382,11 @@ }, { "$type": "Document", - "DocumentIndex": 13, + "DocumentIndex": 21, "Title": "Building_RefuelingVat.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_Building_RefuelingVat\\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": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\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": "AgIAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", @@ -268,23 +394,11 @@ }, { "$type": "Document", - "DocumentIndex": 14, - "Title": "CompProperties_IncubatorData.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs", - "RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs", - "RelativeToolTip": "Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs", - "ViewState": "AgIAANcAAAAAAAAAAIA1wPoAAAAxAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-12-16T04:37:03.042Z" - }, - { - "$type": "Document", - "DocumentIndex": 15, + "DocumentIndex": 22, "Title": "OothecaIncubatorExtension.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\OothecaIncubatorExtension.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\OothecaIncubatorExtension.cs", "RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\OothecaIncubatorExtension.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\OothecaIncubatorExtension.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\OothecaIncubatorExtension.cs", "RelativeToolTip": "Buildings\\Building_Ootheca\\OothecaIncubatorExtension.cs", "ViewState": "AgIAAAAAAAAAAAAAAADwvxUAAABBAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", @@ -292,11 +406,11 @@ }, { "$type": "Document", - "DocumentIndex": 18, + "DocumentIndex": 25, "Title": "Building_EquipmentOotheca.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\Building_EquipmentOotheca.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\Building_EquipmentOotheca.cs", "RelativeDocumentMoniker": "Buildings\\Building_EquipmentOotheca\\Building_EquipmentOotheca.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\Building_EquipmentOotheca.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\Building_EquipmentOotheca.cs", "RelativeToolTip": "Buildings\\Building_EquipmentOotheca\\Building_EquipmentOotheca.cs", "ViewState": "AgIAACcAAAAAAAAAAAAAADoDAABSAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", @@ -304,11 +418,11 @@ }, { "$type": "Document", - "DocumentIndex": 16, + "DocumentIndex": 23, "Title": "Building_Ootheca.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\Building_Ootheca.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\Building_Ootheca.cs", "RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\Building_Ootheca.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\Building_Ootheca.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\Building_Ootheca.cs", "RelativeToolTip": "Buildings\\Building_Ootheca\\Building_Ootheca.cs", "ViewState": "AgIAALcCAAAAAAAAAAAewNgCAAAVAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", @@ -316,11 +430,11 @@ }, { "$type": "Document", - "DocumentIndex": 17, + "DocumentIndex": 24, "Title": "CompProperties_EquipmentIncubatorData.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\CompProperties_EquipmentIncubatorData.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\CompProperties_EquipmentIncubatorData.cs", "RelativeDocumentMoniker": "Buildings\\Building_EquipmentOotheca\\CompProperties_EquipmentIncubatorData.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\CompProperties_EquipmentIncubatorData.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\CompProperties_EquipmentIncubatorData.cs", "RelativeToolTip": "Buildings\\Building_EquipmentOotheca\\CompProperties_EquipmentIncubatorData.cs", "ViewState": "AgIAAA4AAAAAAAAAAADwvyYAAAAaAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj index d904c86..5966b79 100644 --- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj +++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj @@ -124,11 +124,17 @@ + + + + + + - - - + + + diff --git a/Source/ArachnaeSwarm/Buildings/Building_Ootheca/CompProperties_IncubatorData.cs b/Source/ArachnaeSwarm/Buildings/Building_Ootheca/CompProperties_IncubatorData.cs index eb3c4c0..ea634f1 100644 --- a/Source/ArachnaeSwarm/Buildings/Building_Ootheca/CompProperties_IncubatorData.cs +++ b/Source/ArachnaeSwarm/Buildings/Building_Ootheca/CompProperties_IncubatorData.cs @@ -294,7 +294,7 @@ namespace ArachnaeSwarm new QualityHediffReward(0.30f, 1, false, "ARA_QualityReward_1Hediff"), new QualityHediffReward(0.50f, 2, false, "ARA_QualityReward_2Hediff"), new QualityHediffReward(0.85f, 3, false, "ARA_QualityReward_3Hediff"), - new QualityHediffReward(0.99f, 4, true, "ARA_QualityReward_AllHediff") + new QualityHediffReward(0.99f, 4, false, "ARA_QualityReward_4Hediff") }; } diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_Building_RefuelingVat/Building_RefuelingVat.cs b/Source/ArachnaeSwarm/Buildings/Building_RefuelingVat/Building_RefuelingVat.cs similarity index 100% rename from Source/ArachnaeSwarm/Building_Comps/ARA_Building_RefuelingVat/Building_RefuelingVat.cs rename to Source/ArachnaeSwarm/Buildings/Building_RefuelingVat/Building_RefuelingVat.cs diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_Building_RefuelingVat/CompProperties_RefuelingVat.cs b/Source/ArachnaeSwarm/Buildings/Building_RefuelingVat/CompProperties_RefuelingVat.cs similarity index 100% rename from Source/ArachnaeSwarm/Building_Comps/ARA_Building_RefuelingVat/CompProperties_RefuelingVat.cs rename to Source/ArachnaeSwarm/Buildings/Building_RefuelingVat/CompProperties_RefuelingVat.cs diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_Building_RefuelingVat/CompRefuelingVat.cs b/Source/ArachnaeSwarm/Buildings/Building_RefuelingVat/CompRefuelingVat.cs similarity index 100% rename from Source/ArachnaeSwarm/Building_Comps/ARA_Building_RefuelingVat/CompRefuelingVat.cs rename to Source/ArachnaeSwarm/Buildings/Building_RefuelingVat/CompRefuelingVat.cs diff --git a/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/Building_ResearchBlueprintReader.cs b/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/Building_ResearchBlueprintReader.cs new file mode 100644 index 0000000..1b6b943 --- /dev/null +++ b/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/Building_ResearchBlueprintReader.cs @@ -0,0 +1,598 @@ +// File: Buildings/Building_ResearchBlueprintReader.cs +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using Verse; + +namespace ArachnaeSwarm +{ + public class Building_ResearchBlueprintReader : Building + { + // 当前正在研究的科技 + private ResearchProjectDef currentResearch; + + // 当前研究进度 + private float progress; + + // 自动研究标志 + private bool autoResearch; + + // 储存的科技 + private ResearchProjectDef storedResearch; + + // 锁定信息 + private ResearchBlueprintLockInfo lockInfo; + + // 管理器引用 + private ResearchBlueprintReaderManager manager; + + // 电力组件 + private CompPowerTrader powerComp; + + public ResearchProjectDef CurrentResearch => currentResearch; + public float Progress => progress; + public float ProgressPercent => currentResearch != null ? progress / currentResearch.baseCost : 0f; + public ResearchProjectDef StoredResearch => storedResearch; + public bool IsLocked => storedResearch != null; + public ResearchBlueprintReaderManager Manager + { + get => manager; + set => manager = value; + } + + // 获取研究速度 + private float ResearchSpeed + { + get + { + var ext = this.def.GetModExtension(); + return ext?.researchSpeed ?? 10f; + } + } + + // 是否允许储存科技 + private bool CanStoreResearch + { + get + { + var ext = this.def.GetModExtension(); + return ext?.canStoreResearch ?? true; + } + } + + public override void ExposeData() + { + base.ExposeData(); + + Scribe_Defs.Look(ref currentResearch, "currentResearch"); + Scribe_Values.Look(ref progress, "progress", 0f); + Scribe_Values.Look(ref autoResearch, "autoResearch", false); + Scribe_Defs.Look(ref storedResearch, "storedResearch"); + Scribe_Deep.Look(ref lockInfo, "lockInfo"); + + if (Scribe.mode == LoadSaveMode.LoadingVars) + { + // 加载时重建与管理器的连接 + manager = ResearchBlueprintReaderManager.Instance; + if (manager != null) + { + manager.RegisterReader(this); + } + } + } + + public override void SpawnSetup(Map map, bool respawningAfterLoad) + { + base.SpawnSetup(map, respawningAfterLoad); + + // 获取管理器 + manager = ResearchBlueprintReaderManager.Instance; + if (manager != null) + { + manager.RegisterReader(this); + } + + // 获取电力组件 + powerComp = GetComp(); + + Log.Message($"[ResearchBlueprintReader] Spawned at {Position}, Manager: {manager != null}"); + } + + public override void Destroy(DestroyMode mode = DestroyMode.Vanish) + { + // 如果建筑储存了科技,先释放 + if (storedResearch != null) + { + if (manager != null) + { + manager.ReleaseStoredResearch(storedResearch); + } + else + { + // 如果没有管理器,直接移除科技 + Utilities.ResearchRemover.RemoveResearchProject(storedResearch, false); + } + } + + // 注销建筑 + if (manager != null) + { + manager.UnregisterReader(this); + } + + base.Destroy(mode); + } + + protected override void Tick() + { + base.Tick(); + + // 检查电力 + bool hasPower = powerComp == null || powerComp.PowerOn; + + // 如果启用了自动研究且有研究项目,则增加进度 + if (hasPower && autoResearch && currentResearch != null && !currentResearch.IsFinished && !IsLocked) + { + float speed = ResearchSpeed; + + // 应用电力效率 + if (powerComp != null) + { + var ext = this.def.GetModExtension(); + if (ext != null) + { + float efficiency = powerComp.PowerNet.CurrentStoredEnergy() / powerComp.PowerNet.batteryComps.Sum(b => b.Props.storedEnergyMax); + speed *= Mathf.Lerp(0.5f, 1f, efficiency); + } + } + + AddResearchProgress(speed / 60f); // 转换为每Tick + + // 检查是否完成 + if (progress >= currentResearch.baseCost) + { + CompleteCurrentResearch(); + } + } + } + + private void AddResearchProgress(float amount) + { + progress += amount; + + // 将进度添加到研究管理器 + Find.ResearchManager.AddProgress(currentResearch, amount); + + // 更新进度显示 + if (Find.TickManager.TicksGame % 60 == 0) // 每秒更新一次视觉效果 + { + // 可以添加一些视觉效果,比如闪烁灯光 + } + } + + private void CompleteCurrentResearch() + { + if (currentResearch != null && !currentResearch.IsFinished) + { + Log.Message($"[ResearchBlueprintReader] Completing research: {currentResearch.defName} at {Position}"); + + if (CanStoreResearch && manager != null) + { + // 请求管理器处理完成和储存 + manager.RequestResearchCompletion(this, currentResearch); + } + else + { + // 如果不能储存,直接完成 + Find.ResearchManager.FinishProject(currentResearch, doCompletionDialog: false); + Messages.Message($"研究完成: {currentResearch.LabelCap}", + MessageTypeDefOf.PositiveEvent); + + // 重置状态 + currentResearch = null; + progress = 0f; + autoResearch = false; + } + } + } + + /// + /// 锁定建筑以储存科技(由管理器调用) + /// + public void LockForStorage(ResearchProjectDef project, ResearchBlueprintLockInfo info) + { + if (project == null || info == null) return; + + storedResearch = project; + lockInfo = info; + + // 停止当前研究 + currentResearch = null; + progress = 0f; + autoResearch = false; + + Log.Message($"[ResearchBlueprintReader] Locked for storing {project.defName}"); + } + + /// + /// 解锁建筑(释放储存的科技) + /// + public void UnlockBuilding() + { + if (storedResearch != null) + { + var project = storedResearch; + storedResearch = null; + lockInfo = null; + + // 移除科技完成状态 + Utilities.ResearchRemover.RemoveResearchProject(project, false); + + Messages.Message($"建筑已解锁,科技已移除: {project.LabelCap}", + MessageTypeDefOf.NeutralEvent); + + Log.Message($"[ResearchBlueprintReader] Unlocked and removed {project.defName}"); + } + } + + public void StartResearch(ResearchProjectDef project) + { + if (IsLocked) + { + Messages.Message("建筑已锁定储存科技,无法开始新研究", + MessageTypeDefOf.RejectInput); + return; + } + + if (project == null || project.IsFinished || project.techprintCount <= 0) + return; + + // 检查科技是否已被其他建筑储存 + if (manager != null && manager.IsResearchStored(project)) + { + Messages.Message($"科技已被其他建筑储存: {project.LabelCap}", + MessageTypeDefOf.RejectInput); + return; + } + + currentResearch = project; + progress = Find.ResearchManager.GetProgress(project); + + Messages.Message($"开始研究: {project.LabelCap}", + MessageTypeDefOf.NeutralEvent); + } + + public void StopResearch() + { + if (currentResearch != null) + { + Messages.Message($"停止研究: {currentResearch.LabelCap}", + MessageTypeDefOf.NeutralEvent); + + currentResearch = null; + progress = 0f; + autoResearch = false; + } + } + + public override IEnumerable GetGizmos() + { + foreach (Gizmo gizmo in base.GetGizmos()) + { + yield return gizmo; + } + + // 如果已锁定,显示解锁按钮 + if (IsLocked) + { + var unlockCmd = new Command_Action(); + unlockCmd.defaultLabel = "解锁建筑"; + unlockCmd.defaultDesc = "释放储存的科技,允许重新研究"; + unlockCmd.icon = ContentFinder.Get("UI/Designators/Unlock", false); + unlockCmd.action = delegate + { + if (manager != null) + { + manager.ReleaseStoredResearch(storedResearch); + storedResearch = null; + lockInfo = null; + } + }; + yield return unlockCmd; + + // 显示储存信息 + var infoCmd = new Command_Action(); + infoCmd.defaultLabel = $"储存: {storedResearch.LabelCap}"; + infoCmd.defaultDesc = "点击查看详细信息"; + infoCmd.icon = ContentFinder.Get("UI/Designators/Info", false); + infoCmd.action = delegate + { + Messages.Message($"此建筑储存着: {storedResearch.LabelCap}\n" + + $"描述: {storedResearch.description.StripTags()}", + MessageTypeDefOf.NeutralEvent); + }; + yield return infoCmd; + + yield break; // 锁定状态下不显示其他按钮 + } + + // 选择研究按钮 + var selectCmd = new Command_Action(); + selectCmd.defaultLabel = "选择研究项目"; + selectCmd.defaultDesc = "选择要自动研究的科技项目"; + selectCmd.icon = ContentFinder.Get("UI/Designators/Research", false); + selectCmd.action = delegate + { + ShowResearchMenu(); + }; + yield return selectCmd; + + // 如果已有研究项目,显示停止按钮 + if (currentResearch != null) + { + var stopCmd = new Command_Action(); + stopCmd.defaultLabel = "停止研究"; + stopCmd.defaultDesc = "停止当前的研究项目"; + stopCmd.icon = ContentFinder.Get("UI/Designators/Cancel", false); + stopCmd.action = StopResearch; + yield return stopCmd; + } + + // 自动研究切换按钮 + var autoCmd = new Command_Toggle(); + autoCmd.defaultLabel = "自动研究"; + autoCmd.defaultDesc = "开启/关闭自动研究功能"; + autoCmd.icon = ContentFinder.Get("UI/Widgets/CheckOn", false); + autoCmd.isActive = () => autoResearch; + autoCmd.toggleAction = delegate + { + autoResearch = !autoResearch; + Messages.Message($"自动研究: {(autoResearch ? "开启" : "关闭")}", + MessageTypeDefOf.NeutralEvent); + }; + yield return autoCmd; + + // 调试按钮:快速完成研究 + if (DebugSettings.godMode && currentResearch != null) + { + var debugCmd = new Command_Action(); + debugCmd.defaultLabel = "调试: 快速完成"; + debugCmd.defaultDesc = "立即完成当前研究"; + debugCmd.icon = ContentFinder.Get("UI/Designators/Dev", false); + debugCmd.action = delegate + { + progress = currentResearch.baseCost; + CompleteCurrentResearch(); + }; + yield return debugCmd; + } + } + + private void ShowResearchMenu() + { + try + { + var araTab = DefDatabase.GetNamedSilentFail("ARA_ResearchTab"); + if (araTab == null) + { + Messages.Message("ARA_ResearchTab未找到", MessageTypeDefOf.RejectInput); + return; + } + + var availableProjects = DefDatabase.AllDefsListForReading + .Where(p => p.tab == araTab && p.techprintCount > 0 && !p.IsFinished) + .ToList(); + + if (availableProjects.Count == 0) + { + Messages.Message("没有可用的科技项目", MessageTypeDefOf.NeutralEvent); + return; + } + + List options = new List(); + var sortedProjects = availableProjects.OrderBy(p => p.defName).ToList(); + + foreach (var project in sortedProjects) + { + bool allPrerequisitesMet = AreAllPrerequisitesCompleted(project); + + // 检查是否已被储存 + bool isStored = manager != null && manager.IsResearchStored(project); + + string label = project.LabelCap.RawText ?? project.defName; + float currentProgress = Find.ResearchManager.GetProgress(project); + + if (currentProgress > 0) + label += $" ({currentProgress:F0}/{project.baseCost:F0})"; + + if (isStored) + { + label = $"{label} [已储存]"; + } + else if (!allPrerequisitesMet) + { + bool missingHidden = HasMissingHiddenPrerequisites(project); + if (missingHidden) + label = $"{label} [需要隐藏前置]"; + else + label = $"{label} [需要前置条件]"; + } + + var option = new FloatMenuOption(label, () => StartResearch(project)) + { + Disabled = !allPrerequisitesMet || isStored, + tooltip = GetProjectTooltip(project, allPrerequisitesMet, isStored) + }; + + options.Add(option); + } + + if (options.Count > 0) + { + Find.WindowStack.Add(new FloatMenu(options)); + } + } + catch (Exception ex) + { + Log.Error($"[ResearchBlueprintReader] Error in ShowResearchMenu: {ex}"); + Messages.Message($"显示研究菜单时出错: {ex.Message}", + MessageTypeDefOf.NegativeEvent); + } + } + + private bool AreAllPrerequisitesCompleted(ResearchProjectDef project) + { + // 检查普通前置 + if (project.prerequisites != null) + { + foreach (var prereq in project.prerequisites) + { + if (!prereq.IsFinished) + return false; + } + } + + // 检查隐藏前置 + if (project.hiddenPrerequisites != null) + { + foreach (var hiddenPrereq in project.hiddenPrerequisites) + { + if (hiddenPrereq != null && !hiddenPrereq.IsFinished) + return false; + } + } + + return true; + } + + private bool HasMissingHiddenPrerequisites(ResearchProjectDef project) + { + if (project.hiddenPrerequisites != null) + { + foreach (var hiddenPrereq in project.hiddenPrerequisites) + { + if (hiddenPrereq != null && !hiddenPrereq.IsFinished) + return true; + } + } + return false; + } + + private string GetProjectTooltip(ResearchProjectDef project, bool prerequisitesMet, bool isStored) + { + var builder = new System.Text.StringBuilder(); + + builder.AppendLine(project.description.StripTags()); + builder.AppendLine(); + + builder.AppendLine($"成本: {project.baseCost}"); + builder.AppendLine($"所需蓝图数量: {project.techprintCount}"); + + if (isStored) + { + builder.AppendLine(); + builder.AppendLine("⚠ 此科技已被其他建筑储存"); + var storageBuilding = manager?.GetStorageBuildingFor(project); + if (storageBuilding != null) + { + builder.AppendLine($"储存建筑: {storageBuilding.Position}"); + } + } + + // 检查所有未完成的前置(包括隐藏的) + List missingPrereqs = new List(); + + // 普通前置 + if (project.prerequisites != null) + { + foreach (var prereq in project.prerequisites) + { + if (!prereq.IsFinished) + missingPrereqs.Add(prereq); + } + } + + // 隐藏前置 + if (project.hiddenPrerequisites != null) + { + foreach (var hiddenPrereq in project.hiddenPrerequisites) + { + if (hiddenPrereq != null && !hiddenPrereq.IsFinished) + missingPrereqs.Add(hiddenPrereq); + } + } + + if (missingPrereqs.Count > 0) + { + builder.AppendLine(); + builder.AppendLine("缺失的前置科技:"); + + foreach (var prereq in missingPrereqs) + { + string label = prereq.LabelCap.RawText ?? prereq.defName; + bool isHidden = project.hiddenPrerequisites != null && + project.hiddenPrerequisites.Contains(prereq); + + if (isHidden) + builder.AppendLine($" • {label} [隐藏前置]"); + else + builder.AppendLine($" • {label}"); + } + } + + return builder.ToString(); + } + + public override string GetInspectString() + { + var builder = new System.Text.StringBuilder(base.GetInspectString()); + + if (builder.Length > 0) + builder.AppendLine(); + + if (IsLocked) + { + builder.AppendLine($"🔒 储存科技: {storedResearch.LabelCap}"); + if (lockInfo != null) + { + int days = lockInfo.storeTime / 60000; + builder.AppendLine($"储存时间: {days}天"); + } + } + else if (currentResearch != null) + { + builder.AppendLine($"正在研究: {currentResearch.LabelCap}"); + builder.AppendLine($"进度: {progress:F0}/{currentResearch.baseCost:F0} ({ProgressPercent:P0})"); + builder.Append($"自动研究: {(autoResearch ? "开启" : "关闭")}"); + + // 显示研究速度 + builder.AppendLine(); + builder.Append($"研究速度: {ResearchSpeed:F1}/秒"); + } + else + { + builder.Append("未选择研究项目"); + } + + return builder.ToString().TrimEndNewlines(); + } + + // 供其他系统调用的方法 + public bool IsResearchingProject(ResearchProjectDef project) + { + return currentResearch == project; + } + + public bool CanResearchProject(ResearchProjectDef project) + { + if (project == null) return false; + if (project.tab == null || project.tab.defName != "ARA_ResearchTab") return false; + if (project.techprintCount <= 0) return false; + if (project.IsFinished) return false; + if (manager != null && manager.IsResearchStored(project)) return false; + return AreAllPrerequisitesCompleted(project); + } + } +} diff --git a/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/ResearchBlueprintReaderExtension.cs b/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/ResearchBlueprintReaderExtension.cs new file mode 100644 index 0000000..5764e0d --- /dev/null +++ b/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/ResearchBlueprintReaderExtension.cs @@ -0,0 +1,18 @@ +// File: ModExtensions/ResearchBlueprintReaderExtension.cs +using RimWorld; +using Verse; + +namespace ArachnaeSwarm +{ + public class ResearchBlueprintReaderExtension : DefModExtension + { + // 研究速度(每秒增加的点数),可以配置 + public float researchSpeed = 10f; + + // 是否允许储存科技(锁定功能) + public bool canStoreResearch = true; + + // 科技储存的持续时间(天),0表示永久 + public float researchStorageDays = 0f; + } +} diff --git a/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/ResearchBlueprintReaderManager.cs b/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/ResearchBlueprintReaderManager.cs new file mode 100644 index 0000000..55013c0 --- /dev/null +++ b/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/ResearchBlueprintReaderManager.cs @@ -0,0 +1,386 @@ +// File: Managers/ResearchBlueprintReaderManager.cs +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using Verse; + +namespace ArachnaeSwarm +{ + public class ResearchBlueprintReaderManager : GameComponent + { + // 单例实例 + private static ResearchBlueprintReaderManager instance; + + // 储存已锁定科技的建筑列表 + private Dictionary lockedResearches; + + // 所有正在运行的建筑 + private List activeReaders; + + // 所有储存科技的建筑 + private List storageReaders; + + // 待处理的完成研究列表(防止竞争条件) + private List pendingCompletions; + + // 清理计时器 + private int cleanupTimer; + private const int CleanupInterval = 2500; // 每2500ticks清理一次 + + public ResearchBlueprintReaderManager(Game game) : base() + { + instance = this; + lockedResearches = new Dictionary(); + activeReaders = new List(); + storageReaders = new List(); + pendingCompletions = new List(); + } + + public static ResearchBlueprintReaderManager Instance => instance; + + public override void ExposeData() + { + base.ExposeData(); + + Scribe_Collections.Look(ref lockedResearches, "lockedResearches", LookMode.Def, LookMode.Deep); + Scribe_Collections.Look(ref activeReaders, "activeReaders", LookMode.Reference); + Scribe_Collections.Look(ref storageReaders, "storageReaders", LookMode.Reference); + Scribe_Collections.Look(ref pendingCompletions, "pendingCompletions", LookMode.Deep); + + // 修复引用丢失问题 + if (Scribe.mode == LoadSaveMode.LoadingVars) + { + lockedResearches = lockedResearches ?? new Dictionary(); + activeReaders = activeReaders ?? new List(); + storageReaders = storageReaders ?? new List(); + pendingCompletions = pendingCompletions ?? new List(); + } + + if (Scribe.mode == LoadSaveMode.PostLoadInit) + { + // 移除空引用 + activeReaders.RemoveAll(r => r == null || r.Destroyed); + storageReaders.RemoveAll(r => r == null || r.Destroyed); + + // 重建管理器与建筑的连接 + foreach (var reader in activeReaders.Concat(storageReaders)) + { + if (reader != null && !reader.Destroyed) + { + reader.Manager = this; + } + } + } + } + + public override void GameComponentTick() + { + base.GameComponentTick(); + + // 清理计时器 + cleanupTimer++; + if (cleanupTimer >= CleanupInterval) + { + CleanupDestroyedBuildings(); + cleanupTimer = 0; + } + + // 处理待完成的请求 + if (pendingCompletions.Count > 0) + { + ProcessPendingCompletions(); + } + } + + /// + /// 注册活动建筑 + /// + public void RegisterReader(Building_ResearchBlueprintReader reader) + { + if (reader == null || reader.Destroyed) return; + + if (!activeReaders.Contains(reader)) + { + activeReaders.Add(reader); + reader.Manager = this; + Log.Message($"[ResearchManager] Registered reader at {reader.Position}"); + } + } + + /// + /// 注销建筑 + /// + public void UnregisterReader(Building_ResearchBlueprintReader reader) + { + activeReaders.Remove(reader); + storageReaders.Remove(reader); + + // 如果建筑储存了科技,释放该科技 + if (reader.StoredResearch != null) + { + ReleaseStoredResearch(reader.StoredResearch); + Log.Message($"[ResearchManager] Unregistered and released research from reader at {reader.Position}"); + } + } + + /// + /// 请求完成研究(由建筑调用) + /// + public void RequestResearchCompletion(Building_ResearchBlueprintReader reader, ResearchProjectDef project) + { + if (reader == null || project == null || reader.Destroyed) return; + + // 检查是否已经有建筑在储存这个科技 + if (lockedResearches.ContainsKey(project)) + { + Log.Message($"[ResearchManager] {project.defName} is already stored, rejecting request from {reader.Position}"); + reader.StopResearch(); + Messages.Message($"科技已由其他建筑储存: {project.LabelCap}", + MessageTypeDefOf.RejectInput); + return; + } + + // 添加待处理请求 + var request = new ResearchCompletionRequest + { + reader = reader, + project = project, + timestamp = Find.TickManager.TicksGame + }; + + pendingCompletions.Add(request); + Log.Message($"[ResearchManager] Added completion request for {project.defName} from {reader.Position}"); + } + + /// + /// 处理待完成的请求 + /// + private void ProcessPendingCompletions() + { + // 按时间顺序处理 + var sortedRequests = pendingCompletions + .OrderBy(r => r.timestamp) + .ToList(); + + foreach (var request in sortedRequests) + { + if (request.reader == null || request.reader.Destroyed || + request.project == null || request.project.IsFinished) + { + pendingCompletions.Remove(request); + continue; + } + + // 检查是否仍然有效 + if (!lockedResearches.ContainsKey(request.project)) + { + CompleteResearchAndStore(request.reader, request.project); + pendingCompletions.Remove(request); + return; // 一次只处理一个 + } + else + { + // 已经被其他建筑储存,拒绝这个请求 + request.reader.StopResearch(); + pendingCompletions.Remove(request); + Log.Message($"[ResearchManager] Rejected duplicate request for {request.project.defName}"); + } + } + } + + /// + /// 完成研究并储存在建筑中 + /// + private void CompleteResearchAndStore(Building_ResearchBlueprintReader reader, ResearchProjectDef project) + { + try + { + Log.Message($"[ResearchManager] Completing and storing {project.defName} at {reader.Position}"); + + // 1. 标记科技为已完成 + Find.ResearchManager.FinishProject(project, doCompletionDialog: false); + + // 2. 创建锁定信息 + var lockInfo = new ResearchBlueprintLockInfo + { + storedProject = project, + storingBuilding = reader, + storeTime = Find.TickManager.TicksGame, + mapIndex = reader.Map.Index + }; + + // 3. 将建筑移到储存列表 + activeReaders.Remove(reader); + if (!storageReaders.Contains(reader)) + { + storageReaders.Add(reader); + } + + // 4. 锁定建筑 + reader.LockForStorage(project, lockInfo); + + // 5. 记录锁定信息 + lockedResearches[project] = lockInfo; + + // 6. 发送消息 + Messages.Message($"科技已储存至建筑: {project.LabelCap}", + MessageTypeDefOf.PositiveEvent); + + Log.Message($"[ResearchManager] Successfully stored {project.defName} at {reader.Position}"); + } + catch (Exception ex) + { + Log.Error($"[ResearchManager] Error storing research {project.defName}: {ex}"); + Messages.Message($"储存科技时出错: {ex.Message}", + MessageTypeDefOf.NegativeEvent); + } + } + + /// + /// 检查建筑是否正在研究已储存的科技 + /// + public bool IsResearchStored(ResearchProjectDef project) + { + return lockedResearches.ContainsKey(project); + } + + /// + /// 释放储存的科技(当建筑被摧毁时) + /// + public void ReleaseStoredResearch(ResearchProjectDef project) + { + if (lockedResearches.TryGetValue(project, out var lockInfo)) + { + // 移除科技完成状态 + Utilities.ResearchRemover.RemoveResearchProject(project, false); + + // 从字典中移除 + lockedResearches.Remove(project); + + // 从储存列表中移除建筑 + if (lockInfo.storingBuilding != null && !lockInfo.storingBuilding.Destroyed) + { + storageReaders.Remove(lockInfo.storingBuilding); + activeReaders.Remove(lockInfo.storingBuilding); + } + + Messages.Message($"科技已丢失: {project.LabelCap}", + MessageTypeDefOf.NegativeEvent); + + Log.Message($"[ResearchManager] Released stored research: {project.defName}"); + } + } + + /// + /// 清理被摧毁的建筑 + /// + private void CleanupDestroyedBuildings() + { + // 清理活动建筑 + int activeCount = activeReaders.Count; + activeReaders.RemoveAll(r => r == null || r.Destroyed); + + // 清理储存建筑 + int storageCount = storageReaders.Count; + storageReaders.RemoveAll(r => r == null || r.Destroyed); + + // 清理锁定的研究中已摧毁的建筑 + var toRemove = new List(); + foreach (var kvp in lockedResearches) + { + var building = kvp.Value.storingBuilding; + if (building == null || building.Destroyed) + { + toRemove.Add(kvp.Key); + } + } + + foreach (var project in toRemove) + { + ReleaseStoredResearch(project); + } + + // 清理待处理请求 + pendingCompletions.RemoveAll(r => + r.reader == null || r.reader.Destroyed || + r.project == null || r.project.IsFinished); + + Log.Message($"[ResearchManager] Cleanup: removed {activeCount - activeReaders.Count} active, {storageCount - storageReaders.Count} storage, {toRemove.Count} locked"); + } + + /// + /// 获取所有储存的建筑 + /// + public IEnumerable GetStorageBuildings() + { + return storageReaders.Where(r => r != null && !r.Destroyed); + } + + /// + /// 获取特定科技的储存建筑 + /// + public Building_ResearchBlueprintReader GetStorageBuildingFor(ResearchProjectDef project) + { + if (lockedResearches.TryGetValue(project, out var lockInfo)) + { + return lockInfo.storingBuilding; + } + return null; + } + + public static void ShowManagerStatus() + { + if (Instance == null) + { + Log.Message("[ResearchManager] No instance found"); + return; + } + + Log.Message($"=== 研究管理器状态 ==="); + Log.Message($"活动建筑: {Instance.activeReaders.Count}"); + Log.Message($"储存建筑: {Instance.storageReaders.Count}"); + Log.Message($"锁定科技: {Instance.lockedResearches.Count}"); + Log.Message($"待处理请求: {Instance.pendingCompletions.Count}"); + + foreach (var kvp in Instance.lockedResearches) + { + var building = kvp.Value.storingBuilding; + Log.Message($" - {kvp.Key.defName}: 储存于 {building?.Position.ToString() ?? "无建筑"}"); + } + } + } + + // 研究锁定信息 + public class ResearchBlueprintLockInfo : IExposable + { + public ResearchProjectDef storedProject; + public Building_ResearchBlueprintReader storingBuilding; + public int storeTime; + public int mapIndex; + + public void ExposeData() + { + Scribe_Defs.Look(ref storedProject, "storedProject"); + Scribe_References.Look(ref storingBuilding, "storingBuilding"); + Scribe_Values.Look(ref storeTime, "storeTime", 0); + Scribe_Values.Look(ref mapIndex, "mapIndex", 0); + } + } + + // 研究完成请求 + public class ResearchCompletionRequest : IExposable + { + public Building_ResearchBlueprintReader reader; + public ResearchProjectDef project; + public int timestamp; + + public void ExposeData() + { + Scribe_References.Look(ref reader, "reader"); + Scribe_Defs.Look(ref project, "project"); + Scribe_Values.Look(ref timestamp, "timestamp", 0); + } + } +} diff --git a/Source/ArachnaeSwarm/HarmonyPatches/DestroyRemovesResearch/CompDestroyRemovesResearch.cs b/Source/ArachnaeSwarm/HarmonyPatches/DestroyRemovesResearch/CompDestroyRemovesResearch.cs new file mode 100644 index 0000000..ead679a --- /dev/null +++ b/Source/ArachnaeSwarm/HarmonyPatches/DestroyRemovesResearch/CompDestroyRemovesResearch.cs @@ -0,0 +1,235 @@ +// File: Comps/CompDestroyRemovesResearch.cs +using RimWorld; +using System.Collections.Generic; +using System.Linq; +using Verse; +using UnityEngine; + +namespace ArachnaeSwarm.Comps +{ + public class CompDestroyRemovesResearch : ThingComp + { + private CompProperties_DestroyRemovesResearch Props => (CompProperties_DestroyRemovesResearch)props; + + private bool researchRemoved = false; + + public override void PostDestroy(DestroyMode mode, Map previousMap) + { + base.PostDestroy(mode, previousMap); + + // 只在特定摧毁模式下触发 + if (mode == DestroyMode.Vanish || mode == DestroyMode.WillReplace) + { + return; + } + + // 确保只执行一次 + if (researchRemoved) return; + researchRemoved = true; + + // 获取所有已完成的科技 + var finishedProjects = DefDatabase.AllDefs + .Where(p => p.IsFinished) + .ToList(); + + if (finishedProjects.Count == 0) + { + return; + } + + // 确定要移除的数量 + int numToRemove = Props.minResearchToRemove; + if (Props.maxResearchToRemove > Props.minResearchToRemove) + { + numToRemove = Rand.RangeInclusive(Props.minResearchToRemove, Props.maxResearchToRemove); + } + numToRemove = Mathf.Min(numToRemove, finishedProjects.Count); + + // 选择要移除的科技 + List projectsToRemove = new List(); + + for (int i = 0; i < numToRemove; i++) + { + var project = SelectResearchProject(finishedProjects, projectsToRemove); + if (project != null) + { + projectsToRemove.Add(project); + } + else + { + break; + } + } + + if (projectsToRemove.Count == 0) + { + return; + } + + // 移除选中的科技 + int removedCount = 0; + foreach (var project in projectsToRemove) + { + if (Utilities.ResearchRemover.RemoveResearchProject(project, false)) + { + removedCount++; + } + } + + // 发送消息(如果启用) + if (Props.sendMessage && removedCount > 0) + { + SendRemovalMessage(projectsToRemove, removedCount); + } + } + + private ResearchProjectDef SelectResearchProject(List availableProjects, + List alreadySelected) + { + // 移除已选中的项目 + var candidates = availableProjects + .Where(p => !alreadySelected.Contains(p)) + .ToList(); + + if (candidates.Count == 0) return null; + + return candidates.RandomElement(); + } + + private void SendRemovalMessage(List projectsRemoved, int removedCount) + { + if (projectsRemoved.Count == 0) return; + + string messageKey = Props.customMessageKey ?? "BuildingDestroyed_ResearchRemoved"; + string message; + + if (projectsRemoved.Count == 1) + { + var project = projectsRemoved[0]; + message = messageKey.Translate( + parent.LabelCap, + project.LabelCap + ); + } + else + { + var projectNames = string.Join(", ", projectsRemoved.Select(p => p.LabelCap)); + message = messageKey.Translate( + parent.LabelCap, + removedCount, + projectNames + ); + } + + Messages.Message(message, MessageTypeDefOf.NegativeEvent); + + // 同时在日志中记录 + Log.Message($"[ResearchRemover] Building {parent.LabelCap} destroyed, removed {removedCount} research projects: " + + string.Join(", ", projectsRemoved.Select(p => p.defName))); + } + + public override string CompInspectStringExtra() + { + var builder = new System.Text.StringBuilder(); + + if (Props.minResearchToRemove == Props.maxResearchToRemove) + { + builder.AppendLine("ResearchRemovalOnDestroy_Single".Translate(Props.minResearchToRemove)); + } + else + { + builder.AppendLine("ResearchRemovalOnDestroy_Range".Translate(Props.minResearchToRemove, Props.maxResearchToRemove)); + } + + // 显示选择策略 + if (Props.removeHighestTech) + { + builder.AppendLine("ResearchRemovalOnDestroy_HighestTech".Translate()); + } + else if (Props.removeLowestTech) + { + builder.AppendLine("ResearchRemovalOnDestroy_LowestTech".Translate()); + } + else if (Props.removeMostExpensive) + { + builder.AppendLine("ResearchRemovalOnDestroy_MostExpensive".Translate()); + } + else if (Props.removeLeastExpensive) + { + builder.AppendLine("ResearchRemovalOnDestroy_LeastExpensive".Translate()); + } + else if (Props.removeRandom) + { + builder.AppendLine("ResearchRemovalOnDestroy_Random".Translate()); + } + + return builder.ToString().TrimEndNewlines(); + } + + public override IEnumerable CompGetGizmosExtra() + { + if (DebugSettings.godMode) + { + // 测试按钮:模拟摧毁效果 + yield return new Command_Action + { + defaultLabel = "Debug: Trigger Research Removal", + defaultDesc = "Simulate building destruction and remove random research", + icon = TexCommand.DesirePower, + action = () => + { + // 手动触发移除逻辑 + if (!researchRemoved) + { + // 获取所有已完成的科技 + var finishedProjects = DefDatabase.AllDefs + .Where(p => p.IsFinished) + .ToList(); + + if (finishedProjects.Count == 0) + { + Messages.Message("No finished research to remove", MessageTypeDefOf.RejectInput); + return; + } + + // 选择要移除的科技 + int numToRemove = Rand.RangeInclusive(Props.minResearchToRemove, Props.maxResearchToRemove); + numToRemove = Mathf.Min(numToRemove, finishedProjects.Count); + + var projectsToRemove = new List(); + for (int i = 0; i < numToRemove; i++) + { + var project = SelectResearchProject(finishedProjects, projectsToRemove); + if (project != null) + { + projectsToRemove.Add(project); + } + } + + // 执行移除 + int removedCount = 0; + foreach (var project in projectsToRemove) + { + if (Utilities.ResearchRemover.RemoveResearchProject(project, false)) + { + removedCount++; + } + } + + if (removedCount > 0) + { + Messages.Message($"Debug: Removed {removedCount} research projects", MessageTypeDefOf.NeutralEvent); + } + } + } + }; + } + } + + public override void PostExposeData() + { + base.PostExposeData(); + Scribe_Values.Look(ref researchRemoved, "researchRemoved", false); + } + } +} diff --git a/Source/ArachnaeSwarm/HarmonyPatches/DestroyRemovesResearch/CompProperties_DestroyRemovesResearch.cs b/Source/ArachnaeSwarm/HarmonyPatches/DestroyRemovesResearch/CompProperties_DestroyRemovesResearch.cs new file mode 100644 index 0000000..2f7565d --- /dev/null +++ b/Source/ArachnaeSwarm/HarmonyPatches/DestroyRemovesResearch/CompProperties_DestroyRemovesResearch.cs @@ -0,0 +1,46 @@ +// File: Comps/CompProperties_DestroyRemovesResearch.cs +using System.Collections.Generic; +using RimWorld; +using Verse; + +namespace ArachnaeSwarm.Comps +{ + public class CompProperties_DestroyRemovesResearch : CompProperties + { + public int minResearchToRemove = 1; + public int maxResearchToRemove = 1; + public bool removeRandom = true; + public bool removeHighestTech = false; + public bool removeLowestTech = false; + public bool removeMostExpensive = false; + public bool removeLeastExpensive = false; + public bool sendMessage = true; + public bool createExplosion = false; + public float explosionRadius = 3f; + public DamageDef explosionDamage = DamageDefOf.Bomb; + public string customMessageKey = null; + + public CompProperties_DestroyRemovesResearch() + { + compClass = typeof(CompDestroyRemovesResearch); + } + + public override IEnumerable ConfigErrors(ThingDef parentDef) + { + foreach (string error in base.ConfigErrors(parentDef)) + { + yield return error; + } + + if (minResearchToRemove < 1) + { + yield return "minResearchToRemove must be at least 1"; + } + + if (maxResearchToRemove < minResearchToRemove) + { + yield return "maxResearchToRemove must be greater than or equal to minResearchToRemove"; + } + } + } +} diff --git a/Source/ArachnaeSwarm/HarmonyPatches/Patch_ResearchManager_AddRemoveMethod.cs b/Source/ArachnaeSwarm/HarmonyPatches/Patch_ResearchManager_AddRemoveMethod.cs new file mode 100644 index 0000000..a378a44 --- /dev/null +++ b/Source/ArachnaeSwarm/HarmonyPatches/Patch_ResearchManager_AddRemoveMethod.cs @@ -0,0 +1,264 @@ +// File: Utilities/ResearchRemover.cs +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Verse; + +namespace ArachnaeSwarm.Utilities +{ + public static class ResearchRemover + { + private static FieldInfo progressField; + private static FieldInfo techprintsField; + private static FieldInfo anomalyKnowledgeField; + private static FieldInfo currentProjField; + private static FieldInfo currentAnomalyKnowledgeProjectsField; + + static ResearchRemover() + { + // 一次性初始化反射字段 + var type = typeof(ResearchManager); + progressField = type.GetField("progress", BindingFlags.NonPublic | BindingFlags.Instance); + techprintsField = type.GetField("techprints", BindingFlags.NonPublic | BindingFlags.Instance); + anomalyKnowledgeField = type.GetField("anomalyKnowledge", BindingFlags.NonPublic | BindingFlags.Instance); + currentProjField = type.GetField("currentProj", BindingFlags.NonPublic | BindingFlags.Instance); + currentAnomalyKnowledgeProjectsField = type.GetField("currentAnomalyKnowledgeProjects", BindingFlags.NonPublic | BindingFlags.Instance); + + if (progressField == null || techprintsField == null || anomalyKnowledgeField == null || currentProjField == null) + { + Log.Error("[ResearchRemover] Failed to find ResearchManager private fields!"); + } + } + + /// + /// 移除一个已研发的科技项目 + /// + /// 要移除的科技项目 + /// 是否同时移除依赖于此科技的科技 + /// 是否成功移除 + public static bool RemoveResearchProject(ResearchProjectDef projectDef, bool removeDependencies = false) + { + try + { + if (projectDef == null) + { + Log.Warning("[ResearchRemover] ProjectDef is null"); + return false; + } + + if (!projectDef.IsFinished) + { + Log.Warning($"[ResearchRemover] {projectDef.defName} is not finished, cannot remove."); + return false; + } + + var manager = Find.ResearchManager; + if (manager == null) + { + Log.Error("[ResearchRemover] ResearchManager not found!"); + return false; + } + + Log.Message($"[ResearchRemover] Removing research project: {projectDef.defName}"); + + // 获取字段值 + var progress = (Dictionary)progressField.GetValue(manager); + var techprints = (Dictionary)techprintsField.GetValue(manager); + var anomalyKnowledge = (Dictionary)anomalyKnowledgeField.GetValue(manager); + var currentProj = (ResearchProjectDef)currentProjField.GetValue(manager); + var currentAnomalyKnowledgeProjects = (List)currentAnomalyKnowledgeProjectsField?.GetValue(manager); + + // 检查是否有其他已完成的科技依赖于此科技 + if (!CanSafelyRemove(projectDef, removeDependencies)) + { + Log.Warning($"[ResearchRemover] Cannot remove {projectDef.defName}: other completed projects depend on it."); + return false; + } + + // 1. 从进度字典中移除 + if (progress != null && progress.ContainsKey(projectDef)) + { + progress.Remove(projectDef); + Log.Message($" Removed from progress dictionary"); + } + + // 2. 从科技碎片字典中移除 + if (techprints != null && techprints.ContainsKey(projectDef)) + { + techprints.Remove(projectDef); + Log.Message($" Removed from techprints dictionary"); + } + + // 3. 从异常知识字典中移除 + if (anomalyKnowledge != null && anomalyKnowledge.ContainsKey(projectDef)) + { + anomalyKnowledge.Remove(projectDef); + Log.Message($" Removed from anomalyKnowledge dictionary"); + } + + // 4. 如果这是当前项目,停止它 + if (currentProj == projectDef) + { + manager.StopProject(projectDef); + currentProjField.SetValue(manager, null); + Log.Message($" Stopped current project"); + } + + // 5. 从异常知识项目中移除 + if (currentAnomalyKnowledgeProjects != null) + { + bool removed = false; + for (int i = currentAnomalyKnowledgeProjects.Count - 1; i >= 0; i--) + { + var knowledgeProject = currentAnomalyKnowledgeProjects[i]; + if (knowledgeProject != null && knowledgeProject.project == projectDef) + { + knowledgeProject.project = null; + removed = true; + } + } + if (removed) Log.Message($" Removed from anomaly knowledge projects"); + } + + // 6. 如果设置了移除依赖项,递归移除依赖于此科技的项目 + if (removeDependencies) + { + RemoveDependentProjects(projectDef, progress, techprints, anomalyKnowledge, + currentProj, currentAnomalyKnowledgeProjects, manager); + } + + // 7. 重新应用所有mod(取消该科技的效果) + manager.ReapplyAllMods(); + + // 8. 发送通知 + Messages.Message("ResearchRemovedMessage".Translate(projectDef.LabelCap), MessageTypeDefOf.NeutralEvent); + + // 9. 发送信号 + Find.SignalManager.SendSignal(new Signal("ResearchRemoved", projectDef.defName)); + + Log.Message($"[ResearchRemover] Successfully removed research project: {projectDef.defName}"); + return true; + } + catch (Exception ex) + { + Log.Error($"[ResearchRemover] Error removing research project {projectDef.defName}: {ex}"); + return false; + } + } + + /// + /// 检查是否可以安全移除科技 + /// + private static bool CanSafelyRemove(ResearchProjectDef projectDef, bool removeDependencies) + { + if (removeDependencies) + return true; + + // 检查是否有其他已完成的科技依赖于此科技 + foreach (var otherProject in DefDatabase.AllDefs) + { + if (otherProject == projectDef || !otherProject.IsFinished) + continue; + + if (otherProject.prerequisites != null && otherProject.prerequisites.Contains(projectDef)) + { + Log.Warning($" - {otherProject.defName} depends on {projectDef.defName}"); + return false; + } + } + + return true; + } + + /// + /// 移除所有依赖于此科技的科技项目 + /// + private static void RemoveDependentProjects(ResearchProjectDef projectDef, + Dictionary progress, + Dictionary techprints, + Dictionary anomalyKnowledge, + ResearchProjectDef currentProj, + List currentAnomalyKnowledgeProjects, + ResearchManager manager) + { + // 查找所有依赖于此科技的项目 + var dependentProjects = DefDatabase.AllDefs + .Where(p => p != projectDef && p.IsFinished && p.prerequisites != null && p.prerequisites.Contains(projectDef)) + .ToList(); + + foreach (var dependent in dependentProjects) + { + Log.Message($" Removing dependent project: {dependent.defName}"); + + // 递归移除依赖项 + RemoveDependentProjects(dependent, progress, techprints, anomalyKnowledge, + currentProj, currentAnomalyKnowledgeProjects, manager); + + // 移除当前项目 + if (progress != null && progress.ContainsKey(dependent)) + progress.Remove(dependent); + + if (techprints != null && techprints.ContainsKey(dependent)) + techprints.Remove(dependent); + + if (anomalyKnowledge != null && anomalyKnowledge.ContainsKey(dependent)) + anomalyKnowledge.Remove(dependent); + + if (currentProj == dependent) + { + manager.StopProject(dependent); + currentProjField.SetValue(manager, null); + } + + if (currentAnomalyKnowledgeProjects != null) + { + for (int i = currentAnomalyKnowledgeProjects.Count - 1; i >= 0; i--) + { + var knowledgeProject = currentAnomalyKnowledgeProjects[i]; + if (knowledgeProject != null && knowledgeProject.project == dependent) + { + knowledgeProject.project = null; + } + } + } + } + } + + /// + /// 批量移除多个科技项目 + /// + public static int RemoveMultipleProjects(IEnumerable projectDefs, bool removeDependencies = false) + { + int count = 0; + foreach (var project in projectDefs) + { + if (RemoveResearchProject(project, removeDependencies)) + count++; + } + return count; + } + + /// + /// 移除所有科技(重置研究) + /// + public static void RemoveAllResearch() + { + var manager = Find.ResearchManager; + if (manager == null) return; + + var allFinishedProjects = DefDatabase.AllDefs + .Where(p => p.IsFinished) + .ToList(); + + Log.Message($"[ResearchRemover] Removing all {allFinishedProjects.Count} finished research projects"); + + // 批量移除所有科技 + RemoveMultipleProjects(allFinishedProjects, false); + + // 也可以调用原版的 ResetAllProgress 方法 + // manager.ResetAllProgress(); + } + } +}