11
This commit is contained in:
Binary file not shown.
@@ -1,7 +1,148 @@
|
||||
{
|
||||
"Version": 1,
|
||||
"WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
|
||||
"Documents": [],
|
||||
"WorkspaceRootPath": "E:\\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\\building_comps\\ara_buildingterrainspawn\\compdelayedterrainspawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_buildingterrainspawn\\compdelayedterrainspawn.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\\needs\\need_honeyproduction.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:needs\\need_honeyproduction.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\\workgivers\\workgiver_feedwithhoney.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:workgivers\\workgiver_feedwithhoney.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}",
|
||||
"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\\workgivers\\workgiver_refuel_nutrition.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:workgivers\\workgiver_refuel_nutrition.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_feedwithhoney\\jobdriver_feedwithhoney.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_feedwithhoney\\jobdriver_feedwithhoney.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\\workgivers\\workgiver_extracthoney.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:workgivers\\workgiver_extracthoney.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\\workgivers\\workgiver_stripchitin.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:workgivers\\workgiver_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_feedwithhoney\\jobdriver_extracthoney.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_feedwithhoney\\jobdriver_extracthoney.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_feedwithhoney\\thinknode_jobgiver_extracthoney.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_feedwithhoney\\thinknode_jobgiver_extracthoney.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_swarmmaintain\\jobdriver_swarmmaintain.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_swarmmaintain\\jobdriver_swarmmaintain.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\\cleave\\compcleave.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:verbs\\cleave\\compcleave.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_swarmmaintenance\\comp_swarmmaintenance.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_swarmmaintenance\\comp_swarmmaintenance.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\\needs\\need_chitinarmor.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:needs\\need_chitinarmor.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\\workgivers\\workgiver_swarmmaintain.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:workgivers\\workgiver_swarmmaintain.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_dormancyvat\\building_dormancyvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_dormancyvat\\building_dormancyvat.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_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|E:\\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\\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}",
|
||||
"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}",
|
||||
"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}",
|
||||
"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}",
|
||||
"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\\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\\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}",
|
||||
"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}",
|
||||
"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}",
|
||||
"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}",
|
||||
"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\\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}",
|
||||
"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}",
|
||||
"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}",
|
||||
"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}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_equipmentootheca\\building_equipmentootheca.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|E:\\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:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
}
|
||||
],
|
||||
"DocumentGroupContainers": [
|
||||
{
|
||||
"Orientation": 0,
|
||||
@@ -9,11 +150,433 @@
|
||||
"DocumentGroups": [
|
||||
{
|
||||
"DockedWidth": 200,
|
||||
"SelectedChildIndex": -1,
|
||||
"SelectedChildIndex": 1,
|
||||
"Children": [
|
||||
{
|
||||
"$type": "Bookmark",
|
||||
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 0,
|
||||
"Title": "CompDelayedTerrainSpawn.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_BuildingTerrainSpawn\\CompDelayedTerrainSpawn.cs",
|
||||
"RelativeDocumentMoniker": "Building_Comps\\ARA_BuildingTerrainSpawn\\CompDelayedTerrainSpawn.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_BuildingTerrainSpawn\\CompDelayedTerrainSpawn.cs",
|
||||
"RelativeToolTip": "Building_Comps\\ARA_BuildingTerrainSpawn\\CompDelayedTerrainSpawn.cs",
|
||||
"ViewState": "AgIAACMAAAAAAAAAAAAQwDoAAAAJAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-17T15:47:19.767Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 4,
|
||||
"Title": "WorkGiver_Refuel_Nutrition.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\WorkGivers\\WorkGiver_Refuel_Nutrition.cs",
|
||||
"RelativeDocumentMoniker": "WorkGivers\\WorkGiver_Refuel_Nutrition.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\WorkGivers\\WorkGiver_Refuel_Nutrition.cs",
|
||||
"RelativeToolTip": "WorkGivers\\WorkGiver_Refuel_Nutrition.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAADwvwAAAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-17T13:59:44.439Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 2,
|
||||
"Title": "WorkGiver_FeedWithHoney.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\WorkGivers\\WorkGiver_FeedWithHoney.cs",
|
||||
"RelativeDocumentMoniker": "WorkGivers\\WorkGiver_FeedWithHoney.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\WorkGivers\\WorkGiver_FeedWithHoney.cs",
|
||||
"RelativeToolTip": "WorkGivers\\WorkGiver_FeedWithHoney.cs",
|
||||
"ViewState": "AgIAAB0AAAAAAAAAAAAQwD0AAAAQAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-17T13:59:28.915Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 7,
|
||||
"Title": "WorkGiver_StripChitin.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\WorkGivers\\WorkGiver_StripChitin.cs",
|
||||
"RelativeDocumentMoniker": "WorkGivers\\WorkGiver_StripChitin.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\WorkGivers\\WorkGiver_StripChitin.cs",
|
||||
"RelativeToolTip": "WorkGivers\\WorkGiver_StripChitin.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAABMAAAAZAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-17T13:33:53.307Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 6,
|
||||
"Title": "WorkGiver_ExtractHoney.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\WorkGivers\\WorkGiver_ExtractHoney.cs",
|
||||
"RelativeDocumentMoniker": "WorkGivers\\WorkGiver_ExtractHoney.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\WorkGivers\\WorkGiver_ExtractHoney.cs",
|
||||
"RelativeToolTip": "WorkGivers\\WorkGiver_ExtractHoney.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAgwB0AAAAyAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-17T13:33:29.75Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 3,
|
||||
"Title": "ARA_HediffDefOf.cs",
|
||||
"DocumentMoniker": "E:\\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",
|
||||
"RelativeToolTip": "ARA_HediffDefOf.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAADwvxIAAAAkAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-15T17:32:18.493Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 1,
|
||||
"Title": "Need_HoneyProduction.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Needs\\Need_HoneyProduction.cs",
|
||||
"RelativeDocumentMoniker": "Needs\\Need_HoneyProduction.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Needs\\Need_HoneyProduction.cs",
|
||||
"RelativeToolTip": "Needs\\Need_HoneyProduction.cs",
|
||||
"ViewState": "AgIAAGIAAAAAAAAAAAAkwG4AAAAJAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-17T13:17:51.898Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 8,
|
||||
"Title": "JobDriver_ExtractHoney.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FeedWithHoney\\JobDriver_ExtractHoney.cs",
|
||||
"RelativeDocumentMoniker": "Jobs\\JobDriver_FeedWithHoney\\JobDriver_ExtractHoney.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FeedWithHoney\\JobDriver_ExtractHoney.cs",
|
||||
"RelativeToolTip": "Jobs\\JobDriver_FeedWithHoney\\JobDriver_ExtractHoney.cs",
|
||||
"ViewState": "AgIAAA8AAAAAAAAAAAAAwCYAAAAlAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-17T13:26:42.845Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 9,
|
||||
"Title": "ThinkNode_JobGiver_ExtractHoney.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FeedWithHoney\\ThinkNode_JobGiver_ExtractHoney.cs",
|
||||
"RelativeDocumentMoniker": "Jobs\\JobDriver_FeedWithHoney\\ThinkNode_JobGiver_ExtractHoney.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FeedWithHoney\\ThinkNode_JobGiver_ExtractHoney.cs",
|
||||
"RelativeToolTip": "Jobs\\JobDriver_FeedWithHoney\\ThinkNode_JobGiver_ExtractHoney.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAABQAAAAcAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-17T13:25:27.255Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 10,
|
||||
"Title": "JobDriver_SwarmMaintain.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_SwarmMaintain\\JobDriver_SwarmMaintain.cs",
|
||||
"RelativeDocumentMoniker": "Jobs\\JobDriver_SwarmMaintain\\JobDriver_SwarmMaintain.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_SwarmMaintain\\JobDriver_SwarmMaintain.cs",
|
||||
"RelativeToolTip": "Jobs\\JobDriver_SwarmMaintain\\JobDriver_SwarmMaintain.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAADwvxcAAAAJAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-17T13:32:29.359Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 5,
|
||||
"Title": "JobDriver_FeedWithHoney.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FeedWithHoney\\JobDriver_FeedWithHoney.cs",
|
||||
"RelativeDocumentMoniker": "Jobs\\JobDriver_FeedWithHoney\\JobDriver_FeedWithHoney.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FeedWithHoney\\JobDriver_FeedWithHoney.cs",
|
||||
"RelativeToolTip": "Jobs\\JobDriver_FeedWithHoney\\JobDriver_FeedWithHoney.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAgAAAAoAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-17T13:43:47.266Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 11,
|
||||
"Title": "CompCleave.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Verbs\\Cleave\\CompCleave.cs",
|
||||
"RelativeDocumentMoniker": "Verbs\\Cleave\\CompCleave.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Verbs\\Cleave\\CompCleave.cs",
|
||||
"RelativeToolTip": "Verbs\\Cleave\\CompCleave.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAABEAAAAkAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-17T13:40:25.528Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 12,
|
||||
"Title": "Comp_SwarmMaintenance.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SwarmMaintenance\\Comp_SwarmMaintenance.cs",
|
||||
"RelativeDocumentMoniker": "Building_Comps\\ARA_SwarmMaintenance\\Comp_SwarmMaintenance.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SwarmMaintenance\\Comp_SwarmMaintenance.cs",
|
||||
"RelativeToolTip": "Building_Comps\\ARA_SwarmMaintenance\\Comp_SwarmMaintenance.cs",
|
||||
"ViewState": "AgIAAKYAAAAAAAAAAAAQwH0AAAAQAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-17T13:35:29.771Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 13,
|
||||
"Title": "Need_ChitinArmor.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Needs\\Need_ChitinArmor.cs",
|
||||
"RelativeDocumentMoniker": "Needs\\Need_ChitinArmor.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Needs\\Need_ChitinArmor.cs",
|
||||
"RelativeToolTip": "Needs\\Need_ChitinArmor.cs",
|
||||
"ViewState": "AgIAAAMAAAAAAAAAAADwvwAAAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-17T13:23:16.771Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 14,
|
||||
"Title": "WorkGiver_SwarmMaintain.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\WorkGivers\\WorkGiver_SwarmMaintain.cs",
|
||||
"RelativeDocumentMoniker": "WorkGivers\\WorkGiver_SwarmMaintain.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\WorkGivers\\WorkGiver_SwarmMaintain.cs",
|
||||
"RelativeToolTip": "WorkGivers\\WorkGiver_SwarmMaintain.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAF0AAAAcAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-17T13:13:35.358Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 15,
|
||||
"Title": "Building_DormancyVat.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_DormancyVat\\Building_DormancyVat.cs",
|
||||
"RelativeDocumentMoniker": "Buildings\\Building_DormancyVat\\Building_DormancyVat.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_DormancyVat\\Building_DormancyVat.cs",
|
||||
"RelativeToolTip": "Buildings\\Building_DormancyVat\\Building_DormancyVat.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAOcAAAAjAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-17T11:50:41.189Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 16,
|
||||
"Title": "Building_ResearchBlueprintReader.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ResearchBlueprintReader\\Building_ResearchBlueprintReader.cs",
|
||||
"RelativeDocumentMoniker": "Buildings\\Building_ResearchBlueprintReader\\Building_ResearchBlueprintReader.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ResearchBlueprintReader\\Building_ResearchBlueprintReader.cs",
|
||||
"RelativeToolTip": "Buildings\\Building_ResearchBlueprintReader\\Building_ResearchBlueprintReader.cs",
|
||||
"ViewState": "AgIAAPQAAAAAAAAAAAAywAoBAABrAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-17T10:38:40.669Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 18,
|
||||
"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": "AgIAAD4AAAAAAAAAAAAAAE0AAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-16T15:50:38.09Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 20,
|
||||
"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==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-16T15:49:51.675Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 21,
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 22,
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 17,
|
||||
"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": "AgIAAAAAAAAAAAAAAAAAAAUAAAABAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-16T14:32:31.389Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 19,
|
||||
"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==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-16T15:50:04.277Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 23,
|
||||
"Title": "CompResearchProducer.cs",
|
||||
"DocumentMoniker": "E:\\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",
|
||||
"RelativeToolTip": "Building_Comps\\ARA_CompInteractiveProducer\\CompResearchProducer.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAADwvy0AAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-16T14:29:05.969Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 24,
|
||||
"Title": "CompCorpseConverter.cs",
|
||||
"DocumentMoniker": "E:\\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",
|
||||
"RelativeToolTip": "Building_Comps\\ARA_CorpseConverter\\CompCorpseConverter.cs",
|
||||
"ViewState": "AgIAABwDAAAAAAAAAAAIwCoDAAARAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-16T12:23:40.696Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 25,
|
||||
"Title": "CompProperties_CorpseConverter.cs",
|
||||
"DocumentMoniker": "E:\\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",
|
||||
"RelativeToolTip": "Building_Comps\\ARA_CorpseConverter\\CompProperties_CorpseConverter.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAADwvwAAAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-16T12:23:39.636Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 28,
|
||||
"Title": "CompRefuelableNutrition_WithKey.cs",
|
||||
"DocumentMoniker": "E:\\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",
|
||||
"RelativeToolTip": "Building_Comps\\WULA_MutiFuelSpawner\\CompRefuelableNutrition_WithKey.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAACUAAABAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-16T10:38:33.135Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 26,
|
||||
"Title": "CompTerrainChanger.cs",
|
||||
"DocumentMoniker": "E:\\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",
|
||||
"RelativeToolTip": "Building_Comps\\ARA_TerrainChanger\\CompTerrainChanger.cs",
|
||||
"ViewState": "AgIAAK0CAAAAAAAAAAAcwPYCAAAMAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-16T10:30:16.921Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 27,
|
||||
"Title": "CompProperties_TerrainChanger.cs",
|
||||
"DocumentMoniker": "E:\\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",
|
||||
"RelativeToolTip": "Building_Comps\\ARA_TerrainChanger\\CompProperties_TerrainChanger.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-16T10:30:15.601Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 34,
|
||||
"Title": "Building_RefuelingVat.cs",
|
||||
"DocumentMoniker": "E:\\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",
|
||||
"RelativeToolTip": "Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-16T10:28:54.756Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 29,
|
||||
"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": 30,
|
||||
"Title": "OothecaIncubatorExtension.cs",
|
||||
"DocumentMoniker": "E:\\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",
|
||||
"RelativeToolTip": "Buildings\\Building_Ootheca\\OothecaIncubatorExtension.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAADwvxUAAABBAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-16T04:36:59.394Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 33,
|
||||
"Title": "Building_EquipmentOotheca.cs",
|
||||
"DocumentMoniker": "E:\\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",
|
||||
"RelativeToolTip": "Buildings\\Building_EquipmentOotheca\\Building_EquipmentOotheca.cs",
|
||||
"ViewState": "AgIAACcAAAAAAAAAAAAAADoDAABSAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-15T18:22:14.171Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 31,
|
||||
"Title": "Building_Ootheca.cs",
|
||||
"DocumentMoniker": "E:\\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",
|
||||
"RelativeToolTip": "Buildings\\Building_Ootheca\\Building_Ootheca.cs",
|
||||
"ViewState": "AgIAALcCAAAAAAAAAAAewNgCAAAVAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-15T18:22:12.217Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 32,
|
||||
"Title": "CompProperties_EquipmentIncubatorData.cs",
|
||||
"DocumentMoniker": "E:\\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",
|
||||
"RelativeToolTip": "Buildings\\Building_EquipmentOotheca\\CompProperties_EquipmentIncubatorData.cs",
|
||||
"ViewState": "AgIAAA4AAAAAAAAAAADwvyYAAAAaAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-15T17:55:40.041Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -21,6 +21,9 @@ namespace ArachnaeSwarm
|
||||
public static JobDef ARA_OperateIncubator;
|
||||
public static JobDef ARA_OperateEquipmentIncubator;
|
||||
public static JobDef ARA_SwarmMaintain;
|
||||
public static JobDef ARA_ExtractHoney;
|
||||
public static JobDef ARA_StripChitin;
|
||||
public static JobDef ARA_FeedWithHoney;
|
||||
|
||||
static ARA_JobDefOf()
|
||||
{
|
||||
|
||||
@@ -114,6 +114,8 @@
|
||||
<Compile Include="Abilities\CompAbilityEffect_RandomHediff.cs" />
|
||||
<Compile Include="Abilities\CompAbilityEffect_TransformCorpse.cs" />
|
||||
<Compile Include="Buildings\Building_ArachnaeGravEngine.cs" />
|
||||
<Compile Include="Buildings\Building_DormancyVat\Building_DormancyVat.cs" />
|
||||
<Compile Include="Buildings\Building_DormancyVat\DefModExtension_DormancyVat.cs" />
|
||||
<Compile Include="Buildings\Building_EquipmentOotheca\Building_EquipmentOotheca.cs" />
|
||||
<Compile Include="Buildings\Building_EquipmentOotheca\CompProperties_EquipmentIncubatorData.cs" />
|
||||
<Compile Include="Buildings\Building_EquipmentOotheca\ITab_EquipmentOotheca_Incubation.cs" />
|
||||
@@ -131,6 +133,9 @@
|
||||
<Compile Include="HarmonyPatches\DestroyRemovesResearch\CompDestroyRemovesResearch.cs" />
|
||||
<Compile Include="HarmonyPatches\DestroyRemovesResearch\CompProperties_DestroyRemovesResearch.cs" />
|
||||
<Compile Include="HarmonyPatches\Patch_ResearchManager_AddRemoveMethod.cs" />
|
||||
<Compile Include="Pawn_Comps\ARA_SwarmMaintainer\CompProperties_SwarmMaintainer.cs" />
|
||||
<Compile Include="Pawn_Comps\ARA_SwarmMaintainer\Comp_SwarmMaintainer.cs" />
|
||||
<Compile Include="RoomRole\RoomRoleWorker_JellyVat.cs" />
|
||||
<Compile Include="RoomRole\RoomRoleWorker_Incubator.cs" />
|
||||
<Compile Include="Buildings\Building_TurretGunHasSpeed.cs" />
|
||||
<Compile Include="Buildings\Building_RefuelingVat\Building_RefuelingVat.cs" />
|
||||
@@ -256,6 +261,8 @@
|
||||
<Compile Include="Building_Comps\CompNutritionToFuelConverter.cs" />
|
||||
<Compile Include="Building_Comps\CompAutoEjector.cs" />
|
||||
<Compile Include="Jobs\JobDriver_Refuel_Nutrition.cs" />
|
||||
<Compile Include="WorkGivers\WorkGiver_ExtractHoney.cs" />
|
||||
<Compile Include="WorkGivers\WorkGiver_FeedWithHoney.cs" />
|
||||
<Compile Include="WorkGivers\WorkGiver_Refuel_Nutrition.cs" />
|
||||
<Compile Include="Hediffs\ARA_ConfigurableMutant\Hediff_ConfigurableMutant.cs" />
|
||||
<Compile Include="Hediffs\ARA_ConfigurableMutant\Hediff_NecroticVirus_Configurable.cs" />
|
||||
@@ -371,6 +378,8 @@
|
||||
<Compile Include="PowerArmor\CompPowerArmorStation.cs" />
|
||||
<Compile Include="PowerArmor\Gizmo_StructurePanel.cs" />
|
||||
<Compile Include="PowerArmor\JobDriver_EnterPowerArmor.cs" />
|
||||
<Compile Include="WorkGivers\WorkGiver_StripChitin.cs" />
|
||||
<Compile Include="WorkGivers\WorkGiver_SwarmMaintain.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Jobs\JobDriver_SuperCarry\SuperCarryExtension.cs" />
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace ArachnaeSwarm
|
||||
/// <returns>如果地形有 ARA_Creep 标签则返回 true</returns>
|
||||
private bool HasCreepTag(TerrainDef terrain)
|
||||
{
|
||||
return terrain.tags != null && terrain.tags.Contains("ARA_Creep");
|
||||
return terrain.tags != null && terrain.tags.Contains("ARA_Creep") || terrain.tags.Contains("ARA_Incubator_Nutrient_Solution");
|
||||
}
|
||||
|
||||
// NOTICE: There is NO CompTick() method here. This component does not perform any updates after it has spawned.
|
||||
|
||||
@@ -19,13 +19,10 @@ namespace ArachnaeSwarm
|
||||
// 维护度达到多少时开始显示警告(百分比)
|
||||
public float warningThreshold = 0.3f;
|
||||
|
||||
// 可维护的种族列表
|
||||
public List<ThingDef> allowedRaces;
|
||||
// 可维护的种族列表(现在由WorkGiver处理)
|
||||
// public List<ThingDef> allowedRaces;
|
||||
|
||||
// 检查分配工作的间隔(ticks)
|
||||
public int assignJobCheckInterval = 600; // 10秒
|
||||
|
||||
// 维护度低于多少时开始寻找维护者(百分比)
|
||||
// 维护度低于多少时开始需要维护工作(百分比)
|
||||
public float maintenanceThresholdForJob = 0.9f;
|
||||
|
||||
public CompProperties_SwarmMaintenance()
|
||||
|
||||
@@ -18,19 +18,14 @@ namespace ArachnaeSwarm
|
||||
// 上次更新维护度的时间
|
||||
private int lastMaintenanceTick = -99999;
|
||||
|
||||
// 上次检查分配工作的时间
|
||||
private int lastJobCheckTick = -99999;
|
||||
|
||||
// 当维护度为0时,每秒受到的伤害计时器
|
||||
private int nextDamageTick = -99999;
|
||||
|
||||
// 是否正在寻找维护者
|
||||
private bool seekingMaintainer = false;
|
||||
|
||||
// 找不到维护者的提示信息
|
||||
private string noMaintainerWarning = "";
|
||||
// 警告计时器
|
||||
private int lastWarningTick = -99999;
|
||||
private const int WarningDuration = 2500; // 警告显示41.67秒
|
||||
private const int WarningInterval = 2500; // 警告间隔时间
|
||||
private const float CriticalWarningThreshold = 0.3f; // 警告阈值(百分比)
|
||||
private bool lastWarningState = false;
|
||||
|
||||
// 属性访问
|
||||
public float CurrentMaintenance => currentMaintenance;
|
||||
@@ -46,7 +41,6 @@ namespace ArachnaeSwarm
|
||||
base.Initialize(props);
|
||||
currentMaintenance = Props.maxMaintenance; // 初始时满维护度
|
||||
lastMaintenanceTick = Find.TickManager.TicksGame;
|
||||
lastJobCheckTick = Find.TickManager.TicksGame;
|
||||
}
|
||||
|
||||
// 序列化
|
||||
@@ -55,11 +49,9 @@ namespace ArachnaeSwarm
|
||||
base.PostExposeData();
|
||||
Scribe_Values.Look(ref currentMaintenance, "currentMaintenance", Props.maxMaintenance);
|
||||
Scribe_Values.Look(ref lastMaintenanceTick, "lastMaintenanceTick", -99999);
|
||||
Scribe_Values.Look(ref lastJobCheckTick, "lastJobCheckTick", -99999);
|
||||
Scribe_Values.Look(ref nextDamageTick, "nextDamageTick", -99999);
|
||||
Scribe_Values.Look(ref seekingMaintainer, "seekingMaintainer", false);
|
||||
Scribe_Values.Look(ref noMaintainerWarning, "noMaintainerWarning", "");
|
||||
Scribe_Values.Look(ref lastWarningTick, "lastWarningTick", -99999);
|
||||
Scribe_Values.Look(ref lastWarningState, "lastWarningState", false);
|
||||
}
|
||||
|
||||
// 每tick更新
|
||||
@@ -76,11 +68,11 @@ namespace ArachnaeSwarm
|
||||
lastMaintenanceTick = currentTick;
|
||||
}
|
||||
|
||||
// 定期检查是否需要分配维护工作
|
||||
if (currentTick - lastJobCheckTick >= Props.assignJobCheckInterval)
|
||||
// 检查是否需要显示警告
|
||||
if (currentTick - lastWarningTick >= WarningInterval)
|
||||
{
|
||||
CheckAndAssignMaintenanceJob();
|
||||
lastJobCheckTick = currentTick;
|
||||
CheckWarning();
|
||||
lastWarningTick = currentTick;
|
||||
}
|
||||
|
||||
// 如果维护度为0,每秒造成伤害
|
||||
@@ -89,12 +81,6 @@ namespace ArachnaeSwarm
|
||||
ApplyDamageWhenEmpty();
|
||||
nextDamageTick = currentTick + 60; // 60ticks = 1秒
|
||||
}
|
||||
|
||||
// 更新警告信息显示时间
|
||||
if (currentTick - lastWarningTick >= WarningDuration)
|
||||
{
|
||||
noMaintainerWarning = "";
|
||||
}
|
||||
}
|
||||
|
||||
// 更新维护度递减
|
||||
@@ -112,6 +98,39 @@ namespace ArachnaeSwarm
|
||||
currentMaintenance = 0f;
|
||||
}
|
||||
|
||||
// 检查是否需要显示警告
|
||||
private void CheckWarning()
|
||||
{
|
||||
if (parent == null || parent.Destroyed || parent.Map == null)
|
||||
return;
|
||||
|
||||
bool isCritical = MaintenancePercentage <= CriticalWarningThreshold;
|
||||
|
||||
// 如果状态改变,显示警告
|
||||
if (isCritical && !lastWarningState)
|
||||
{
|
||||
ShowMaintenanceWarning();
|
||||
lastWarningState = true;
|
||||
}
|
||||
else if (!isCritical && lastWarningState)
|
||||
{
|
||||
lastWarningState = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 显示维护警告
|
||||
private void ShowMaintenanceWarning()
|
||||
{
|
||||
if (parent == null)
|
||||
return;
|
||||
|
||||
// 添加警告标记
|
||||
if (parent.Spawned)
|
||||
{
|
||||
MoteMaker.ThrowText(parent.DrawPos, parent.Map, "ARA_SwarmMaintenance.NeedsMaintenance".Translate(), Color.yellow);
|
||||
}
|
||||
}
|
||||
|
||||
// 当维护度为0时应用伤害
|
||||
private void ApplyDamageWhenEmpty()
|
||||
{
|
||||
@@ -130,188 +149,53 @@ namespace ArachnaeSwarm
|
||||
));
|
||||
}
|
||||
|
||||
// 检查并分配维护工作
|
||||
private void CheckAndAssignMaintenanceJob()
|
||||
{
|
||||
if (parent == null || parent.Map == null || parent.Faction == null)
|
||||
return;
|
||||
|
||||
// 如果不需要维护,重置状态
|
||||
if (!NeedsMaintenance)
|
||||
{
|
||||
seekingMaintainer = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果正在寻找维护者,尝试分配工作
|
||||
if (!seekingMaintainer)
|
||||
{
|
||||
seekingMaintainer = true;
|
||||
}
|
||||
|
||||
// 尝试寻找符合条件的Pawn
|
||||
Pawn maintainer = FindAvailableMaintainer();
|
||||
|
||||
if (maintainer != null)
|
||||
{
|
||||
// 分配维护工作
|
||||
AssignMaintenanceJobTo(maintainer);
|
||||
seekingMaintainer = false;
|
||||
noMaintainerWarning = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
// 记录找不到维护者的警告
|
||||
if (noMaintainerWarning == "")
|
||||
{
|
||||
noMaintainerWarning = "ARA_SwarmMaintenance.NoMaintainerFound".Translate();
|
||||
lastWarningTick = Find.TickManager.TicksGame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 寻找可用的维护者
|
||||
private Pawn FindAvailableMaintainer()
|
||||
{
|
||||
if (parent.Map == null || parent.Faction == null)
|
||||
return null;
|
||||
|
||||
// 查找地图中所有属于玩家阵营的Pawn
|
||||
List<Pawn> allPawns = parent.Map.mapPawns.SpawnedPawnsInFaction(parent.Faction);
|
||||
|
||||
foreach (Pawn pawn in allPawns)
|
||||
{
|
||||
if (CanPawnMaintain(pawn))
|
||||
{
|
||||
return pawn;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// 判断Pawn是否可以维护
|
||||
private bool CanPawnMaintain(Pawn pawn)
|
||||
{
|
||||
if (pawn == null || pawn.Dead || pawn.Downed || pawn.InMentalState)
|
||||
return false;
|
||||
|
||||
// 检查种族是否在允许列表中
|
||||
if (Props.allowedRaces != null && Props.allowedRaces.Count > 0)
|
||||
{
|
||||
if (!Props.allowedRaces.Contains(pawn.def))
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查Pawn是否处于GotoWander或Wait_Wander状态
|
||||
if (!IsPawnWandering(pawn))
|
||||
return false;
|
||||
|
||||
// 检查Pawn是否已经有维护工作
|
||||
if (HasMaintenanceJob(pawn))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 检查Pawn是否处于漫游状态
|
||||
private bool IsPawnWandering(Pawn pawn)
|
||||
{
|
||||
if (pawn.jobs == null || pawn.jobs.curJob == null)
|
||||
return false;
|
||||
|
||||
Job curJob = pawn.jobs.curJob;
|
||||
|
||||
// 检查是否是漫游工作
|
||||
if (curJob.def == JobDefOf.GotoWander || curJob.def == JobDefOf.Wait_Wander)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查Pawn是否已经有维护工作
|
||||
private bool HasMaintenanceJob(Pawn pawn)
|
||||
{
|
||||
if (pawn.jobs == null)
|
||||
return false;
|
||||
|
||||
// 检查当前工作是否是维护工作
|
||||
if (pawn.jobs.curJob != null && pawn.jobs.curJob.def == ARA_JobDefOf.ARA_SwarmMaintain)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// 检查工作队列中是否有维护工作
|
||||
if (pawn.jobs.jobQueue != null && pawn.jobs.jobQueue.Count > 0)
|
||||
{
|
||||
foreach (QueuedJob queuedJob in pawn.jobs.jobQueue)
|
||||
{
|
||||
if (queuedJob.job.def == ARA_JobDefOf.ARA_SwarmMaintain)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 为Pawn分配维护工作
|
||||
private void AssignMaintenanceJobTo(Pawn pawn)
|
||||
{
|
||||
if (pawn == null || pawn.jobs == null)
|
||||
return;
|
||||
|
||||
// 创建维护工作
|
||||
Job job = JobMaker.MakeJob(ARA_JobDefOf.ARA_SwarmMaintain, parent);
|
||||
job.expiryInterval = 30000; // 工作过期时间
|
||||
job.ignoreForbidden = false;
|
||||
|
||||
// 记录Pawn原来的工作以便恢复
|
||||
Job oldJob = pawn.jobs.curJob;
|
||||
|
||||
// 将工作添加到队列末尾
|
||||
pawn.jobs.TryTakeOrderedJob(job, JobTag.MiscWork);
|
||||
|
||||
// 如果Pawn原来在漫游,我们可以在维护工作完成后恢复漫游状态
|
||||
if (oldJob != null && (oldJob.def == JobDefOf.GotoWander || oldJob.def == JobDefOf.Wait_Wander))
|
||||
{
|
||||
// 我们可以在维护工作完成后添加一个恢复漫游的工作
|
||||
// 这里暂时不做处理,因为维护工作完成后Pawn会回到空闲状态
|
||||
// 如果需要更精细的控制,可以在JobDriver_SwarmMaintain完成时添加漫游工作
|
||||
}
|
||||
}
|
||||
|
||||
// 添加维护度
|
||||
public void AddMaintenance(float amount)
|
||||
{
|
||||
currentMaintenance += amount;
|
||||
if (currentMaintenance > MaxMaintenance)
|
||||
currentMaintenance = MaxMaintenance;
|
||||
|
||||
// 维护后重置警告状态
|
||||
lastWarningState = false;
|
||||
}
|
||||
|
||||
// 重置维护度
|
||||
public void ResetMaintenance()
|
||||
{
|
||||
currentMaintenance = MaxMaintenance;
|
||||
lastWarningState = false;
|
||||
}
|
||||
|
||||
// 获取可维护的优先级(用于WorkGiver排序)
|
||||
public float GetMaintenancePriority()
|
||||
{
|
||||
// 维护度越低,优先级越高
|
||||
return 1f - MaintenancePercentage;
|
||||
}
|
||||
|
||||
// 在建筑信息面板中追加维护信息
|
||||
public override string CompInspectStringExtra()
|
||||
{
|
||||
// 基础信息
|
||||
string text = "ARA_SwarmMaintenance.MaintenanceLevel".Translate(currentMaintenance.ToString("F1"), MaxMaintenance.ToString("F1"), MaintenancePercentage.ToString("P1"));
|
||||
string text = "ARA_SwarmMaintenance.MaintenanceLevel".Translate(
|
||||
currentMaintenance.ToString("F1"),
|
||||
MaxMaintenance.ToString("F1"),
|
||||
MaintenancePercentage.ToString("P1"));
|
||||
|
||||
// 添加维护度递减信息
|
||||
text += "\n" + "ARA_SwarmMaintenance.DailyDecay".Translate(Props.maintenanceDecayPerDay.ToString("F1"));
|
||||
|
||||
|
||||
// 显示找不到维护者的警告
|
||||
if (noMaintainerWarning != "")
|
||||
// 显示维护状态
|
||||
if (NeedsMaintenance)
|
||||
{
|
||||
text += "\n<color=orange>" + noMaintainerWarning + "</color>";
|
||||
text += "\n" + "ARA_SwarmMaintenance.NeedsMaintenance".Translate();
|
||||
}
|
||||
|
||||
// 显示警告信息
|
||||
if (IsCritical)
|
||||
{
|
||||
text += "\n<color=orange>" + "ARA_SwarmMaintenance.CriticalLevel".Translate() + "</color>";
|
||||
}
|
||||
|
||||
return text;
|
||||
@@ -323,58 +207,9 @@ namespace ArachnaeSwarm
|
||||
// 只在玩家控制下显示
|
||||
if (parent.Faction?.IsPlayer == true)
|
||||
{
|
||||
// 调试按钮:手动触发寻找维护者 - 仅在GodMode下显示
|
||||
// 调试按钮 - 仅在GodMode下显示
|
||||
if (DebugSettings.godMode)
|
||||
{
|
||||
yield return new Command_Action
|
||||
{
|
||||
defaultLabel = "Debug: Find Maintainer",
|
||||
action = () =>
|
||||
{
|
||||
Pawn maintainer = FindAvailableMaintainer();
|
||||
if (maintainer != null)
|
||||
{
|
||||
Messages.Message($"找到维护者: {maintainer.LabelShort} (当前工作: {maintainer.jobs.curJob?.def.defName ?? "无"})", MessageTypeDefOf.PositiveEvent);
|
||||
AssignMaintenanceJobTo(maintainer);
|
||||
}
|
||||
else
|
||||
{
|
||||
Messages.Message("未找到符合条件的空闲维护者", MessageTypeDefOf.NegativeEvent);
|
||||
|
||||
// 列出所有符合条件的Pawn及其状态
|
||||
List<Pawn> allPawns = parent.Map.mapPawns.SpawnedPawnsInFaction(parent.Faction);
|
||||
List<string> pawnStatus = new List<string>();
|
||||
|
||||
foreach (Pawn pawn in allPawns)
|
||||
{
|
||||
if (Props.allowedRaces != null && Props.allowedRaces.Count > 0 && !Props.allowedRaces.Contains(pawn.def))
|
||||
continue;
|
||||
|
||||
string status = $"{pawn.LabelShort}: ";
|
||||
if (pawn.Dead) status += "死亡";
|
||||
else if (pawn.Downed) status += "倒地";
|
||||
else if (pawn.InMentalState) status += "精神崩溃";
|
||||
else if (pawn.jobs?.curJob != null)
|
||||
{
|
||||
status += $"{pawn.jobs.curJob.def.defName}";
|
||||
if (HasMaintenanceJob(pawn)) status += " (已有维护工作)";
|
||||
}
|
||||
else
|
||||
{
|
||||
status += "空闲";
|
||||
}
|
||||
|
||||
pawnStatus.Add(status);
|
||||
}
|
||||
|
||||
if (pawnStatus.Count > 0)
|
||||
{
|
||||
Messages.Message("符合条件的Pawn状态:\n" + string.Join("\n", pawnStatus), MessageTypeDefOf.SilentInput);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
yield return new Command_Action
|
||||
{
|
||||
defaultLabel = "Debug: Reset Maintenance",
|
||||
@@ -392,6 +227,15 @@ namespace ArachnaeSwarm
|
||||
defaultLabel = "Debug: Reduce to 0",
|
||||
action = () => currentMaintenance = 0f
|
||||
};
|
||||
|
||||
yield return new Command_Action
|
||||
{
|
||||
defaultLabel = "Debug: Show Priority",
|
||||
action = () =>
|
||||
{
|
||||
Messages.Message($"维护优先级: {GetMaintenancePriority():F2}", MessageTypeDefOf.SilentInput);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,459 @@
|
||||
using RimWorld;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
using Verse.AI;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
[StaticConstructorOnStartup]
|
||||
public class Building_DormancyVat : Building_Enterable, IThingHolder, IThingHolderWithDrawnPawn
|
||||
{
|
||||
private Graphic cachedTopGraphic;
|
||||
|
||||
// IThingHolderWithDrawnPawn implementation
|
||||
public float HeldPawnDrawPos_Y => DrawPos.y + 0.03658537f;
|
||||
public float HeldPawnBodyAngle => base.Rotation.AsAngle;
|
||||
public PawnPosture HeldPawnPosture => PawnPosture.LayingOnGroundFaceUp;
|
||||
|
||||
private Graphic TopGraphic
|
||||
{
|
||||
get
|
||||
{
|
||||
if (cachedTopGraphic == null)
|
||||
{
|
||||
var modExtension = def.GetModExtension<DefModExtension_DormancyVat>();
|
||||
if (modExtension != null && !modExtension.topGraphicPath.NullOrEmpty())
|
||||
{
|
||||
cachedTopGraphic = GraphicDatabase.Get(modExtension.graphicClass, modExtension.topGraphicPath, ShaderDatabase.Transparent, def.graphicData.drawSize, Color.white, Color.white);
|
||||
}
|
||||
}
|
||||
return cachedTopGraphic;
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector3 PawnDrawOffset => Vector3.zero;
|
||||
|
||||
public override void SpawnSetup(Map map, bool respawningAfterLoad)
|
||||
{
|
||||
base.SpawnSetup(map, respawningAfterLoad);
|
||||
}
|
||||
|
||||
public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish)
|
||||
{
|
||||
if (mode != DestroyMode.WillReplace)
|
||||
{
|
||||
if (selectedPawn != null && innerContainer.Contains(selectedPawn))
|
||||
{
|
||||
Finish(); // 弹出里面的pawn
|
||||
}
|
||||
}
|
||||
base.DeSpawn(mode);
|
||||
}
|
||||
|
||||
protected override void Tick()
|
||||
{
|
||||
base.Tick();
|
||||
|
||||
if (selectedPawn != null && (selectedPawn.Destroyed || !innerContainer.Contains(selectedPawn)))
|
||||
{
|
||||
OnStop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (base.Working && selectedPawn != null)
|
||||
{
|
||||
// 检查pawn是否死亡
|
||||
if (selectedPawn.Dead || selectedPawn.Destroyed)
|
||||
{
|
||||
Finish(); // 弹出死亡的pawn
|
||||
return;
|
||||
}
|
||||
|
||||
// 休眠Vat不产生任何效果,只需保持pawn在里面
|
||||
}
|
||||
}
|
||||
|
||||
public override AcceptanceReport CanAcceptPawn(Pawn pawn)
|
||||
{
|
||||
if (base.Working)
|
||||
{
|
||||
return "DormancyVat_Occupied".Translate();
|
||||
}
|
||||
if (selectedPawn != null && selectedPawn != pawn)
|
||||
{
|
||||
return "DormancyVat_WaitingForArachnae".Translate(selectedPawn.Named("PAWN"));
|
||||
}
|
||||
|
||||
// 只允许虫族成员进入
|
||||
bool isArachnaeMember =
|
||||
pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindDrone);
|
||||
|
||||
if (!isArachnaeMember)
|
||||
{
|
||||
return "DormancyVat_OnlyArachnaeAllowed".Translate(pawn.Named("PAWN"));
|
||||
}
|
||||
|
||||
// 不允许已经死亡的pawn
|
||||
if (pawn.Dead)
|
||||
{
|
||||
return "DormancyVat_CannotAcceptDeadPawn".Translate(pawn.Named("PAWN"));
|
||||
}
|
||||
|
||||
// 允许殖民者、囚犯和奴隶,但必须是虫族成员
|
||||
bool isColonist = pawn.IsColonist;
|
||||
bool isPrisoner = pawn.IsPrisonerOfColony;
|
||||
bool isSlave = pawn.IsSlaveOfColony;
|
||||
|
||||
return (isColonist || isPrisoner || isSlave) && !pawn.IsQuestLodger();
|
||||
}
|
||||
|
||||
public override void TryAcceptPawn(Pawn pawn)
|
||||
{
|
||||
if (!CanAcceptPawn(pawn).Accepted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
selectedPawn = pawn;
|
||||
bool deselected = pawn.DeSpawnOrDeselect();
|
||||
if (innerContainer.TryAddOrTransfer(pawn))
|
||||
{
|
||||
startTick = Find.TickManager.TicksGame;
|
||||
}
|
||||
if (deselected)
|
||||
{
|
||||
Find.Selector.Select(pawn, playSound: false, forceDesignatorDeselect: false);
|
||||
}
|
||||
}
|
||||
|
||||
private void Finish()
|
||||
{
|
||||
if (selectedPawn != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 检查pawn是否还活着
|
||||
if (selectedPawn.Dead)
|
||||
{
|
||||
Notify_PawnRemoved();
|
||||
|
||||
// 对死亡的pawn,将其尸体弹出
|
||||
bool ejected = false;
|
||||
|
||||
if (innerContainer.Contains(selectedPawn))
|
||||
{
|
||||
ejected = innerContainer.TryDrop(selectedPawn, InteractionCell, base.Map, ThingPlaceMode.Near, 1, out var _);
|
||||
}
|
||||
|
||||
if (!ejected && innerContainer.Contains(selectedPawn))
|
||||
{
|
||||
var adjacentCells = GenAdj.CellsAdjacent8Way(this).Where(c => c.Walkable(base.Map) && c.InBounds(base.Map)).ToList();
|
||||
if (adjacentCells.Count > 0)
|
||||
{
|
||||
IntVec3 randomCell = adjacentCells.RandomElement();
|
||||
ejected = innerContainer.TryDrop(selectedPawn, randomCell, base.Map, ThingPlaceMode.Direct, 1, out var _);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ejected && innerContainer.Contains(selectedPawn))
|
||||
{
|
||||
innerContainer.Remove(selectedPawn);
|
||||
GenPlace.TryPlaceThing(selectedPawn, this.Position, base.Map, ThingPlaceMode.Near);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Notify_PawnRemoved();
|
||||
|
||||
// 对活着的pawn,安全弹出
|
||||
bool ejected = false;
|
||||
|
||||
if (innerContainer.Contains(selectedPawn))
|
||||
{
|
||||
ejected = innerContainer.TryDrop(selectedPawn, InteractionCell, base.Map, ThingPlaceMode.Near, 1, out var _);
|
||||
}
|
||||
|
||||
if (!ejected && innerContainer.Contains(selectedPawn))
|
||||
{
|
||||
var adjacentCells = GenAdj.CellsAdjacent8Way(this).Where(c => c.Walkable(base.Map) && c.InBounds(base.Map)).ToList();
|
||||
if (adjacentCells.Count > 0)
|
||||
{
|
||||
IntVec3 randomCell = adjacentCells.RandomElement();
|
||||
ejected = innerContainer.TryDrop(selectedPawn, randomCell, base.Map, ThingPlaceMode.Direct, 1, out var _);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ejected && innerContainer.Contains(selectedPawn))
|
||||
{
|
||||
innerContainer.Remove(selectedPawn);
|
||||
GenPlace.TryPlaceThing(selectedPawn, this.Position, base.Map, ThingPlaceMode.Near);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("DormancyVat_ErrorEjecting".Translate(selectedPawn.Label) + ": " + ex.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
OnStop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnStop()
|
||||
{
|
||||
if (selectedPawn != null)
|
||||
{
|
||||
if (innerContainer.Contains(selectedPawn))
|
||||
{
|
||||
innerContainer.Remove(selectedPawn);
|
||||
}
|
||||
}
|
||||
selectedPawn = null;
|
||||
startTick = -1;
|
||||
}
|
||||
|
||||
private void Notify_PawnRemoved()
|
||||
{
|
||||
// 可以在这里添加音效
|
||||
// SoundDefOf.GrowthVat_Open.PlayOneShot(SoundInfo.InMap(this));
|
||||
}
|
||||
|
||||
public override IEnumerable<Gizmo> GetGizmos()
|
||||
{
|
||||
// 基础Gizmos
|
||||
foreach (Gizmo gizmo in base.GetGizmos())
|
||||
{
|
||||
yield return gizmo;
|
||||
}
|
||||
|
||||
if (base.Working)
|
||||
{
|
||||
// 休眠Vat工作时显示"弹出"按钮
|
||||
Command_Action ejectCommand = new Command_Action
|
||||
{
|
||||
defaultLabel = "DormancyVat_EjectButton".Translate(),
|
||||
defaultDesc = "DormancyVat_EjectButtonDesc".Translate(),
|
||||
icon = ContentFinder<Texture2D>.Get("UI/Commands/Cancel", false),
|
||||
action = () => Finish()
|
||||
};
|
||||
yield return ejectCommand;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 选择虫族成员的操作
|
||||
Command_Action command_Action = new Command_Action
|
||||
{
|
||||
defaultLabel = "DormancyVat_InsertButton".Translate() + "...",
|
||||
defaultDesc = "DormancyVat_InsertButtonDesc".Translate(),
|
||||
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_InsertPawn", false),
|
||||
action = () =>
|
||||
{
|
||||
List<FloatMenuOption> list = new List<FloatMenuOption>();
|
||||
foreach (Pawn p in base.Map.mapPawns.AllPawnsSpawned)
|
||||
{
|
||||
if (CanAcceptPawn(p).Accepted)
|
||||
{
|
||||
string pawnType = "";
|
||||
if (p.IsColonist) pawnType = "DormancyVat_Colonist".Translate();
|
||||
else if (p.IsPrisoner) pawnType = "DormancyVat_Prisoner".Translate();
|
||||
else if (p.IsSlave) pawnType = "DormancyVat_Slave".Translate();
|
||||
|
||||
list.Add(new FloatMenuOption(
|
||||
p.LabelCap + " (" + pawnType + ")",
|
||||
() => SelectPawn(p),
|
||||
p,
|
||||
Color.white
|
||||
));
|
||||
}
|
||||
}
|
||||
if (!list.Any())
|
||||
{
|
||||
list.Add(new FloatMenuOption("DormancyVat_NoArachnaeAvailable".Translate(), null));
|
||||
}
|
||||
Find.WindowStack.Add(new FloatMenu(list));
|
||||
}
|
||||
};
|
||||
if (!base.AnyAcceptablePawns)
|
||||
{
|
||||
command_Action.Disable("DormancyVat_NoArachnaeAvailable".Translate());
|
||||
}
|
||||
yield return command_Action;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetArachnaeType(Pawn pawn)
|
||||
{
|
||||
if (pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindMaster))
|
||||
return "DormancyVat_ArachnaeType_Master".Translate();
|
||||
else if (pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindDrone))
|
||||
return "DormancyVat_ArachnaeType_Drone".Translate();
|
||||
else if (pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindWorker))
|
||||
return "DormancyVat_ArachnaeType_Worker".Translate();
|
||||
else
|
||||
return "DormancyVat_ArachnaeType_Unknown".Translate();
|
||||
}
|
||||
|
||||
public override string GetInspectString()
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.Append(base.GetInspectString());
|
||||
|
||||
if (base.Working && selectedPawn != null)
|
||||
{
|
||||
stringBuilder.AppendLineIfNotEmpty().Append("DormancyVat_Contains".Translate() + ": " + selectedPawn.NameShortColored.Resolve());
|
||||
stringBuilder.AppendLineIfNotEmpty().Append("DormancyVat_TypeLabel".Translate() + ": " + GetArachnaeType(selectedPawn));
|
||||
|
||||
// 显示休眠时间
|
||||
if (startTick > 0)
|
||||
{
|
||||
int ticksInVat = Find.TickManager.TicksGame - startTick;
|
||||
int days = ticksInVat / 60000;
|
||||
int hours = (ticksInVat % 60000) / 2500;
|
||||
stringBuilder.AppendLineIfNotEmpty().Append("DormancyVat_DormancyTime".Translate() + $": {days}" + "DormancyVat_Days".Translate() + $"{hours}" + "DormancyVat_Hours".Translate());
|
||||
}
|
||||
|
||||
// 显示健康状态
|
||||
stringBuilder.AppendLineIfNotEmpty().Append("DormancyVat_HealthStatus".Translate() + ": " + selectedPawn.health.summaryHealth.SummaryHealthPercent.ToStringPercent());
|
||||
}
|
||||
else if (selectedPawn != null)
|
||||
{
|
||||
stringBuilder.AppendLineIfNotEmpty().Append("DormancyVat_WaitingForArachnae".Translate(selectedPawn.Named("PAWN")).Resolve());
|
||||
}
|
||||
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
public override IEnumerable<FloatMenuOption> GetFloatMenuOptions(Pawn selPawn)
|
||||
{
|
||||
foreach (FloatMenuOption floatMenuOption in base.GetFloatMenuOptions(selPawn))
|
||||
{
|
||||
yield return floatMenuOption;
|
||||
}
|
||||
if (!selPawn.CanReach(this, PathEndMode.InteractionCell, Danger.Deadly))
|
||||
{
|
||||
yield return new FloatMenuOption("DormancyVat_CannotEnter".Translate(this) + ": " + "DormancyVat_NoPath".Translate().CapitalizeFirst(), null);
|
||||
yield break;
|
||||
}
|
||||
AcceptanceReport acceptanceReport = CanAcceptPawn(selPawn);
|
||||
if (acceptanceReport.Accepted)
|
||||
{
|
||||
yield return FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("DormancyVat_Enter".Translate(this), () => SelectPawn(selPawn)), selPawn, this);
|
||||
}
|
||||
else if (!acceptanceReport.Reason.NullOrEmpty())
|
||||
{
|
||||
yield return new FloatMenuOption("DormancyVat_CannotEnter".Translate(this) + ": " + acceptanceReport.Reason.CapitalizeFirst(), null);
|
||||
}
|
||||
}
|
||||
|
||||
public override void DynamicDrawPhaseAt(DrawPhase phase, Vector3 drawLoc, bool flip = false)
|
||||
{
|
||||
if (base.Working && selectedPawn != null && innerContainer.Contains(selectedPawn))
|
||||
{
|
||||
selectedPawn.Drawer.renderer.DynamicDrawPhaseAt(phase, drawLoc + PawnDrawOffset, null, neverAimWeapon: true);
|
||||
}
|
||||
base.DynamicDrawPhaseAt(phase, drawLoc, flip);
|
||||
}
|
||||
|
||||
protected override void DrawAt(Vector3 drawLoc, bool flip = false)
|
||||
{
|
||||
base.DrawAt(drawLoc, flip);
|
||||
// 绘制顶部图形(如果存在)
|
||||
if (TopGraphic != null)
|
||||
{
|
||||
TopGraphic.Draw(DrawPos + Altitudes.AltIncVect * 2f, base.Rotation, this);
|
||||
}
|
||||
}
|
||||
|
||||
public Job CreateCarryJobForMember(Pawn member, Pawn carrier)
|
||||
{
|
||||
if (member == null || carrier == null)
|
||||
return null;
|
||||
if (!CanAcceptPawn(member).Accepted)
|
||||
return null;
|
||||
|
||||
// 创建搬运工作定义
|
||||
JobDef carryJobDef = DefDatabase<JobDef>.GetNamed("ARA_CarryMemberToDormancyVat");
|
||||
if (carryJobDef == null)
|
||||
return null;
|
||||
Job job = JobMaker.MakeJob(carryJobDef, member, this);
|
||||
job.count = 1;
|
||||
return job;
|
||||
}
|
||||
|
||||
public IEnumerable<Pawn> GetAvailableCarriers()
|
||||
{
|
||||
foreach (Pawn pawn in base.Map.mapPawns.AllPawnsSpawned)
|
||||
{
|
||||
// 检查是否是虫群成员
|
||||
if (pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindDrone) ||
|
||||
pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindWorker) ||
|
||||
pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindMaster))
|
||||
{
|
||||
// 检查是否能够工作且不是囚犯
|
||||
if (pawn.workSettings != null && pawn.workSettings.WorkIsActive(WorkTypeDefOf.Hauling) &&
|
||||
!pawn.Downed && !pawn.IsPrisoner && pawn.CanReach(this, PathEndMode.InteractionCell, Danger.Some))
|
||||
{
|
||||
yield return pawn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AssignCarrierForMember(Pawn member)
|
||||
{
|
||||
if (member == null)
|
||||
return;
|
||||
|
||||
// 获取可用的搬运者
|
||||
var availableCarriers = GetAvailableCarriers().ToList();
|
||||
|
||||
if (!availableCarriers.Any())
|
||||
{
|
||||
Messages.Message("DormancyVat_NoAvailableCarriers".Translate(), MessageTypeDefOf.RejectInput);
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建浮动菜单选择搬运者
|
||||
List<FloatMenuOption> options = new List<FloatMenuOption>();
|
||||
|
||||
foreach (Pawn carrier in availableCarriers)
|
||||
{
|
||||
options.Add(new FloatMenuOption(
|
||||
carrier.LabelCap + " (" + GetArachnaeType(carrier) + ")",
|
||||
() =>
|
||||
{
|
||||
Job carryJob = CreateCarryJobForMember(member, carrier);
|
||||
if (carryJob != null)
|
||||
{
|
||||
carrier.jobs.TryTakeOrderedJob(carryJob, JobTag.MiscWork);
|
||||
Messages.Message("DormancyVat_CarrierAssigned".Translate(carrier.LabelShort, member.LabelShort), MessageTypeDefOf.NeutralEvent);
|
||||
}
|
||||
},
|
||||
carrier,
|
||||
Color.white
|
||||
));
|
||||
}
|
||||
|
||||
if (options.Any())
|
||||
{
|
||||
Find.WindowStack.Add(new FloatMenu(options));
|
||||
}
|
||||
else
|
||||
{
|
||||
Messages.Message("DormancyVat_NoAvailableCarriers".Translate(), MessageTypeDefOf.RejectInput);
|
||||
}
|
||||
}
|
||||
|
||||
// 保存和加载数据
|
||||
public override void ExposeData()
|
||||
{
|
||||
base.ExposeData();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class DefModExtension_DormancyVat : DefModExtension
|
||||
{
|
||||
public string topGraphicPath;
|
||||
public Type graphicClass = typeof(Graphic_Multi); // 如果在XML中没有指定,默认使用Graphic_Multi
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
// File: Buildings/Building_ResearchBlueprintReader.cs
|
||||
using AlienRace;
|
||||
using RimWorld;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -150,7 +151,7 @@ namespace ArachnaeSwarm
|
||||
isResearching = false;
|
||||
|
||||
// 发送消息
|
||||
Messages.Message($"科技研究完成: {storedResearch.LabelCap}",
|
||||
Messages.Message("ResearchBlueprintReader_ResearchCompleted".Translate(storedResearch.LabelCap),
|
||||
MessageTypeDefOf.PositiveEvent);
|
||||
|
||||
Log.Message($"[ResearchBlueprintReader] Research completed: {storedResearch.defName}");
|
||||
@@ -174,7 +175,7 @@ namespace ArachnaeSwarm
|
||||
{
|
||||
if (IsLocked)
|
||||
{
|
||||
Messages.Message("建筑已锁定储存科技,无法开始新研究",
|
||||
Messages.Message("ResearchBlueprintReader_LockedBuilding".Translate(),
|
||||
MessageTypeDefOf.RejectInput);
|
||||
return;
|
||||
}
|
||||
@@ -185,7 +186,7 @@ namespace ArachnaeSwarm
|
||||
// 检查前置条件
|
||||
if (!AreAllPrerequisitesCompleted(project))
|
||||
{
|
||||
Messages.Message("未满足前置科技条件",
|
||||
Messages.Message("ResearchBlueprintReader_PrerequisitesNotMet".Translate(),
|
||||
MessageTypeDefOf.RejectInput);
|
||||
return;
|
||||
}
|
||||
@@ -202,7 +203,7 @@ namespace ArachnaeSwarm
|
||||
manager.RegisterResearch(this, project);
|
||||
}
|
||||
|
||||
Messages.Message($"开始研究: {project.LabelCap}(已绑定)",
|
||||
Messages.Message("ResearchBlueprintReader_ResearchStarted".Translate(project.LabelCap),
|
||||
MessageTypeDefOf.NeutralEvent);
|
||||
}
|
||||
|
||||
@@ -233,7 +234,7 @@ namespace ArachnaeSwarm
|
||||
isResearching = false;
|
||||
researchStartTime = 0;
|
||||
|
||||
Messages.Message($"建筑已解锁: {project.LabelCap}",
|
||||
Messages.Message("ResearchBlueprintReader_BuildingUnlocked".Translate(project.LabelCap),
|
||||
MessageTypeDefOf.NeutralEvent);
|
||||
}
|
||||
}
|
||||
@@ -261,37 +262,23 @@ namespace ArachnaeSwarm
|
||||
if (IsLocked)
|
||||
{
|
||||
var unlockCmd = new Command_Action();
|
||||
unlockCmd.defaultLabel = "解锁建筑";
|
||||
unlockCmd.defaultDesc = "释放储存的科技,允许重新研究";
|
||||
unlockCmd.icon = ContentFinder<Texture2D>.Get("UI/Designators/Unlock", false);
|
||||
unlockCmd.defaultLabel = "ResearchBlueprintReader_UnlockBuilding".Translate();
|
||||
unlockCmd.defaultDesc = "ResearchBlueprintReader_UnlockBuildingDesc".Translate();
|
||||
unlockCmd.icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Abilities/ARA_Ability_Morph", false);
|
||||
unlockCmd.action = delegate
|
||||
{
|
||||
UnlockBuilding();
|
||||
};
|
||||
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.IsFinished ? "已完成" : "研究中")}\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.defaultLabel = "ResearchBlueprintReader_SelectProject".Translate();
|
||||
selectCmd.defaultDesc = "ResearchBlueprintReader_SelectProjectDesc".Translate();
|
||||
selectCmd.icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Abilities/ARA_EggSpew_Techprint", false);
|
||||
selectCmd.action = delegate
|
||||
{
|
||||
ShowResearchMenu();
|
||||
@@ -302,8 +289,8 @@ namespace ArachnaeSwarm
|
||||
if (DebugSettings.godMode && storedResearch != null && !storedResearch.IsFinished)
|
||||
{
|
||||
var debugCmd = new Command_Action();
|
||||
debugCmd.defaultLabel = "调试: 强制完成";
|
||||
debugCmd.defaultDesc = "立即完成当前研究";
|
||||
debugCmd.defaultLabel = "ResearchBlueprintReader_DebugComplete".Translate();
|
||||
debugCmd.defaultDesc = "ResearchBlueprintReader_DebugCompleteDesc".Translate();
|
||||
debugCmd.icon = ContentFinder<Texture2D>.Get("UI/Designators/Dev", false);
|
||||
debugCmd.action = delegate
|
||||
{
|
||||
@@ -320,7 +307,7 @@ namespace ArachnaeSwarm
|
||||
var araTab = DefDatabase<ResearchTabDef>.GetNamedSilentFail("ARA_ResearchTab");
|
||||
if (araTab == null)
|
||||
{
|
||||
Messages.Message("ARA_ResearchTab未找到", MessageTypeDefOf.RejectInput);
|
||||
Messages.Message("ResearchBlueprintReader_TabNotFound".Translate(), MessageTypeDefOf.RejectInput);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -330,7 +317,7 @@ namespace ArachnaeSwarm
|
||||
|
||||
if (availableProjects.Count == 0)
|
||||
{
|
||||
Messages.Message("没有可用的科技项目", MessageTypeDefOf.NeutralEvent);
|
||||
Messages.Message("ResearchBlueprintReader_NoProjectsAvailable".Translate(), MessageTypeDefOf.NeutralEvent);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -351,9 +338,9 @@ namespace ArachnaeSwarm
|
||||
{
|
||||
bool missingHidden = HasMissingHiddenPrerequisites(project);
|
||||
if (missingHidden)
|
||||
label = $"<color=#ff9900>{label} [需要隐藏前置]</color>";
|
||||
label = $"<color=#ff9900>{label} [{"ResearchBlueprintReader_HiddenPrerequisite".Translate()}]</color>";
|
||||
else
|
||||
label = $"<color=#999999>{label} [需要前置条件]</color>";
|
||||
label = $"<color=#999999>{label} [{"ResearchBlueprintReader_PrerequisitesNeeded".Translate()}]</color>";
|
||||
}
|
||||
|
||||
var option = new FloatMenuOption(label, () => StartResearch(project))
|
||||
@@ -373,7 +360,7 @@ namespace ArachnaeSwarm
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error($"[ResearchBlueprintReader] Error in ShowResearchMenu: {ex}");
|
||||
Messages.Message($"显示研究菜单时出错: {ex.Message}",
|
||||
Messages.Message("ResearchBlueprintReader_MenuError".Translate(ex.Message),
|
||||
MessageTypeDefOf.NegativeEvent);
|
||||
}
|
||||
}
|
||||
@@ -423,9 +410,9 @@ namespace ArachnaeSwarm
|
||||
builder.AppendLine(project.description.StripTags());
|
||||
builder.AppendLine();
|
||||
|
||||
builder.AppendLine($"成本: {project.baseCost}");
|
||||
builder.AppendLine($"所需蓝图数量: {project.techprintCount}");
|
||||
builder.AppendLine($"当前全球进度: {Find.ResearchManager.GetProgress(project):F0}/{project.baseCost:F0}");
|
||||
builder.AppendLine("ResearchBlueprintReader_ProjectCost".Translate() + $": {project.baseCost}");
|
||||
builder.AppendLine("ResearchBlueprintReader_BlueprintCount".Translate() + $": {project.techprintCount}");
|
||||
builder.AppendLine("ResearchBlueprintReader_CurrentProgress".Translate() + $": {Find.ResearchManager.GetProgress(project):F0}/{project.baseCost:F0}");
|
||||
|
||||
// 检查所有未完成的前置(包括隐藏的)
|
||||
List<ResearchProjectDef> missingPrereqs = new List<ResearchProjectDef>();
|
||||
@@ -453,7 +440,7 @@ namespace ArachnaeSwarm
|
||||
if (missingPrereqs.Count > 0)
|
||||
{
|
||||
builder.AppendLine();
|
||||
builder.AppendLine("<color=#ff9999>缺失的前置科技:</color>");
|
||||
builder.AppendLine("<color=#ff9999>" + "ResearchBlueprintReader_MissingPrerequisites".Translate() + ":</color>");
|
||||
|
||||
foreach (var prereq in missingPrereqs)
|
||||
{
|
||||
@@ -462,7 +449,7 @@ namespace ArachnaeSwarm
|
||||
project.hiddenPrerequisites.Contains(prereq);
|
||||
|
||||
if (isHidden)
|
||||
builder.AppendLine($" • {label} <color=#ffcc00>[隐藏前置]</color>");
|
||||
builder.AppendLine($" • {label} <color=#ffcc00>[{"ResearchBlueprintReader_MissingHiddenPrerequisites".Translate()}]</color>");
|
||||
else
|
||||
builder.AppendLine($" • {label}");
|
||||
}
|
||||
@@ -482,29 +469,31 @@ namespace ArachnaeSwarm
|
||||
{
|
||||
if (storedResearch.IsFinished)
|
||||
{
|
||||
builder.AppendLine($"<color=#00ff00>✓ 已研究: {storedResearch.LabelCap}</color>");
|
||||
builder.AppendLine("<color=#00ff00>" + "ResearchBlueprintReader_StatusCompleted".Translate(storedResearch.LabelCap) + "</color>");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AppendLine($"<color=#ff9900>🔒 正在研究: {storedResearch.LabelCap}</color>");
|
||||
builder.AppendLine($"本建筑进度: {progress:F0}/{storedResearch.baseCost:F0} ({(progress / storedResearch.baseCost * 100):F1}%)");
|
||||
builder.Append($"全球进度: {Find.ResearchManager.GetProgress(storedResearch):F0}/{storedResearch.baseCost:F0}");
|
||||
builder.AppendLine("<color=#ff9900>" + "ResearchBlueprintReader_StatusResearching".Translate(storedResearch.LabelCap) + "</color>");
|
||||
builder.AppendLine("ResearchBlueprintReader_BuildingProgress".Translate(
|
||||
progress, storedResearch.baseCost, (progress / storedResearch.baseCost * 100)));
|
||||
builder.Append("ResearchBlueprintReader_GlobalProgress".Translate(
|
||||
Find.ResearchManager.GetProgress(storedResearch), storedResearch.baseCost));
|
||||
|
||||
// 显示研究速度
|
||||
builder.AppendLine();
|
||||
builder.Append($"研究速度: {ResearchSpeed:F1}/秒");
|
||||
builder.Append("ResearchBlueprintReader_ResearchSpeed".Translate(ResearchSpeed));
|
||||
|
||||
if (researchStartTime > 0)
|
||||
{
|
||||
int days = (Find.TickManager.TicksGame - researchStartTime) / 60000;
|
||||
builder.AppendLine();
|
||||
builder.Append($"已研究时间: {days}天");
|
||||
builder.Append("ResearchBlueprintReader_ResearchTime".Translate(days));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Append("未选择研究项目");
|
||||
builder.Append("ResearchBlueprintReader_NoProjectSelected".Translate());
|
||||
}
|
||||
|
||||
return builder.ToString().TrimEndNewlines();
|
||||
|
||||
@@ -179,7 +179,7 @@ namespace ArachnaeSwarm
|
||||
Utilities.ResearchRemover.RemoveResearchProject(project, false);
|
||||
|
||||
// 发送消息
|
||||
Messages.Message($"科技已丢失: {project.LabelCap}",
|
||||
Messages.Message("ResearchManager_ResearchLost".Translate(project.LabelCap),
|
||||
MessageTypeDefOf.NegativeEvent);
|
||||
|
||||
Log.Message($"[ResearchManager] Successfully removed research project: {project.defName}");
|
||||
@@ -287,14 +287,15 @@ namespace ArachnaeSwarm
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Message($"=== 研究管理器状态 ===");
|
||||
Log.Message($"所有建筑: {Instance.allReaders.Count}");
|
||||
Log.Message($"进行中研究: {Instance.researchBuildings.Count}");
|
||||
Log.Message("ResearchManager_StatusTitle".Translate());
|
||||
Log.Message("ResearchManager_TotalBuildings".Translate(Instance.allReaders.Count));
|
||||
Log.Message("ResearchManager_ActiveResearch".Translate(Instance.researchBuildings.Count));
|
||||
|
||||
foreach (var kvp in Instance.researchBuildings)
|
||||
{
|
||||
int activeBuildings = kvp.Value.Count(b => b != null && !b.Destroyed);
|
||||
Log.Message($" {kvp.Key.defName}: {activeBuildings}个活跃建筑 / {kvp.Value.Count}个总建筑");
|
||||
Log.Message("ResearchManager_ProjectStatus".Translate(
|
||||
kvp.Key.defName, activeBuildings, kvp.Value.Count));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -132,12 +132,6 @@ namespace ArachnaeSwarm.Utilities
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -18,8 +18,9 @@ namespace ArachnaeSwarm
|
||||
|
||||
public override bool TryMakePreToilReservations(bool errorOnFailed)
|
||||
{
|
||||
// 只需要保留目标位置
|
||||
return pawn.Reserve(job.targetA, job, 1, -1, null, errorOnFailed);
|
||||
// 原地工作,不需要保留特定单元格
|
||||
// 我们只保留自己的位置作为工作位置
|
||||
return pawn.Reserve(pawn, job, 1, -1, null, errorOnFailed);
|
||||
}
|
||||
|
||||
protected override IEnumerable<Toil> MakeNewToils()
|
||||
@@ -27,15 +28,13 @@ namespace ArachnaeSwarm
|
||||
// 确保自身有蜜罐需求且达到挤出阈值
|
||||
this.FailOn(() => HoneyNeed == null || !CanExtract(HoneyNeed));
|
||||
|
||||
// Toil 1: 移动到目标位置
|
||||
yield return Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.Touch);
|
||||
|
||||
// Toil 2: 执行挤出工作
|
||||
// Toil 1: 原地执行挤出工作
|
||||
Toil extractToil = new Toil
|
||||
{
|
||||
initAction = delegate
|
||||
{
|
||||
// 初始化挤出动作
|
||||
pawn.pather.StopDead();
|
||||
},
|
||||
tickAction = delegate
|
||||
{
|
||||
@@ -45,7 +44,7 @@ namespace ArachnaeSwarm
|
||||
defaultDuration = ExtractDurationTicks
|
||||
};
|
||||
|
||||
// 添加特效和音效
|
||||
// 添加特效和音效(在原地显示)
|
||||
extractToil.WithEffect(() => ExtractEffect, TargetIndex.A);
|
||||
extractToil.PlaySustainerOrSound(() => ExtractSound);
|
||||
|
||||
@@ -55,12 +54,13 @@ namespace ArachnaeSwarm
|
||||
ExtractHoney();
|
||||
});
|
||||
|
||||
// 进度条显示在Pawn自己身上
|
||||
extractToil.WithProgressBar(TargetIndex.A,
|
||||
() => extractToil.actor.jobs.curDriver.ticksLeftThisToil / (float)ExtractDurationTicks);
|
||||
|
||||
yield return extractToil;
|
||||
|
||||
// Toil 3: 完成后的清理
|
||||
// Toil 2: 完成后的清理
|
||||
yield return new Toil
|
||||
{
|
||||
initAction = delegate
|
||||
@@ -69,7 +69,8 @@ namespace ArachnaeSwarm
|
||||
// 如果蜜罐存量达到阈值,可以安排下一个挤出工作
|
||||
if (HoneyNeed != null && CanExtract(HoneyNeed))
|
||||
{
|
||||
pawn.jobs.jobQueue.EnqueueLast(CreateExtractJob());
|
||||
// 不再创建新工作,让WorkGiver系统处理
|
||||
// 这样可以避免无限循环
|
||||
}
|
||||
},
|
||||
defaultCompleteMode = ToilCompleteMode.Instant
|
||||
@@ -121,36 +122,14 @@ namespace ArachnaeSwarm
|
||||
Thing jelly = ThingMaker.MakeThing(DefDatabase<ThingDef>.GetNamed("ARA_InsectJelly"));
|
||||
jelly.stackCount = jellyCount;
|
||||
|
||||
// 尝试将虫蜜放在目标位置
|
||||
GenPlace.TryPlaceThing(jelly, job.targetA.Cell, pawn.Map, ThingPlaceMode.Near);
|
||||
// 在Pawn当前位置放置虫蜜
|
||||
GenPlace.TryPlaceThing(jelly, pawn.Position, pawn.Map, ThingPlaceMode.Near);
|
||||
|
||||
// 减少蜜罐存量
|
||||
HoneyNeed.ExtractHoney(jellyCount);
|
||||
|
||||
// 播放视觉反馈
|
||||
MoteMaker.ThrowText(job.targetA.Cell.ToVector3Shifted(), pawn.Map,"ARA_ExtractHoney_Message".Translate(jellyCount));
|
||||
}
|
||||
|
||||
// 创建挤出工作的辅助方法
|
||||
private Job CreateExtractJob()
|
||||
{
|
||||
// 寻找最近的空地
|
||||
IntVec3 targetCell = FindNearestEmptyCell(pawn.Position, pawn.Map);
|
||||
|
||||
Job job = JobMaker.MakeJob(DefDatabase<JobDef>.GetNamed("ARA_ExtractHoney"), targetCell);
|
||||
return job;
|
||||
}
|
||||
|
||||
// 寻找最近的空单元格
|
||||
private IntVec3 FindNearestEmptyCell(IntVec3 from, Map map)
|
||||
{
|
||||
if (CellFinder.TryFindBestPawnStandCell(pawn, out IntVec3 cell, false))
|
||||
{
|
||||
return cell;
|
||||
}
|
||||
|
||||
// 如果找不到最佳位置,使用原位置
|
||||
return from;
|
||||
MoteMaker.ThrowText(pawn.DrawPos, pawn.Map, "ARA_ExtractHoney_Message".Translate(jellyCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,16 +12,27 @@ namespace ArachnaeSwarm
|
||||
private const float FoodTransferPerTick = 0.01f; // 每tick传输的食物量
|
||||
|
||||
private Pawn TargetPawn => job.targetA.Pawn;
|
||||
private Need_HoneyProduction HoneyNeed => pawn.needs?.TryGetNeed<Need_HoneyProduction>();
|
||||
|
||||
// 获取喂食者的蜜罐需求
|
||||
private Need_HoneyProduction FeederHoneyNeed => pawn.needs?.TryGetNeed<Need_HoneyProduction>();
|
||||
|
||||
// 获取目标的食物需求
|
||||
private Need_Food TargetFoodNeed => TargetPawn.needs?.TryGetNeed<Need_Food>();
|
||||
|
||||
// 使用喂养效果 - 参考Toils_Ingest中的用法
|
||||
// 检查目标是否有蜜罐需求
|
||||
private Need_HoneyProduction TargetHoneyNeed => TargetPawn.needs?.TryGetNeed<Need_HoneyProduction>();
|
||||
|
||||
// 使用喂养效果
|
||||
private static readonly EffecterDef FeedEffect = ARA_EffecterDefOf.EatVegetarian;
|
||||
private static readonly SoundDef FeedSound = SoundDefOf.RawMeat_Eat;
|
||||
|
||||
public override bool TryMakePreToilReservations(bool errorOnFailed)
|
||||
{
|
||||
if (TargetPawn == null || TargetFoodNeed == null || HoneyNeed == null)
|
||||
if (TargetPawn == null || TargetFoodNeed == null || FeederHoneyNeed == null)
|
||||
return false;
|
||||
|
||||
// 检查目标是否有蜜罐需求,如果有则不能喂食
|
||||
if (TargetHoneyNeed != null)
|
||||
return false;
|
||||
|
||||
// 保留目标pawn的位置,以便接近
|
||||
@@ -32,13 +43,16 @@ namespace ArachnaeSwarm
|
||||
{
|
||||
// 确保目标有效
|
||||
this.FailOnDespawnedOrNull(TargetIndex.A);
|
||||
this.FailOn(() => TargetPawn.Dead || TargetFoodNeed == null || HoneyNeed == null);
|
||||
this.FailOn(() => TargetPawn.Dead || TargetFoodNeed == null || FeederHoneyNeed == null);
|
||||
|
||||
// 额外检查:目标不能有蜜罐需求
|
||||
this.FailOn(() => TargetHoneyNeed != null);
|
||||
|
||||
// Toil 1: 移动到目标面前
|
||||
yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch)
|
||||
.FailOnDespawnedOrNull(TargetIndex.A);
|
||||
|
||||
// Toil 2: 进行喂养工作(参考Toils_Ingest中的效果添加方式)
|
||||
// Toil 2: 进行喂养工作
|
||||
Toil feedToil = new Toil
|
||||
{
|
||||
initAction = delegate
|
||||
@@ -48,7 +62,7 @@ namespace ArachnaeSwarm
|
||||
tickAction = delegate
|
||||
{
|
||||
// 每tick检查是否还能继续喂养
|
||||
if (HoneyNeed.CurLevel <= 0 || TargetFoodNeed.CurLevelPercentage >= 1.0f)
|
||||
if (FeederHoneyNeed.CurLevel <= 0 || TargetFoodNeed.CurLevelPercentage >= 1.0f)
|
||||
{
|
||||
ReadyForNextToil();
|
||||
return;
|
||||
@@ -56,7 +70,7 @@ namespace ArachnaeSwarm
|
||||
|
||||
// 计算本次tick传输的量
|
||||
float transferAmount = FoodTransferPerTick;
|
||||
float honeyAvailable = HoneyNeed.CurLevel;
|
||||
float honeyAvailable = FeederHoneyNeed.CurLevel;
|
||||
|
||||
// 确保不超过蜜罐存量
|
||||
if (transferAmount > honeyAvailable)
|
||||
@@ -68,14 +82,14 @@ namespace ArachnaeSwarm
|
||||
transferAmount = targetFoodSpace;
|
||||
|
||||
// 执行传输
|
||||
HoneyNeed.ExtractHoney(transferAmount);
|
||||
FeederHoneyNeed.ExtractHoney(transferAmount);
|
||||
TargetFoodNeed.CurLevel += transferAmount;
|
||||
},
|
||||
defaultCompleteMode = ToilCompleteMode.Delay,
|
||||
defaultDuration = FeedDurationTicks
|
||||
};
|
||||
|
||||
// 添加特效和音效(参考Toils_Ingest.AddIngestionEffects)
|
||||
// 添加特效和音效
|
||||
feedToil.WithEffect(() => FeedEffect, TargetIndex.A);
|
||||
feedToil.PlaySustainerOrSound(() => FeedSound);
|
||||
|
||||
@@ -91,12 +105,12 @@ namespace ArachnaeSwarm
|
||||
|
||||
yield return feedToil;
|
||||
|
||||
// 修改:移除了第三个Toil中的提示消息,只剩下一个简单的完成Toil
|
||||
// 完成Toil
|
||||
yield return new Toil
|
||||
{
|
||||
initAction = delegate
|
||||
{
|
||||
// 这里可以放置任何清理代码,但不要显示消息
|
||||
// 清理代码
|
||||
},
|
||||
defaultCompleteMode = ToilCompleteMode.Instant
|
||||
};
|
||||
|
||||
@@ -37,8 +37,8 @@ namespace ArachnaeSwarm
|
||||
|
||||
public override bool TryMakePreToilReservations(bool errorOnFailed)
|
||||
{
|
||||
// 只需要保留目标位置
|
||||
return pawn.Reserve(job.targetA, job, 1, -1, null, errorOnFailed);
|
||||
// 原地工作,不需要保留特定单元格
|
||||
return pawn.Reserve(pawn, job, 1, -1, null, errorOnFailed);
|
||||
}
|
||||
|
||||
protected override IEnumerable<Toil> MakeNewToils()
|
||||
@@ -49,15 +49,13 @@ namespace ArachnaeSwarm
|
||||
this.FailOn(() => !StripComp.CanStripNow(pawn));
|
||||
this.FailOn(() => !StripComp.CanStripChitin); // 检查开关
|
||||
|
||||
// Toil 1: 移动到目标位置
|
||||
yield return Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.Touch);
|
||||
|
||||
// Toil 2: 执行剥离工作
|
||||
// Toil 1: 原地执行剥离工作
|
||||
Toil stripToil = new Toil
|
||||
{
|
||||
initAction = delegate
|
||||
{
|
||||
// 初始化剥离动作
|
||||
pawn.pather.StopDead();
|
||||
},
|
||||
tickAction = delegate
|
||||
{
|
||||
@@ -77,13 +75,13 @@ namespace ArachnaeSwarm
|
||||
StripChitin();
|
||||
});
|
||||
|
||||
// 进度条显示在Pawn自己身上
|
||||
stripToil.WithProgressBar(TargetIndex.A,
|
||||
() => stripToil.actor.jobs.curDriver.ticksLeftThisToil / (float)StripDurationTicks,
|
||||
interpolateBetweenActorAndTarget: true);
|
||||
() => stripToil.actor.jobs.curDriver.ticksLeftThisToil / (float)StripDurationTicks);
|
||||
|
||||
yield return stripToil;
|
||||
|
||||
// Toil 3: 完成后的清理
|
||||
// Toil 2: 完成后的清理
|
||||
yield return new Toil
|
||||
{
|
||||
initAction = delegate
|
||||
@@ -91,11 +89,7 @@ namespace ArachnaeSwarm
|
||||
// 记录剥离时间
|
||||
StripComp?.NotifyStripped();
|
||||
|
||||
// 如果甲壳存量仍然达到阈值,可以安排下一个剥离工作
|
||||
if (ChitinNeed != null && StripComp != null && StripComp.CanStripNow(pawn))
|
||||
{
|
||||
pawn.jobs.jobQueue.EnqueueLast(CreateStripJob());
|
||||
}
|
||||
// 不再自动安排下一个工作,让WorkGiver系统处理
|
||||
},
|
||||
defaultCompleteMode = ToilCompleteMode.Instant
|
||||
};
|
||||
@@ -124,37 +118,15 @@ namespace ArachnaeSwarm
|
||||
Thing carapace = ThingMaker.MakeThing(carapaceDef);
|
||||
carapace.stackCount = stripCount;
|
||||
|
||||
// 尝试将甲壳放在目标位置
|
||||
GenPlace.TryPlaceThing(carapace, job.targetA.Cell, pawn.Map, ThingPlaceMode.Near);
|
||||
// 在Pawn当前位置放置甲壳
|
||||
GenPlace.TryPlaceThing(carapace, pawn.Position, pawn.Map, ThingPlaceMode.Near);
|
||||
|
||||
// 减少甲壳存量
|
||||
ChitinNeed.ReduceChitin(stripCount);
|
||||
|
||||
// 播放视觉反馈
|
||||
MoteMaker.ThrowText(job.targetA.Cell.ToVector3Shifted(), pawn.Map,
|
||||
MoteMaker.ThrowText(pawn.DrawPos, pawn.Map,
|
||||
"ARA_StripChitin_Message".Translate(stripCount));
|
||||
}
|
||||
|
||||
// 创建剥离工作的辅助方法
|
||||
private Job CreateStripJob()
|
||||
{
|
||||
// 寻找最近的空地
|
||||
IntVec3 targetCell = FindNearestEmptyCell(pawn.Position, pawn.Map);
|
||||
|
||||
Job job = JobMaker.MakeJob(DefDatabase<JobDef>.GetNamed("ARA_StripChitin"), targetCell);
|
||||
return job;
|
||||
}
|
||||
|
||||
// 寻找最近的空单元格
|
||||
private IntVec3 FindNearestEmptyCell(IntVec3 from, Map map)
|
||||
{
|
||||
if (CellFinder.TryFindBestPawnStandCell(pawn, out IntVec3 cell, false))
|
||||
{
|
||||
return cell;
|
||||
}
|
||||
|
||||
// 如果找不到最佳位置,使用原位置
|
||||
return from;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace ArachnaeSwarm
|
||||
public class JobDriver_SwarmMaintain : JobDriver
|
||||
{
|
||||
// 工作完成后增加的维护度
|
||||
public const float MaintenancePerWork = 25f;
|
||||
public const float MaintenancePerWork = 100f;
|
||||
|
||||
// 工作时间(ticks)
|
||||
private const int WorkDuration = 600; // 10秒
|
||||
|
||||
@@ -1,52 +1,16 @@
|
||||
// File: Need_HoneyProduction.cs
|
||||
using RimWorld;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class HoneyProductionExtension : DefModExtension
|
||||
{
|
||||
// 蜜罐生产的基础转化率(相对于食物流失的百分比)
|
||||
public float baseConversionRate = 0.5f;
|
||||
|
||||
// 最大蜜罐容量(可选,覆盖默认值)
|
||||
public float maxHoneyCapacity = 1f;
|
||||
|
||||
// 是否启用蜜罐生产
|
||||
public bool enableHoneyProduction = true;
|
||||
|
||||
// 生产速率乘数(影响生产速度)
|
||||
public float productionSpeedFactor = 1f;
|
||||
|
||||
// 蜜罐类别对应的生产效率(可选,覆盖默认值)
|
||||
public float fullProductionEfficiency = 1.5f;
|
||||
public float highProductionEfficiency = 1.2f;
|
||||
public float mediumProductionEfficiency = 1f;
|
||||
public float lowProductionEfficiency = 0.5f;
|
||||
public float emptyProductionEfficiency = 0f;
|
||||
|
||||
// 生产间隔(ticks,可选覆盖默认值)
|
||||
public int productionInterval = 150;
|
||||
|
||||
public static HoneyProductionExtension Get(Pawn pawn)
|
||||
{
|
||||
if (pawn?.def?.GetModExtension<HoneyProductionExtension>() is HoneyProductionExtension ext)
|
||||
return ext;
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取转化率
|
||||
public float GetConversionRate()
|
||||
{
|
||||
return baseConversionRate * productionSpeedFactor;
|
||||
}
|
||||
}
|
||||
|
||||
public class Need_HoneyProduction : Need
|
||||
{
|
||||
// 转化率:多少食物流失转换为蜂蜜
|
||||
public float ConversionRate = 10f;
|
||||
|
||||
// 基础流失速率(与食物需要对应)
|
||||
private const float BaseHoneyGainPerTick = 2.6666667E-05f * 0.5f; // 食物流失速率的50%作为默认值
|
||||
private const float BaseHoneyGainPerTick = 2.6666667E-05f;
|
||||
|
||||
// 用于存储对食物需要的引用
|
||||
private Need_Food cachedFoodNeed;
|
||||
@@ -54,25 +18,8 @@ namespace ArachnaeSwarm
|
||||
// 当前类别
|
||||
private HoneyProductionCategory curCategoryInt = HoneyProductionCategory.Empty;
|
||||
|
||||
// 上次满的时间点
|
||||
private int lastFullTick = -99999;
|
||||
|
||||
// 缓存的ModExtension
|
||||
private HoneyProductionExtension cachedExtension;
|
||||
|
||||
// 蜜罐的最大容量 - 优先使用ModExtension的值
|
||||
public override float MaxLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
var ext = GetExtension();
|
||||
if (ext != null && ext.maxHoneyCapacity > 0)
|
||||
{
|
||||
return ext.maxHoneyCapacity;
|
||||
}
|
||||
return FoodNeed?.MaxLevel ?? 1f;
|
||||
}
|
||||
}
|
||||
// 最大容量 - 跟随食物需求的最大容量
|
||||
public override float MaxLevel => FoodNeed?.MaxLevel ?? 1f;
|
||||
|
||||
// 当前类别
|
||||
public HoneyProductionCategory CurCategory => curCategoryInt;
|
||||
@@ -83,72 +30,6 @@ namespace ArachnaeSwarm
|
||||
// 是否为空
|
||||
public bool IsEmpty => CurCategory == HoneyProductionCategory.Empty;
|
||||
|
||||
// 当前类别对应的生产效率
|
||||
public float ProductionEfficiency
|
||||
{
|
||||
get
|
||||
{
|
||||
var ext = GetExtension();
|
||||
|
||||
// 如果有扩展定义,使用扩展的值
|
||||
if (ext != null)
|
||||
{
|
||||
switch (curCategoryInt)
|
||||
{
|
||||
case HoneyProductionCategory.Full:
|
||||
return ext.fullProductionEfficiency;
|
||||
case HoneyProductionCategory.High:
|
||||
return ext.highProductionEfficiency;
|
||||
case HoneyProductionCategory.Medium:
|
||||
return ext.mediumProductionEfficiency;
|
||||
case HoneyProductionCategory.Low:
|
||||
return ext.lowProductionEfficiency;
|
||||
case HoneyProductionCategory.Empty:
|
||||
return ext.emptyProductionEfficiency;
|
||||
default:
|
||||
return 0f;
|
||||
}
|
||||
}
|
||||
|
||||
// 默认值
|
||||
switch (curCategoryInt)
|
||||
{
|
||||
case HoneyProductionCategory.Full:
|
||||
return 1.0f;
|
||||
case HoneyProductionCategory.High:
|
||||
return 0.8f;
|
||||
case HoneyProductionCategory.Medium:
|
||||
return 0.5f;
|
||||
case HoneyProductionCategory.Low:
|
||||
return 0.3f;
|
||||
case HoneyProductionCategory.Empty:
|
||||
return 0f;
|
||||
default:
|
||||
return 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取扩展
|
||||
private HoneyProductionExtension GetExtension()
|
||||
{
|
||||
if (cachedExtension == null && pawn != null)
|
||||
{
|
||||
cachedExtension = pawn.def?.GetModExtension<HoneyProductionExtension>();
|
||||
}
|
||||
return cachedExtension;
|
||||
}
|
||||
|
||||
// 是否启用蜜罐生产
|
||||
private bool IsEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
var ext = GetExtension();
|
||||
return ext == null || ext.enableHoneyProduction; // 默认启用
|
||||
}
|
||||
}
|
||||
|
||||
// 获取食物需要的引用
|
||||
private Need_Food FoodNeed
|
||||
{
|
||||
@@ -174,19 +55,9 @@ namespace ArachnaeSwarm
|
||||
};
|
||||
}
|
||||
|
||||
public override void ExposeData()
|
||||
{
|
||||
base.ExposeData();
|
||||
Scribe_Values.Look(ref lastFullTick, "lastFullTick", -99999);
|
||||
}
|
||||
|
||||
public override void NeedInterval()
|
||||
{
|
||||
// 如果不启用,直接返回
|
||||
if (!IsEnabled)
|
||||
return;
|
||||
|
||||
// 检查是否需要冻结(与食物需要类似的条件)
|
||||
// 检查是否需要冻结
|
||||
if (IsFrozen)
|
||||
{
|
||||
return;
|
||||
@@ -195,17 +66,11 @@ namespace ArachnaeSwarm
|
||||
// 获取食物需要的流失速率
|
||||
float foodFallRate = GetFoodFallRate();
|
||||
|
||||
// 获取转化率(从ModExtension或使用默认值)
|
||||
float conversionRate = GetExtension()?.GetConversionRate() ?? 0.5f;
|
||||
|
||||
// 蜜罐的增长速率 = 食物流失速率 × 转化率
|
||||
float honeyGainRate = foodFallRate * conversionRate;
|
||||
|
||||
// 获取生产间隔
|
||||
int interval = GetExtension()?.productionInterval ?? 150;
|
||||
float honeyGainRate = foodFallRate * ConversionRate;
|
||||
|
||||
// 应用间隔
|
||||
CurLevel += honeyGainRate * interval;
|
||||
CurLevel += honeyGainRate * 150; // 150 ticks间隔
|
||||
|
||||
// 确保不超过最大容量
|
||||
if (CurLevel > MaxLevel)
|
||||
@@ -213,12 +78,6 @@ namespace ArachnaeSwarm
|
||||
|
||||
// 更新类别
|
||||
UpdateCategory();
|
||||
|
||||
// 记录满的时间
|
||||
if (IsFull)
|
||||
{
|
||||
lastFullTick = Find.TickManager.TicksGame;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取食物流失速率
|
||||
@@ -227,7 +86,7 @@ namespace ArachnaeSwarm
|
||||
if (FoodNeed == null)
|
||||
{
|
||||
// 如果没有食物需要,使用默认值
|
||||
return BaseHoneyGainPerTick / 0.5f; // 反向计算基础食物流失速率
|
||||
return BaseHoneyGainPerTick;
|
||||
}
|
||||
|
||||
// 获取当前食物类别对应的流失速率
|
||||
@@ -275,49 +134,6 @@ namespace ArachnaeSwarm
|
||||
curCategoryInt = HoneyProductionCategory.Empty;
|
||||
}
|
||||
|
||||
// 获取提示字符串
|
||||
public override string GetTipString()
|
||||
{
|
||||
string text = (LabelCap + ": " + CurLevelPercentage.ToStringPercent()).Colorize(ColoredText.TipSectionTitleColor);
|
||||
text += "\n" + def.description;
|
||||
text += $"\n{"ARA_HoneyProduction.Efficiency".Translate()} {ProductionEfficiency.ToStringPercent()}";
|
||||
|
||||
// 获取每tick的速率
|
||||
float foodFallPerTick = GetFoodFallRate();
|
||||
float conversionRate = GetExtension()?.GetConversionRate() ?? 0.5f;
|
||||
float honeyGainPerTick = foodFallPerTick * conversionRate;
|
||||
|
||||
// 转换为每秒:1秒 = 60tick
|
||||
float foodFallPerSecond = foodFallPerTick * 60f;
|
||||
float honeyGainPerSecond = honeyGainPerTick * 60f;
|
||||
|
||||
text += $"\n{"ARA_HoneyProduction.FoodDrainRate".Translate()}: {foodFallPerSecond:0.#####}/ {"LetterSecond".Translate()}";
|
||||
text += $"\n{"ARA_HoneyProduction.HoneyGainRate".Translate()}: {honeyGainPerSecond:0.#####}/ {"LetterSecond".Translate()}";
|
||||
|
||||
// 显示转化率信息
|
||||
if (GetExtension() != null)
|
||||
{
|
||||
text += $"\n{"ARA_HoneyProduction.ConversionRate".Translate()}: {conversionRate:P1}";
|
||||
if (GetExtension().productionSpeedFactor != 1f)
|
||||
{
|
||||
text += $"\n{"ARA_HoneyProduction.SpeedFactor".Translate()}: {GetExtension().productionSpeedFactor:F2}";
|
||||
}
|
||||
}
|
||||
|
||||
if (IsFull)
|
||||
{
|
||||
text += $"\n\n{"ARA_HoneyProduction.FullWarning".Translate()}";
|
||||
}
|
||||
|
||||
// 显示是否启用
|
||||
if (!IsEnabled)
|
||||
{
|
||||
text += $"\n\n<color=orange>{"ARA_HoneyProduction.Disabled".Translate()}</color>";
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
// 获取类别标签
|
||||
public string GetCategoryLabel()
|
||||
{
|
||||
@@ -338,24 +154,6 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
}
|
||||
|
||||
// 在UI上绘制
|
||||
public override void DrawOnGUI(Rect rect, int maxThresholdMarkers = int.MaxValue, float customMargin = -1f, bool drawArrows = true, bool doTooltip = true, Rect? rectForTooltip = null, bool drawLabel = true)
|
||||
{
|
||||
// 如果不启用,不显示
|
||||
if (!IsEnabled)
|
||||
return;
|
||||
|
||||
if (threshPercents == null)
|
||||
{
|
||||
threshPercents = new System.Collections.Generic.List<float>
|
||||
{
|
||||
0.25f, 0.5f, 0.75f
|
||||
};
|
||||
}
|
||||
|
||||
base.DrawOnGUI(rect, maxThresholdMarkers, customMargin, false, doTooltip, rectForTooltip, drawLabel);
|
||||
}
|
||||
|
||||
// 是否冻结
|
||||
protected override bool IsFrozen
|
||||
{
|
||||
@@ -374,7 +172,7 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
|
||||
// GUI变化箭头(总是显示增长)
|
||||
public override int GUIChangeArrow => IsEnabled ? 1 : 0;
|
||||
public override int GUIChangeArrow => 1;
|
||||
|
||||
// 调试调整百分比
|
||||
protected override void OffsetDebugPercent(float offsetPercent)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class CompProperties_SwarmMaintainer : CompProperties
|
||||
{
|
||||
// 是否在信息面板显示调试信息
|
||||
public bool showDebugInfo = false;
|
||||
|
||||
// 维护工作的优先级(相对其他工作)
|
||||
public int workPriority = 50;
|
||||
|
||||
// 维护技能类型(可选)
|
||||
public SkillDef relevantSkill = SkillDefOf.Construction;
|
||||
|
||||
// 最小技能等级(可选)
|
||||
public int minimumSkillLevel = 0;
|
||||
|
||||
// 是否必须有虫群意识hediff
|
||||
public bool requiresHiveMind = true;
|
||||
|
||||
public CompProperties_SwarmMaintainer()
|
||||
{
|
||||
compClass = typeof(Comp_SwarmMaintainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class Comp_SwarmMaintainer : ThingComp
|
||||
{
|
||||
// 属性访问器
|
||||
public CompProperties_SwarmMaintainer Props => (CompProperties_SwarmMaintainer)props;
|
||||
|
||||
// 简单的属性访问
|
||||
public bool CanMaintainSwarmBuildings => true; // 默认都可以维护
|
||||
|
||||
// 维护效率(可选)
|
||||
public float MaintenanceEfficiency
|
||||
{
|
||||
get
|
||||
{
|
||||
// 可以根据Pawn的技能或其他属性调整效率
|
||||
if (parent is Pawn pawn)
|
||||
{
|
||||
// 如果有建造技能,效率更高
|
||||
if (pawn.skills != null)
|
||||
{
|
||||
return 1.0f + (pawn.skills.GetSkill(SkillDefOf.Construction).Level * 0.02f);
|
||||
}
|
||||
}
|
||||
return 1.0f; // 默认效率
|
||||
}
|
||||
}
|
||||
|
||||
// 组件不需要复杂的逻辑,主要用于标记
|
||||
public override void PostSpawnSetup(bool respawningAfterLoad)
|
||||
{
|
||||
base.PostSpawnSetup(respawningAfterLoad);
|
||||
}
|
||||
|
||||
public override void PostExposeData()
|
||||
{
|
||||
base.PostExposeData();
|
||||
// 这个组件不需要保存额外数据
|
||||
}
|
||||
|
||||
// 可选:提供一些简单的调试信息
|
||||
public override string CompInspectStringExtra()
|
||||
{
|
||||
if (Props.showDebugInfo && DebugSettings.godMode)
|
||||
{
|
||||
return $"虫群维护者 (效率: {MaintenanceEfficiency:P0})";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Source/ArachnaeSwarm/RoomRole/RoomRoleWorker_JellyVat.cs
Normal file
51
Source/ArachnaeSwarm/RoomRole/RoomRoleWorker_JellyVat.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System.Collections.Generic;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class RoomRoleWorker_JellyVat : RoomRoleWorker
|
||||
{
|
||||
// 孵化间的评分 - 比重很小,设为10分(实验室是60分)
|
||||
private const float ScorePerJellyVat = 100f;
|
||||
|
||||
// 最低分数要求 - 需要至少1个孵化器才能成为孵化间
|
||||
private const float MinimumScore = 10f;
|
||||
|
||||
public override float GetScore(Room room)
|
||||
{
|
||||
int JellyVatCount = 0;
|
||||
|
||||
// 检查房间内和相邻的所有建筑
|
||||
List<Thing> containedAndAdjacentThings = room.ContainedAndAdjacentThings;
|
||||
for (int i = 0; i < containedAndAdjacentThings.Count; i++)
|
||||
{
|
||||
Thing thing = containedAndAdjacentThings[i];
|
||||
|
||||
// 检查建筑的工作台房间角色是否为ARA_JellyVat_Room
|
||||
if (thing.def.building?.workTableRoomRole != null &&
|
||||
thing.def.building.workTableRoomRole.defName == "ARA_JellyVat_Room")
|
||||
{
|
||||
JellyVatCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果有孵化器,返回分数
|
||||
float score = ScorePerJellyVat * JellyVatCount;
|
||||
|
||||
// 必须有至少一个孵化器才能成为孵化间
|
||||
return JellyVatCount > 0 ? score : 0f;
|
||||
}
|
||||
|
||||
public override float GetScoreDeltaIfBuildingPlaced(Room room, ThingDef buildingDef)
|
||||
{
|
||||
// 如果放置的建筑具有ARA_JellyVat_Room工作台房间角色,返回分数增量
|
||||
if (buildingDef.building?.workTableRoomRole != null &&
|
||||
buildingDef.building.workTableRoomRole.defName == "ARA_JellyVat_Room")
|
||||
{
|
||||
return ScorePerJellyVat;
|
||||
}
|
||||
return 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
117
Source/ArachnaeSwarm/WorkGivers/WorkGiver_ExtractHoney.cs
Normal file
117
Source/ArachnaeSwarm/WorkGivers/WorkGiver_ExtractHoney.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
using Verse.AI;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class WorkGiver_ExtractHoney : WorkGiver_Scanner
|
||||
{
|
||||
public override PathEndMode PathEndMode => PathEndMode.Touch;
|
||||
|
||||
public override Danger MaxPathDanger(Pawn pawn)
|
||||
{
|
||||
return Danger.None;
|
||||
}
|
||||
|
||||
// 扫描所有虫族成员,检查是否需要挤出蜂蜜
|
||||
public override IEnumerable<Thing> PotentialWorkThingsGlobal(Pawn pawn)
|
||||
{
|
||||
// 返回所有有蜂蜜需求的虫族Pawn
|
||||
IReadOnlyList<Pawn> allPawns = pawn.Map.mapPawns.AllPawnsSpawned;
|
||||
List<Thing> workThings = new List<Thing>();
|
||||
|
||||
foreach (Pawn potentialPawn in allPawns)
|
||||
{
|
||||
// 只检查玩家阵营的虫族成员
|
||||
if (potentialPawn.Faction == Faction.OfPlayer &&
|
||||
HasHoneyNeed(potentialPawn))
|
||||
{
|
||||
workThings.Add(potentialPawn);
|
||||
}
|
||||
}
|
||||
|
||||
return workThings;
|
||||
}
|
||||
|
||||
public override bool ShouldSkip(Pawn pawn, bool forced = false)
|
||||
{
|
||||
// 检查Pawn是否属于玩家阵营
|
||||
if (pawn.Faction != Faction.OfPlayer)
|
||||
return true;
|
||||
|
||||
// 检查Pawn是否是虫族成员
|
||||
if (!IsSwarmMember(pawn))
|
||||
return true;
|
||||
|
||||
// 检查Pawn是否能够工作
|
||||
if (pawn.Dead || pawn.Downed || pawn.InMentalState)
|
||||
return true;
|
||||
|
||||
// 检查Pawn是否正在执行其他挤出工作
|
||||
if (pawn.CurJobDef == ARA_JobDefOf.ARA_ExtractHoney)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false)
|
||||
{
|
||||
// 如果目标不是Pawn,返回false
|
||||
if (t == null || !(t is Pawn targetPawn))
|
||||
return false;
|
||||
|
||||
// 检查是否是挤出自己的蜂蜜
|
||||
if (targetPawn != pawn)
|
||||
return false; // 只能挤出自己的蜂蜜
|
||||
|
||||
// 检查目标Pawn是否有蜂蜜需求
|
||||
Need_HoneyProduction honeyNeed = targetPawn.needs?.TryGetNeed<Need_HoneyProduction>();
|
||||
if (honeyNeed == null)
|
||||
return false;
|
||||
|
||||
// 检查是否可以挤出
|
||||
return CanExtractNow(honeyNeed);
|
||||
}
|
||||
|
||||
public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
|
||||
{
|
||||
if (t == null || !(t is Pawn targetPawn) || targetPawn != pawn)
|
||||
return null;
|
||||
|
||||
// 创建挤出工作,使用Pawn自身作为目标
|
||||
Job job = JobMaker.MakeJob(ARA_JobDefOf.ARA_ExtractHoney, pawn);
|
||||
job.count = 1;
|
||||
return job;
|
||||
}
|
||||
|
||||
// 检查是否有蜂蜜需求
|
||||
private bool HasHoneyNeed(Pawn pawn)
|
||||
{
|
||||
return pawn.needs?.TryGetNeed<Need_HoneyProduction>() != null;
|
||||
}
|
||||
|
||||
// 检查是否可以立即挤出
|
||||
private bool CanExtractNow(Need_HoneyProduction honeyNeed)
|
||||
{
|
||||
// 如果MaxLevel大于1.5,需要超过80%储量才考虑挤蜜
|
||||
if (honeyNeed.MaxLevel > 1.5f)
|
||||
{
|
||||
return honeyNeed.CurLevelPercentage > 0.8f;
|
||||
}
|
||||
// 否则在大于1时挤蜜
|
||||
else
|
||||
{
|
||||
return honeyNeed.CurLevel >= 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否是虫族成员
|
||||
private bool IsSwarmMember(Pawn pawn)
|
||||
{
|
||||
return pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindMaster) ||
|
||||
pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindDrone) ||
|
||||
pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindWorker);
|
||||
}
|
||||
}
|
||||
}
|
||||
171
Source/ArachnaeSwarm/WorkGivers/WorkGiver_FeedWithHoney.cs
Normal file
171
Source/ArachnaeSwarm/WorkGivers/WorkGiver_FeedWithHoney.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
using Verse.AI;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class WorkGiver_FeedWithHoney : WorkGiver_Scanner
|
||||
{
|
||||
public override PathEndMode PathEndMode => PathEndMode.Touch;
|
||||
|
||||
public override Danger MaxPathDanger(Pawn pawn)
|
||||
{
|
||||
return Danger.None;
|
||||
}
|
||||
|
||||
// 扫描所有需要喂食的Pawn(没有蜜罐需求但需要食物的虫族成员)
|
||||
public override IEnumerable<Thing> PotentialWorkThingsGlobal(Pawn pawn)
|
||||
{
|
||||
IReadOnlyList<Pawn> allPawns = pawn.Map.mapPawns.AllPawnsSpawned;
|
||||
List<Thing> workThings = new List<Thing>();
|
||||
|
||||
foreach (Pawn potentialPawn in allPawns)
|
||||
{
|
||||
// 只检查玩家阵营的Pawn
|
||||
if (potentialPawn.Faction == Faction.OfPlayer &&
|
||||
!potentialPawn.Dead &&
|
||||
!potentialPawn.Downed &&
|
||||
!HasHoneyNeed(potentialPawn) && // 不能有蜜罐需求
|
||||
HasFoodNeed(potentialPawn) && // 必须有食物需求
|
||||
IsFeedingAllowed(potentialPawn)) // 其他条件检查
|
||||
{
|
||||
workThings.Add(potentialPawn);
|
||||
}
|
||||
}
|
||||
|
||||
return workThings;
|
||||
}
|
||||
|
||||
public override bool ShouldSkip(Pawn pawn, bool forced = false)
|
||||
{
|
||||
// 检查Pawn是否属于玩家阵营
|
||||
if (pawn.Faction != Faction.OfPlayer)
|
||||
return true;
|
||||
|
||||
// 检查Pawn是否是虫族成员
|
||||
if (!IsSwarmMember(pawn))
|
||||
return true;
|
||||
|
||||
// 检查Pawn是否能够工作
|
||||
if (pawn.Dead || pawn.Downed || pawn.InMentalState)
|
||||
return true;
|
||||
|
||||
// 检查Pawn是否有蜂蜜需求
|
||||
if (!HasHoneyNeed(pawn))
|
||||
return true;
|
||||
|
||||
// 检查Pawn的蜜罐是否有足够的蜂蜜
|
||||
Need_HoneyProduction honeyNeed = pawn.needs?.TryGetNeed<Need_HoneyProduction>();
|
||||
if (honeyNeed == null || honeyNeed.CurLevel <= 0.25)
|
||||
return true;
|
||||
|
||||
// 检查Pawn是否正在执行其他喂食工作
|
||||
if (pawn.CurJobDef == ARA_JobDefOf.ARA_FeedWithHoney)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false)
|
||||
{
|
||||
// 如果目标不是Pawn,返回false
|
||||
if (t == null || !(t is Pawn targetPawn))
|
||||
return false;
|
||||
|
||||
// 检查目标是否有效
|
||||
if (targetPawn.Dead || targetPawn.Downed)
|
||||
return false;
|
||||
|
||||
// 检查目标是否是喂食者自己
|
||||
if (targetPawn == pawn)
|
||||
return false; // 不能喂食自己
|
||||
|
||||
// 检查目标是否有蜜罐需求
|
||||
if (HasHoneyNeed(targetPawn))
|
||||
return false; // 不能喂食有蜜罐需求的目标
|
||||
|
||||
// 检查目标是否有食物需求
|
||||
Need_Food targetFoodNeed = targetPawn.needs?.TryGetNeed<Need_Food>();
|
||||
if (targetFoodNeed == null)
|
||||
return false;
|
||||
|
||||
// 检查目标是否已经吃饱
|
||||
if (targetFoodNeed.CurLevelPercentage >= 0.95f) // 95%以上算吃饱
|
||||
return false;
|
||||
|
||||
// 检查喂食者是否有蜂蜜需求
|
||||
Need_HoneyProduction feederHoneyNeed = pawn.needs?.TryGetNeed<Need_HoneyProduction>();
|
||||
if (feederHoneyNeed == null)
|
||||
return false;
|
||||
|
||||
// 检查喂食者是否有足够的蜂蜜
|
||||
if (feederHoneyNeed.CurLevel <= 0)
|
||||
return false;
|
||||
|
||||
// 检查Pawn是否可以到达目标
|
||||
if (!pawn.CanReserveAndReach(targetPawn, PathEndMode.Touch, pawn.NormalMaxDanger(), 1, -1, null, forced))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
|
||||
{
|
||||
if (t == null || !(t is Pawn targetPawn))
|
||||
return null;
|
||||
|
||||
// 创建喂食工作
|
||||
Job job = JobMaker.MakeJob(ARA_JobDefOf.ARA_FeedWithHoney, targetPawn);
|
||||
job.count = 1;
|
||||
return job;
|
||||
}
|
||||
|
||||
// 检查是否有蜂蜜需求
|
||||
private bool HasHoneyNeed(Pawn pawn)
|
||||
{
|
||||
return pawn.needs?.TryGetNeed<Need_HoneyProduction>() != null;
|
||||
}
|
||||
|
||||
// 检查是否有食物需求
|
||||
private bool HasFoodNeed(Pawn pawn)
|
||||
{
|
||||
return pawn.needs?.TryGetNeed<Need_Food>() != null;
|
||||
}
|
||||
|
||||
// 检查是否是虫族成员
|
||||
private bool IsSwarmMember(Pawn pawn)
|
||||
{
|
||||
return pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindMaster) ||
|
||||
pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindDrone) ||
|
||||
pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindWorker);
|
||||
}
|
||||
|
||||
// 检查是否允许喂食
|
||||
private bool IsFeedingAllowed(Pawn pawn)
|
||||
{
|
||||
// 可以添加额外的条件,比如:
|
||||
// - 是否处于特殊状态
|
||||
// - 是否有特殊的Hediff阻止喂食
|
||||
// - 是否正在被喂食等
|
||||
|
||||
// 检查是否正在被其他虫族喂食
|
||||
if (pawn.jobs?.curDriver is JobDriver_FeedWithHoney)
|
||||
return false;
|
||||
|
||||
// 检查是否有其他虫族正在向这个Pawn移动以喂食
|
||||
IReadOnlyList<Pawn> allPawns = pawn.Map.mapPawns.AllPawnsSpawned;
|
||||
foreach (Pawn otherPawn in allPawns)
|
||||
{
|
||||
if (otherPawn != pawn &&
|
||||
otherPawn.CurJobDef == ARA_JobDefOf.ARA_FeedWithHoney &&
|
||||
otherPawn.CurJob.targetA.Thing == pawn)
|
||||
{
|
||||
return false; // 已经有人正在喂食这个Pawn
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
95
Source/ArachnaeSwarm/WorkGivers/WorkGiver_StripChitin.cs
Normal file
95
Source/ArachnaeSwarm/WorkGivers/WorkGiver_StripChitin.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
using Verse.AI;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class WorkGiver_StripChitin : WorkGiver_Scanner
|
||||
{
|
||||
public override PathEndMode PathEndMode => PathEndMode.Touch;
|
||||
|
||||
public override Danger MaxPathDanger(Pawn pawn)
|
||||
{
|
||||
return Danger.None;
|
||||
}
|
||||
|
||||
// 扫描所有有甲壳剥离组件的虫族成员
|
||||
public override IEnumerable<Thing> PotentialWorkThingsGlobal(Pawn pawn)
|
||||
{
|
||||
IReadOnlyList<Pawn> allPawns = pawn.Map.mapPawns.AllPawnsSpawned;
|
||||
List<Thing> workThings = new List<Thing>();
|
||||
|
||||
foreach (Pawn potentialPawn in allPawns)
|
||||
{
|
||||
// 检查是否有甲壳剥离组件
|
||||
if (potentialPawn.TryGetComp<Comp_ChitinStripping>() != null &&
|
||||
potentialPawn.Faction == Faction.OfPlayer)
|
||||
{
|
||||
workThings.Add(potentialPawn);
|
||||
}
|
||||
}
|
||||
|
||||
return workThings;
|
||||
}
|
||||
|
||||
public override bool ShouldSkip(Pawn pawn, bool forced = false)
|
||||
{
|
||||
// 检查Pawn是否属于玩家阵营
|
||||
if (pawn.Faction != Faction.OfPlayer)
|
||||
return true;
|
||||
|
||||
// 检查Pawn是否是虫族成员
|
||||
if (!IsSwarmMember(pawn))
|
||||
return true;
|
||||
|
||||
// 检查Pawn是否能够工作
|
||||
if (pawn.Dead || pawn.Downed || pawn.InMentalState)
|
||||
return true;
|
||||
|
||||
// 检查Pawn是否正在执行其他剥离工作
|
||||
if (pawn.CurJobDef == ARA_JobDefOf.ARA_StripChitin)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false)
|
||||
{
|
||||
// 如果目标不是Pawn,返回false
|
||||
if (t == null || !(t is Pawn targetPawn))
|
||||
return false;
|
||||
|
||||
// 检查是否是剥离自己的甲壳
|
||||
if (targetPawn != pawn)
|
||||
return false; // 只能剥离自己的甲壳
|
||||
|
||||
// 获取剥离组件
|
||||
Comp_ChitinStripping stripComp = targetPawn.TryGetComp<Comp_ChitinStripping>();
|
||||
if (stripComp == null)
|
||||
return false;
|
||||
|
||||
// 检查是否可以立即剥离
|
||||
return stripComp.CanStripNow(pawn) && stripComp.CanStripChitin;
|
||||
}
|
||||
|
||||
public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
|
||||
{
|
||||
if (t == null || !(t is Pawn targetPawn) || targetPawn != pawn)
|
||||
return null;
|
||||
|
||||
// 创建剥离工作,使用Pawn自身作为目标
|
||||
Job job = JobMaker.MakeJob(ARA_JobDefOf.ARA_StripChitin, pawn);
|
||||
job.count = 1;
|
||||
return job;
|
||||
}
|
||||
|
||||
// 检查是否是虫族成员
|
||||
private bool IsSwarmMember(Pawn pawn)
|
||||
{
|
||||
return pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindMaster) ||
|
||||
pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindDrone) ||
|
||||
pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindWorker);
|
||||
}
|
||||
}
|
||||
}
|
||||
110
Source/ArachnaeSwarm/WorkGivers/WorkGiver_SwarmMaintain.cs
Normal file
110
Source/ArachnaeSwarm/WorkGivers/WorkGiver_SwarmMaintain.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
using Verse.AI;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class WorkGiver_SwarmMaintain : WorkGiver_Scanner
|
||||
{
|
||||
public override PathEndMode PathEndMode => PathEndMode.Touch;
|
||||
|
||||
public override Danger MaxPathDanger(Pawn pawn)
|
||||
{
|
||||
return Danger.Some;
|
||||
}
|
||||
|
||||
public override IEnumerable<Thing> PotentialWorkThingsGlobal(Pawn pawn)
|
||||
{
|
||||
// 获取所有需要维护的建筑
|
||||
List<Thing> allThings = pawn.Map.listerThings.AllThings;
|
||||
List<Thing> maintenanceThings = new List<Thing>();
|
||||
|
||||
foreach (Thing thing in allThings)
|
||||
{
|
||||
if (thing.TryGetComp<Comp_SwarmMaintenance>() != null)
|
||||
{
|
||||
maintenanceThings.Add(thing);
|
||||
}
|
||||
}
|
||||
|
||||
return maintenanceThings;
|
||||
}
|
||||
|
||||
public override bool ShouldSkip(Pawn pawn, bool forced = false)
|
||||
{
|
||||
// 检查Pawn是否属于玩家阵营
|
||||
if (pawn.Faction != Faction.OfPlayer)
|
||||
return true;
|
||||
|
||||
// 检查Pawn是否有虫群维护者组件
|
||||
var maintainerComp = pawn.TryGetComp<Comp_SwarmMaintainer>();
|
||||
if (maintainerComp == null)
|
||||
return true;
|
||||
|
||||
// 检查组件配置要求
|
||||
var props = maintainerComp.Props;
|
||||
if (props != null)
|
||||
{
|
||||
// 如果要求必须有虫群意识hediff
|
||||
if (props.requiresHiveMind && !IsSwarmMember(pawn))
|
||||
return true;
|
||||
|
||||
// 检查最小技能等级要求
|
||||
if (props.minimumSkillLevel > 0 && pawn.skills != null)
|
||||
{
|
||||
var skill = pawn.skills.GetSkill(props.relevantSkill);
|
||||
if (skill == null || skill.Level < props.minimumSkillLevel)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查Pawn是否能够工作
|
||||
if (pawn.Dead || pawn.Downed || pawn.InMentalState)
|
||||
return true;
|
||||
|
||||
// 检查Pawn是否有能力进行维护工作
|
||||
if (pawn.WorkTagIsDisabled(WorkTags.ManualSkilled))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false)
|
||||
{
|
||||
if (t == null || t.Destroyed || !t.Spawned)
|
||||
return false;
|
||||
|
||||
// 检查Pawn是否可以到达建筑
|
||||
if (!pawn.CanReserveAndReach(t, PathEndMode.Touch, pawn.NormalMaxDanger(), 1, -1, null, forced))
|
||||
return false;
|
||||
|
||||
// 获取维护组件
|
||||
Comp_SwarmMaintenance comp = t.TryGetComp<Comp_SwarmMaintenance>();
|
||||
if (comp == null)
|
||||
return false;
|
||||
|
||||
// 检查建筑是否需要维护
|
||||
return comp.NeedsMaintenance;
|
||||
}
|
||||
|
||||
public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
|
||||
{
|
||||
if (t == null || t.Destroyed)
|
||||
return null;
|
||||
|
||||
// 创建维护工作
|
||||
Job job = JobMaker.MakeJob(ARA_JobDefOf.ARA_SwarmMaintain, t);
|
||||
job.count = 1;
|
||||
return job;
|
||||
}
|
||||
|
||||
private bool IsSwarmMember(Pawn pawn)
|
||||
{
|
||||
// 检查Pawn是否是虫群成员
|
||||
return pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindMaster) ||
|
||||
pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindDrone) ||
|
||||
pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindWorker);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user