This commit is contained in:
2025-10-21 17:34:41 +08:00
parent a3ca5040e0
commit ef79645c19
19 changed files with 1319 additions and 92 deletions

View File

@@ -3,11 +3,63 @@
"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\\hediffs\\ara_drawmoteinrange\\hediffcomp_drawmoteinrange.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_arachnidgravengine.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_arachnidgravengine.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_incubatable.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_incubatable.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_spawnpawnfromlist\\compspawnpawnfromlist.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_spawnpawnfromlist\\compspawnpawnfromlist.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_spawnpawnfromlist\\compproperties_spawnpawnfromlist.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_spawnpawnfromlist\\compproperties_spawnpawnfromlist.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_showspawnablepawnslist\\compabilityeffect_abilityshowspawnablepawns.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_showspawnablepawnslist\\compabilityeffect_abilityshowspawnablepawns.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\\patch_uniquepawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_uniquepawn\\patch_uniquepawn.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\\pawn_comps\\ara_uniquepawn\\compproperties_uniquepawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_uniquepawn\\compproperties_uniquepawn.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_turretgunhasspeed.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_turretgunhasspeed.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\building_comps\\ara_building_refuelingvat\\building_refuelingvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_building_refuelingvat\\building_refuelingvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\building_comps\\ara_nutrientvat\\building_nutrientvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_nutrientvat\\building_nutrientvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\buildings\\building_catastrophemissilesilo\\building_catastrophemissilesilo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_catastrophemissilesilo\\building_catastrophemissilesilo.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_aranutrientdispenser\\building_aranutrientdispenser.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_aranutrientdispenser\\building_aranutrientdispenser.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_drawmoteinrange\\hediffcomp_drawmoteinrange.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_drawmoteinrange\\hediffcomp_drawmoteinrange.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_hivemind\\hediff_hivemindmaster.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_hivemind\\hediff_hivemindmaster.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_hivemind\\hediff_hivemindmaster.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
@@ -34,28 +86,189 @@
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 1,
"SelectedChildIndex": 0,
"Children": [
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "Building_ArachnidGravEngine.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ArachnidGravEngine.cs",
"RelativeDocumentMoniker": "Buildings\\Building_ArachnidGravEngine.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ArachnidGravEngine.cs",
"RelativeToolTip": "Buildings\\Building_ArachnidGravEngine.cs",
"ViewState": "AgIAAAMAAAAAAAAAAAAkwBUAAAAJAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T09:12:42.006Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "Building_Incubatable.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Incubatable.cs",
"RelativeDocumentMoniker": "Buildings\\Building_Incubatable.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Incubatable.cs",
"RelativeToolTip": "Buildings\\Building_Incubatable.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABAAAAARAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T08:39:15.745Z",
"EditorCaption": ""
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
},
{
"$type": "Document",
"DocumentIndex": 0,
"DocumentIndex": 2,
"Title": "CompSpawnPawnFromList.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SpawnPawnFromList\\CompSpawnPawnFromList.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_SpawnPawnFromList\\CompSpawnPawnFromList.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SpawnPawnFromList\\CompSpawnPawnFromList.cs",
"RelativeToolTip": "Building_Comps\\ARA_SpawnPawnFromList\\CompSpawnPawnFromList.cs",
"ViewState": "AgIAAAsAAAAAAAAAAAAIwBkAAAANAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T08:29:44.344Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "CompProperties_SpawnPawnFromList.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SpawnPawnFromList\\CompProperties_SpawnPawnFromList.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_SpawnPawnFromList\\CompProperties_SpawnPawnFromList.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SpawnPawnFromList\\CompProperties_SpawnPawnFromList.cs",
"RelativeToolTip": "Building_Comps\\ARA_SpawnPawnFromList\\CompProperties_SpawnPawnFromList.cs",
"ViewState": "AgIAAA8AAAAAAAAAAAAuwBoAAAAvAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T08:29:42.187Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 4,
"Title": "CompAbilityEffect_AbilityShowSpawnablePawns.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs",
"RelativeToolTip": "Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs",
"ViewState": "AgIAADgAAAAAAAAAAAAuwEwAAAA8AAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T08:29:37.669Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "Patch_UniquePawn.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\Patch_UniquePawn.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\Patch_UniquePawn.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\Patch_UniquePawn.cs",
"RelativeToolTip": "Pawn_Comps\\ARA_UniquePawn\\Patch_UniquePawn.cs",
"ViewState": "AgIAACUAAAAAAAAAAAAkwDEAAAAlAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T07:20:36.341Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 8,
"Title": "Building_TurretGunHasSpeed.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_TurretGunHasSpeed.cs",
"RelativeDocumentMoniker": "Buildings\\Building_TurretGunHasSpeed.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_TurretGunHasSpeed.cs",
"RelativeToolTip": "Buildings\\Building_TurretGunHasSpeed.cs",
"ViewState": "AgIAAL4CAAAAAAAAAAAAAL4CAABZAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T07:00:48.984Z"
},
{
"$type": "Document",
"DocumentIndex": 7,
"Title": "CompProperties_UniquePawn.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\CompProperties_UniquePawn.cs",
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\CompProperties_UniquePawn.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\CompProperties_UniquePawn.cs",
"RelativeToolTip": "Pawn_Comps\\ARA_UniquePawn\\CompProperties_UniquePawn.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T07:00:00.021Z"
},
{
"$type": "Document",
"DocumentIndex": 6,
"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",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs",
"RelativeToolTip": "Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs",
"ViewState": "AgIAADQAAAAAAAAAAAAkwEYAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T07:00:02.43Z"
},
{
"$type": "Document",
"DocumentIndex": 9,
"Title": "Building_RefuelingVat.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
"RelativeToolTip": "Building_Comps\\ARA_Building_RefuelingVat\\Building_RefuelingVat.cs",
"ViewState": "AgIAAPUAAAAAAAAAAAAAAPUAAAA2AAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T07:00:47.792Z"
},
{
"$type": "Document",
"DocumentIndex": 10,
"Title": "Building_NutrientVat.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_NutrientVat\\Building_NutrientVat.cs",
"RelativeDocumentMoniker": "Building_Comps\\ARA_NutrientVat\\Building_NutrientVat.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_NutrientVat\\Building_NutrientVat.cs",
"RelativeToolTip": "Building_Comps\\ARA_NutrientVat\\Building_NutrientVat.cs",
"ViewState": "AgIAAJUBAAAAAAAAAAAmwKgBAABmAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T07:00:43.042Z"
},
{
"$type": "Document",
"DocumentIndex": 11,
"Title": "Building_CatastropheMissileSilo.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CatastropheMissileSilo\\Building_CatastropheMissileSilo.cs",
"RelativeDocumentMoniker": "Buildings\\Building_CatastropheMissileSilo\\Building_CatastropheMissileSilo.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_CatastropheMissileSilo\\Building_CatastropheMissileSilo.cs",
"RelativeToolTip": "Buildings\\Building_CatastropheMissileSilo\\Building_CatastropheMissileSilo.cs",
"ViewState": "AgIAALAAAAAAAAAAAAAAAL8AAABMAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T07:00:24.191Z"
},
{
"$type": "Document",
"DocumentIndex": 12,
"Title": "Building_ARANutrientDispenser.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ARANutrientDispenser\\Building_ARANutrientDispenser.cs",
"RelativeDocumentMoniker": "Buildings\\Building_ARANutrientDispenser\\Building_ARANutrientDispenser.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ARANutrientDispenser\\Building_ARANutrientDispenser.cs",
"RelativeToolTip": "Buildings\\Building_ARANutrientDispenser\\Building_ARANutrientDispenser.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAgAAACMAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T07:00:20.274Z"
},
{
"$type": "Document",
"DocumentIndex": 13,
"Title": "HediffComp_DrawMoteInRange.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_DrawMoteInRange\\HediffComp_DrawMoteInRange.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_DrawMoteInRange\\HediffComp_DrawMoteInRange.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_DrawMoteInRange\\HediffComp_DrawMoteInRange.cs",
"RelativeToolTip": "Hediffs\\ARA_DrawMoteInRange\\HediffComp_DrawMoteInRange.cs",
"ViewState": "AgIAABUAAAAAAAAAAAAIwBcAAABHAAAAAAAAAA==",
"ViewState": "AgIAAAgAAAAAAAAAAADwvw4AAAAJAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-21T03:59:47.61Z",
"EditorCaption": ""
"WhenOpened": "2025-10-21T03:59:47.61Z"
},
{
"$type": "Document",
"DocumentIndex": 2,
"DocumentIndex": 15,
"Title": "Hediff_HiveMindDrone.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\Hediff_HiveMindDrone.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\Hediff_HiveMindDrone.cs",
@@ -67,7 +280,7 @@
},
{
"$type": "Document",
"DocumentIndex": 1,
"DocumentIndex": 14,
"Title": "Hediff_HiveMindMaster.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs",
@@ -75,12 +288,11 @@
"RelativeToolTip": "Hediffs\\ARA_HiveMind\\Hediff_HiveMindMaster.cs",
"ViewState": "AgIAADkAAAAAAAAAAAAgwI0AAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-20T17:25:29.183Z",
"EditorCaption": ""
"WhenOpened": "2025-10-20T17:25:29.183Z"
},
{
"$type": "Document",
"DocumentIndex": 3,
"DocumentIndex": 16,
"Title": "CompAbilityEffect_BindDrone.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\CompAbilityEffect_BindDrone.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\CompAbilityEffect_BindDrone.cs",
@@ -92,7 +304,7 @@
},
{
"$type": "Document",
"DocumentIndex": 4,
"DocumentIndex": 17,
"Title": "CompProperties_AbilityBindDrone.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HiveMind\\CompProperties_AbilityBindDrone.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_HiveMind\\CompProperties_AbilityBindDrone.cs",
@@ -104,7 +316,7 @@
},
{
"$type": "Document",
"DocumentIndex": 5,
"DocumentIndex": 18,
"Title": "Verb_ShootArc.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Verbs\\Verb_ShootArc.cs",
"RelativeDocumentMoniker": "Verbs\\Verb_ShootArc.cs",

View File

@@ -100,6 +100,8 @@
<Compile Include="Abilities\ARA_ShowSpawnablePawnsList\CompAbilityEffect_AbilityShowSpawnablePawns.cs" />
<Compile Include="Abilities\ARA_ShowSpawnablePawnsList\CompProperties_AbilityShowSpawnablePawns.cs" />
<Compile Include="Abilities\CompAbilityEffect_TransformCorpse.cs" />
<Compile Include="Buildings\Building_ArachnidGravEngine.cs" />
<Compile Include="Buildings\Building_Incubatable.cs" />
<Compile Include="Buildings\Building_TurretGunHasSpeed.cs" />
<Compile Include="Building_Comps\ARA_Building_RefuelingVat\Building_RefuelingVat.cs" />
<Compile Include="Building_Comps\ARA_Building_RefuelingVat\CompProperties_RefuelingVat.cs" />
@@ -125,6 +127,9 @@
<Compile Include="Hediffs\ARA_DrawMoteInRange\HediffComp_DrawMoteInRange.cs" />
<Compile Include="Hediffs\HediffComp_LifespanDisplay.cs" />
<Compile Include="Jobs\JobDriver_CarryPrisonerToRefuelingVat.cs" />
<Compile Include="Pawn_Comps\ARA_UniquePawn\CompProperties_UniquePawn.cs" />
<Compile Include="Pawn_Comps\ARA_UniquePawn\CompUniquePawn.cs" />
<Compile Include="Pawn_Comps\ARA_UniquePawn\Patch_UniquePawn.cs" />
<Compile Include="Storyteller\CustomRaidDef.cs" />
<Compile Include="Storyteller\CustomRaidTracker.cs" />
<Compile Include="Storyteller\IncidentParmsExtensions.cs" />

View File

@@ -24,18 +24,16 @@ namespace ArachnaeSwarm
{
yield break;
}
if (Props.whitelist == null || !Props.whitelist.Contains(selPawn.kindDef))
// 修改这里:只有当 whitelist 不为空时才检查白名单
if (Props.whitelist != null && Props.whitelist.Count > 0 && !Props.whitelist.Contains(selPawn.kindDef))
{
yield break;
}
if (Props.spawnablePawns != null)
{
foreach (PawnSpawnEntry entry in Props.spawnablePawns)
{
if (entry.pawnKind == null) continue;
if (entry.requiredResearch != null && !entry.requiredResearch.IsFinished)
{
string disabledText = "ARA_Incubate".Translate(entry.pawnKind.label) + " (" + "Requires".Translate() + ": " + entry.requiredResearch.label + ")";

View File

@@ -0,0 +1,222 @@
using System;
using System.Collections.Generic;
using System.Linq;
using RimWorld;
using RimWorld.Planet;
using UnityEngine;
using Verse;
namespace ArachnaeSwarm
{
public class Building_ArachnidGravEngine : Building_GravEngine
{
// 通过 ModExtension 暴露的纹理路径
private ArachnidGravEngineExtension modExtension;
// 覆盖的纹理资源
private Texture2D customInspectCommandTex;
private CachedMaterial customOrbMat;
private Graphic customOnCooldownGraphic;
public ArachnidGravEngineExtension ModExtension
{
get
{
if (modExtension == null)
{
modExtension = def.GetModExtension<ArachnidGravEngineExtension>();
}
return modExtension;
}
}
// 重写 Graphic 属性以使用自定义纹理
public override Graphic Graphic
{
get
{
if (Find.TickManager.TicksGame >= cooldownCompleteTick)
{
return base.Graphic;
}
return CustomOnCooldownGraphic;
}
}
private Texture2D CustomInspectCommandTex
{
get
{
if (customInspectCommandTex == null && ModExtension?.inspectCommandTexPath != null)
{
customInspectCommandTex = ContentFinder<Texture2D>.Get(ModExtension.inspectCommandTexPath);
}
return customInspectCommandTex ?? ContentFinder<Texture2D>.Get("UI/Commands/Inspect");
}
}
private CachedMaterial CustomOrbMat
{
get
{
if (customOrbMat == null && ModExtension?.orbTexPath != null)
{
customOrbMat = new CachedMaterial(ModExtension.orbTexPath, ShaderDatabase.Cutout);
}
return customOrbMat ?? new CachedMaterial("Things/Building/GravEngine/GravEngine_Orb", ShaderDatabase.Cutout);
}
}
private Graphic CustomOnCooldownGraphic
{
get
{
if (customOnCooldownGraphic == null && ModExtension?.cooldownTexPath != null)
{
customOnCooldownGraphic = GraphicDatabase.Get<Graphic_Single>(
ModExtension.cooldownTexPath,
ShaderDatabase.Cutout,
Vector2.one * 3f,
Color.white);
}
return customOnCooldownGraphic ?? GraphicDatabase.Get<Graphic_Single>("Things/Building/GravEngine/GravEngine_Cooldown", ShaderDatabase.Cutout, Vector2.one * 3f, Color.white);
}
}
// 禁用检查系统 - 重写 Inspect 方法为空
public new void Inspect(bool silent = false)
{
// 完全禁用检查系统,不执行任何操作
// 虫群建筑不需要人类的研究检查流程
}
// 重写 GetGizmos 方法,移除检查相关的 gizmo
public override IEnumerable<Gizmo> GetGizmos()
{
foreach (Gizmo gizmo in base.GetGizmos())
{
// 过滤掉检查相关的 gizmo
if (gizmo is Command_Action command &&
command.defaultLabel?.Contains("CommandInspectGravEngine") == true)
{
continue;
}
yield return gizmo;
}
// 可以添加虫群特有的 gizmo
if (DebugSettings.ShowDevGizmos)
{
yield return new Command_Action
{
defaultLabel = "DEV: Spawn Arachnid Swarm",
action = delegate
{
// 虫群特有的调试功能
SpawnArachnidSwarm();
}
};
}
}
// 重写 GetFloatMenuOptions 方法,移除检查选项
public override IEnumerable<FloatMenuOption> GetFloatMenuOptions(Pawn selPawn)
{
foreach (FloatMenuOption floatMenuOption in base.GetFloatMenuOptions(selPawn))
{
// 过滤掉检查相关的选项
if (floatMenuOption.Label.Contains("CommandInspectGravEngine"))
{
continue;
}
yield return floatMenuOption;
}
}
// 重写 ClaimableBy 方法,移除检查限制
public override AcceptanceReport ClaimableBy(Faction by)
{
// 虫群建筑不需要检查就可以被认领
AcceptanceReport result = base.ClaimableBy(by);
if (!result.Accepted)
{
return result;
}
return true; // 总是返回 true忽略检查限制
}
// 重写 GetInspectString 方法,移除检查相关的文本
public override string GetInspectString()
{
string text = base.GetInspectString();
// 移除关于未检查的文本
if (text.Contains("GravEngineNotInspected"))
{
text = text.Replace("GravEngineNotInspected".Translate() + "\n", "");
}
// 添加虫群特有的信息
if (!string.IsNullOrEmpty(text))
{
text += "\n";
}
text += "ArachnidSwarmControl".Translate();
return text;
}
// 虫群特有的方法
private void SpawnArachnidSwarm()
{
// 虫群特有的生成逻辑
// 这里可以添加生成虫群单位的代码
Messages.Message("ArachnidSwarmActivated".Translate(), this, MessageTypeDefOf.PositiveEvent);
}
// 重写 DrawAt 方法以使用自定义材质
protected override void DrawAt(Vector3 drawLoc, bool flip = false)
{
base.DrawAt(drawLoc, flip);
if (base.Spawned)
{
if (Find.TickManager.TicksGame >= cooldownCompleteTick)
{
// 使用 Mathf 替代 MathF
drawLoc.z += 0.5f * (1f + Mathf.Sin(Mathf.PI * 2f * (float)GenTicks.TicksGame / 500f)) * 0.3f;
}
drawLoc.y += 0.03658537f;
Vector3 s = new Vector3(def.graphicData.drawSize.x, 1f, def.graphicData.drawSize.y);
// 使用自定义的球体材质
Graphics.DrawMesh(MeshPool.plane10Back, Matrix4x4.TRS(drawLoc, base.Rotation.AsQuat, s), CustomOrbMat.Material, 0, null, 0);
}
}
public override void SpawnSetup(Map map, bool respawningAfterLoad)
{
base.SpawnSetup(map, respawningAfterLoad);
// 虫群建筑自动属于玩家,不需要检查
if (base.Faction != Faction.OfPlayer)
{
SetFaction(Faction.OfPlayer);
}
// 标记为已检查,避免父类的检查逻辑
Find.ResearchManager.gravEngineInspected = true;
}
// 由于父类的私有字段无法访问,我们移除 UpdateSubstructureIfNeeded 的重写
// 如果需要修改子结构逻辑,可能需要通过其他方式
}
// ModExtension 定义,用于在 XML 中配置纹理路径
public class ArachnidGravEngineExtension : DefModExtension
{
public string inspectCommandTexPath;
public string orbTexPath;
public string cooldownTexPath;
public string swarmIconPath;
}
}

View File

@@ -0,0 +1,93 @@
using System.Collections.Generic;
using System.Linq;
using Verse;
using RimWorld;
namespace ArachnaeSwarm
{
public class Building_Incubatable : Building
{
private CompSpawnPawnFromList spawnComp;
public CompSpawnPawnFromList SpawnComp
{
get
{
if (spawnComp == null)
{
spawnComp = this.GetComp<CompSpawnPawnFromList>();
}
return spawnComp;
}
}
public bool IsHatching => SpawnComp?.IsHatching == true;
public override IEnumerable<Gizmo> GetGizmos()
{
foreach (Gizmo gizmo in base.GetGizmos())
{
// 如果正在孵化,过滤掉卸载相关的 gizmo
if (IsHatching && IsUninstallGizmo(gizmo))
{
continue;
}
yield return gizmo;
}
// 确保组件的 gizmo 也能正常显示
if (SpawnComp != null)
{
foreach (Gizmo compGizmo in SpawnComp.CompGetGizmosExtra())
{
yield return compGizmo;
}
}
}
private bool IsUninstallGizmo(Gizmo gizmo)
{
// 检查是否是卸载/重新安装相关的 gizmo
if (gizmo is Command_Action commandAction)
{
string label = commandAction.defaultLabel?.ToLower() ?? "";
string desc = commandAction.defaultDesc?.ToLower() ?? "";
return label.Contains("uninstall") ||
label.Contains("reinstall") ||
desc.Contains("uninstall") ||
desc.Contains("reinstall");
}
if (gizmo is Designator designator)
{
string label = designator.defaultLabel?.ToLower() ?? "";
string desc = designator.defaultDesc?.ToLower() ?? "";
return label.Contains("uninstall") ||
label.Contains("reinstall") ||
desc.Contains("uninstall") ||
desc.Contains("reinstall");
}
return false;
}
public override string GetInspectString()
{
string baseString = base.GetInspectString();
if (IsHatching)
{
if (!string.IsNullOrEmpty(baseString))
{
baseString += "\n";
}
baseString += "CannotBeUninstalled".Translate();
}
return baseString;
}
}
}

View File

@@ -0,0 +1,208 @@
using System.Collections.Generic;
using System.Linq;
using RimWorld;
using Verse;
namespace ArachnaeSwarm
{
public class MentalState_HiveMindCascade : MentalState
{
private bool hasCascaded = false;
public override void PostStart(string reason)
{
base.PostStart(reason);
// 发送通知
if (PawnUtility.ShouldSendNotificationAbout(pawn))
{
string labelText = def.beginLetterLabel.NullOrEmpty() ? def.label : def.beginLetterLabel;
TaggedString letterLabel = labelText.Formatted(pawn.LabelShort, pawn.Named("PAWN")).CapitalizeFirst();
TaggedString letterText = def.beginLetter.Formatted(pawn.LabelShort, pawn.Named("PAWN")).CapitalizeFirst();
if (reason != null)
{
letterText += "\n\n" + reason;
}
Find.LetterStack.ReceiveLetter(letterLabel, letterText, LetterDefOf.NegativeEvent, pawn);
}
// 立即执行级联传播
ExecuteCascadeBreakdown();
}
public override void MentalStateTick(int delta)
{
base.MentalStateTick(delta);
// 确保级联只执行一次
if (!hasCascaded)
{
ExecuteCascadeBreakdown();
}
// 设置强制恢复时间
if (this.forceRecoverAfterTicks <= 0)
{
this.forceRecoverAfterTicks = 300; // 5秒后恢复
}
// 如果级联已完成且超过恢复时间,则恢复
if (hasCascaded && age > forceRecoverAfterTicks)
{
RecoverFromState();
}
}
private void ExecuteCascadeBreakdown()
{
if (hasCascaded) return;
var extension = def.GetModExtension<MentalStateDefExtension_HiveMindCascade>();
if (extension?.mentalStatesToSpread == null || extension.mentalStatesToSpread.Count == 0)
{
Log.Error($"[ArachnaeSwarm] MentalState_HiveMindCascade: No mentalStatesToSpread defined for {def.defName}");
hasCascaded = true;
return;
}
// 获取主节点的HiveMindMaster hediff
var masterHediff = pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("ARA_HiveMindMaster")) as Hediff_HiveMindMaster;
if (masterHediff == null)
{
Log.Warning($"[ArachnaeSwarm] MentalState_HiveMindCascade: Pawn {pawn.LabelShort} does not have ARA_HiveMindMaster hediff");
hasCascaded = true;
return;
}
// 通过反射或其他方式获取无人机列表
var drones = GetDronesFromMaster(masterHediff);
if (drones == null || drones.Count == 0)
{
Log.Message($"[ArachnaeSwarm] MentalState_HiveMindCascade: No drones found for master {pawn.LabelShort}");
hasCascaded = true;
return;
}
int spreadCount = 0;
foreach (var drone in drones)
{
if (drone == null || drone.Dead || !drone.Spawned || drone.Destroyed)
continue;
// 随机选择一个精神崩溃状态
var randomMentalState = extension.mentalStatesToSpread.RandomElement();
if (randomMentalState == null)
continue;
// 强制无人机进入选定的精神崩溃状态
if (drone.mindState.mentalStateHandler.TryStartMentalState(randomMentalState, "HiveMindCascade", force: true))
{
spreadCount++;
Log.Message($"[ArachnaeSwarm] Cascaded {randomMentalState.defName} to drone {drone.LabelShort}");
}
else
{
Log.Warning($"[ArachnaeSwarm] Failed to cascade {randomMentalState.defName} to drone {drone.LabelShort}");
}
}
Log.Message($"[ArachnaeSwarm] HiveMindCascade: Successfully spread {spreadCount} mental breaks to drones");
hasCascaded = true;
// 显示级联完成的消息
if (spreadCount > 0 && PawnUtility.ShouldSendNotificationAbout(pawn))
{
Messages.Message("ARA_HiveMindCascadeComplete".Translate(pawn.LabelShort, spreadCount), pawn, MessageTypeDefOf.NegativeEvent);
}
}
/// <summary>
/// 通过反射获取HiveMindMaster中的无人机列表
/// </summary>
private List<Pawn> GetDronesFromMaster(Hediff_HiveMindMaster masterHediff)
{
// 方法1: 如果HiveMindMaster有公共属性暴露无人机列表
// return masterHediff.Drones; // 如果存在这样的属性
// 方法2: 通过反射访问私有字段
try
{
var dronesField = typeof(Hediff_HiveMindMaster).GetField("drones",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (dronesField != null)
{
return dronesField.GetValue(masterHediff) as List<Pawn>;
}
}
catch (System.Exception ex)
{
Log.Error($"[ArachnaeSwarm] Failed to access drones field via reflection: {ex.Message}");
}
// 方法3: 如果以上都失败,尝试通过其他方式
Log.Error($"[ArachnaeSwarm] Could not access drones list from HiveMindMaster");
return new List<Pawn>();
}
public override bool ForceRecoverFromState()
{
// 确保级联已经执行
if (!hasCascaded)
{
ExecuteCascadeBreakdown();
}
return base.ForceRecoverFromState();
}
public override void ExposeData()
{
base.ExposeData();
Scribe_Values.Look(ref hasCascaded, "hasCascaded", false);
}
}
public class MentalStateDefExtension_HiveMindCascade : DefModExtension
{
public List<MentalStateDef> mentalStatesToSpread;
// 可选:可以添加传播概率或其他参数
public float spreadChance = 1.0f;
public bool includeMasterInSpread = false;
}
public class MentalBreakWorker_HiveMindCascade : MentalBreakWorker
{
public override bool TryStart(Pawn pawn, string reason, bool causedByMood)
{
// 检查pawn是否有HiveMindMaster hediff
var hasHiveMindMaster = pawn.health.hediffSet.HasHediff(HediffDef.Named("ARA_HiveMindMaster"));
if (!hasHiveMindMaster)
{
Log.Message($"[ArachnaeSwarm] MentalBreakWorker_HiveMindCascade: Pawn {pawn.LabelShort} does not have ARA_HiveMindMaster, cannot start cascade");
return false;
}
// 调用基类方法启动精神状态
if (base.TryStart(pawn, reason, causedByMood))
{
Log.Message($"[ArachnaeSwarm] Started HiveMindCascade mental state on {pawn.LabelShort}");
return true;
}
return false;
}
public override float CommonalityFor(Pawn pawn, bool moodInduced = false)
{
// 只有拥有HiveMindMaster的pawn才能触发这种崩溃
var hasHiveMindMaster = pawn.health.hediffSet.HasHediff(HediffDef.Named("ARA_HiveMindMaster"));
if (!hasHiveMindMaster)
return 0f;
return base.CommonalityFor(pawn, moodInduced);
}
}
}

View File

@@ -0,0 +1,24 @@
using Verse;
namespace ArachnaeSwarm
{
public class CompProperties_UniquePawn : CompProperties
{
// 全局变量的唯一标识符
public string globalVariable;
// 可选杀死pawn时是否显示消息
public bool showDeathMessage = true;
// 可选:死亡消息的翻译键
public string deathMessageKey = "ARA_UniquePawnDeathMessage";
// 可选杀死pawn的方式
public DamageDef killDamageDef = null;
public CompProperties_UniquePawn()
{
this.compClass = typeof(CompUniquePawn);
}
}
}

View File

@@ -0,0 +1,151 @@
using System;
using RimWorld;
using Verse;
namespace ArachnaeSwarm
{
public class CompUniquePawn : ThingComp
{
private bool _checked = false;
private bool _scheduledForCheck = false;
public CompProperties_UniquePawn Props => (CompProperties_UniquePawn)this.props;
public override void PostSpawnSetup(bool respawningAfterLoad)
{
base.PostSpawnSetup(respawningAfterLoad);
// 基本安全检查
if (this.parent == null || !(this.parent is Pawn pawn) || !pawn.Spawned)
return;
// 只在首次生成时检查,不是加载存档时
if (respawningAfterLoad || _checked || _scheduledForCheck)
return;
// 确保属性有效
if (this.props == null || string.IsNullOrEmpty(Props?.globalVariable))
return;
try
{
// 延迟整个检查过程到下一帧
_scheduledForCheck = true;
LongEventHandler.QueueLongEvent(() =>
{
try
{
if (this.parent is Pawn delayedPawn && delayedPawn.Spawned && !_checked)
{
CheckAndHandleUniquePawn(delayedPawn);
_checked = true;
}
_scheduledForCheck = false;
}
catch (Exception ex)
{
Log.Error($"Error in delayed unique pawn check: {ex}");
_scheduledForCheck = false;
}
}, "ArachnaeSwarm_UniquePawnCheck", false, null);
}
catch (Exception ex)
{
Log.Error($"Error in CompUniquePawn.PostSpawnSetup: {ex}");
_scheduledForCheck = false;
}
}
private void CheckAndHandleUniquePawn(Pawn pawn)
{
try
{
string variable = Props.globalVariable;
if (string.IsNullOrEmpty(variable))
{
Log.Error("CompUniquePawn: globalVariable is null or empty");
return;
}
// 检查变量是否已存在
if (GlobalVariableManager.HasVariable(variable))
{
// 变量已存在杀死pawn
KillPawn(pawn, variable);
}
else
{
// 变量不存在,添加变量
GlobalVariableManager.SetVariable(variable);
if (Prefs.DevMode)
{
Log.Message($"Added global variable '{variable}' for pawn {pawn.Label}");
}
}
}
catch (Exception ex)
{
Log.Error($"Error in CheckAndHandleUniquePawn: {ex}");
}
}
private void KillPawn(Pawn pawn, string variable)
{
try
{
// 显示死亡消息
if (Props.showDeathMessage && !string.IsNullOrEmpty(Props.deathMessageKey))
{
string deathMessage = Props.deathMessageKey.Translate(pawn.Label, variable);
if (!string.IsNullOrEmpty(deathMessage))
{
Messages.Message(deathMessage, MessageTypeDefOf.NegativeEvent);
}
}
if (Prefs.DevMode)
{
Log.Message($"Killing pawn {pawn.Label} because global variable '{variable}' already exists");
}
// 使用更安全的延迟执行
LongEventHandler.QueueLongEvent(() =>
{
try
{
if (pawn != null && pawn.Spawned && !pawn.Destroyed)
{
if (Props.killDamageDef != null)
{
var damageInfo = new DamageInfo(Props.killDamageDef, 99999f, -1f, -1f);
pawn.TakeDamage(damageInfo);
}
else
{
pawn.Kill(null);
}
}
}
catch (Exception ex)
{
Log.Error($"Error in delayed pawn kill: {ex}");
}
}, "ArachnaeSwarm_KillDuplicatePawn", false, null);
}
catch (Exception ex)
{
Log.Error($"Error in KillPawn: {ex}");
}
}
public override void PostExposeData()
{
base.PostExposeData();
Scribe_Values.Look(ref _checked, "checked", false);
Scribe_Values.Look(ref _scheduledForCheck, "scheduledForCheck", false);
}
}
}

View File

@@ -0,0 +1,217 @@
using System.Collections.Generic;
using System.Reflection;
using HarmonyLib;
using RimWorld;
using Verse;
namespace ArachnaeSwarm
{
[StaticConstructorOnStartup]
public static class ModInit
{
static ModInit()
{
var harmony = new Harmony("ArachnaeSwarm.Mod");
harmony.PatchAll();
}
}
[HarmonyPatch(typeof(Game), "ExposeData")]
public static class Game_ExposeData_Patch
{
public static void Postfix()
{
GlobalVariableManager.ExposeData();
}
}
// 复活拦截补丁
[HarmonyPatch]
public static class ResurrectionUtility_Patch
{
private static MethodInfo TargetMethod()
{
// 尝试找到复活方法
return AccessTools.Method("ResurrectionUtility:TryResurrect") ??
AccessTools.Method("RimWorld.ResurrectionUtility:TryResurrect");
}
[HarmonyPrefix]
public static bool Prefix(Pawn pawn, ref bool __result)
{
try
{
// 检查 pawn 是否有 CompUniquePawn 组件
var comp = pawn?.GetComp<CompUniquePawn>();
if (comp != null && !string.IsNullOrEmpty(comp.Props?.globalVariable))
{
string variable = comp.Props.globalVariable;
// 如果全局变量已存在,阻止复活
if (GlobalVariableManager.HasVariable(variable))
{
// 显示阻止复活的消息
if (comp.Props.showDeathMessage && !string.IsNullOrEmpty(comp.Props.deathMessageKey))
{
string preventMessage = "ARA_ResurrectionPrevented".Translate(pawn.Label, variable);
if (string.IsNullOrEmpty(preventMessage) || preventMessage == "ARA_ResurrectionPrevented")
{
preventMessage = "无法复活 {0},因为 {1} 已经存在。".Translate(pawn.Label, variable);
}
Messages.Message(preventMessage, MessageTypeDefOf.NegativeEvent);
}
if (Prefs.DevMode)
{
Log.Message($"阻止复活 {pawn.Label},因为全局变量 '{variable}' 已存在");
}
__result = false; // 返回 false 表示复活失败
return false; // 跳过原始方法
}
}
}
catch (System.Exception ex)
{
Log.Error($"Error in resurrection prevention: {ex}");
}
return true; // 继续执行原始方法
}
}
// 带副作用的复活拦截补丁
[HarmonyPatch]
public static class ResurrectionUtility_Patch2
{
private static MethodInfo TargetMethod()
{
// 尝试找到带副作用的复活方法
return AccessTools.Method("ResurrectionUtility:TryResurrectWithSideEffects") ??
AccessTools.Method("RimWorld.ResurrectionUtility:TryResurrectWithSideEffects");
}
[HarmonyPrefix]
public static bool Prefix(Pawn pawn, ref bool __result)
{
try
{
// 检查 pawn 是否有 CompUniquePawn 组件
var comp = pawn?.GetComp<CompUniquePawn>();
if (comp != null && !string.IsNullOrEmpty(comp.Props?.globalVariable))
{
string variable = comp.Props.globalVariable;
// 如果全局变量已存在,阻止复活
if (GlobalVariableManager.HasVariable(variable))
{
// 显示阻止复活的消息
if (comp.Props.showDeathMessage && !string.IsNullOrEmpty(comp.Props.deathMessageKey))
{
string preventMessage = "ARA_ResurrectionPrevented".Translate(pawn.Label, variable);
if (string.IsNullOrEmpty(preventMessage) || preventMessage == "ARA_ResurrectionPrevented")
{
preventMessage = "无法复活 {0},因为 {1} 已经存在。".Translate(pawn.Label, variable);
}
Messages.Message(preventMessage, MessageTypeDefOf.NegativeEvent);
}
if (Prefs.DevMode)
{
Log.Message($"阻止复活 {pawn.Label},因为全局变量 '{variable}' 已存在");
}
__result = false; // 返回 false 表示复活失败
return false; // 跳过原始方法
}
}
}
catch (System.Exception ex)
{
Log.Error($"Error in resurrection prevention: {ex}");
}
return true; // 继续执行原始方法
}
}
public static class GlobalVariableManager
{
private static HashSet<string> _globalVariables;
private static bool _initialized = false;
private static void EnsureInitialized()
{
if (!_initialized)
{
_globalVariables = new HashSet<string>();
_initialized = true;
}
}
public static void ExposeData()
{
try
{
if (Scribe.mode == LoadSaveMode.Saving)
{
EnsureInitialized();
if (_globalVariables.Count > 0)
{
List<string> variablesList = new List<string>(_globalVariables);
Scribe_Collections.Look(ref variablesList, "ArachnaeSwarm_GlobalVariables", LookMode.Value);
}
}
else if (Scribe.mode == LoadSaveMode.LoadingVars)
{
List<string> variablesList = null;
Scribe_Collections.Look(ref variablesList, "ArachnaeSwarm_GlobalVariables", LookMode.Value);
if (variablesList != null)
{
_globalVariables = new HashSet<string>(variablesList);
}
else
{
_globalVariables = new HashSet<string>();
}
_initialized = true;
}
}
catch (System.Exception ex)
{
Log.Error($"Error in GlobalVariableManager.ExposeData: {ex}");
}
}
public static bool HasVariable(string variable)
{
EnsureInitialized();
return _globalVariables.Contains(variable);
}
public static void SetVariable(string variable)
{
EnsureInitialized();
_globalVariables.Add(variable);
}
public static bool RemoveVariable(string variable)
{
EnsureInitialized();
return _globalVariables.Remove(variable);
}
public static IEnumerable<string> GetAllVariables()
{
EnsureInitialized();
return _globalVariables;
}
public static void ClearAllVariables()
{
EnsureInitialized();
_globalVariables.Clear();
}
}
}