diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index 5c6fd68..bcc5bc6 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/Scenarios/ARA_Scenarios.xml b/1.6/1.6/Defs/Scenarios/ARA_Scenarios.xml index 7d7f6ad..acff9c7 100644 --- a/1.6/1.6/Defs/Scenarios/ARA_Scenarios.xml +++ b/1.6/1.6/Defs/Scenarios/ARA_Scenarios.xml @@ -39,18 +39,23 @@
  • StartingThing_Defined ARA_InsectJelly - 200 + 300
  • StartingThing_Defined ARA_Medicine - 10 + 30
  • StartingThing_Defined ARA_InteractiveEggSac_Start 4
  • +
  • + StartingThing_Defined + ARA_Gene_Essence + 20 +
  • - -
  • - 1 -
  • -
    - - - 2 - - true - false - false - 0 - 6.9 - - true - false - true - -
  • ARA_InsectCreep
  • -
    -
    - -
  • PlaceWorker_GlowRadius
  • -
    - -
  • - 100 - 85 + 45 2 0.2 1800 @@ -1255,7 +1163,7 @@
  • 100 - 85 + 45 2 0.2 1800 @@ -1311,7 +1219,7 @@
  • 100 - 85 + 45 2 0.2 1800 diff --git a/1.6/1.6/Defs/Thing_building/ARA_DropPod.xml b/1.6/1.6/Defs/Thing_building/ARA_DropPod.xml index 6727842..1036fe0 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_DropPod.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_DropPod.xml @@ -48,7 +48,7 @@
  • 100 - 85 + 45 2 0.2 1800 diff --git a/1.6/1.6/Defs/Thing_building/ARA_NutrientNetworkBuilding.xml b/1.6/1.6/Defs/Thing_building/ARA_NutrientNetworkBuilding.xml index f304da7..06ee162 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_NutrientNetworkBuilding.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_NutrientNetworkBuilding.xml @@ -38,7 +38,7 @@
  • 100 - 85 + 45 2 0.2 1800 @@ -173,7 +173,7 @@
  • 100 - 85 + 45 2 0.2 1800 @@ -467,7 +467,7 @@
  • 100 - 85 + 45 2 0.2 1800 @@ -674,7 +674,7 @@
  • 100 - 85 + 45 2 0.2 1800 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 72d1a6a..bedcf8f 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_Ootheca.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_Ootheca.xml @@ -155,7 +155,7 @@
  • 100 - 85 + 45 2 0.2 1800 @@ -377,11 +377,6 @@ 6 (113,141,117,0)
  • -
  • - 6 - 36 - 0.015 -
  • @@ -474,7 +469,7 @@
  • 100 - 85 + 45 2 0.2 1800 @@ -502,39 +497,34 @@ 6 (113,141,117,0)
  • -
  • - 6 - 36 - 0.015 -
  • ARA_InteractiveEggSac_Techprint - 一个内部近乎无序发育的卵,无法孵化任何虫族,主要用于实验变异方向,可以产出阿拉克涅虫族科技的蓝图,阿拉克涅女皇种可以通过与其交互将其激活。\n\n该虫卵需要使用大量精华素维持工作,并且能研究的项目以其落地时的研究完成度为准,那些尚未解锁的科技将无法孵化其蓝图。 - Building + 一个内部近乎无序发育的卵,无法孵化任何虫族,主要用于实验变异方向,必须在零下环境中储存。\n\n需要蓝图的阿拉克涅科技只能由基因试验卵完成,完成时科技的基因信息会被储存在卵中,一旦所有储存同一科技的基因试验卵损坏,则该科技将丢失! + ArachnaeSwarm.Building_ResearchBlueprintReader ArachnaeSwarm/Building/ARA_InteractiveEggSac_Techprint Graphic_Single - (1.1,1.1) + (2,2) (0.7, 0.4, 0.7) (0,0,-0.1) - (1,1) + (2,2) ARA_Buildings Building PassThroughOnly 0.3 false Normal - ARA_Incubator_Nutrient_Solution + ARA_Creep 2000 - 50 + 250 1 @@ -547,48 +537,29 @@ 25 + 20 - - -
  • - 100 - 精华素 - - -
  • ARA_Gene_Essence
  • - - - 0 - false - 0.02 - 1 - 0 + +
  • + 1
  • +
    + +
  • CocoonDestroyed
  • - -
  • - -
  • ARA_ArachnaeQueen
  • - - true - 0.2 - 1.0 - 0.06 - 30 -
  • - 6 - 36 + -200 + 0 0.00005 0.005 0.001
  • 100 - 85 + 45 2 0.2 1800 diff --git a/1.6/1.6/Defs/Thing_building/ARA_RefuelingVat.xml b/1.6/1.6/Defs/Thing_building/ARA_RefuelingVat.xml index 3637a3d..59e6a0b 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_RefuelingVat.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_RefuelingVat.xml @@ -65,7 +65,7 @@
  • 100 - 85 + 45 2 0.2 1800 diff --git a/1.6/1.6/Defs/Thing_building/ARA_SwarmTurret.xml b/1.6/1.6/Defs/Thing_building/ARA_SwarmTurret.xml index 44d6476..1986723 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_SwarmTurret.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_SwarmTurret.xml @@ -290,7 +290,7 @@
  • 100 - 85 + 45 2 0.2 1800 @@ -439,7 +439,7 @@
  • 100 - 85 + 45 2 0.2 1800 @@ -611,7 +611,7 @@
  • 100 - 85 + 45 2 0.2 1800 diff --git a/1.6/1.6/Defs/Thing_building/ARA_WormholeDefs.xml b/1.6/1.6/Defs/Thing_building/ARA_WormholeDefs.xml index ffbad6b..44027c7 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_WormholeDefs.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_WormholeDefs.xml @@ -41,7 +41,7 @@
  • 100 - 85 + 45 2 0.2 1800 diff --git a/1.6/1.6/Defs/ThinkTreeDefs/ARA_ThinkTrees.xml b/1.6/1.6/Defs/ThinkTreeDefs/ARA_ThinkTrees.xml index 303ebaf..770dc9e 100644 --- a/1.6/1.6/Defs/ThinkTreeDefs/ARA_ThinkTrees.xml +++ b/1.6/1.6/Defs/ThinkTreeDefs/ARA_ThinkTrees.xml @@ -929,6 +929,29 @@
  • Humanlike_PreMain
  • + + +
  • + ArachnaeNode_Race_Myrmecocystus + +
  • + +
  • + +
  • + ARA_HiveMindMaster + 0~5 + +
  • + +
  • +
  • + ARA_HiveMindDrone + 0~5 + +
  • + +
  • @@ -947,28 +970,6 @@
  • -
  • - ArachnaeNode_Race_Myrmecocystus - -
  • - -
  • - - -
  • - ARA_HiveMindMaster - 0~5 - -
  • - -
  • -
  • - ARA_HiveMindDrone - 0~5 - -
  • - -
  • diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo index 8ecad50..9be7bd4 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 b05fd31..b9401a9 100644 --- a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json +++ b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json @@ -7,13 +7,17 @@ "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\\researchblueprintdata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_researchblueprintreader\\researchblueprintdata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, { "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\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\\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\\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}" @@ -114,17 +118,30 @@ "DocumentGroups": [ { "DockedWidth": 200, - "SelectedChildIndex": 1, + "SelectedChildIndex": 2, "Children": [ { "$type": "Document", "DocumentIndex": 1, + "Title": "ResearchBlueprintData.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ResearchBlueprintReader\\ResearchBlueprintData.cs", + "RelativeDocumentMoniker": "Buildings\\Building_ResearchBlueprintReader\\ResearchBlueprintData.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ResearchBlueprintReader\\ResearchBlueprintData.cs", + "RelativeToolTip": "Buildings\\Building_ResearchBlueprintReader\\ResearchBlueprintData.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-17T08:53:33.402Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 3, "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==", + "ViewState": "AgIAAC8AAAAAAAAAAAAQwDcAAABVAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2025-12-17T03:27:44.163Z", "EditorCaption": "" @@ -137,7 +154,7 @@ "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==", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAwAAAAlAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2025-12-17T03:27:11.518Z", "EditorCaption": "" @@ -150,14 +167,14 @@ "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==", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAA0AAAAyAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2025-12-17T01:51:43.528Z", "EditorCaption": "" }, { "$type": "Document", - "DocumentIndex": 5, + "DocumentIndex": 6, "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", @@ -170,7 +187,7 @@ }, { "$type": "Document", - "DocumentIndex": 6, + "DocumentIndex": 7, "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", @@ -187,7 +204,7 @@ }, { "$type": "Document", - "DocumentIndex": 4, + "DocumentIndex": 5, "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", @@ -200,7 +217,7 @@ }, { "$type": "Document", - "DocumentIndex": 3, + "DocumentIndex": 4, "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", @@ -213,7 +230,7 @@ }, { "$type": "Document", - "DocumentIndex": 7, + "DocumentIndex": 8, "Title": "CompDestroyRemovesResearch.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\HarmonyPatches\\DestroyRemovesResearch\\CompDestroyRemovesResearch.cs", "RelativeDocumentMoniker": "HarmonyPatches\\DestroyRemovesResearch\\CompDestroyRemovesResearch.cs", @@ -226,7 +243,7 @@ }, { "$type": "Document", - "DocumentIndex": 8, + "DocumentIndex": 9, "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", @@ -238,7 +255,7 @@ }, { "$type": "Document", - "DocumentIndex": 9, + "DocumentIndex": 10, "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", @@ -250,7 +267,7 @@ }, { "$type": "Document", - "DocumentIndex": 10, + "DocumentIndex": 11, "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", @@ -262,7 +279,7 @@ }, { "$type": "Document", - "DocumentIndex": 11, + "DocumentIndex": 12, "Title": "Verb_ShootSelfUnderfoot.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Verbs\\Verb_ShootSelfUnderfoot.cs", "RelativeDocumentMoniker": "Verbs\\Verb_ShootSelfUnderfoot.cs", @@ -274,7 +291,7 @@ }, { "$type": "Document", - "DocumentIndex": 12, + "DocumentIndex": 13, "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", @@ -286,7 +303,7 @@ }, { "$type": "Document", - "DocumentIndex": 13, + "DocumentIndex": 14, "Title": "RoomRoleWorker_Incubator.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\RoomRole\\RoomRoleWorker_Incubator.cs", "RelativeDocumentMoniker": "RoomRole\\RoomRoleWorker_Incubator.cs", @@ -298,7 +315,7 @@ }, { "$type": "Document", - "DocumentIndex": 14, + "DocumentIndex": 15, "Title": "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", @@ -310,7 +327,7 @@ }, { "$type": "Document", - "DocumentIndex": 16, + "DocumentIndex": 17, "Title": "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", @@ -322,7 +339,7 @@ }, { "$type": "Document", - "DocumentIndex": 15, + "DocumentIndex": 16, "Title": "ARA_HediffDefOf.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_HediffDefOf.cs", "RelativeDocumentMoniker": "ARA_HediffDefOf.cs", @@ -334,7 +351,7 @@ }, { "$type": "Document", - "DocumentIndex": 17, + "DocumentIndex": 18, "Title": "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", @@ -346,7 +363,7 @@ }, { "$type": "Document", - "DocumentIndex": 20, + "DocumentIndex": 21, "Title": "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", @@ -358,7 +375,7 @@ }, { "$type": "Document", - "DocumentIndex": 18, + "DocumentIndex": 19, "Title": "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", @@ -370,7 +387,7 @@ }, { "$type": "Document", - "DocumentIndex": 19, + "DocumentIndex": 20, "Title": "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", @@ -382,7 +399,7 @@ }, { "$type": "Document", - "DocumentIndex": 21, + "DocumentIndex": 22, "Title": "Building_RefuelingVat.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs", "RelativeDocumentMoniker": "Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs", @@ -394,7 +411,7 @@ }, { "$type": "Document", - "DocumentIndex": 22, + "DocumentIndex": 23, "Title": "OothecaIncubatorExtension.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\OothecaIncubatorExtension.cs", "RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\OothecaIncubatorExtension.cs", @@ -406,7 +423,7 @@ }, { "$type": "Document", - "DocumentIndex": 25, + "DocumentIndex": 26, "Title": "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", @@ -418,7 +435,7 @@ }, { "$type": "Document", - "DocumentIndex": 23, + "DocumentIndex": 24, "Title": "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", @@ -430,7 +447,7 @@ }, { "$type": "Document", - "DocumentIndex": 24, + "DocumentIndex": 25, "Title": "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", diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj index 5966b79..ec3ab3d 100644 --- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj +++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj @@ -125,6 +125,7 @@ + diff --git a/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/Building_ResearchBlueprintReader.cs b/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/Building_ResearchBlueprintReader.cs index 1b6b943..19fd260 100644 --- a/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/Building_ResearchBlueprintReader.cs +++ b/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/Building_ResearchBlueprintReader.cs @@ -10,37 +10,28 @@ namespace ArachnaeSwarm { public class Building_ResearchBlueprintReader : Building { - // 当前正在研究的科技 - private ResearchProjectDef currentResearch; + // 储存的科技 + private ResearchProjectDef storedResearch; // 当前研究进度 private float progress; - // 自动研究标志 - private bool autoResearch; - - // 储存的科技 - private ResearchProjectDef storedResearch; - - // 锁定信息 - private ResearchBlueprintLockInfo lockInfo; - // 管理器引用 private ResearchBlueprintReaderManager manager; + // 是否正在研究 + private bool isResearching = false; + // 电力组件 private CompPowerTrader powerComp; - public ResearchProjectDef CurrentResearch => currentResearch; - public float Progress => progress; - public float ProgressPercent => currentResearch != null ? progress / currentResearch.baseCost : 0f; + // 锁定信息 + private int researchStartTime; + public ResearchProjectDef StoredResearch => storedResearch; + public float Progress => progress; public bool IsLocked => storedResearch != null; - public ResearchBlueprintReaderManager Manager - { - get => manager; - set => manager = value; - } + public bool IsResearching => isResearching && storedResearch != null && !storedResearch.IsFinished; // 获取研究速度 private float ResearchSpeed @@ -52,34 +43,19 @@ namespace ArachnaeSwarm } } - // 是否允许储存科技 - 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"); + Scribe_Values.Look(ref progress, "progress", 0f); + Scribe_Values.Look(ref isResearching, "isResearching", false); + Scribe_Values.Look(ref researchStartTime, "researchStartTime", 0); if (Scribe.mode == LoadSaveMode.LoadingVars) { - // 加载时重建与管理器的连接 + // 重建管理器连接 manager = ResearchBlueprintReaderManager.Instance; - if (manager != null) - { - manager.RegisterReader(this); - } } } @@ -97,29 +73,19 @@ namespace ArachnaeSwarm // 获取电力组件 powerComp = GetComp(); - Log.Message($"[ResearchBlueprintReader] Spawned at {Position}, Manager: {manager != null}"); + // 如果加载时有储存的科技,确保注册到管理器 + if (storedResearch != null && manager != null) + { + manager.RegisterResearch(this, storedResearch); + } } public override void Destroy(DestroyMode mode = DestroyMode.Vanish) { - // 如果建筑储存了科技,先释放 - if (storedResearch != null) + // 通知管理器建筑被摧毁 + if (manager != null && storedResearch != null) { - if (manager != null) - { - manager.ReleaseStoredResearch(storedResearch); - } - else - { - // 如果没有管理器,直接移除科技 - Utilities.ResearchRemover.RemoveResearchProject(storedResearch, false); - } - } - - // 注销建筑 - if (manager != null) - { - manager.UnregisterReader(this); + manager.OnBuildingDestroyed(this, storedResearch); } base.Destroy(mode); @@ -129,114 +95,81 @@ namespace ArachnaeSwarm { base.Tick(); + // 如果没有储存科技或者科技已完成,不进行研究 + if (storedResearch == null || storedResearch.IsFinished) + { + isResearching = false; + return; + } + // 检查电力 bool hasPower = powerComp == null || powerComp.PowerOn; - // 如果启用了自动研究且有研究项目,则增加进度 - if (hasPower && autoResearch && currentResearch != null && !currentResearch.IsFinished && !IsLocked) + // 如果正在研究且有储存的科技,则增加进度 + if (hasPower && isResearching) { float speed = ResearchSpeed; // 应用电力效率 - if (powerComp != null) + if (powerComp != null && powerComp.PowerNet != null) { - var ext = this.def.GetModExtension(); - if (ext != null) + var batteryComps = powerComp.PowerNet.batteryComps; + if (batteryComps != null && batteryComps.Count > 0) { - float efficiency = powerComp.PowerNet.CurrentStoredEnergy() / powerComp.PowerNet.batteryComps.Sum(b => b.Props.storedEnergyMax); - speed *= Mathf.Lerp(0.5f, 1f, efficiency); + float storedEnergy = powerComp.PowerNet.CurrentStoredEnergy(); + float maxEnergy = batteryComps.Sum(b => b.Props.storedEnergyMax); + if (maxEnergy > 0) + { + float efficiency = storedEnergy / maxEnergy; + speed *= Mathf.Lerp(0.5f, 1f, efficiency); + } } } - AddResearchProgress(speed / 60f); // 转换为每Tick - - // 检查是否完成 - if (progress >= currentResearch.baseCost) - { - CompleteCurrentResearch(); - } + // 增加进度 + AddResearchProgress(speed / 60f); } } private void AddResearchProgress(float amount) { + if (storedResearch == null || storedResearch.IsFinished) return; + progress += amount; - // 将进度添加到研究管理器 - Find.ResearchManager.AddProgress(currentResearch, amount); + // 获取全局进度 + float globalProgress = Find.ResearchManager.GetProgress(storedResearch); - // 更新进度显示 - if (Find.TickManager.TicksGame % 60 == 0) // 每秒更新一次视觉效果 + // 检查科技是否已完成 + if (!storedResearch.IsFinished && progress >= storedResearch.baseCost) { - // 可以添加一些视觉效果,比如闪烁灯光 - } - } - - private void CompleteCurrentResearch() - { - if (currentResearch != null && !currentResearch.IsFinished) - { - Log.Message($"[ResearchBlueprintReader] Completing research: {currentResearch.defName} at {Position}"); + // 完成科技 + Find.ResearchManager.AddProgress(storedResearch, storedResearch.baseCost - globalProgress); - if (CanStoreResearch && manager != null) + // 停止研究 + isResearching = false; + + // 发送消息 + Messages.Message($"科技研究完成: {storedResearch.LabelCap}", + MessageTypeDefOf.PositiveEvent); + + Log.Message($"[ResearchBlueprintReader] Research completed: {storedResearch.defName}"); + } + else + { + // 只添加未完成的进度 + float remaining = storedResearch.baseCost - globalProgress; + float toAdd = Mathf.Min(amount, remaining); + if (toAdd > 0) { - // 请求管理器处理完成和储存 - manager.RequestResearchCompletion(this, currentResearch); - } - else - { - // 如果不能储存,直接完成 - Find.ResearchManager.FinishProject(currentResearch, doCompletionDialog: false); - Messages.Message($"研究完成: {currentResearch.LabelCap}", - MessageTypeDefOf.PositiveEvent); - - // 重置状态 - currentResearch = null; - progress = 0f; - autoResearch = false; + Find.ResearchManager.AddProgress(storedResearch, toAdd); } } } /// - /// 锁定建筑以储存科技(由管理器调用) + /// 开始研究新科技 /// - 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) @@ -249,31 +182,71 @@ namespace ArachnaeSwarm if (project == null || project.IsFinished || project.techprintCount <= 0) return; - // 检查科技是否已被其他建筑储存 - if (manager != null && manager.IsResearchStored(project)) + // 检查前置条件 + if (!AreAllPrerequisitesCompleted(project)) { - Messages.Message($"科技已被其他建筑储存: {project.LabelCap}", + Messages.Message("未满足前置科技条件", MessageTypeDefOf.RejectInput); return; } - currentResearch = project; + // 立即绑定科技 + storedResearch = project; progress = Find.ResearchManager.GetProgress(project); + isResearching = true; + researchStartTime = Find.TickManager.TicksGame; - Messages.Message($"开始研究: {project.LabelCap}", + // 通知管理器 + if (manager != null) + { + manager.RegisterResearch(this, project); + } + + Messages.Message($"开始研究: {project.LabelCap}(已绑定)", MessageTypeDefOf.NeutralEvent); } - public void StopResearch() + /// + /// 解锁建筑(释放储存的科技) + /// + public void UnlockBuilding() { - if (currentResearch != null) + if (storedResearch != null && manager != null) { - Messages.Message($"停止研究: {currentResearch.LabelCap}", - MessageTypeDefOf.NeutralEvent); + var project = storedResearch; - currentResearch = null; + // 如果科技未完成,需要移除进度 + if (!project.IsFinished) + { + // 计算当前建筑的贡献 + float contributedProgress = progress; + float globalProgress = Find.ResearchManager.GetProgress(project); + + // 移除这个建筑的贡献(简化处理:减去当前建筑的进度) + // 注意:这里可能有多个建筑同时研究,所以不能简单减去 + // 我们让管理器来处理复杂的逻辑 + manager.OnBuildingUnlocked(this, project); + } + + storedResearch = null; progress = 0f; - autoResearch = false; + isResearching = false; + researchStartTime = 0; + + Messages.Message($"建筑已解锁: {project.LabelCap}", + MessageTypeDefOf.NeutralEvent); + } + } + + /// + /// 强制完成研究(用于调试) + /// + public void ForceCompleteResearch() + { + if (storedResearch != null && !storedResearch.IsFinished) + { + progress = storedResearch.baseCost; + AddResearchProgress(0); // 触发完成检查 } } @@ -293,12 +266,7 @@ namespace ArachnaeSwarm unlockCmd.icon = ContentFinder.Get("UI/Designators/Unlock", false); unlockCmd.action = delegate { - if (manager != null) - { - manager.ReleaseStoredResearch(storedResearch); - storedResearch = null; - lockInfo = null; - } + UnlockBuilding(); }; yield return unlockCmd; @@ -310,6 +278,7 @@ namespace ArachnaeSwarm infoCmd.action = delegate { Messages.Message($"此建筑储存着: {storedResearch.LabelCap}\n" + + $"状态: {(storedResearch.IsFinished ? "已完成" : "研究中")}\n" + $"描述: {storedResearch.description.StripTags()}", MessageTypeDefOf.NeutralEvent); }; @@ -321,7 +290,7 @@ namespace ArachnaeSwarm // 选择研究按钮 var selectCmd = new Command_Action(); selectCmd.defaultLabel = "选择研究项目"; - selectCmd.defaultDesc = "选择要自动研究的科技项目"; + selectCmd.defaultDesc = "选择要研究的科技项目(一旦选择将永久绑定)"; selectCmd.icon = ContentFinder.Get("UI/Designators/Research", false); selectCmd.action = delegate { @@ -329,42 +298,16 @@ namespace ArachnaeSwarm }; 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) + // 调试按钮:强制完成研究 + if (DebugSettings.godMode && storedResearch != null && !storedResearch.IsFinished) { var debugCmd = new Command_Action(); - debugCmd.defaultLabel = "调试: 快速完成"; + debugCmd.defaultLabel = "调试: 强制完成"; debugCmd.defaultDesc = "立即完成当前研究"; debugCmd.icon = ContentFinder.Get("UI/Designators/Dev", false); debugCmd.action = delegate { - progress = currentResearch.baseCost; - CompleteCurrentResearch(); + ForceCompleteResearch(); }; yield return debugCmd; } @@ -398,20 +341,13 @@ namespace ArachnaeSwarm { 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) + if (!allPrerequisitesMet) { bool missingHidden = HasMissingHiddenPrerequisites(project); if (missingHidden) @@ -422,8 +358,8 @@ namespace ArachnaeSwarm var option = new FloatMenuOption(label, () => StartResearch(project)) { - Disabled = !allPrerequisitesMet || isStored, - tooltip = GetProjectTooltip(project, allPrerequisitesMet, isStored) + Disabled = !allPrerequisitesMet, + tooltip = GetProjectTooltip(project, allPrerequisitesMet) }; options.Add(option); @@ -480,7 +416,7 @@ namespace ArachnaeSwarm return false; } - private string GetProjectTooltip(ResearchProjectDef project, bool prerequisitesMet, bool isStored) + private string GetProjectTooltip(ResearchProjectDef project, bool prerequisitesMet) { var builder = new System.Text.StringBuilder(); @@ -489,17 +425,7 @@ namespace ArachnaeSwarm 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}"); - } - } + builder.AppendLine($"当前全球进度: {Find.ResearchManager.GetProgress(project):F0}/{project.baseCost:F0}"); // 检查所有未完成的前置(包括隐藏的) List missingPrereqs = new List(); @@ -552,24 +478,29 @@ namespace ArachnaeSwarm if (builder.Length > 0) builder.AppendLine(); - if (IsLocked) + if (storedResearch != null) { - builder.AppendLine($"🔒 储存科技: {storedResearch.LabelCap}"); - if (lockInfo != null) + if (storedResearch.IsFinished) { - int days = lockInfo.storeTime / 60000; - builder.AppendLine($"储存时间: {days}天"); + builder.AppendLine($"✓ 已研究: {storedResearch.LabelCap}"); + } + else + { + builder.AppendLine($"🔒 正在研究: {storedResearch.LabelCap}"); + builder.AppendLine($"本建筑进度: {progress:F0}/{storedResearch.baseCost:F0} ({(progress / storedResearch.baseCost * 100):F1}%)"); + builder.Append($"全球进度: {Find.ResearchManager.GetProgress(storedResearch):F0}/{storedResearch.baseCost:F0}"); + + // 显示研究速度 + builder.AppendLine(); + builder.Append($"研究速度: {ResearchSpeed:F1}/秒"); + + if (researchStartTime > 0) + { + int days = (Find.TickManager.TicksGame - researchStartTime) / 60000; + builder.AppendLine(); + builder.Append($"已研究时间: {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 { @@ -579,20 +510,12 @@ namespace ArachnaeSwarm return builder.ToString().TrimEndNewlines(); } - // 供其他系统调用的方法 - public bool IsResearchingProject(ResearchProjectDef project) + /// + /// 供管理器调用的方法 + /// + public void UpdateProgress(float newProgress) { - 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); + progress = newProgress; } } } diff --git a/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/ResearchBlueprintData.cs b/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/ResearchBlueprintData.cs new file mode 100644 index 0000000..4d29951 --- /dev/null +++ b/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/ResearchBlueprintData.cs @@ -0,0 +1,39 @@ +// File: Data/ResearchBlueprintData.cs +using RimWorld; +using System; +using Verse; + +namespace ArachnaeSwarm +{ + // 研究锁定信息 + 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/Buildings/Building_ResearchBlueprintReader/ResearchBlueprintReaderExtension.cs b/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/ResearchBlueprintReaderExtension.cs index 5764e0d..8395a2c 100644 --- a/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/ResearchBlueprintReaderExtension.cs +++ b/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/ResearchBlueprintReaderExtension.cs @@ -9,10 +9,7 @@ namespace ArachnaeSwarm // 研究速度(每秒增加的点数),可以配置 public float researchSpeed = 10f; - // 是否允许储存科技(锁定功能) - public bool canStoreResearch = true; - - // 科技储存的持续时间(天),0表示永久 - public float researchStorageDays = 0f; + // 是否允许解锁建筑 + public bool canUnlock = false; } } diff --git a/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/ResearchBlueprintReaderManager.cs b/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/ResearchBlueprintReaderManager.cs index 55013c0..6504180 100644 --- a/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/ResearchBlueprintReaderManager.cs +++ b/Source/ArachnaeSwarm/Buildings/Building_ResearchBlueprintReader/ResearchBlueprintReaderManager.cs @@ -13,29 +13,21 @@ namespace ArachnaeSwarm // 单例实例 private static ResearchBlueprintReaderManager instance; - // 储存已锁定科技的建筑列表 - private Dictionary lockedResearches; + // 所有建筑 + private List allReaders; - // 所有正在运行的建筑 - private List activeReaders; - - // 所有储存科技的建筑 - private List storageReaders; - - // 待处理的完成研究列表(防止竞争条件) - private List pendingCompletions; + // 科技到研究建筑的映射 + private Dictionary> researchBuildings; // 清理计时器 private int cleanupTimer; - private const int CleanupInterval = 2500; // 每2500ticks清理一次 + private const int CleanupInterval = 2500; public ResearchBlueprintReaderManager(Game game) : base() { instance = this; - lockedResearches = new Dictionary(); - activeReaders = new List(); - storageReaders = new List(); - pendingCompletions = new List(); + allReaders = new List(); + researchBuildings = new Dictionary>(); } public static ResearchBlueprintReaderManager Instance => instance; @@ -44,32 +36,32 @@ namespace ArachnaeSwarm { 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); + Scribe_Collections.Look(ref allReaders, "allReaders", LookMode.Reference); - // 修复引用丢失问题 - if (Scribe.mode == LoadSaveMode.LoadingVars) + // 序列化研究建筑映射 + if (Scribe.mode == LoadSaveMode.Saving) { - lockedResearches = lockedResearches ?? new Dictionary(); - activeReaders = activeReaders ?? new List(); - storageReaders = storageReaders ?? new List(); - pendingCompletions = pendingCompletions ?? new List(); + List keys = researchBuildings.Keys.ToList(); + List> values = researchBuildings.Values.ToList(); + Scribe_Collections.Look(ref keys, "researchKeys", LookMode.Def); + Scribe_Collections.Look(ref values, "researchValues", LookMode.Deep); } - - if (Scribe.mode == LoadSaveMode.PostLoadInit) + else if (Scribe.mode == LoadSaveMode.LoadingVars) { - // 移除空引用 - activeReaders.RemoveAll(r => r == null || r.Destroyed); - storageReaders.RemoveAll(r => r == null || r.Destroyed); + allReaders = allReaders ?? new List(); - // 重建管理器与建筑的连接 - foreach (var reader in activeReaders.Concat(storageReaders)) + List keys = null; + List> values = null; + Scribe_Collections.Look(ref keys, "researchKeys", LookMode.Def); + Scribe_Collections.Look(ref values, "researchValues", LookMode.Deep); + + researchBuildings = new Dictionary>(); + if (keys != null && values != null && keys.Count == values.Count) { - if (reader != null && !reader.Destroyed) + for (int i = 0; i < keys.Count; i++) { - reader.Manager = this; + if (keys[i] != null) + researchBuildings[keys[i]] = values[i] ?? new List(); } } } @@ -79,198 +71,173 @@ namespace ArachnaeSwarm { 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)) + if (!allReaders.Contains(reader)) { - activeReaders.Add(reader); - reader.Manager = this; - Log.Message($"[ResearchManager] Registered reader at {reader.Position}"); + allReaders.Add(reader); } } /// - /// 注销建筑 + /// 注册研究 /// - public void UnregisterReader(Building_ResearchBlueprintReader reader) + public void RegisterResearch(Building_ResearchBlueprintReader reader, ResearchProjectDef project) { - activeReaders.Remove(reader); - storageReaders.Remove(reader); + if (reader == null || project == null) return; - // 如果建筑储存了科技,释放该科技 - if (reader.StoredResearch != null) - { - ReleaseStoredResearch(reader.StoredResearch); - Log.Message($"[ResearchManager] Unregistered and released research from reader at {reader.Position}"); - } + if (!researchBuildings.ContainsKey(project)) + researchBuildings[project] = new List(); + + if (!researchBuildings[project].Contains(reader)) + researchBuildings[project].Add(reader); + + Log.Message($"[ResearchManager] Registered research: {project.defName} at building {reader.Position}"); } /// - /// 请求完成研究(由建筑调用) + /// 建筑被摧毁时的处理 /// - public void RequestResearchCompletion(Building_ResearchBlueprintReader reader, ResearchProjectDef project) + public void OnBuildingDestroyed(Building_ResearchBlueprintReader building, ResearchProjectDef project) { - if (reader == null || project == null || reader.Destroyed) return; - - // 检查是否已经有建筑在储存这个科技 - if (lockedResearches.ContainsKey(project)) + if (project == null) { - Log.Message($"[ResearchManager] {project.defName} is already stored, rejecting request from {reader.Position}"); - reader.StopResearch(); - Messages.Message($"科技已由其他建筑储存: {project.LabelCap}", - MessageTypeDefOf.RejectInput); + Log.Message("[ResearchManager] Project is null, cannot process building destruction"); return; } - // 添加待处理请求 - var request = new ResearchCompletionRequest - { - reader = reader, - project = project, - timestamp = Find.TickManager.TicksGame - }; + Log.Message($"[ResearchManager] Processing building destruction for project: {project.defName}"); - pendingCompletions.Add(request); - Log.Message($"[ResearchManager] Added completion request for {project.defName} from {reader.Position}"); + // 从列表中移除 + if (researchBuildings.ContainsKey(project)) + { + researchBuildings[project].Remove(building); + Log.Message($"[ResearchManager] Removed building from project list. Remaining buildings: {researchBuildings[project].Count}"); + + // 检查是否还有建筑 + CheckResearchStatus(project); + } + + // 从所有建筑列表中移除 + allReaders.Remove(building); } /// - /// 处理待完成的请求 + /// 检查科技状态 /// - private void ProcessPendingCompletions() + private void CheckResearchStatus(ResearchProjectDef project) { - // 按时间顺序处理 - var sortedRequests = pendingCompletions - .OrderBy(r => r.timestamp) - .ToList(); + if (project == null) return; - foreach (var request in sortedRequests) + // 检查是否还有建筑研究这个科技 + bool hasBuildings = false; + if (researchBuildings.ContainsKey(project)) { - if (request.reader == null || request.reader.Destroyed || - request.project == null || request.project.IsFinished) - { - pendingCompletions.Remove(request); - continue; - } + // 清理列表中的空引用 + researchBuildings[project].RemoveAll(b => b == null || b.Destroyed); + hasBuildings = researchBuildings[project].Count > 0; - // 检查是否仍然有效 - if (!lockedResearches.ContainsKey(request.project)) + if (!hasBuildings) { - 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}"); + researchBuildings.Remove(project); + Log.Message($"[ResearchManager] No buildings left for project: {project.defName}"); } } + + // 如果没有建筑了,移除科技 + if (!hasBuildings) + { + RemoveResearchProject(project); + } } /// - /// 完成研究并储存在建筑中 + /// 移除科技 /// - private void CompleteResearchAndStore(Building_ResearchBlueprintReader reader, ResearchProjectDef project) + private void RemoveResearchProject(ResearchProjectDef project) { + if (project == null) return; + + Log.Message($"[ResearchManager] Removing research project: {project.defName}"); + 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}", + // 发送消息 + Messages.Message($"科技已丢失: {project.LabelCap}", MessageTypeDefOf.NegativeEvent); - Log.Message($"[ResearchManager] Released stored research: {project.defName}"); + Log.Message($"[ResearchManager] Successfully removed research project: {project.defName}"); } + catch (Exception ex) + { + Log.Error($"[ResearchManager] Error removing research project {project.defName}: {ex}"); + } + } + + /// + /// 建筑解锁时的处理 + /// + public void OnBuildingUnlocked(Building_ResearchBlueprintReader building, ResearchProjectDef project) + { + if (project == null) return; + + Log.Message($"[ResearchManager] Processing building unlock for project: {project.defName}"); + + // 从研究中移除 + if (researchBuildings.ContainsKey(project)) + { + researchBuildings[project].Remove(building); + Log.Message($"[ResearchManager] Removed building from project list due to unlock. Remaining buildings: {researchBuildings[project].Count}"); + + // 检查是否还有建筑 + CheckResearchStatus(project); + } + } + + /// + /// 检查科技是否还有建筑研究 + /// + public bool HasResearchBuildings(ResearchProjectDef project) + { + if (project == null) return false; + + if (researchBuildings.ContainsKey(project)) + { + researchBuildings[project].RemoveAll(b => b == null || b.Destroyed); + return researchBuildings[project].Count > 0; + } + + return false; + } + + /// + /// 获取研究某个科技的建筑数量 + /// + public int GetResearchBuildingCount(ResearchProjectDef project) + { + if (researchBuildings.ContainsKey(project)) + { + researchBuildings[project].RemoveAll(b => b == null || b.Destroyed); + return researchBuildings[project].Count; + } + + return 0; } /// @@ -278,58 +245,40 @@ namespace ArachnaeSwarm /// private void CleanupDestroyedBuildings() { - // 清理活动建筑 - int activeCount = activeReaders.Count; - activeReaders.RemoveAll(r => r == null || r.Destroyed); + int removedCount = 0; - // 清理储存建筑 - int storageCount = storageReaders.Count; - storageReaders.RemoveAll(r => r == null || r.Destroyed); + // 清理所有建筑列表 + allReaders.RemoveAll(b => b == null || b.Destroyed); - // 清理锁定的研究中已摧毁的建筑 - var toRemove = new List(); - foreach (var kvp in lockedResearches) + // 清理研究建筑映射,并检查科技状态 + List projectsToCheck = new List(); + + foreach (var kvp in researchBuildings.ToList()) { - var building = kvp.Value.storingBuilding; - if (building == null || building.Destroyed) + kvp.Value.RemoveAll(b => b == null || b.Destroyed); + removedCount += kvp.Value.Count(b => b == null || b.Destroyed); + + if (kvp.Value.Count == 0) { - toRemove.Add(kvp.Key); + projectsToCheck.Add(kvp.Key); } } - foreach (var project in toRemove) + // 检查需要处理的科技 + foreach (var project in projectsToCheck) { - ReleaseStoredResearch(project); + CheckResearchStatus(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"); + if (removedCount > 0) + { + Log.Message($"[ResearchManager] Cleanup: removed {removedCount} destroyed buildings"); + } } /// - /// 获取所有储存的建筑 + /// 调试命令 /// - 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) @@ -339,48 +288,27 @@ namespace ArachnaeSwarm } Log.Message($"=== 研究管理器状态 ==="); - Log.Message($"活动建筑: {Instance.activeReaders.Count}"); - Log.Message($"储存建筑: {Instance.storageReaders.Count}"); - Log.Message($"锁定科技: {Instance.lockedResearches.Count}"); - Log.Message($"待处理请求: {Instance.pendingCompletions.Count}"); + Log.Message($"所有建筑: {Instance.allReaders.Count}"); + Log.Message($"进行中研究: {Instance.researchBuildings.Count}"); - foreach (var kvp in Instance.lockedResearches) + foreach (var kvp in Instance.researchBuildings) { - var building = kvp.Value.storingBuilding; - Log.Message($" - {kvp.Key.defName}: 储存于 {building?.Position.ToString() ?? "无建筑"}"); + int activeBuildings = kvp.Value.Count(b => b != null && !b.Destroyed); + Log.Message($" {kvp.Key.defName}: {activeBuildings}个活跃建筑 / {kvp.Value.Count}个总建筑"); + } + } + + /// + /// 强制检查所有科技状态(调试用) + /// + public static void ForceCheckAllResearch() + { + if (Instance == null) return; + + foreach (var project in Instance.researchBuildings.Keys.ToList()) + { + Instance.CheckResearchStatus(project); } } } - - // 研究锁定信息 - 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); - } - } }