This commit is contained in:
2026-01-23 17:19:38 +08:00
parent 44f8cfb4f9
commit 78493879e2
20 changed files with 506 additions and 339 deletions

View File

@@ -3,40 +3,36 @@
"WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_corpsevat\\building_corpsevat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_corpsevat\\building_corpsevat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\jobs\\jobdriver_plant\\jobgiver_grower.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_plant\\jobgiver_grower.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_corpsevat\\jobdriver_haulcorpsetovat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_corpsevat\\jobdriver_haulcorpsetovat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\jobs\\jobdriver_clean\\jobgiver_cleaner.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_clean\\jobgiver_cleaner.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_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|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\ara_huggingface\\hediff_possession.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_huggingface\\hediff_possession.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_corpsevat\\corpsevatextension.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_corpsevat\\corpsevatextension.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\ara_huggingface\\compabilityeffect_possess.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_huggingface\\compabilityeffect_possess.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\jobs\\jobdriver_followproducer\\thinknode_conditionalnotproducedbymechcarrier.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_followproducer\\thinknode_conditionalnotproducedbymechcarrier.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\building_comps\\ara_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|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\pawn_comps\\ara_flight\\pawn_flighttrackerpatches.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_flight\\pawn_flighttrackerpatches.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_hediffterrainspawn\\compproperties_hediffterrainspawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_hediffterrainspawn\\compproperties_hediffterrainspawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\pawn_comps\\ara_flight\\compproperties_pawnflight.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_flight\\compproperties_pawnflight.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_hediffterrainspawn\\comphediffterrainspawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_hediffterrainspawn\\comphediffterrainspawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\hediffs\\ara_productionqueue\\hediffcompproperties_productionqueue.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_productionqueue\\hediffcompproperties_productionqueue.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\hediffs\\ara_productionqueue\\hediffcomp_productionqueue.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_productionqueue\\hediffcomp_productionqueue.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_ootheca\\building_ootheca.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_ootheca\\building_ootheca.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
"DocumentGroupContainers": [
@@ -46,125 +42,115 @@
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 2,
"SelectedChildIndex": 1,
"Children": [
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "CorpseVatExtension.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CorpseVat\\CorpseVatExtension.cs",
"RelativeDocumentMoniker": "Buildings\\Building_CorpseVat\\CorpseVatExtension.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CorpseVat\\CorpseVatExtension.cs",
"RelativeToolTip": "Buildings\\Building_CorpseVat\\CorpseVatExtension.cs",
"ViewState": "AgIAAAYAAAAAAAAAAAAAABkAAAAIAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-23T04:01:21.774Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "JobDriver_HaulCorpseToVat.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CorpseVat\\JobDriver_HaulCorpseToVat.cs",
"RelativeDocumentMoniker": "Buildings\\Building_CorpseVat\\JobDriver_HaulCorpseToVat.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CorpseVat\\JobDriver_HaulCorpseToVat.cs",
"RelativeToolTip": "Buildings\\Building_CorpseVat\\JobDriver_HaulCorpseToVat.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAA0AAAA0AAAAAAAAAA==",
"Title": "JobGiver_Cleaner.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_Clean\\JobGiver_Cleaner.cs",
"RelativeDocumentMoniker": "Jobs\\JobDriver_Clean\\JobGiver_Cleaner.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_Clean\\JobGiver_Cleaner.cs",
"RelativeToolTip": "Jobs\\JobDriver_Clean\\JobGiver_Cleaner.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABYAAABwAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-23T04:01:20.292Z",
"WhenOpened": "2026-01-23T08:51:58.899Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "Building_CorpseVat.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CorpseVat\\Building_CorpseVat.cs",
"RelativeDocumentMoniker": "Buildings\\Building_CorpseVat\\Building_CorpseVat.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CorpseVat\\Building_CorpseVat.cs",
"RelativeToolTip": "Buildings\\Building_CorpseVat\\Building_CorpseVat.cs",
"ViewState": "AgIAAEYBAAAAAAAAAAAawFgBAAAMAAAAAAAAAA==",
"Title": "JobGiver_Grower.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_Plant\\JobGiver_Grower.cs",
"RelativeDocumentMoniker": "Jobs\\JobDriver_Plant\\JobGiver_Grower.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_Plant\\JobGiver_Grower.cs",
"RelativeToolTip": "Jobs\\JobDriver_Plant\\JobGiver_Grower.cs",
"ViewState": "AgIAAFMAAAAAAAAAAAAQwGEAAAAvAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-23T04:01:18.535Z",
"WhenOpened": "2026-01-23T08:51:03.439Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "Building_DormancyVat.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_DormancyVat\\Building_DormancyVat.cs",
"RelativeDocumentMoniker": "Buildings\\Building_DormancyVat\\Building_DormancyVat.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_DormancyVat\\Building_DormancyVat.cs",
"RelativeToolTip": "Buildings\\Building_DormancyVat\\Building_DormancyVat.cs",
"ViewState": "AgIAACUAAAAAAAAAAIA8wDcAAAAAAAAAAAAAAA==",
"Title": "Hediff_Possession.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HuggingFace\\Hediff_Possession.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_HuggingFace\\Hediff_Possession.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HuggingFace\\Hediff_Possession.cs",
"RelativeToolTip": "Abilities\\ARA_HuggingFace\\Hediff_Possession.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABMAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-23T03:49:32.234Z",
"WhenOpened": "2026-01-23T08:50:05.221Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "CompAbilityEffect_Possess.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HuggingFace\\CompAbilityEffect_Possess.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_HuggingFace\\CompAbilityEffect_Possess.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HuggingFace\\CompAbilityEffect_Possess.cs",
"RelativeToolTip": "Abilities\\ARA_HuggingFace\\CompAbilityEffect_Possess.cs",
"ViewState": "AgIAAHcAAAAAAAAAAAAAAIkAAAA5AAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-23T08:50:01.549Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 4,
"Title": "CompDelayedTerrainSpawn.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_BuildingTerrainSpawn\\CompDelayedTerrainSpawn.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_BuildingTerrainSpawn\\CompDelayedTerrainSpawn.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_BuildingTerrainSpawn\\CompDelayedTerrainSpawn.cs",
"RelativeToolTip": "Building_Comps\\ARA_BuildingTerrainSpawn\\CompDelayedTerrainSpawn.cs",
"ViewState": "AgIAAFEAAAAAAAAAAAAAAF8AAAA+AAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-23T08:46:06.784Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "CompProperties_HediffTerrainSpawn.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HediffTerrainSpawn\\CompProperties_HediffTerrainSpawn.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_HediffTerrainSpawn\\CompProperties_HediffTerrainSpawn.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HediffTerrainSpawn\\CompProperties_HediffTerrainSpawn.cs",
"RelativeToolTip": "Hediffs\\ARA_HediffTerrainSpawn\\CompProperties_HediffTerrainSpawn.cs",
"ViewState": "AgIAAAUAAAAAAAAAAAAtwBkAAAAxAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-23T08:44:14.682Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 6,
"Title": "CompHediffTerrainSpawn.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HediffTerrainSpawn\\CompHediffTerrainSpawn.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_HediffTerrainSpawn\\CompHediffTerrainSpawn.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HediffTerrainSpawn\\CompHediffTerrainSpawn.cs",
"RelativeToolTip": "Hediffs\\ARA_HediffTerrainSpawn\\CompHediffTerrainSpawn.cs",
"ViewState": "AgIAAKIAAAAAAAAAAAAawLQAAAAMAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-23T08:44:10.075Z",
"EditorCaption": ""
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
},
{
"$type": "Document",
"DocumentIndex": 4,
"Title": "ThinkNode_ConditionalNotProducedByMechCarrier.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FollowProducer\\ThinkNode_ConditionalNotProducedByMechCarrier.cs",
"RelativeDocumentMoniker": "Jobs\\JobDriver_FollowProducer\\ThinkNode_ConditionalNotProducedByMechCarrier.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FollowProducer\\ThinkNode_ConditionalNotProducedByMechCarrier.cs",
"RelativeToolTip": "Jobs\\JobDriver_FollowProducer\\ThinkNode_ConditionalNotProducedByMechCarrier.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAoAAAA+AAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-23T02:44:35.619Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "Pawn_FlightTrackerPatches.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_Flight\\Pawn_FlightTrackerPatches.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_Flight\\Pawn_FlightTrackerPatches.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_Flight\\Pawn_FlightTrackerPatches.cs",
"RelativeToolTip": "Pawn_Comps\\ARA_Flight\\Pawn_FlightTrackerPatches.cs",
"ViewState": "AgIAAB0AAAAAAAAAAAAuwEsAAAAfAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-22T14:03:17.973Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 6,
"Title": "CompProperties_PawnFlight.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_Flight\\CompProperties_PawnFlight.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_Flight\\CompProperties_PawnFlight.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_Flight\\CompProperties_PawnFlight.cs",
"RelativeToolTip": "Pawn_Comps\\ARA_Flight\\CompProperties_PawnFlight.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAA4AAAAeAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-22T14:02:45.434Z"
},
{
"$type": "Document",
"DocumentIndex": 8,
"Title": "HediffComp_ProductionQueue.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_ProductionQueue\\HediffComp_ProductionQueue.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_ProductionQueue\\HediffComp_ProductionQueue.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_ProductionQueue\\HediffComp_ProductionQueue.cs",
"RelativeToolTip": "Hediffs\\ARA_ProductionQueue\\HediffComp_ProductionQueue.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAB8AAAAMAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-22T10:31:06.201Z"
},
{
"$type": "Document",
"DocumentIndex": 7,
"Title": "HediffCompProperties_ProductionQueue.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_ProductionQueue\\HediffCompProperties_ProductionQueue.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_ProductionQueue\\HediffCompProperties_ProductionQueue.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_ProductionQueue\\HediffCompProperties_ProductionQueue.cs",
"RelativeToolTip": "Hediffs\\ARA_ProductionQueue\\HediffCompProperties_ProductionQueue.cs",
"ViewState": "AgIAAB8AAAAAAAAAAAAewEoAAAApAAAAAAAAAA==",
"Title": "Building_Ootheca.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\Building_Ootheca.cs",
"RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\Building_Ootheca.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\Building_Ootheca.cs",
"RelativeToolTip": "Buildings\\Building_Ootheca\\Building_Ootheca.cs",
"ViewState": "AgIAALwAAAAAAAAAAAAowC4BAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-22T09:30:17.721Z"
"WhenOpened": "2026-01-23T08:31:14.555Z",
"EditorCaption": ""
}
]
}

