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);
- }
- }
}