11
This commit is contained in:
Binary file not shown.
@@ -2,28 +2,40 @@
|
||||
"Version": 1,
|
||||
"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\\pawnsarrivalmode\\pawnsarrivalmodeworker_wormholeportal.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawnsarrivalmode\\pawnsarrivalmodeworker_wormholeportal.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_wormholeportal\\comp_wormholeportal.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_wormholeportal\\comp_wormholeportal.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_wormholeportal\\compproperties_wormholeportal.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_wormholeportal\\compproperties_wormholeportal.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_uniquepawn\\uniquepawnmanager.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_uniquepawn\\uniquepawnmanager.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_uniquepawn\\compuniquepawn.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_uniquepawn\\compuniquepawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_uniquepawn\\compuniquepawn.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\\needs\\need_honeyproduction.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\\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|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\jobs\\jobdriver_extracthoney\\jobdriver_extracthoney.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_extracthoney\\jobdriver_extracthoney.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_extracthoney\\jobdriver_extracthoney.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\\needs\\need_chitinarmor.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\\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|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\ara_psychicloaddump\\compabilityeffect_psychicloaddump.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_psychicloaddump\\compabilityeffect_psychicloaddump.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_psychicloaddump\\compabilityeffect_psychicloaddump.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
@@ -111,19 +123,58 @@
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 0,
|
||||
"Title": "PawnsArrivalModeWorker_WormholePortal.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PawnsArrivalMode\\PawnsArrivalModeWorker_WormholePortal.cs",
|
||||
"RelativeDocumentMoniker": "PawnsArrivalMode\\PawnsArrivalModeWorker_WormholePortal.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PawnsArrivalMode\\PawnsArrivalModeWorker_WormholePortal.cs*",
|
||||
"RelativeToolTip": "PawnsArrivalMode\\PawnsArrivalModeWorker_WormholePortal.cs*",
|
||||
"ViewState": "AgIAADEBAAAAAAAAAAAkwEABAABSAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2026-02-06T09:04:02.296Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 2,
|
||||
"Title": "CompProperties_WormholePortal.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_WormholePortal\\CompProperties_WormholePortal.cs",
|
||||
"RelativeDocumentMoniker": "Building_Comps\\ARA_WormholePortal\\CompProperties_WormholePortal.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_WormholePortal\\CompProperties_WormholePortal.cs",
|
||||
"RelativeToolTip": "Building_Comps\\ARA_WormholePortal\\CompProperties_WormholePortal.cs",
|
||||
"ViewState": "AgIAAAMAAAAAAAAAAAAuwBoAAAAIAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2026-02-06T09:03:50.674Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 1,
|
||||
"Title": "Comp_WormholePortal.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_WormholePortal\\Comp_WormholePortal.cs",
|
||||
"RelativeDocumentMoniker": "Building_Comps\\ARA_WormholePortal\\Comp_WormholePortal.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_WormholePortal\\Comp_WormholePortal.cs",
|
||||
"RelativeToolTip": "Building_Comps\\ARA_WormholePortal\\Comp_WormholePortal.cs",
|
||||
"ViewState": "AgIAABQBAAAAAAAAAAAowCcBAAAJAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2026-02-06T09:01:19.98Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 3,
|
||||
"Title": "UniquePawnManager.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\UniquePawnManager.cs",
|
||||
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\UniquePawnManager.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\UniquePawnManager.cs",
|
||||
"RelativeToolTip": "Pawn_Comps\\ARA_UniquePawn\\UniquePawnManager.cs",
|
||||
"ViewState": "AgIAAIYAAAAAAAAAAAAUwJ4AAAANAAAAAAAAAA==",
|
||||
"ViewState": "AgIAAHQAAAAAAAAAAAAiwJEAAAAJAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2026-02-05T03:36:35.207Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 1,
|
||||
"DocumentIndex": 4,
|
||||
"Title": "CompUniquePawn.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs",
|
||||
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs",
|
||||
@@ -131,12 +182,11 @@
|
||||
"RelativeToolTip": "Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs",
|
||||
"ViewState": "AgIAAKgAAAAAAAAAAAAtwLkAAAARAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2026-02-05T03:36:24.458Z",
|
||||
"EditorCaption": ""
|
||||
"WhenOpened": "2026-02-05T03:36:24.458Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 3,
|
||||
"DocumentIndex": 6,
|
||||
"Title": "JobDriver_ExtractHoney.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_ExtractHoney\\JobDriver_ExtractHoney.cs",
|
||||
"RelativeDocumentMoniker": "Jobs\\JobDriver_ExtractHoney\\JobDriver_ExtractHoney.cs",
|
||||
@@ -144,12 +194,11 @@
|
||||
"RelativeToolTip": "Jobs\\JobDriver_ExtractHoney\\JobDriver_ExtractHoney.cs",
|
||||
"ViewState": "AgIAAAQAAAAAAAAAAAAswBMAAAAJAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2026-02-05T03:32:58.466Z",
|
||||
"EditorCaption": ""
|
||||
"WhenOpened": "2026-02-05T03:32:58.466Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 2,
|
||||
"DocumentIndex": 5,
|
||||
"Title": "Need_HoneyProduction.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Needs\\Need_HoneyProduction.cs",
|
||||
"RelativeDocumentMoniker": "Needs\\Need_HoneyProduction.cs",
|
||||
@@ -157,12 +206,11 @@
|
||||
"RelativeToolTip": "Needs\\Need_HoneyProduction.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAoAAAAIAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2026-02-05T03:21:22.655Z",
|
||||
"EditorCaption": ""
|
||||
"WhenOpened": "2026-02-05T03:21:22.655Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 4,
|
||||
"DocumentIndex": 7,
|
||||
"Title": "Need_ChitinArmor.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Needs\\Need_ChitinArmor.cs",
|
||||
"RelativeDocumentMoniker": "Needs\\Need_ChitinArmor.cs",
|
||||
@@ -170,12 +218,11 @@
|
||||
"RelativeToolTip": "Needs\\Need_ChitinArmor.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2026-02-05T03:21:22.016Z",
|
||||
"EditorCaption": ""
|
||||
"WhenOpened": "2026-02-05T03:21:22.016Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 6,
|
||||
"DocumentIndex": 9,
|
||||
"Title": "CompProperties_AbilityPsychicLoadDump.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicLoadDump\\CompProperties_AbilityPsychicLoadDump.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\ARA_PsychicLoadDump\\CompProperties_AbilityPsychicLoadDump.cs",
|
||||
@@ -187,7 +234,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 5,
|
||||
"DocumentIndex": 8,
|
||||
"Title": "CompAbilityEffect_PsychicLoadDump.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicLoadDump\\CompAbilityEffect_PsychicLoadDump.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\ARA_PsychicLoadDump\\CompAbilityEffect_PsychicLoadDump.cs",
|
||||
@@ -195,12 +242,11 @@
|
||||
"RelativeToolTip": "Abilities\\ARA_PsychicLoadDump\\CompAbilityEffect_PsychicLoadDump.cs",
|
||||
"ViewState": "AgIAAAgAAAAAAAAAAAAowBIAAAASAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2026-02-04T08:36:23.647Z",
|
||||
"EditorCaption": ""
|
||||
"WhenOpened": "2026-02-04T08:36:23.647Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 10,
|
||||
"DocumentIndex": 13,
|
||||
"Title": "CompAbilityEffect_PsychicResearchHarvest.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicResearchHarvest\\CompAbilityEffect_PsychicResearchHarvest.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\ARA_PsychicResearchHarvest\\CompAbilityEffect_PsychicResearchHarvest.cs",
|
||||
@@ -212,7 +258,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 14,
|
||||
"DocumentIndex": 17,
|
||||
"Title": "CompProperties_AbilityPsychicLoadCost.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicLoadCost\\CompProperties_AbilityPsychicLoadCost.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\ARA_PsychicLoadCost\\CompProperties_AbilityPsychicLoadCost.cs",
|
||||
@@ -224,7 +270,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 13,
|
||||
"DocumentIndex": 16,
|
||||
"Title": "SwarmSpellUtility.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_SwarmSpellHolder\\SwarmSpellUtility.cs",
|
||||
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_SwarmSpellHolder\\SwarmSpellUtility.cs",
|
||||
@@ -236,7 +282,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 9,
|
||||
"DocumentIndex": 12,
|
||||
"Title": "CompAbilityEffect_PsychicLoadCost.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicLoadCost\\CompAbilityEffect_PsychicLoadCost.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\ARA_PsychicLoadCost\\CompAbilityEffect_PsychicLoadCost.cs",
|
||||
@@ -248,7 +294,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 7,
|
||||
"DocumentIndex": 10,
|
||||
"Title": "Comp_SwarmSpellHolder.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_SwarmSpellHolder\\Comp_SwarmSpellHolder.cs",
|
||||
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_SwarmSpellHolder\\Comp_SwarmSpellHolder.cs",
|
||||
@@ -260,7 +306,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 8,
|
||||
"DocumentIndex": 11,
|
||||
"Title": "Gizmo_SwarmSpellStatus.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_SwarmSpellHolder\\Gizmo_SwarmSpellStatus.cs",
|
||||
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_SwarmSpellHolder\\Gizmo_SwarmSpellStatus.cs",
|
||||
@@ -272,7 +318,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 15,
|
||||
"DocumentIndex": 18,
|
||||
"Title": "CompAbilityEffect_HediffGacha.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HediffGacha\\CompAbilityEffect_HediffGacha.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\ARA_HediffGacha\\CompAbilityEffect_HediffGacha.cs",
|
||||
@@ -284,7 +330,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 12,
|
||||
"DocumentIndex": 15,
|
||||
"Title": "CompFighterInvisible.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_Fighter_Invisible\\CompFighterInvisible.cs",
|
||||
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_Fighter_Invisible\\CompFighterInvisible.cs",
|
||||
@@ -296,7 +342,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 11,
|
||||
"DocumentIndex": 14,
|
||||
"Title": "CompProperties_AbilityPsychicResearchHarvest.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_PsychicResearchHarvest\\CompProperties_AbilityPsychicResearchHarvest.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\ARA_PsychicResearchHarvest\\CompProperties_AbilityPsychicResearchHarvest.cs",
|
||||
@@ -308,7 +354,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 16,
|
||||
"DocumentIndex": 19,
|
||||
"Title": "CompAbilityEffect_HediffRestriction.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HediffRestriction\\CompAbilityEffect_HediffRestriction.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\ARA_HediffRestriction\\CompAbilityEffect_HediffRestriction.cs",
|
||||
@@ -320,7 +366,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 17,
|
||||
"DocumentIndex": 20,
|
||||
"Title": "Window_HediffSelection.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_HediffGacha\\Window_HediffSelection.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\ARA_HediffGacha\\Window_HediffSelection.cs",
|
||||
@@ -332,7 +378,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 18,
|
||||
"DocumentIndex": 21,
|
||||
"Title": "ARA_PowerArmor.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PowerArmor\\ARA_PowerArmor.cs",
|
||||
"RelativeDocumentMoniker": "PowerArmor\\ARA_PowerArmor.cs",
|
||||
@@ -344,7 +390,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 19,
|
||||
"DocumentIndex": 22,
|
||||
"Title": "PawnCapacityWorker_PsychicStange.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PawnCapacityWorker\\PawnCapacityWorker_PsychicStange.cs",
|
||||
"RelativeDocumentMoniker": "PawnCapacityWorker\\PawnCapacityWorker_PsychicStange.cs",
|
||||
@@ -356,7 +402,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 21,
|
||||
"DocumentIndex": 24,
|
||||
"Title": "CompAbilityEffect_PsychicBrainburn.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\PsychicBrainburn\\CompAbilityEffect_PsychicBrainburn.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\PsychicBrainburn\\CompAbilityEffect_PsychicBrainburn.cs",
|
||||
@@ -368,7 +414,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 20,
|
||||
"DocumentIndex": 23,
|
||||
"Title": "ARA_DefOf.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_DefOf.cs",
|
||||
"RelativeDocumentMoniker": "ARA_DefOf.cs",
|
||||
@@ -380,7 +426,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 22,
|
||||
"DocumentIndex": 25,
|
||||
"Title": "CompAutoMechCarrier.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_AutoMechCarrier\\CompAutoMechCarrier.cs",
|
||||
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_AutoMechCarrier\\CompAutoMechCarrier.cs",
|
||||
|
||||
@@ -42,9 +42,13 @@
|
||||
<Compile Include="Abilities\ARA_PsychicLoadDump\CompProperties_AbilityPsychicLoadDump.cs" />
|
||||
<Compile Include="Abilities\ARA_PsychicResearchHarvest\CompAbilityEffect_PsychicResearchHarvest.cs" />
|
||||
<Compile Include="Abilities\ARA_PsychicResearchHarvest\CompProperties_AbilityPsychicResearchHarvest.cs" />
|
||||
<Compile Include="Buildings\BuildingGroundSpawner_WormholePortal.cs" />
|
||||
<Compile Include="Buildings\Building_CorpseVat\Building_CorpseVat.cs" />
|
||||
<Compile Include="Buildings\Building_CorpseVat\CorpseVatExtension.cs" />
|
||||
<Compile Include="Buildings\Building_CorpseVat\JobDriver_HaulCorpseToVat.cs" />
|
||||
<Compile Include="Building_Comps\ARA_WormholePortal\CompProperties_WormholePortal.cs" />
|
||||
<Compile Include="Building_Comps\ARA_WormholePortal\Comp_WormholePortal.cs" />
|
||||
<Compile Include="Building_Comps\ARA_WormholePortal\WormholePortalSpawnerExtension.cs" />
|
||||
<Compile Include="Damage\DamageDefExtension_TerrainCover.cs" />
|
||||
<Compile Include="Damage\DamageWorker_ExplosionWithTerrain.cs" />
|
||||
<Compile Include="Hediffs\ARA_GestaltNode\CompGestalt.cs" />
|
||||
@@ -339,6 +343,7 @@
|
||||
<Compile Include="Needs\Need_ChitinArmor.cs" />
|
||||
<Compile Include="Needs\Need_HoneyProduction.cs" />
|
||||
<Compile Include="PawnCapacityWorker\PawnCapacityWorker_PsychicStange.cs" />
|
||||
<Compile Include="PawnsArrivalMode\PawnsArrivalModeWorker_WormholePortal.cs" />
|
||||
<Compile Include="Pawn_Comps\ARA_AutoMechCarrier\CompAutoMechCarrier.cs" />
|
||||
<Compile Include="Pawn_Comps\ARA_AutoMechCarrier\CompProducedByMechCarrier.cs" />
|
||||
<Compile Include="Pawn_Comps\ARA_AutoMechCarrier\CompProperties_AutoMechCarrier.cs" />
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
using RimWorld;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
/// <summary>
|
||||
/// 虫洞传送门组件属性
|
||||
/// </summary>
|
||||
public class CompProperties_WormholePortal : CompProperties
|
||||
{
|
||||
#region 时间设置
|
||||
/// <summary>
|
||||
/// 初始延迟(ticks)
|
||||
/// </summary>
|
||||
public int initialDelayTicks = 60; // 1秒
|
||||
|
||||
/// <summary>
|
||||
/// 单位跳出间隔(ticks)
|
||||
/// </summary>
|
||||
public int jumpIntervalTicks = 30; // 0.5秒
|
||||
|
||||
/// <summary>
|
||||
/// 单位跳出时的眩晕时间(ticks)
|
||||
/// </summary>
|
||||
public int stunDurationTicks = 60; // 1秒
|
||||
|
||||
#endregion
|
||||
|
||||
#region 效果设置
|
||||
/// <summary>
|
||||
/// 激活音效
|
||||
/// </summary>
|
||||
public SoundDef activationSound = null;
|
||||
|
||||
/// <summary>
|
||||
/// 停用音效
|
||||
/// </summary>
|
||||
public SoundDef deactivationSound = null;
|
||||
|
||||
/// <summary>
|
||||
/// 跳出音效
|
||||
/// </summary>
|
||||
public SoundDef jumpSound = null;
|
||||
|
||||
/// <summary>
|
||||
/// 激活效果器
|
||||
/// </summary>
|
||||
public EffecterDef activationEffecter = null;
|
||||
|
||||
/// <summary>
|
||||
/// 停用效果器
|
||||
/// </summary>
|
||||
public EffecterDef deactivationEffecter = null;
|
||||
|
||||
/// <summary>
|
||||
/// 每次跳出效果器
|
||||
/// </summary>
|
||||
public EffecterDef perJumpEffecter = null;
|
||||
|
||||
/// <summary>
|
||||
/// 单位跳出效果器
|
||||
/// </summary>
|
||||
public EffecterDef jumpEffecter = null;
|
||||
#endregion
|
||||
|
||||
#region 外观设置
|
||||
/// <summary>
|
||||
/// 活跃时的材质
|
||||
/// </summary>
|
||||
public GraphicData activeGraphicData = null;
|
||||
|
||||
/// <summary>
|
||||
/// 颜色循环
|
||||
/// </summary>
|
||||
public bool useColorCycling = true;
|
||||
|
||||
/// <summary>
|
||||
/// 颜色循环速度
|
||||
/// </summary>
|
||||
public float colorCycleSpeed = 0.5f;
|
||||
#endregion
|
||||
|
||||
#region 构造函数
|
||||
public CompProperties_WormholePortal()
|
||||
{
|
||||
compClass = typeof(Comp_WormholePortal);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Verse;
|
||||
using Verse.Sound;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
/// <summary>
|
||||
/// 虫洞传送门组件
|
||||
/// 处理从虫洞中跳出单位
|
||||
/// </summary>
|
||||
public class Comp_WormholePortal : ThingComp
|
||||
{
|
||||
#region 字段
|
||||
private List<Pawn> emergingPawns = new List<Pawn>();
|
||||
private int currentPawnIndex = 0;
|
||||
private int ticksUntilNextJump = 0;
|
||||
private bool isActive = false;
|
||||
private int activateTick = -1;
|
||||
#endregion
|
||||
|
||||
#region 属性
|
||||
public CompProperties_WormholePortal Props => (CompProperties_WormholePortal)props;
|
||||
|
||||
/// <summary>
|
||||
/// 还有多少单位等待跳出
|
||||
/// </summary>
|
||||
public int RemainingPawns => emergingPawns.Count - currentPawnIndex;
|
||||
|
||||
/// <summary>
|
||||
/// 虫洞是否活跃
|
||||
/// </summary>
|
||||
public bool IsActive => isActive;
|
||||
|
||||
/// <summary>
|
||||
/// 激活后经过的时间
|
||||
/// </summary>
|
||||
public int TicksSinceActivation
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!isActive || activateTick < 0)
|
||||
return 0;
|
||||
return Find.TickManager.TicksGame - activateTick;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 生命周期
|
||||
public override void PostSpawnSetup(bool respawningAfterLoad)
|
||||
{
|
||||
base.PostSpawnSetup(respawningAfterLoad);
|
||||
|
||||
if (respawningAfterLoad)
|
||||
return;
|
||||
|
||||
// 非加载生成时,准备激活
|
||||
PrepareForActivation();
|
||||
}
|
||||
|
||||
public override void CompTick()
|
||||
{
|
||||
base.CompTick();
|
||||
|
||||
if (!isActive || emergingPawns.NullOrEmpty() || currentPawnIndex >= emergingPawns.Count)
|
||||
return;
|
||||
|
||||
// 计时下一个单位跳出
|
||||
if (ticksUntilNextJump > 0)
|
||||
{
|
||||
ticksUntilNextJump--;
|
||||
return;
|
||||
}
|
||||
|
||||
// 跳出当前单位
|
||||
JumpNextPawn();
|
||||
|
||||
// 设置下一个单位的跳出间隔
|
||||
if (currentPawnIndex < emergingPawns.Count)
|
||||
{
|
||||
ticksUntilNextJump = Props.jumpIntervalTicks;
|
||||
}
|
||||
}
|
||||
|
||||
public void PostDeSpawn(Map map)
|
||||
{
|
||||
// 虫洞消失时,销毁剩余未跳出的单位
|
||||
DestroyRemainingPawns();
|
||||
}
|
||||
|
||||
public override void PostDestroy(DestroyMode mode, Map previousMap)
|
||||
{
|
||||
base.PostDestroy(mode, previousMap);
|
||||
|
||||
// 虫洞被摧毁时,销毁剩余未跳出的单位
|
||||
DestroyRemainingPawns();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 公共方法
|
||||
/// <summary>
|
||||
/// 设置要跳出的单位
|
||||
/// </summary>
|
||||
public void SetEmergingPawns(List<Pawn> pawns)
|
||||
{
|
||||
emergingPawns = pawns ?? new List<Pawn>();
|
||||
currentPawnIndex = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激活虫洞
|
||||
/// </summary>
|
||||
public void Activate()
|
||||
{
|
||||
if (isActive)
|
||||
return;
|
||||
|
||||
isActive = true;
|
||||
activateTick = Find.TickManager.TicksGame;
|
||||
|
||||
// 设置第一个单位的跳出计时
|
||||
if (emergingPawns.Count > 0)
|
||||
{
|
||||
ticksUntilNextJump = Props.initialDelayTicks;
|
||||
}
|
||||
|
||||
// 播放激活效果
|
||||
PlayActivationEffects();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取虫洞状态描述
|
||||
/// </summary>
|
||||
public string GetStatusDescription()
|
||||
{
|
||||
if (!isActive)
|
||||
return "休眠中";
|
||||
|
||||
if (RemainingPawns <= 0)
|
||||
return "已完成";
|
||||
|
||||
return $"跳出中: {RemainingPawns} 个单位剩余";
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 私有方法
|
||||
/// <summary>
|
||||
/// 准备激活
|
||||
/// </summary>
|
||||
private void PrepareForActivation()
|
||||
{
|
||||
// 可以在这里添加预热效果
|
||||
// 例如:粒子效果、声音等
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 跳出下一个单位
|
||||
/// </summary>
|
||||
private void JumpNextPawn()
|
||||
{
|
||||
if (currentPawnIndex >= emergingPawns.Count)
|
||||
return;
|
||||
|
||||
Pawn pawn = emergingPawns[currentPawnIndex];
|
||||
currentPawnIndex++;
|
||||
|
||||
// 确保单位存在且有效
|
||||
if (pawn == null || pawn.Destroyed)
|
||||
{
|
||||
Log.Warning("[虫洞传送门] 尝试跳出无效单位");
|
||||
return;
|
||||
}
|
||||
|
||||
// 生成单位
|
||||
TrySpawnPawn(pawn);
|
||||
|
||||
// 播放跳出效果
|
||||
PlayJumpEffects();
|
||||
|
||||
// 如果所有单位都已跳出,关闭虫洞
|
||||
if (currentPawnIndex >= emergingPawns.Count)
|
||||
{
|
||||
StartDeactivation();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试生成单位
|
||||
/// </summary>
|
||||
private void TrySpawnPawn(Pawn pawn)
|
||||
{
|
||||
try
|
||||
{
|
||||
Map map = parent.Map;
|
||||
if (map == null)
|
||||
return;
|
||||
|
||||
// 找到虫洞周围的可行走位置
|
||||
if (CellFinder.TryFindRandomCellNear(parent.Position, map, 2,
|
||||
c => c.Walkable(map) && c.InBounds(map) && !c.Fogged(map), out IntVec3 spawnCell))
|
||||
{
|
||||
// 生成单位
|
||||
GenSpawn.Spawn(pawn, spawnCell, map);
|
||||
|
||||
// 应用跳出效果
|
||||
ApplyJumpEffectsToPawn(pawn, spawnCell);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果找不到位置,在虫洞位置生成
|
||||
GenSpawn.Spawn(pawn, parent.Position, map);
|
||||
Log.Warning($"[虫洞传送门] 无法找到合适位置,在虫洞位置生成 {pawn.Label}");
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Log.Error($"[虫洞传送门] 跳出单位失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 应用跳出效果给单位
|
||||
/// </summary>
|
||||
private void ApplyJumpEffectsToPawn(Pawn pawn, IntVec3 spawnCell)
|
||||
{
|
||||
// 短暂眩晕效果
|
||||
if (Props.stunDurationTicks > 0)
|
||||
{
|
||||
pawn.stances.stunner.StunFor(Props.stunDurationTicks, parent);
|
||||
}
|
||||
|
||||
// 播放音效
|
||||
if (Props.jumpSound != null)
|
||||
{
|
||||
Props.jumpSound.PlayOneShot(new TargetInfo(spawnCell, parent.Map));
|
||||
}
|
||||
|
||||
// 显示效果
|
||||
if (Props.jumpEffecter != null)
|
||||
{
|
||||
Effecter effecter = Props.jumpEffecter.Spawn();
|
||||
effecter.Trigger(new TargetInfo(spawnCell, parent.Map), new TargetInfo(spawnCell, parent.Map));
|
||||
effecter.Cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 播放激活效果
|
||||
/// </summary>
|
||||
private void PlayActivationEffects()
|
||||
{
|
||||
if (Props.activationSound != null)
|
||||
{
|
||||
Props.activationSound.PlayOneShot(new TargetInfo(parent.Position, parent.Map));
|
||||
}
|
||||
|
||||
if (Props.activationEffecter != null)
|
||||
{
|
||||
Effecter effecter = Props.activationEffecter.Spawn();
|
||||
effecter.Trigger(new TargetInfo(parent.Position, parent.Map), new TargetInfo(parent.Position, parent.Map));
|
||||
effecter.Cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 播放跳出效果
|
||||
/// </summary>
|
||||
private void PlayJumpEffects()
|
||||
{
|
||||
if (Props.perJumpEffecter != null)
|
||||
{
|
||||
Effecter effecter = Props.perJumpEffecter.Spawn();
|
||||
effecter.Trigger(new TargetInfo(parent.Position, parent.Map), new TargetInfo(parent.Position, parent.Map));
|
||||
effecter.Cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始停用虫洞
|
||||
/// </summary>
|
||||
private void StartDeactivation()
|
||||
{
|
||||
// 播放停用效果
|
||||
if (Props.deactivationSound != null)
|
||||
{
|
||||
Props.deactivationSound.PlayOneShot(new TargetInfo(parent.Position, parent.Map));
|
||||
}
|
||||
|
||||
if (Props.deactivationEffecter != null)
|
||||
{
|
||||
Effecter effecter = Props.deactivationEffecter.Spawn();
|
||||
effecter.Trigger(new TargetInfo(parent.Position, parent.Map), new TargetInfo(parent.Position, parent.Map));
|
||||
effecter.Cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁剩余未跳出的单位
|
||||
/// </summary>
|
||||
private void DestroyRemainingPawns()
|
||||
{
|
||||
if (emergingPawns.NullOrEmpty())
|
||||
return;
|
||||
|
||||
for (int i = currentPawnIndex; i < emergingPawns.Count; i++)
|
||||
{
|
||||
Pawn pawn = emergingPawns[i];
|
||||
if (pawn != null && !pawn.Destroyed)
|
||||
{
|
||||
pawn.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 序列化
|
||||
public override void PostExposeData()
|
||||
{
|
||||
base.PostExposeData();
|
||||
|
||||
Scribe_Collections.Look(ref emergingPawns, "emergingPawns", LookMode.Reference);
|
||||
Scribe_Values.Look(ref currentPawnIndex, "currentPawnIndex", 0);
|
||||
Scribe_Values.Look(ref ticksUntilNextJump, "ticksUntilNextJump", 0);
|
||||
Scribe_Values.Look(ref isActive, "isActive", false);
|
||||
Scribe_Values.Look(ref activateTick, "activateTick", -1);
|
||||
|
||||
if (Scribe.mode == LoadSaveMode.PostLoadInit)
|
||||
{
|
||||
// 清理空引用
|
||||
emergingPawns?.RemoveAll(p => p == null);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
/// <summary>
|
||||
/// 虫洞传送门生成器扩展
|
||||
/// </summary>
|
||||
public class WormholePortalSpawnerExtension : DefModExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 最小跳出延迟(ticks)
|
||||
/// </summary>
|
||||
public int minEmergeDelayTicks = 180; // 3秒
|
||||
|
||||
/// <summary>
|
||||
/// 最大跳出延迟(ticks)
|
||||
/// </summary>
|
||||
public int maxEmergeDelayTicks = 300; // 5秒
|
||||
|
||||
/// <summary>
|
||||
/// 是否需要露天
|
||||
/// </summary>
|
||||
public bool requiresOpenSky = true;
|
||||
|
||||
/// <summary>
|
||||
/// 最小空间半径
|
||||
/// </summary>
|
||||
public int minSpaceRadius = 3;
|
||||
|
||||
/// <summary>
|
||||
/// 是否破坏地形
|
||||
/// </summary>
|
||||
public bool destroyTerrain = true;
|
||||
|
||||
/// <summary>
|
||||
/// 是否破坏建筑
|
||||
/// </summary>
|
||||
public bool destroyBuildings = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
/// <summary>
|
||||
/// 自定义虫洞传送门生成器
|
||||
/// </summary>
|
||||
public class BuildingGroundSpawner_WormholePortal : BuildingGroundSpawner
|
||||
{
|
||||
// 存储要传递的Pawn列表
|
||||
public List<Pawn> emergingPawns = new List<Pawn>();
|
||||
|
||||
// 延迟参数
|
||||
public IntRange? customEmergeDelay = null;
|
||||
|
||||
protected override void PostMakeInt()
|
||||
{
|
||||
base.PostMakeInt();
|
||||
|
||||
// 创建虫洞传送门
|
||||
ThingDef portalDef = DefDatabase<ThingDef>.GetNamed("ARA_WormholePortal");
|
||||
if (portalDef != null)
|
||||
{
|
||||
thingToSpawn = ThingMaker.MakeThing(portalDef);
|
||||
|
||||
// 设置Pawn列表
|
||||
Comp_WormholePortal comp = thingToSpawn.TryGetComp<Comp_WormholePortal>();
|
||||
if (comp != null && emergingPawns != null)
|
||||
{
|
||||
comp.SetEmergingPawns(emergingPawns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override IntRange ResultSpawnDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
if (customEmergeDelay.HasValue)
|
||||
return customEmergeDelay.Value;
|
||||
return base.ResultSpawnDelay;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ExposeData()
|
||||
{
|
||||
base.ExposeData();
|
||||
Scribe_Collections.Look(ref emergingPawns, "emergingPawns", LookMode.Reference);
|
||||
Scribe_Values.Look(ref customEmergeDelay, "customEmergeDelay");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,387 @@
|
||||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
/// <summary>
|
||||
/// 虫洞传送门到达模式
|
||||
/// 在地图边缘生成虫洞传送门生成器,预热后生成虫洞传送门,单位从虫洞中跳出
|
||||
/// </summary>
|
||||
public class PawnsArrivalModeWorker_WormholePortal : PawnsArrivalModeWorker
|
||||
{
|
||||
#region 常量
|
||||
private const float MIN_EDGE_DISTANCE = 5f; // 最小边缘距离
|
||||
private const float MAX_EDGE_DISTANCE = 20f; // 最大边缘距离
|
||||
private const int MIN_SPACE_RADIUS = 3; // 需要的最小空间半径
|
||||
private const int MAX_SPAWNERS_PER_GROUP = 3; // 每组最大生成器数量
|
||||
private const int DEFAULT_EMERGE_DELAY_TICKS = 60; // 默认跳出延迟(1秒)
|
||||
#endregion
|
||||
|
||||
#region 公共方法
|
||||
/// <summary>
|
||||
/// 单位到达
|
||||
/// </summary>
|
||||
public override void Arrive(List<Pawn> pawns, IncidentParms parms)
|
||||
{
|
||||
Map map = parms.target as Map;
|
||||
if (map == null || pawns.NullOrEmpty())
|
||||
return;
|
||||
|
||||
if (!TryResolveRaidSpawnCenter(parms))
|
||||
return;
|
||||
|
||||
// 将Pawn分组,每组由一个传送门生成器处理
|
||||
List<List<Pawn>> pawnGroups = SplitPawnsIntoGroups(pawns, parms);
|
||||
|
||||
// 为每组生成一个虫洞传送门生成器
|
||||
int spawnedCount = 0;
|
||||
foreach (var group in pawnGroups)
|
||||
{
|
||||
if (TrySpawnWormholePortalGroup(group, parms))
|
||||
{
|
||||
spawnedCount++;
|
||||
}
|
||||
|
||||
// 限制每组数量
|
||||
if (spawnedCount >= MAX_SPAWNERS_PER_GROUP)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 旅行运输器到达
|
||||
/// </summary>
|
||||
public override void TravellingTransportersArrived(List<ActiveTransporterInfo> transporters, Map map)
|
||||
{
|
||||
// 虫洞传送门不支持运输器到达
|
||||
Log.Warning("[虫洞传送门] 不支持运输器到达模式");
|
||||
base.TravellingTransportersArrived(transporters, map);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试解析袭击生成中心
|
||||
/// </summary>
|
||||
public override bool TryResolveRaidSpawnCenter(IncidentParms parms)
|
||||
{
|
||||
Map map = parms.target as Map;
|
||||
if (map == null)
|
||||
return false;
|
||||
|
||||
// 如果没有指定生成中心,找到地图边缘的位置
|
||||
if (!parms.spawnCenter.IsValid)
|
||||
{
|
||||
if (!TryFindEdgeSpawnCenter(map, out IntVec3 spawnCenter))
|
||||
{
|
||||
// 如果找不到边缘位置,使用默认的掉落中心
|
||||
spawnCenter = DropCellFinder.FindRaidDropCenterDistant(map);
|
||||
}
|
||||
parms.spawnCenter = spawnCenter;
|
||||
}
|
||||
|
||||
parms.spawnRotation = Rot4.Random;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否可以在指定地图使用
|
||||
/// </summary>
|
||||
public override bool CanUseOnMap(Map map)
|
||||
{
|
||||
// 检查地图是否允许此到达模式
|
||||
if (map == null)
|
||||
return false;
|
||||
|
||||
// 检查是否有足够的空间生成虫洞
|
||||
return HasEnoughSpaceForWormhole(map);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 私有方法
|
||||
/// <summary>
|
||||
/// 将Pawn分成组
|
||||
/// </summary>
|
||||
private List<List<Pawn>> SplitPawnsIntoGroups(List<Pawn> pawns, IncidentParms parms)
|
||||
{
|
||||
List<List<Pawn>> groups = new List<List<Pawn>>();
|
||||
|
||||
if (pawns.NullOrEmpty())
|
||||
return groups;
|
||||
|
||||
// 根据点数计算每组大小
|
||||
int groupSize = CalculateGroupSize(parms);
|
||||
|
||||
// 如果组大小为1或更小,每个Pawn单独一组
|
||||
if (groupSize <= 1)
|
||||
{
|
||||
foreach (var pawn in pawns)
|
||||
{
|
||||
groups.Add(new List<Pawn> { pawn });
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
|
||||
// 分组
|
||||
List<Pawn> currentGroup = new List<Pawn>();
|
||||
foreach (var pawn in pawns)
|
||||
{
|
||||
currentGroup.Add(pawn);
|
||||
|
||||
if (currentGroup.Count >= groupSize)
|
||||
{
|
||||
groups.Add(currentGroup);
|
||||
currentGroup = new List<Pawn>();
|
||||
}
|
||||
}
|
||||
|
||||
// 添加剩余的Pawn
|
||||
if (currentGroup.Count > 0)
|
||||
{
|
||||
groups.Add(currentGroup);
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算每组大小
|
||||
/// </summary>
|
||||
private int CalculateGroupSize(IncidentParms parms)
|
||||
{
|
||||
// 根据点数动态调整组大小
|
||||
float points = parms.points;
|
||||
|
||||
if (points <= 500f)
|
||||
return 1;
|
||||
else if (points <= 1000f)
|
||||
return 2;
|
||||
else if (points <= 2000f)
|
||||
return 3;
|
||||
else
|
||||
return 4;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试生成虫洞传送门组
|
||||
/// </summary>
|
||||
private bool TrySpawnWormholePortalGroup(List<Pawn> pawns, IncidentParms parms)
|
||||
{
|
||||
Map map = parms.target as Map;
|
||||
if (map == null || pawns.NullOrEmpty())
|
||||
return false;
|
||||
|
||||
// 找到合适的生成位置(靠近边缘,有足够空间)
|
||||
if (!TryFindWormholeSpawnPosition(map, out IntVec3 spawnPosition))
|
||||
return false;
|
||||
|
||||
// 创建虫洞传送门生成器
|
||||
return SpawnWormholePortalSpawner(map, spawnPosition, pawns, parms);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试找到虫洞生成位置
|
||||
/// </summary>
|
||||
private bool TryFindWormholeSpawnPosition(Map map, out IntVec3 spawnPosition)
|
||||
{
|
||||
spawnPosition = IntVec3.Invalid;
|
||||
|
||||
// 尝试在地图边缘区域查找
|
||||
// 使用CellRect.WholeMap而不是CellsInMapRandomOrder
|
||||
CellRect mapRect = CellRect.WholeMap(map);
|
||||
|
||||
// 定义边缘区域(地图边界向内一定距离)
|
||||
int edgeWidth = 5;
|
||||
CellRect edgeRect = new CellRect(
|
||||
edgeWidth,
|
||||
edgeWidth,
|
||||
map.Size.x - edgeWidth * 2,
|
||||
map.Size.z - edgeWidth * 2);
|
||||
|
||||
// 在地图边界但不是边缘区域内部查找
|
||||
for (int attempts = 0; attempts < 30; attempts++)
|
||||
{
|
||||
IntVec3 candidate;
|
||||
|
||||
// 随机选择边界
|
||||
if (Rand.Value < 0.25f) // 北边界
|
||||
{
|
||||
candidate = new IntVec3(Rand.Range(0, map.Size.x), 0, map.Size.z - 1);
|
||||
}
|
||||
else if (Rand.Value < 0.5f) // 南边界
|
||||
{
|
||||
candidate = new IntVec3(Rand.Range(0, map.Size.x), 0, 0);
|
||||
}
|
||||
else if (Rand.Value < 0.75f) // 东边界
|
||||
{
|
||||
candidate = new IntVec3(map.Size.x - 1, 0, Rand.Range(0, map.Size.z));
|
||||
}
|
||||
else // 西边界
|
||||
{
|
||||
candidate = new IntVec3(0, 0, Rand.Range(0, map.Size.z));
|
||||
}
|
||||
|
||||
// 检查位置是否有效
|
||||
if (IsValidWormholePosition(candidate, map))
|
||||
{
|
||||
spawnPosition = candidate;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果找不到边界位置,尝试在地图任意位置查找
|
||||
for (int attempts = 0; attempts < 20; attempts++)
|
||||
{
|
||||
IntVec3 candidate = CellFinder.RandomCell(map);
|
||||
if (IsValidWormholePosition(candidate, map))
|
||||
{
|
||||
spawnPosition = candidate;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否为有效的虫洞位置
|
||||
/// </summary>
|
||||
private bool IsValidWormholePosition(IntVec3 position, Map map)
|
||||
{
|
||||
if (!position.InBounds(map))
|
||||
return false;
|
||||
|
||||
if (!position.Standable(map))
|
||||
return false;
|
||||
|
||||
if (position.Fogged(map))
|
||||
return false;
|
||||
|
||||
// 检查是否有足够的空间(3x3区域)
|
||||
CellRect requiredRect = new CellRect(position.x - 1, position.z - 1, 3, 3);
|
||||
|
||||
// 修复:检查矩形是否完全包含在地图内
|
||||
if (!requiredRect.InBounds(map))
|
||||
return false;
|
||||
|
||||
// 检查区域内所有单元格是否都可行走
|
||||
foreach (IntVec3 cell in requiredRect)
|
||||
{
|
||||
if (!cell.InBounds(map) || !cell.Walkable(map))
|
||||
return false;
|
||||
|
||||
// 检查是否有其他建筑阻挡
|
||||
if (cell.GetEdifice(map) != null)
|
||||
return false;
|
||||
|
||||
// 检查是否有屋顶(虫洞需要露天)
|
||||
if (cell.Roofed(map))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成虫洞传送门生成器
|
||||
/// </summary>
|
||||
private bool SpawnWormholePortalSpawner(Map map, IntVec3 position, List<Pawn> pawns, IncidentParms parms)
|
||||
{
|
||||
try
|
||||
{
|
||||
ThingDef spawnerDef = DefDatabase<ThingDef>.GetNamedSilentFail("ARA_WormholePortal_Spawner");
|
||||
if (spawnerDef == null)
|
||||
{
|
||||
Log.Error("[虫洞传送门] 未找到ARA_WormholePortal_Spawner定义");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 创建自定义生成器
|
||||
BuildingGroundSpawner_WormholePortal spawner = (BuildingGroundSpawner_WormholePortal)ThingMaker.MakeThing(spawnerDef);
|
||||
|
||||
// 设置参数
|
||||
spawner.emergingPawns = pawns;
|
||||
|
||||
// 设置延迟
|
||||
WormholePortalSpawnerExtension spawnerExt = spawnerDef.GetModExtension<WormholePortalSpawnerExtension>();
|
||||
if (spawnerExt != null)
|
||||
{
|
||||
spawner.customEmergeDelay = new IntRange(
|
||||
spawnerExt.minEmergeDelayTicks,
|
||||
spawnerExt.maxEmergeDelayTicks);
|
||||
}
|
||||
|
||||
// 生成到地图
|
||||
GenSpawn.Spawn(spawner, position, map);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Log.Error($"[虫洞传送门] 生成虫洞传送门生成器失败: {ex.Message}\n{ex.StackTrace}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试找到边缘生成中心
|
||||
/// </summary>
|
||||
private bool TryFindEdgeSpawnCenter(Map map, out IntVec3 spawnCenter)
|
||||
{
|
||||
spawnCenter = IntVec3.Invalid;
|
||||
|
||||
// 尝试在地图四个边缘区域查找
|
||||
List<IntVec3> edgeCells = new List<IntVec3>();
|
||||
|
||||
// 北边缘
|
||||
for (int x = 0; x < map.Size.x; x += 5)
|
||||
{
|
||||
IntVec3 cell = new IntVec3(x, 0, map.Size.z - 1);
|
||||
if (cell.InBounds(map) && cell.Walkable(map) && !cell.Fogged(map))
|
||||
edgeCells.Add(cell);
|
||||
}
|
||||
|
||||
// 南边缘
|
||||
for (int x = 0; x < map.Size.x; x += 5)
|
||||
{
|
||||
IntVec3 cell = new IntVec3(x, 0, 0);
|
||||
if (cell.InBounds(map) && cell.Walkable(map) && !cell.Fogged(map))
|
||||
edgeCells.Add(cell);
|
||||
}
|
||||
|
||||
// 东边缘
|
||||
for (int z = 0; z < map.Size.z; z += 5)
|
||||
{
|
||||
IntVec3 cell = new IntVec3(map.Size.x - 1, 0, z);
|
||||
if (cell.InBounds(map) && cell.Walkable(map) && !cell.Fogged(map))
|
||||
edgeCells.Add(cell);
|
||||
}
|
||||
|
||||
// 西边缘
|
||||
for (int z = 0; z < map.Size.z; z += 5)
|
||||
{
|
||||
IntVec3 cell = new IntVec3(0, 0, z);
|
||||
if (cell.InBounds(map) && cell.Walkable(map) && !cell.Fogged(map))
|
||||
edgeCells.Add(cell);
|
||||
}
|
||||
|
||||
if (edgeCells.Count > 0)
|
||||
{
|
||||
spawnCenter = edgeCells.RandomElement();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查地图是否有足够的空间生成虫洞
|
||||
/// </summary>
|
||||
private bool HasEnoughSpaceForWormhole(Map map)
|
||||
{
|
||||
// 简单检查:地图是否至少有一定大小
|
||||
return map.Size.x >= 50 && map.Size.z >= 50;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user