View File

@@ -85,4 +85,16 @@ namespace ArachnaeSwarm
DefOfHelper.EnsureInitializedInCtor(typeof(ARA_ThoughtDefOf));
}
}
[DefOf]
public static class ARA_StatDefOf
{
public static StatDef ARA_GestaltBandwidth;
public static StatDef ARA_GestaltBandwidthCost;
static ARA_StatDefOf()
{
DefOfHelper.EnsureInitializedInCtor(typeof(ARA_StatDefOf));
}
}
}

View File

@@ -4,7 +4,7 @@ using Verse;
namespace ArachnaeSwarm
{
public class Hediff_Possession : HediffWithComps, IThingHolder
public class Hediff_Possession : Hediff_High, IThingHolder
{
public ThingOwner casterContainer;
public OriginalPawnData originalHostData;

View File

@@ -21,6 +21,9 @@ namespace ArachnaeSwarm
// 工作定义
private static readonly JobDef HaulCorpseToVatJobDef = DefDatabase<JobDef>.GetNamedSilentFail("ARA_HaulCorpseToVat");
private const int MaxDistanceForAutoAssignment = 30; // 自动分配工作的最大距离
// 反射缓存
private static System.Reflection.MethodInfo corpseDrawAtMethod;
#endregion
#region
@@ -28,7 +31,6 @@ namespace ArachnaeSwarm
private Corpse selectedCorpse;
private int startTick = -1;
private Graphic cachedTopGraphic;
private CompPowerTrader powerComp;
private CorpseVatExtension vatExtension;
// 绘制相关
@@ -41,7 +43,6 @@ namespace ArachnaeSwarm
public bool HasCorpse => selectedCorpse != null && innerContainer.Contains(selectedCorpse);
public virtual bool IsContentsSuspended => true;
public ThingOwner SearchableContents => innerContainer;
public CompPowerTrader PowerComp => powerComp ??= GetComp<CompPowerTrader>();
// 扩展属性
public CorpseVatExtension VatExtension => vatExtension ??= def.GetModExtension<CorpseVatExtension>();
@@ -65,6 +66,14 @@ namespace ArachnaeSwarm
return cachedTopGraphic;
}
}
// 静态构造函数
static Building_CorpseVat()
{
// 使用反射获取DrawAt方法
corpseDrawAtMethod = typeof(Corpse).GetMethod("DrawAt",
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
}
#endregion
#region
@@ -136,12 +145,6 @@ namespace ArachnaeSwarm
return "CorpseVat_Occupied".Translate();
}
// 检查是否有电源需求且是否供电
if (VatExtension != null && VatExtension.requiresPower && (PowerComp == null || !PowerComp.PowerOn))
{
return "CorpseVat_NoPower".Translate();
}
// 检查尸体是否有效
if (corpse == null || corpse.Destroyed)
{
@@ -239,10 +242,6 @@ namespace ArachnaeSwarm
{
VatExtension.ejectSound.PlayOneShot(new TargetInfo(Position, Map));
}
// 发送消息
Messages.Message("CorpseVat_CorpseEjected".Translate(droppedCorpse.InnerPawn?.LabelShortCap ?? "Unknown"),
MessageTypeDefOf.NeutralEvent);
}
}
}
@@ -505,7 +504,8 @@ namespace ArachnaeSwarm
if (Map == null)
yield break;
foreach (Thing thing in Map.listerThings.ThingsOfDef(ThingDefOf.Corpse))
// 使用 ThingRequestGroup.Corpse 获取所有尸体
foreach (Thing thing in Map.listerThings.ThingsInGroup(ThingRequestGroup.Corpse))
{
Corpse corpse = thing as Corpse;
if (corpse != null && CanAcceptCorpse(corpse).Accepted)
@@ -551,17 +551,6 @@ namespace ArachnaeSwarm
{
base.Tick();
// 检查电源
if (VatExtension != null && VatExtension.requiresPower && (PowerComp == null || !PowerComp.PowerOn))
{
if (HasCorpse)
{
Messages.Message("CorpseVat_PowerLost".Translate(), MessageTypeDefOf.CautionInput);
EjectContents();
}
return;
}
// 检查尸体状态
if (HasCorpse && (selectedCorpse.Destroyed || !innerContainer.Contains(selectedCorpse)))
{
@@ -617,10 +606,23 @@ namespace ArachnaeSwarm
// 调整高度
corpseDrawPos.y += Altitudes.AltIncVect.y * 3f;
// 绘制尸体
// 注意:由于尸体在容器中,其正常绘制方法可能不会自动调用
// 我们需要手动调用绘制方法
selectedCorpse.DrawAt(corpseDrawPos);
// 绘制尸体 - 使用反射调用受保护的DrawAt方法
if (corpseDrawAtMethod != null)
{
try
{
corpseDrawAtMethod.Invoke(selectedCorpse, new object[] { corpseDrawPos, false });
}
catch (Exception ex)
{
Log.Error($"Failed to draw corpse: {ex.Message}");
}
}
else
{
// 如果反射失败,使用替代方法绘制
DrawCorpseAlternative(corpseDrawPos);
}
// 如果需要特殊的绘制效果,可以在这里添加
if (VatExtension != null && VatExtension.drawPreservationEffect)
@@ -629,6 +631,26 @@ namespace ArachnaeSwarm
}
}
/// <summary>
/// 替代的绘制尸体方法
/// </summary>
private void DrawCorpseAlternative(Vector3 position)
{
if (selectedCorpse == null)
return;
// 尝试使用公开的方法绘制
try
{
// 使用DynamicDrawPhaseAt方法
selectedCorpse.DynamicDrawPhaseAt(DrawPhase.Draw, position);
}
catch (Exception ex)
{
Log.Error($"Failed to draw corpse (alternative): {ex.Message}");
}
}
/// <summary>
/// 绘制保存效果
/// </summary>
@@ -650,24 +672,6 @@ namespace ArachnaeSwarm
if (sb.Length > 0)
sb.AppendLine();
// 电源状态
if (VatExtension != null && VatExtension.requiresPower)
{
if (PowerComp == null)
{
sb.Append("CorpseVat_NoPowerComp".Translate());
}
else if (!PowerComp.PowerOn)
{
sb.Append("CorpseVat_PowerOff".Translate());
}
else
{
sb.Append("CorpseVat_PowerOn".Translate());
}
sb.AppendLine();
}
// 内容状态
if (HasCorpse)
{
@@ -677,15 +681,6 @@ namespace ArachnaeSwarm
sb.Append("CorpseVat_Contains".Translate(innerPawn.LabelCap));
sb.AppendLine();
// 显示保存时间
if (startTick > 0)
{
int ticksInVat = Find.TickManager.TicksGame - startTick;
string timeStr = ticksInVats.ToStringTicksToPeriod();
sb.Append("CorpseVat_PreservationTime".Translate(timeStr));
sb.AppendLine();
}
// 显示腐烂状态
CompRottable rottable = selectedCorpse.TryGetComp<CompRottable>();
if (rottable != null)
@@ -752,7 +747,6 @@ namespace ArachnaeSwarm
sb.AppendLine($"是否有尸体: {HasCorpse}");
sb.AppendLine($"是否工作中: {Working}");
sb.AppendLine($"开始Tick: {startTick}");
sb.AppendLine($"电源: {(PowerComp?.PowerOn == true ? "" : "")}");
if (HasCorpse)
{
@@ -764,36 +758,12 @@ namespace ArachnaeSwarm
sb.AppendLine($"扩展配置: {(VatExtension != null ? "" : "")}");
if (VatExtension != null)
{
sb.AppendLine($"需要电源: {VatExtension.requiresPower}");
sb.AppendLine($"减缓腐烂: {VatExtension.slowDecayRate}");
sb.AppendLine($"顶部贴图: {VatExtension.topGraphicPath}");
}
return sb.ToString();
}
/// <summary>
/// 获取所有可用尸体的统计信息
/// </summary>
public string GetAvailableCorpsesInfo()
{
StringBuilder sb = new StringBuilder();
var corpses = GetAvailableCorpses().ToList();
sb.AppendLine("=== 可用尸体列表 ===");
sb.AppendLine($"总计: {corpses.Count}");
sb.AppendLine();
foreach (Corpse corpse in corpses)
{
sb.AppendLine(GetCorpseLabel(corpses));
sb.AppendLine($" 位置: {corpse.Position}");
sb.AppendLine($" 距离: {corpse.Position.DistanceTo(Position):F0}m");
sb.AppendLine();
}
return sb.ToString();
}
#endregion
}
}

