diff --git a/1.6/1.6/Assemblies/AlienRace.dll b/1.6/1.6/Assemblies/AlienRace.dll
new file mode 100644
index 0000000..dbf4c0d
Binary files /dev/null and b/1.6/1.6/Assemblies/AlienRace.dll differ
diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll
index 4bafd8d..a1d8e77 100644
Binary files a/1.6/1.6/Assemblies/ArachnaeSwarm.dll and b/1.6/1.6/Assemblies/ArachnaeSwarm.dll differ
diff --git a/1.6/1.6/Defs/Thing_building/ARA_Building.xml b/1.6/1.6/Defs/Thing_building/ARA_Building.xml
index 74274ed..754988a 100644
--- a/1.6/1.6/Defs/Thing_building/ARA_Building.xml
+++ b/1.6/1.6/Defs/Thing_building/ARA_Building.xml
@@ -119,6 +119,9 @@
0.6
2
+
+ 1
+
10
ConstructMetal
6
diff --git a/1.6/1.6/Defs/Thing_building/ARA_NutrientNetworkBuilding.xml b/1.6/1.6/Defs/Thing_building/ARA_NutrientNetworkBuilding.xml
index 15034fb..272b99c 100644
--- a/1.6/1.6/Defs/Thing_building/ARA_NutrientNetworkBuilding.xml
+++ b/1.6/1.6/Defs/Thing_building/ARA_NutrientNetworkBuilding.xml
@@ -740,7 +740,7 @@
true
true
- true
+ false
200
diff --git a/1.6/1.6/Defs/Thing_building/ARA_SwarmTurret.xml b/1.6/1.6/Defs/Thing_building/ARA_SwarmTurret.xml
index 6d5e181..6165de2 100644
--- a/1.6/1.6/Defs/Thing_building/ARA_SwarmTurret.xml
+++ b/1.6/1.6/Defs/Thing_building/ARA_SwarmTurret.xml
@@ -134,7 +134,7 @@
虫蜜
- true
+ false
true
true
true
@@ -300,7 +300,7 @@
虫蜜
- true
+ false
true
true
@@ -441,7 +441,7 @@
虫蜜
- true
+ false
true
true
@@ -604,7 +604,7 @@
虫蜜
- true
+ false
true
true
diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo
index 6cc79f5..7d4dade 100644
Binary files a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo and b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo differ
diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json
index 3a9bb06..8c60bea 100644
--- a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json
+++ b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json
@@ -3,32 +3,16 @@
"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\\thing\\\u793A\u8303.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}",
- "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:thing\\\u793A\u8303.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}"
- },
- {
- "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\thing\\highaltitudeflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:thing\\highaltitudeflyover.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\\thing\\thingclassflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:thing\\thingclassflyover.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_arachnaegravengine.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_arachnaegravengine.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\building_comps\\ara_nutrientvat\\building_nutrientvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_nutrientvat\\building_nutrientvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\building_comps\\ara_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\\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\\abilities\\compabilityeffect_randomhediff.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\compabilityeffect_randomhediff.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\\powerarmor\\comppowerarmorstation.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:powerarmor\\comppowerarmorstation.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
"DocumentGroupContainers": [
@@ -47,87 +31,39 @@
{
"$type": "Document",
"DocumentIndex": 0,
- "Title": "\u793A\u8303.md",
- "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Thing\\\u793A\u8303.md",
- "RelativeDocumentMoniker": "Thing\\\u793A\u8303.md",
- "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Thing\\\u793A\u8303.md",
- "RelativeToolTip": "Thing\\\u793A\u8303.md",
- "ViewState": "AgIAAAAAAAAAAAAAAAAAABAAAAAkAAAAAAAAAA==",
- "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001818|",
- "WhenOpened": "2025-10-27T03:36:17.112Z",
+ "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": "AgIAAMwAAAAAAAAAAAAswMoAAAAuAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-10-27T07:14:35.288Z",
"EditorCaption": ""
},
- {
- "$type": "Document",
- "DocumentIndex": 1,
- "Title": "HighAltitudeFlyOver.cs",
- "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Thing\\HighAltitudeFlyOver.cs",
- "RelativeDocumentMoniker": "Thing\\HighAltitudeFlyOver.cs",
- "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Thing\\HighAltitudeFlyOver.cs",
- "RelativeToolTip": "Thing\\HighAltitudeFlyOver.cs",
- "ViewState": "AgIAAAAAAAAAAAAAAAAAACMAAAARAAAAAAAAAA==",
- "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2025-10-27T03:32:08.102Z"
- },
{
"$type": "Document",
"DocumentIndex": 2,
- "Title": "ThingclassFlyOver.cs",
- "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Thing\\ThingclassFlyOver.cs",
- "RelativeDocumentMoniker": "Thing\\ThingclassFlyOver.cs",
- "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Thing\\ThingclassFlyOver.cs*",
- "RelativeToolTip": "Thing\\ThingclassFlyOver.cs*",
- "ViewState": "AgIAAAcAAAAAAAAAAAAgwCEAAAAEAAAAAAAAAA==",
+ "Title": "CompPowerArmorStation.cs",
+ "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PowerArmor\\CompPowerArmorStation.cs",
+ "RelativeDocumentMoniker": "PowerArmor\\CompPowerArmorStation.cs",
+ "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PowerArmor\\CompPowerArmorStation.cs",
+ "RelativeToolTip": "PowerArmor\\CompPowerArmorStation.cs",
+ "ViewState": "AgIAABoAAAAAAAAAAAAAwBoAAABhAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2025-10-27T03:03:30.662Z"
+ "WhenOpened": "2025-10-27T06:39:11.711Z"
},
{
"$type": "Document",
- "DocumentIndex": 4,
+ "DocumentIndex": 1,
"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": "AgIAAEQAAAAAAAAAAAAAAEABAAAQAAAAAAAAAA==",
+ "ViewState": "AgIAAMwAAAAAAAAAAAAAwJIAAAAXAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-24T06:16:14.743Z"
- },
- {
- "$type": "Document",
- "DocumentIndex": 3,
- "Title": "Building_ArachnaeGravEngine.cs",
- "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ArachnaeGravEngine.cs",
- "RelativeDocumentMoniker": "Buildings\\Building_ArachnaeGravEngine.cs",
- "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ArachnaeGravEngine.cs",
- "RelativeToolTip": "Buildings\\Building_ArachnaeGravEngine.cs",
- "ViewState": "AgIAAHwAAAAAAAAAAAAgwJcAAAAJAAAAAAAAAA==",
- "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2025-10-24T02:30:45.288Z"
- },
- {
- "$type": "Document",
- "DocumentIndex": 5,
- "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": "AgIAAB0AAAAAAAAAAAAswE0AAABHAAAAAAAAAA==",
- "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2025-10-23T08:00:28.236Z"
- },
- {
- "$type": "Document",
- "DocumentIndex": 6,
- "Title": "CompAbilityEffect_RandomHediff.cs",
- "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\CompAbilityEffect_RandomHediff.cs",
- "RelativeDocumentMoniker": "Abilities\\CompAbilityEffect_RandomHediff.cs",
- "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\CompAbilityEffect_RandomHediff.cs",
- "RelativeToolTip": "Abilities\\CompAbilityEffect_RandomHediff.cs",
- "ViewState": "AgIAALoAAAAAAAAAAAAqwNcAAAAZAAAAAAAAAA==",
- "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2025-10-22T06:34:08.063Z"
}
]
}
diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
index ff222a7..20c20b3 100644
--- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
+++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
@@ -38,6 +38,9 @@
..\..\..\..\..\..\workshop\content\294100\2009463077\1.5\Assemblies\0Harmony.dll
False
+
+ ..\..\..\..\..\..\workshop\content\294100\839005762\1.6\Assemblies\AlienRace.dll
+
..\..\..\..\..\..\common\RimWorld\RimWorldWin64_Data\Managed\Assembly-CSharp.dll
False
diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_Building_RefuelingVat/Building_RefuelingVat.cs b/Source/ArachnaeSwarm/Building_Comps/ARA_Building_RefuelingVat/Building_RefuelingVat.cs
index 61bd1e4..12c9e5c 100644
--- a/Source/ArachnaeSwarm/Building_Comps/ARA_Building_RefuelingVat/Building_RefuelingVat.cs
+++ b/Source/ArachnaeSwarm/Building_Comps/ARA_Building_RefuelingVat/Building_RefuelingVat.cs
@@ -17,6 +17,9 @@ namespace ArachnaeSwarm
private CompAutoEjector cachedAutoEjectorComp;
private Graphic cachedTopGraphic;
+ // 新增字段:跟踪被建筑杀死的pawn
+ private HashSet pawnsKilledByVat = new HashSet();
+
// IThingHolderWithDrawnPawn implementation
public float HeldPawnDrawPos_Y => DrawPos.y + 0.03658537f;
public float HeldPawnBodyAngle => base.Rotation.AsAngle;
@@ -134,12 +137,21 @@ namespace ArachnaeSwarm
1.5f, // 每次1.5点伤害
2f, // 护甲穿透
-1f, // 随机角度
- instigator: null,
+ instigator: this, // 将建筑设为伤害来源
hitPart: targetPart
);
+ // 标记这个pawn将被建筑杀死
+ pawnsKilledByVat.Add(pawn);
+
// 应用伤害
pawn.TakeDamage(acidDamage);
+
+ // 立即检查pawn是否死亡
+ if (pawn.Dead)
+ {
+ HandlePawnDeath(pawn);
+ }
}
catch (Exception ex)
{
@@ -147,6 +159,48 @@ namespace ArachnaeSwarm
}
}
+ // 新增方法:处理pawn死亡
+ private void HandlePawnDeath(Pawn pawn)
+ {
+ try
+ {
+ // 检查是否是被建筑杀死的
+ if (pawnsKilledByVat.Contains(pawn))
+ {
+ Log.Message($"Pawn {pawn.Label} killed by RefuelingVat, destroying corpse.");
+
+ // 从容器中移除pawn
+ if (innerContainer.Contains(pawn))
+ {
+ innerContainer.Remove(pawn);
+ }
+
+ // 销毁pawn的尸体
+ if (!pawn.Destroyed)
+ {
+ pawn.Destroy();
+ }
+
+ // 从跟踪列表中移除
+ pawnsKilledByVat.Remove(pawn);
+ pawnTickCounters.Remove(pawn);
+
+ // 立即调用完成逻辑
+ if (selectedPawn == pawn)
+ {
+ selectedPawn = null;
+ startTick = -1;
+ }
+
+ return; // 直接返回,不执行后续弹出逻辑
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error($"Error handling pawn death for {pawn}: {ex}");
+ }
+ }
+
private BodyPartRecord GetRandomVulnerablePart(Pawn pawn)
{
// 优先选择外部身体部位
@@ -176,7 +230,15 @@ namespace ArachnaeSwarm
// 检查俘虏是否死亡 - 增加更严格的检查
if (selectedPawn.Dead || selectedPawn.Destroyed)
{
- Finish();
+ // 检查是否是被建筑杀死的
+ if (pawnsKilledByVat.Contains(selectedPawn))
+ {
+ HandlePawnDeath(selectedPawn);
+ }
+ else
+ {
+ Finish(); // 其他原因的死亡正常弹出
+ }
return;
}
@@ -246,6 +308,9 @@ namespace ArachnaeSwarm
{
startTick = Find.TickManager.TicksGame;
pawnTickCounters[pawn] = 0; // 初始化伤害计数器
+
+ // 确保pawn不在死亡跟踪列表中
+ pawnsKilledByVat.Remove(pawn);
}
if (deselected)
{
@@ -259,20 +324,27 @@ namespace ArachnaeSwarm
{
try
{
+ // 检查pawn是否还活着,如果已经死亡且是被建筑杀死的,则跳过弹出
+ if (selectedPawn.Dead && pawnsKilledByVat.Contains(selectedPawn))
+ {
+ HandlePawnDeath(selectedPawn);
+ return;
+ }
+
Notify_PawnRemoved();
bool ejected = false;
string ejectionMethod = "None";
// 方法1:标准弹出 - 在交互单元格附近
- if (innerContainer.Contains(selectedPawn))
+ if (innerContainer.Contains(selectedPawn) && !selectedPawn.Dead)
{
ejected = innerContainer.TryDrop(selectedPawn, InteractionCell, base.Map, ThingPlaceMode.Near, 1, out var _);
if (ejected) ejectionMethod = "Standard";
}
// 方法2:尝试随机相邻单元格
- if (!ejected && innerContainer.Contains(selectedPawn))
+ if (!ejected && innerContainer.Contains(selectedPawn) && !selectedPawn.Dead)
{
var adjacentCells = GenAdj.CellsAdjacent8Way(this).Where(c => c.Walkable(base.Map) && c.InBounds(base.Map)).ToList();
if (adjacentCells.Count > 0)
@@ -283,10 +355,10 @@ namespace ArachnaeSwarm
}
}
- // 方法3:强制移除
- if (!ejected && innerContainer.Contains(selectedPawn))
+ // 方法3:强制移除(仅对活着的pawn)
+ if (!ejected && innerContainer.Contains(selectedPawn) && !selectedPawn.Dead)
{
- Log.Warning($"Forcing removal of dead pawn {selectedPawn} from RefuelingVat");
+ Log.Warning($"Forcing removal of pawn {selectedPawn} from RefuelingVat");
innerContainer.Remove(selectedPawn);
GenPlace.TryPlaceThing(selectedPawn, this.Position, base.Map, ThingPlaceMode.Near);
ejected = true;
@@ -297,7 +369,7 @@ namespace ArachnaeSwarm
{
Log.Message($"Successfully ejected {selectedPawn} using method: {ejectionMethod}");
}
- else
+ else if (!selectedPawn.Dead) // 只有活着的pawn弹出失败才报错
{
Log.Error($"Failed to eject {selectedPawn} from RefuelingVat");
}
@@ -317,10 +389,12 @@ namespace ArachnaeSwarm
{
if (selectedPawn != null)
{
+ // 从跟踪列表中移除
+ pawnsKilledByVat.Remove(selectedPawn);
pawnTickCounters.Remove(selectedPawn);
- // 确保pawn不在容器中
- if (innerContainer.Contains(selectedPawn))
+ // 确保pawn不在容器中(除非是被建筑杀死的)
+ if (innerContainer.Contains(selectedPawn) && !(selectedPawn.Dead && pawnsKilledByVat.Contains(selectedPawn)))
{
Log.Warning($"Pawn {selectedPawn} still in container during OnStop, forcing removal.");
innerContainer.Remove(selectedPawn);
@@ -597,6 +671,22 @@ namespace ArachnaeSwarm
{
base.ExposeData();
Scribe_Collections.Look(ref pawnTickCounters, "pawnTickCounters", LookMode.Reference, LookMode.Value);
+ Scribe_Collections.Look(ref pawnsKilledByVat, "pawnsKilledByVat", LookMode.Reference);
+
+ // 确保集合不为null
+ if (Scribe.mode == LoadSaveMode.PostLoadInit)
+ {
+ pawnsKilledByVat ??= new HashSet();
+ pawnTickCounters ??= new Dictionary();
+
+ // 清理可能已销毁的pawn引用
+ pawnsKilledByVat.RemoveWhere(pawn => pawn == null || pawn.Destroyed);
+ var deadPawns = pawnTickCounters.Keys.Where(pawn => pawn == null || pawn.Destroyed).ToList();
+ foreach (var deadPawn in deadPawns)
+ {
+ pawnTickCounters.Remove(deadPawn);
+ }
+ }
}
}
}
diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_NutrientVat/Building_NutrientVat.cs b/Source/ArachnaeSwarm/Building_Comps/ARA_NutrientVat/Building_NutrientVat.cs
index b1ba301..0b47e52 100644
--- a/Source/ArachnaeSwarm/Building_Comps/ARA_NutrientVat/Building_NutrientVat.cs
+++ b/Source/ArachnaeSwarm/Building_Comps/ARA_NutrientVat/Building_NutrientVat.cs
@@ -15,6 +15,9 @@ namespace ArachnaeSwarm
private CompRefuelableNutrition cachedRefuelableComp;
private Graphic cachedTopGraphic;
+ // 新增字段:跟踪被建筑杀死的pawn
+ private HashSet pawnsKilledByVat = new HashSet();
+
// IThingHolderWithDrawnPawn implementation
public float HeldPawnDrawPos_Y => DrawPos.y + 0.03658537f;
public float HeldPawnBodyAngle => base.Rotation.AsAngle;
@@ -124,12 +127,21 @@ namespace ArachnaeSwarm
3f, // 每次3点伤害
2f, // 护甲穿透
-1f, // 随机角度
- instigator: null,
+ instigator: this, // 将建筑设为伤害来源
hitPart: targetPart
);
+ // 标记这个pawn将被建筑杀死
+ pawnsKilledByVat.Add(pawn);
+
// 应用伤害
pawn.TakeDamage(acidDamage);
+
+ // 立即检查pawn是否死亡
+ if (pawn.Dead)
+ {
+ HandlePawnDeath(pawn);
+ }
}
catch (Exception ex)
{
@@ -137,6 +149,48 @@ namespace ArachnaeSwarm
}
}
+ // 新增方法:处理pawn死亡(与RefuelingVat相同)
+ private void HandlePawnDeath(Pawn pawn)
+ {
+ try
+ {
+ // 检查是否是被建筑杀死的
+ if (pawnsKilledByVat.Contains(pawn))
+ {
+ Log.Message($"Pawn {pawn.Label} killed by NutrientVat, destroying corpse.");
+
+ // 从容器中移除pawn
+ if (innerContainer.Contains(pawn))
+ {
+ innerContainer.Remove(pawn);
+ }
+
+ // 销毁pawn的尸体
+ if (!pawn.Destroyed)
+ {
+ pawn.Destroy();
+ }
+
+ // 从跟踪列表中移除
+ pawnsKilledByVat.Remove(pawn);
+ pawnTickCounters.Remove(pawn);
+
+ // 立即调用完成逻辑
+ if (selectedPawn == pawn)
+ {
+ selectedPawn = null;
+ startTick = -1;
+ }
+
+ return; // 直接返回,不执行后续弹出逻辑
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error($"Error handling pawn death for {pawn}: {ex}");
+ }
+ }
+
private BodyPartRecord GetRandomVulnerablePart(Pawn pawn)
{
// 优先选择外部身体部位
@@ -166,7 +220,15 @@ namespace ArachnaeSwarm
// 检查俘虏是否死亡 - 增加更严格的检查
if (selectedPawn.Dead || selectedPawn.Destroyed)
{
- Finish();
+ // 检查是否是被建筑杀死的
+ if (pawnsKilledByVat.Contains(selectedPawn))
+ {
+ HandlePawnDeath(selectedPawn);
+ }
+ else
+ {
+ Finish(); // 其他原因的死亡正常弹出
+ }
return;
}
@@ -270,6 +332,9 @@ namespace ArachnaeSwarm
{
startTick = Find.TickManager.TicksGame;
pawnTickCounters[pawn] = 0; // 初始化伤害计数器
+
+ // 确保pawn不在死亡跟踪列表中
+ pawnsKilledByVat.Remove(pawn);
}
if (deselected)
{
@@ -283,20 +348,27 @@ namespace ArachnaeSwarm
{
try
{
+ // 检查pawn是否还活着,如果已经死亡且是被建筑杀死的,则跳过弹出
+ if (selectedPawn.Dead && pawnsKilledByVat.Contains(selectedPawn))
+ {
+ HandlePawnDeath(selectedPawn);
+ return;
+ }
+
Notify_PawnRemoved();
bool ejected = false;
string ejectionMethod = "None";
// 方法1:标准弹出 - 在交互单元格附近
- if (innerContainer.Contains(selectedPawn))
+ if (innerContainer.Contains(selectedPawn) && !selectedPawn.Dead)
{
ejected = innerContainer.TryDrop(selectedPawn, InteractionCell, base.Map, ThingPlaceMode.Near, 1, out var _);
if (ejected) ejectionMethod = "Standard";
}
// 方法2:尝试随机相邻单元格
- if (!ejected && innerContainer.Contains(selectedPawn))
+ if (!ejected && innerContainer.Contains(selectedPawn) && !selectedPawn.Dead)
{
var adjacentCells = GenAdj.CellsAdjacent8Way(this).Where(c => c.Walkable(base.Map) && c.InBounds(base.Map)).ToList();
if (adjacentCells.Count > 0)
@@ -307,8 +379,8 @@ namespace ArachnaeSwarm
}
}
- // 方法3:强制移除
- if (!ejected && innerContainer.Contains(selectedPawn))
+ // 方法3:强制移除(仅对活着的pawn)
+ if (!ejected && innerContainer.Contains(selectedPawn) && !selectedPawn.Dead)
{
Log.Warning($"Forcing removal of pawn {selectedPawn} from NutrientVat");
innerContainer.Remove(selectedPawn);
@@ -321,7 +393,7 @@ namespace ArachnaeSwarm
{
Log.Message($"Successfully ejected {selectedPawn} using method: {ejectionMethod}");
}
- else
+ else if (!selectedPawn.Dead) // 只有活着的pawn弹出失败才报错
{
Log.Error($"Failed to eject {selectedPawn} from NutrientVat");
}
@@ -343,20 +415,27 @@ namespace ArachnaeSwarm
{
try
{
+ // 检查pawn是否还活着,如果已经死亡且是被建筑杀死的,则跳过弹出
+ if (selectedPawn.Dead && pawnsKilledByVat.Contains(selectedPawn))
+ {
+ HandlePawnDeath(selectedPawn);
+ return;
+ }
+
Notify_PawnRemoved();
bool ejected = false;
string ejectionMethod = "None";
// 方法1:标准弹出 - 在交互单元格附近
- if (innerContainer.Contains(selectedPawn))
+ if (innerContainer.Contains(selectedPawn) && !selectedPawn.Dead)
{
ejected = innerContainer.TryDrop(selectedPawn, InteractionCell, base.Map, ThingPlaceMode.Near, 1, out var _);
if (ejected) ejectionMethod = "Standard";
}
// 方法2:尝试随机相邻单元格
- if (!ejected && innerContainer.Contains(selectedPawn))
+ if (!ejected && innerContainer.Contains(selectedPawn) && !selectedPawn.Dead)
{
var adjacentCells = GenAdj.CellsAdjacent8Way(this).Where(c => c.Walkable(base.Map) && c.InBounds(base.Map)).ToList();
if (adjacentCells.Count > 0)
@@ -367,8 +446,8 @@ namespace ArachnaeSwarm
}
}
- // 方法3:强制移除
- if (!ejected && innerContainer.Contains(selectedPawn))
+ // 方法3:强制移除(仅对活着的pawn)
+ if (!ejected && innerContainer.Contains(selectedPawn) && !selectedPawn.Dead)
{
Log.Warning($"Forcing removal of failed pawn {selectedPawn} from NutrientVat");
innerContainer.Remove(selectedPawn);
@@ -384,7 +463,7 @@ namespace ArachnaeSwarm
Hediff firstHediffOfDef = selectedPawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.BioStarvation);
selectedPawn.Kill(null, firstHediffOfDef);
}
- else
+ else if (!selectedPawn.Dead) // 只有活着的pawn弹出失败才报错
{
Log.Error($"Failed to eject failed pawn {selectedPawn} from NutrientVat");
// 即使弹出失败也要杀死俘虏
@@ -407,10 +486,12 @@ namespace ArachnaeSwarm
{
if (selectedPawn != null)
{
+ // 从跟踪列表中移除
+ pawnsKilledByVat.Remove(selectedPawn);
pawnTickCounters.Remove(selectedPawn);
- // 确保pawn不在容器中
- if (innerContainer.Contains(selectedPawn))
+ // 确保pawn不在容器中(除非是被建筑杀死的)
+ if (innerContainer.Contains(selectedPawn) && !(selectedPawn.Dead && pawnsKilledByVat.Contains(selectedPawn)))
{
Log.Warning($"Pawn {selectedPawn} still in container during OnStop, forcing removal.");
innerContainer.Remove(selectedPawn);
@@ -671,6 +752,22 @@ namespace ArachnaeSwarm
{
base.ExposeData();
Scribe_Collections.Look(ref pawnTickCounters, "pawnTickCounters", LookMode.Reference, LookMode.Value);
+ Scribe_Collections.Look(ref pawnsKilledByVat, "pawnsKilledByVat", LookMode.Reference);
+
+ // 确保集合不为null
+ if (Scribe.mode == LoadSaveMode.PostLoadInit)
+ {
+ pawnsKilledByVat ??= new HashSet();
+ pawnTickCounters ??= new Dictionary();
+
+ // 清理可能已销毁的pawn引用
+ pawnsKilledByVat.RemoveWhere(pawn => pawn == null || pawn.Destroyed);
+ var deadPawns = pawnTickCounters.Keys.Where(pawn => pawn == null || pawn.Destroyed).ToList();
+ foreach (var deadPawn in deadPawns)
+ {
+ pawnTickCounters.Remove(deadPawn);
+ }
+ }
}
}
}
diff --git a/Source/ArachnaeSwarm/PowerArmor/CompPowerArmorStation.cs b/Source/ArachnaeSwarm/PowerArmor/CompPowerArmorStation.cs
index 196ce62..0041b8a 100644
--- a/Source/ArachnaeSwarm/PowerArmor/CompPowerArmorStation.cs
+++ b/Source/ArachnaeSwarm/PowerArmor/CompPowerArmorStation.cs
@@ -1,14 +1,20 @@
using RimWorld;
using Verse;
using System.Collections.Generic;
-using Verse.AI; // For PathEndMode and Danger
-using UnityEngine; // For Texture2D
+using Verse.AI;
+using UnityEngine;
+using AlienRace;
+using System; // 添加 System 命名空间用于 Action 类型
+using System.Text; // 添加 System.Text 命名空间用于 StringBuilder
+using System.Linq; // 添加 System.Linq 命名空间用于 Any() 方法
namespace ArachnaeSwarm
{
public class CompProperties_PowerArmorStation : CompProperties
{
public ThingDef apparelDef;
+ public bool enableRaceRestrictionCheck = true;
+ public string customRestrictionMessage;
public CompProperties_PowerArmorStation()
{
@@ -26,11 +32,64 @@ namespace ArachnaeSwarm
var fuelComp = parent.GetComp();
if (fuelComp != null)
{
- // Set consumption rate to 0 when in building form
fuelComp.currentConsumptionRate = 0f;
}
}
+ // 使用 Alien Race 框架提供的静态方法检查装备限制
+ private AcceptanceReport CheckRaceRestriction(Pawn pawn, ThingDef apparelDef)
+ {
+ if (pawn == null || apparelDef == null)
+ return true;
+
+ if (!Props.enableRaceRestrictionCheck)
+ return true;
+
+ // 使用 Alien Race 框架的 CanWear 方法
+ bool canWear = RaceRestrictionSettings.CanWear(apparelDef, pawn.def);
+
+ if (!canWear)
+ {
+ if (!Props.customRestrictionMessage.NullOrEmpty())
+ {
+ return Props.customRestrictionMessage.Translate(pawn.def.label, apparelDef.label);
+ }
+
+ return "ARA_PowerArmorForbiddenByRace".Translate(pawn.def.label, apparelDef.label);
+ }
+
+ return true;
+ }
+
+ public AcceptanceReport CanPawnEnter(Pawn pawn)
+ {
+ // 基础可达性检查
+ if (!pawn.CanReserveAndReach(parent, PathEndMode.InteractionCell, Danger.Deadly))
+ {
+ return "CannotReach".Translate();
+ }
+
+ if (Props.apparelDef == null)
+ {
+ return "ARA_NoApparelDefined".Translate();
+ }
+
+ // 使用 Alien Race 框架的方法检查种族限制
+ AcceptanceReport raceCheck = CheckRaceRestriction(pawn, Props.apparelDef);
+ if (!raceCheck.Accepted)
+ {
+ return raceCheck;
+ }
+
+ // 检查是否已经穿戴了同类型装备
+ if (pawn.apparel?.WornApparel?.Any(a => a.def == Props.apparelDef) == true)
+ {
+ return "ARA_AlreadyWearingSameApparel".Translate(Props.apparelDef.label);
+ }
+
+ return true;
+ }
+
public override IEnumerable CompFloatMenuOptions(Pawn selPawn)
{
foreach (FloatMenuOption option in base.CompFloatMenuOptions(selPawn))
@@ -38,26 +97,58 @@ namespace ArachnaeSwarm
yield return option;
}
- // Check if there's an apparelDef defined
if (Props.apparelDef == null)
{
- yield break; // No apparel to wear
+ yield break;
}
- // Check if the pawn can interact with the building
- if (!selPawn.CanReserveAndReach(parent, PathEndMode.InteractionCell, Danger.Deadly))
+ AcceptanceReport canEnter = CanPawnEnter(selPawn);
+
+ string label = "ARA_EnterPowerArmor".Translate(parent.Label);
+ if (!canEnter.Accepted)
{
- yield return new FloatMenuOption("CannotEnterPowerArmor".Translate() + ": " + "CannotReach".Translate(), null);
+ label += ": " + canEnter.Reason;
}
- else
+
+ Action enterAction = null;
+ if (canEnter.Accepted)
{
- void enterAction()
+ enterAction = () =>
{
Job job = JobMaker.MakeJob(DefDatabase.GetNamed("ARA_EnterPowerArmor"), parent);
selPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
- }
- yield return new FloatMenuOption("ARA_EnterPowerArmor".Translate(parent.Label), enterAction);
+ };
}
+
+ yield return new FloatMenuOption(label, enterAction)
+ {
+ Disabled = !canEnter.Accepted
+ };
+ }
+
+ public override string CompInspectStringExtra()
+ {
+ StringBuilder sb = new StringBuilder();
+ string baseString = base.CompInspectStringExtra();
+
+ if (!string.IsNullOrEmpty(baseString))
+ sb.Append(baseString);
+
+ if (Props.apparelDef != null)
+ {
+ if (sb.Length > 0)
+ sb.AppendLine();
+
+ sb.Append("ARA_PowerArmorStationApparel".Translate(Props.apparelDef.label));
+
+ if (Props.enableRaceRestrictionCheck)
+ {
+ sb.AppendLine();
+ sb.Append("ARA_RaceRestrictionEnabled".Translate());
+ }
+ }
+
+ return sb.ToString();
}
}
-}
\ No newline at end of file
+}