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