View File

@@ -21,7 +21,6 @@ namespace ArachnaeSwarm
public bool drawPreservationEffect = true; // 是否绘制保存效果
// ===== 功能配置 =====
public bool requiresPower = true; // 是否需要电源
public float slowDecayRate = 0.1f; // 腐烂减缓率0-10=完全停止腐烂1=正常腐烂)
// ===== 音效配置 =====
@@ -32,7 +31,6 @@ namespace ArachnaeSwarm
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.AppendLine("=== CorpseVat 配置摘要 ===");
sb.AppendLine($"需要电源: {requiresPower}");
sb.AppendLine($"减缓腐烂: {(slowDecayRate * 100):F0}%");
sb.AppendLine($"顶部贴图: {topGraphicPath ?? ""}");
sb.AppendLine($"绘制偏移: {corpseDrawOffset}");

View File

@@ -1,4 +1,6 @@
using RimWorld;
using System.Collections.Generic;
using UnityEngine;
using Verse;
using Verse.AI;
@@ -7,66 +9,230 @@ namespace ArachnaeSwarm
/// <summary>
/// 自定义的搬运尸体工作驱动
/// </summary>
public class JobDriver_HaulCorpseToVat : JobDriver_HaulToContainer
public class JobDriver_HaulCorpseToVat : JobDriver_HaulToContainer, IBuildableDriver
{
protected override Toil CarryToContainerToil()
// 自定义工作效果器
private Effecter workEffecter;
// 工作间隔tick
private const int WorkEffectInterval = 80;
/// <summary>
/// 获取要搬运的尸体
/// </summary>
private Corpse CorpseToCarry => job.targetA.Thing as Corpse;
/// <summary>
/// 获取尸体保存罐
/// </summary>
private Building_CorpseVat CorpseVat => job.targetB.Thing as Building_CorpseVat;
/// <summary>
/// 构建工作流程
/// </summary>
protected override IEnumerable<Toil> MakeNewToils()
{
Toil toil = base.CarryToContainerToil();
// 添加失败条件
this.FailOn(() => CorpseToCarry == null || CorpseToCarry.Destroyed);
this.FailOn(() => CorpseVat == null || CorpseVat.Destroyed);
// 添加自定义行为
toil.AddPreTickAction(() =>
// 添加自定义失败条件:检查尸体是否仍然可以被接受
this.FailOn(() =>
{
Corpse corpse = TargetThingA as Corpse;
Building_CorpseVat vat = TargetThingB as Building_CorpseVat;
if (corpse != null && vat != null && pawn != null)
{
// 检查距离,如果太远可以取消工作
float distance = corpse.Position.DistanceTo(vat.Position);
if (distance > 100f) // 最大距离限制
{
pawn.jobs.EndCurrentJob(JobCondition.Incompletable);
}
}
if (CorpseToCarry == null || CorpseVat == null)
return true;
AcceptanceReport report = CorpseVat.CanAcceptCorpse(CorpseToCarry);
return !report.Accepted;
});
return toil;
}
protected override Toil FindCarryToCellToil()
{
Toil toil = base.FindCarryToCellToil();
// 添加额外条件检查
toil.AddFailCondition(() =>
// 添加自定义失败条件:检查距离是否过远
this.FailOn(() =>
{
Corpse corpse = TargetThingA as Corpse;
Building_CorpseVat vat = TargetThingB as Building_CorpseVat;
if (corpse == null || corpse.Destroyed || vat == null || vat.Destroyed)
{
if (CorpseToCarry == null || CorpseVat == null)
return true;
float distance = CorpseToCarry.Position.DistanceTo(CorpseVat.Position);
return distance > 100f; // 最大距离100格
});
// 调用基类的工作流程
foreach (Toil toil in base.MakeNewToils())
{
// 我们可以对每个toil进行自定义修改
if (toil.defaultCompleteMode == ToilCompleteMode.Delay)
{
// 这是等待/工作toil添加自定义效果
toil.AddPreTickAction(() =>
{
UpdateWorkEffecter(toil);
});
toil.AddFinishAction(() =>
{
CleanupWorkEffecter();
});
}
// 检查尸体是否仍然可以被接受
yield return toil;
}
}
/// <summary>
/// 更新工作效果器
/// </summary>
private void UpdateWorkEffecter(Toil toil)
{
if (CorpseVat == null || !pawn.IsHashIntervalTick(WorkEffectInterval))
return;
// 创建或更新效果器
if (workEffecter == null && WorkEffecter != null)
{
workEffecter = WorkEffecter.Spawn();
workEffecter.Trigger(CorpseVat, CorpseVat);
}
workEffecter?.EffectTick(CorpseVat, CorpseVat);
}
/// <summary>
/// 清理工作效果器
/// </summary>
private void CleanupWorkEffecter()
{
workEffecter?.Cleanup();
workEffecter = null;
}
/// <summary>
/// 重写报告字符串
/// </summary>
public override string GetReport()
{
if (CorpseToCarry == null || CorpseVat == null)
return "ReportHaulingUnknown".Translate();
Pawn innerPawn = CorpseToCarry.InnerPawn;
string pawnName = innerPawn?.LabelCap ?? "Unknown";
return "CorpseVat_ReportHauling".Translate(pawnName, CorpseVat.LabelShort);
}
/// <summary>
/// 重写预留方法
/// </summary>
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
// 调用基类预留
bool result = base.TryMakePreToilReservations(errorOnFailed);
if (result && Prefs.DevMode)
{
Log.Message($"JobDriver_HaulCorpseToVat: 成功预留 {CorpseToCarry?.LabelCap ?? "null"} 到 {CorpseVat?.LabelCap ?? "null"}");
}
return result;
}
/// <summary>
/// 添加自定义准备步骤
/// </summary>
protected override void ModifyPrepareToil(Toil toil)
{
base.ModifyPrepareToil(toil);
// 添加自定义准备步骤
toil.AddPreInitAction(() =>
{
if (CorpseToCarry != null && CorpseVat != null)
{
// 记录开始时间
Log.Message($"开始搬运尸体 {CorpseToCarry.InnerPawn?.LabelCap ?? "Unknown"} 到 {CorpseVat.LabelCap}");
}
});
}
/// <summary>
/// 获取调试信息
/// </summary>
public string GetDebugInfo()
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.AppendLine("=== JobDriver_HaulCorpseToVat 调试信息 ===");
sb.AppendLine($"Pawn: {pawn?.LabelCap ?? "null"}");
sb.AppendLine($"Corpse: {CorpseToCarry?.InnerPawn?.LabelCap ?? "null"}");
sb.AppendLine($"Vat: {CorpseVat?.LabelCap ?? "null"}");
sb.AppendLine($"工作状态: {(CorpseToCarry != null && CorpseVat != null ? "" : "")}");
if (CorpseToCarry != null && CorpseVat != null)
{
float distance = CorpseToCarry.Position.DistanceTo(CorpseVat.Position);
sb.AppendLine($"距离: {distance:F1} 格");
AcceptanceReport report = CorpseVat.CanAcceptCorpse(CorpseToCarry);
sb.AppendLine($"尸体是否可接受: {report.Accepted}");
if (!report.Accepted)
sb.AppendLine($"原因: {report.Reason}");
}
return sb.ToString();
}
}
/// <summary>
/// 简化的搬运尸体工作驱动(如果需要更简单的版本)
/// </summary>
public class JobDriver_HaulCorpseToVatSimple : JobDriver_HaulToContainer
{
protected override IEnumerable<Toil> MakeNewToils()
{
// 基本工作流程
this.FailOnDestroyedOrNull(TargetIndex.A);
this.FailOnDestroyedOrNull(TargetIndex.B);
this.FailOnForbidden(TargetIndex.B);
// 获取尸体和建筑
Corpse corpse = TargetThingA as Corpse;
Building_CorpseVat vat = TargetThingB as Building_CorpseVat;
// 添加自定义失败条件
this.FailOn(() =>
{
if (corpse == null || vat == null)
return true;
// 检查是否仍然可以接受
AcceptanceReport report = vat.CanAcceptCorpse(corpse);
return !report.Accepted;
});
return toil;
// 检查距离
this.FailOn(() =>
{
if (corpse == null || vat == null)
return true;
float distance = corpse.Position.DistanceTo(vat.Position);
return distance > 100f;
});
// 调用基类工作流程
foreach (Toil toil in base.MakeNewToils())
{
yield return toil;
}
}
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
// 尸体和建筑预留
if (!pawn.Reserve(TargetA, job, 1, -1, null, errorOnFailed))
{
// 简单预留:只预留尸体和建筑
if (!pawn.Reserve(job.targetA, job, 1, -1, null, errorOnFailed))
return false;
}
if (!pawn.Reserve(TargetB, job, 1, -1, null, errorOnFailed))
{
if (!pawn.Reserve(job.targetB, job, 1, -1, null, errorOnFailed))
return false;
}
return true;
}
}

View File

@@ -1,6 +1,7 @@
// File: Building_Ootheca.cs
using RimWorld;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using Verse;
@@ -199,24 +200,107 @@ namespace ArachnaeSwarm
builder.AppendLine(config.pawnKind.LabelCap);
return builder.ToString().TrimEndNewlines();
}
// === 幼虫交互 ===
public void CallLarva()
{
// 检查是否已经有幼虫在操作或正在孵化
if (isIncubating || assignedLarva != null) return;
// 获取当前选中的所有同类建筑
var selectedOothecas = GetSelectedOothecas();
// 如果选择了多个,检查是否有其他卵已经启动召唤
if (selectedOothecas.Count > 1)
{
// 检查是否有其他卵已经分配了幼虫
foreach (var ootheca in selectedOothecas)
{
if (ootheca != this && ootheca.assignedLarva != null)
{
// 已经有其他卵开始召唤幼虫了,跳过
return;
}
}
// 检查是否有其他卵已经处于孵化状态
foreach (var ootheca in selectedOothecas)
{
if (ootheca != this && ootheca.isIncubating)
{
// 已经有其他卵在孵化了,跳过
return;
}
}
// 如果是同时按下gizmo我们希望只有一个卵响应
// 我们可以使用一个简单的规则:只让最近选择的一个卵响应
// 这里我们选择第一个(可能是玩家最后点击的,取决于选择顺序)
// 或者我们可以使用位置排序
if (!IsFirstValidOotheca(selectedOothecas))
{
return;
}
}
var larva = FindLarva();
if (larva == null)
{
Messages.Message("ARA_OothecaIncubator.NoLarvaeFound".Translate(), MessageTypeDefOf.RejectInput);
return;
}
var job = JobMaker.MakeJob(ARA_JobDefOf.ARA_OperateIncubator, this);
larva.jobs.TryTakeOrderedJob(job, JobTag.MiscWork);
assignedLarva = larva;
Messages.Message("ARA_OothecaIncubator.LarvaCalled".Translate(), MessageTypeDefOf.PositiveEvent);
}
/// <summary>
/// 获取当前选中的所有Building_Ootheca
/// </summary>
private List<Building_Ootheca> GetSelectedOothecas()
{
List<Building_Ootheca> result = new List<Building_Ootheca>();
if (Find.Selector == null)
return result;
// 获取所有选中的建筑
var selected = Find.Selector.SelectedObjects;
foreach (var obj in selected)
{
if (obj is Building_Ootheca ootheca && ootheca.Map == this.Map)
{
result.Add(ootheca);
}
}
return result;
}
/// <summary>
/// 判断当前建筑是否是第一个有效的卵(用于多选时只让一个响应)
/// </summary>
private bool IsFirstValidOotheca(List<Building_Ootheca> oothecas)
{
// 过滤掉无效的(正在孵化或已有幼虫的)
var validOothecas = oothecas.Where(o =>
!o.isIncubating &&
o.assignedLarva == null
).ToList();
if (validOothecas.Count == 0)
return false;
// 排序规则:我们可以使用多种规则
// 1. 按距离玩家视角中心排序(最近的优先)
// 2. 按位置排序XZ坐标
// 3. 按建筑ID排序稳定的顺序
// 这里我们使用简单的排序按建筑位置X坐标为主Z坐标为辅
var sorted = validOothecas.OrderBy(o => o.Position.x).ThenBy(o => o.Position.z).ToList();
// 返回是否是第一个
return sorted.First() == this;
}
private Pawn FindLarva()
{
float searchRadius = 30f;

View File

@@ -29,10 +29,10 @@ namespace ArachnaeSwarm
public List<Pawn> ControlledPawns => controlledPawns;
// 计算已使用的带宽(包括超载部分)
public int UsedBandwidth => (int)ControlledPawns.Sum(p => p.GetStatValue(StatDefOf.BandwidthCost));
public int UsedBandwidth => (int)ControlledPawns.Sum(p => p.GetStatValue(ARA_StatDefOf.ARA_GestaltBandwidthCost));
// 计算基础带宽限制
public int TotalBandwidth => (int)pawn.GetStatValue(StatDefOf.MechBandwidth);
public int TotalBandwidth => (int)pawn.GetStatValue(ARA_StatDefOf.ARA_GestaltBandwidth);
// 计算总可用控制组
public int TotalAvailableControlGroups => (int)pawn.GetStatValue(StatDefOf.MechControlGroups);

View File

@@ -111,14 +111,6 @@ namespace ArachnaeSwarm
{
continue; // 跳过有排除tag的地面
}
// === 新增检查是否只影响自己的Creep ===
if (Props.affectOwnCreepOnly && currentTerrain.tags != null &&
currentTerrain.tags.Contains("ARA_Creep"))
{
// 这里可以添加派系检查逻辑
// 例如只覆盖自己派系的Creep
}
// 应用地形变化
map.terrainGrid.SetTerrain(current, Props.terrainToSpawn);
affectedCells.Add(current);
@@ -187,33 +179,6 @@ namespace ArachnaeSwarm
return true;
}
// 2. 检查允许性(如果启用)
if (Props.checkAffordances && terrain.affordances != null && Props.excludeAffordances != null)
{
foreach (var affordance in terrain.affordances)
{
if (affordance != null && Props.excludeAffordances.Contains(affordance.defName))
{
return true;
}
}
}
// 3. 检查优先地形(如果启用智能覆盖)
if (Props.smartOverlay && Props.IsPreferredTerrain(terrain))
{
return true;
}
// 4. 检查路径(如果启用路径保护)
if (Props.preservePaths)
{
if (IsPathCell(cell, map))
{
return true;
}
}
// 5. 检查是否是水或其他特殊地形
if (terrain.IsWater || terrain.defName.Contains("Water") || terrain.defName.Contains("Marsh"))
{

View File

@@ -22,19 +22,12 @@ namespace ArachnaeSwarm
public List<string> excludedTerrainTags = null; // 要排除的tag列表
public bool useDefaultExclusions = true; // 是否使用默认排除项ARA_Creep和ARA_Incubator_Nutrient_Solution
// === 新增:扩展检查选项 ===
public bool checkAffordances = false; // 是否检查地形允许性affordances
public List<string> excludeAffordances = null; // 要排除的允许性列表
// === 新增:智能覆盖选项 ===
public bool smartOverlay = false; // 是否智能覆盖(仅覆盖"较差"的地形)
public List<TerrainDef> preferredTerrains = null; // 优先地形列表,这些不会被覆盖
public bool preservePaths = false; // 是否保留路径
// === 新增:行为选项 ===
public bool onlyWhenOnCreep = false; // 是否只在Creep上生效
public bool ignoreOccupiedCells = true; // 是否忽略被占用的单元格
public bool affectOwnCreepOnly = false; // 是否只影响自己的Creep如果有派系
public bool ignoreOccupiedCells = false; // 是否忽略被占用的单元格
// === 新增:视觉效果选项 ===
public EffecterDef spawnEffecter = null; // 生成地形时的效果