This commit is contained in:
2025-12-16 17:22:56 +08:00
parent 4c010b6db4
commit baeab4e6c5
22 changed files with 756 additions and 1341 deletions

View File

@@ -11,28 +11,12 @@
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_ootheca\\compproperties_incubatordata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\buildings\\building_ootheca\\building_ootheca.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_ootheca\\building_ootheca.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_ootheca\\itab_ootheca_incubation.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_ootheca\\itab_ootheca_incubation.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\buildings\\building_ootheca\\oothecaincubatorextension.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_ootheca\\oothecaincubatorextension.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\buildings\\building_equipmentootheca\\itab_equipmentootheca_incubation.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_equipmentootheca\\itab_equipmentootheca_incubation.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_equipmentootheca\\building_equipmentootheca.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_equipmentootheca\\building_equipmentootheca.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_equipmentootheca\\building_equipmentootheca.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\buildings\\building_equipmentootheca\\compproperties_equipmentincubatordata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_equipmentootheca\\compproperties_equipmentincubatordata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ara_hediffdefof.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:ara_hediffdefof.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
"DocumentGroupContainers": [
@@ -42,25 +26,8 @@
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 1,
"SelectedChildIndex": 4,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
},
{
"$type": "Document",
"DocumentIndex": 0,
"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": "AgIAAEEAAAAAAAAAAAAkwBYAAAAzAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-12-16T04:00:20.165Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 1,
@@ -69,82 +36,53 @@
"RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs",
"RelativeToolTip": "Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs",
"ViewState": "AgIAAAIBAAAAAAAAAAAawB8BAAAAAAAAAAAAAA==",
"ViewState": "AgIAAAAAAAAAAAAAAAAAADEAAAAlAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-12-16T02:36:56.126Z",
"WhenOpened": "2025-12-16T08:17:40.867Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "ITab_Ootheca_Incubation.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\ITab_Ootheca_Incubation.cs",
"RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\ITab_Ootheca_Incubation.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\ITab_Ootheca_Incubation.cs",
"RelativeToolTip": "Buildings\\Building_Ootheca\\ITab_Ootheca_Incubation.cs",
"ViewState": "AgIAAJUAAAAAAAAAAAAewMkAAAANAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-12-16T08:14:08.752Z",
"EditorCaption": ""
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "OothecaIncubatorExtension.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\OothecaIncubatorExtension.cs",
"RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\OothecaIncubatorExtension.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\OothecaIncubatorExtension.cs",
"RelativeToolTip": "Buildings\\Building_Ootheca\\OothecaIncubatorExtension.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAkAAAArAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-12-16T00:38:04.247Z"
},
{
"$type": "Document",
"DocumentIndex": 4,
"Title": "ITab_EquipmentOotheca_Incubation.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\ITab_EquipmentOotheca_Incubation.cs",
"RelativeDocumentMoniker": "Buildings\\Building_EquipmentOotheca\\ITab_EquipmentOotheca_Incubation.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\ITab_EquipmentOotheca_Incubation.cs",
"RelativeToolTip": "Buildings\\Building_EquipmentOotheca\\ITab_EquipmentOotheca_Incubation.cs",
"ViewState": "AgIAAIAAAAAAAAAAAADgv5AAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-12-16T00:29:36.407Z"
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "Building_EquipmentOotheca.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\Building_EquipmentOotheca.cs",
"RelativeDocumentMoniker": "Buildings\\Building_EquipmentOotheca\\Building_EquipmentOotheca.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\Building_EquipmentOotheca.cs",
"RelativeToolTip": "Buildings\\Building_EquipmentOotheca\\Building_EquipmentOotheca.cs",
"ViewState": "AgIAAEgCAAAAAAAAAAAewF8CAABDAAAAAAAAAA==",
"ViewState": "AgIAALgCAAAAAAAAAAAAAMQCAAAjAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-12-15T18:22:14.171Z"
"WhenOpened": "2025-12-16T08:13:46.678Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "Building_Ootheca.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\Building_Ootheca.cs",
"RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\Building_Ootheca.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\Building_Ootheca.cs",
"RelativeToolTip": "Buildings\\Building_Ootheca\\Building_Ootheca.cs",
"ViewState": "AgIAACkBAAAAAAAAAAAhwC0BAAApAAAAAAAAAA==",
"DocumentIndex": 0,
"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": "AgIAAPsAAAAAAAAAAAAewBMBAAAfAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-12-15T18:22:12.217Z"
},
{
"$type": "Document",
"DocumentIndex": 6,
"Title": "CompProperties_EquipmentIncubatorData.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\CompProperties_EquipmentIncubatorData.cs",
"RelativeDocumentMoniker": "Buildings\\Building_EquipmentOotheca\\CompProperties_EquipmentIncubatorData.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_EquipmentOotheca\\CompProperties_EquipmentIncubatorData.cs",
"RelativeToolTip": "Buildings\\Building_EquipmentOotheca\\CompProperties_EquipmentIncubatorData.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAACYAAAAaAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-12-15T17:55:40.041Z"
},
{
"$type": "Document",
"DocumentIndex": 7,
"Title": "ARA_HediffDefOf.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_HediffDefOf.cs",
"RelativeDocumentMoniker": "ARA_HediffDefOf.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_HediffDefOf.cs",
"RelativeToolTip": "ARA_HediffDefOf.cs",
"ViewState": "AgIAAAAAAAAAAAAAAADwvxgAAAAdAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-12-15T17:32:18.493Z"
"WhenOpened": "2025-12-16T04:00:20.165Z",
"EditorCaption": ""
}
]
}

View File

@@ -1,4 +1,5 @@
using RimWorld;
// File: Building_RefuelingVat.cs
using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -17,6 +18,11 @@ namespace ArachnaeSwarm
private CompAutoEjector cachedAutoEjectorComp;
private Graphic cachedTopGraphic;
// === 新增字段:销毁系统 ===
private bool selfDestructInitiated = false;
private int pawnMissingTickCount = 0;
private const int MissingTicksBeforeDestruction = 60; // Pawn失踪后60ticks1秒销毁建筑
// 新增字段跟踪被建筑杀死的pawn
private HashSet<Pawn> pawnsKilledByVat = new HashSet<Pawn>();
@@ -103,6 +109,86 @@ namespace ArachnaeSwarm
private const int AcidDamageInterval = 6000;
private Dictionary<Pawn, int> pawnTickCounters = new Dictionary<Pawn, int>();
// === 新增方法检查Pawn是否在容器内 ===
private bool IsPawnInContainer(Pawn pawn)
{
if (pawn == null || pawn.Destroyed) return false;
return innerContainer.Contains(pawn);
}
// === 新增方法:启动自毁系统 ===
private void InitiateSelfDestruct()
{
if (selfDestructInitiated) return;
selfDestructInitiated = true;
pawnMissingTickCount = 0;
Log.Message($"RefuelingVat at {Position}: Pawn missing from container. Self-destruct initiated. Will destroy in {MissingTicksBeforeDestruction} ticks.");
// 发送警告消息
Messages.Message("RefuelingVat_ContainmentBreach".Translate(), this, MessageTypeDefOf.NegativeEvent);
}
// === 新增方法:执行建筑销毁 ===
private void ExecuteSelfDestruct()
{
Log.Message($"RefuelingVat at {Position}: Self-destruct sequence complete. Destroying building.");
// 显示爆炸效果
if (!Destroyed)
{
// 销毁建筑
Destroy(DestroyMode.Vanish);
}
}
// === 修改检查Pawn状态 ===
private void CheckPawnContainment()
{
if (!base.Working || selectedPawn == null)
{
// 如果不在工作状态,重置自毁系统
selfDestructInitiated = false;
pawnMissingTickCount = 0;
return;
}
// 检查Pawn是否还在容器内
if (!IsPawnInContainer(selectedPawn))
{
// Pawn不在容器内启动或继续自毁
if (!selfDestructInitiated)
{
InitiateSelfDestruct();
}
else
{
pawnMissingTickCount++;
// 检查是否达到销毁时间
if (pawnMissingTickCount >= MissingTicksBeforeDestruction)
{
ExecuteSelfDestruct();
}
else if (pawnMissingTickCount % 30 == 0) // 每0.5秒报告一次
{
Log.Message($"RefuelingVat at {Position}: Pawn still missing. Self-destruct in {MissingTicksBeforeDestruction - pawnMissingTickCount} ticks.");
}
}
}
else
{
// Pawn在容器内重置自毁系统
if (selfDestructInitiated)
{
Log.Message($"RefuelingVat at {Position}: Pawn returned to container. Self-destruct cancelled.");
selfDestructInitiated = false;
pawnMissingTickCount = 0;
Messages.Message("RefuelingVat_ContainmentRestored".Translate(), this, MessageTypeDefOf.PositiveEvent);
}
}
}
// 安全字典操作方法
private bool SafeTryGetTickCount(Pawn pawn, out int tickCount)
{
@@ -163,7 +249,7 @@ namespace ArachnaeSwarm
{
if (selectedPawn != null && innerContainer.Contains(selectedPawn))
{
ArachnaeLog.Debug($"RefuelingVat despawned with pawn inside, forcing ejection.");
Log.Message($"RefuelingVat despawned with pawn inside, forcing ejection.");
Finish(); // 使用修改后的Finish方法
}
}
@@ -186,10 +272,10 @@ namespace ArachnaeSwarm
DamageInfo acidDamage = new DamageInfo(
acidDamageDef,
1.5f, // 每次1.5点伤害
1000f, // 每次1.5点伤害
2f, // 护甲穿透
-1f, // 随机角度
instigator: this, // 将建筑设为伤害来源
null, // 将建筑设为伤害来源
hitPart: targetPart
);
@@ -207,11 +293,11 @@ namespace ArachnaeSwarm
}
catch (Exception ex)
{
ArachnaeLog.Debug($"Error applying acid damage to {pawn}: {ex.Message}");
Log.Error($"Error applying acid damage to {pawn}: {ex.Message}");
}
}
// 新增方法处理pawn死亡
// === 修改处理pawn死亡 ===
private void HandlePawnDeath(Pawn pawn)
{
try
@@ -222,36 +308,22 @@ namespace ArachnaeSwarm
// 检查是否是被建筑杀死的
if (pawnsKilledByVat.Contains(pawn))
{
ArachnaeLog.Debug($"Pawn {pawn.Label} killed by RefuelingVat, destroying corpse.");
Log.Message($"Pawn {pawn.Label} killed by RefuelingVat.");
// 从容器中移除pawn
if (innerContainer.Contains(pawn))
{
innerContainer.Remove(pawn);
}
// 注意:现在不再需要从容器中移除Pawn或销毁尸体
// 因为建筑会被销毁Pawn会自然弹出
// 销毁pawn的尸体
if (!pawn.Destroyed)
{
pawn.Destroy();
}
// 从跟踪列表中移除
// 只是从跟踪列表中移除
SafeRemoveFromDictionaries(pawn);
// 立即调用完成逻辑
if (selectedPawn == pawn)
{
selectedPawn = null;
startTick = -1;
}
return; // 直接返回,不执行后续弹出逻辑
// 不需要重置selectedPawn因为建筑即将被销毁
// 自毁系统会处理Pawn不在容器中的情况
return;
}
}
catch (Exception ex)
{
ArachnaeLog.Debug($"Error handling pawn death for {pawn}: {ex}");
Log.Error($"Error handling pawn death for {pawn}: {ex}");
}
}
@@ -272,10 +344,17 @@ namespace ArachnaeSwarm
pawn.RaceProps.body.corePart;
}
// === 修改Tick方法 ===
protected override void Tick()
{
base.Tick();
// 检查Pawn是否还在容器内
CheckPawnContainment();
// 如果自毁已启动,跳过其他逻辑
if (selfDestructInitiated) return;
// 更严格的空值检查
if (selectedPawn == null || selectedPawn.Destroyed || !innerContainer.Contains(selectedPawn))
{
@@ -295,7 +374,9 @@ namespace ArachnaeSwarm
}
else
{
Finish(); // 其他原因的死亡正常弹出
// 其他原因的死亡 - 启动自毁系统
Log.Message($"Pawn {selectedPawn.Label} died unexpectedly. Starting self-destruct.");
InitiateSelfDestruct();
}
return;
}
@@ -379,6 +460,12 @@ namespace ArachnaeSwarm
// 确保pawn不在死亡跟踪列表中
pawnsKilledByVat.Remove(pawn);
// 重置自毁系统
selfDestructInitiated = false;
pawnMissingTickCount = 0;
Log.Message($"Pawn {pawn.Label} inserted into RefuelingVat at {Position}. Self-destruct monitoring active.");
}
if (deselected)
{
@@ -392,10 +479,11 @@ namespace ArachnaeSwarm
{
try
{
// 检查pawn是否还活着如果已经死亡且是被建筑杀死的跳过弹出
// 检查pawn是否还活着如果已经死亡且是被建筑杀死的启动自毁
if (selectedPawn.Dead && pawnsKilledByVat.Contains(selectedPawn))
{
HandlePawnDeath(selectedPawn);
Log.Message($"Pawn {selectedPawn.Label} killed by vat. Starting self-destruct.");
InitiateSelfDestruct();
return;
}
@@ -426,7 +514,7 @@ namespace ArachnaeSwarm
// 方法3强制移除仅对活着的pawn
if (!ejected && innerContainer.Contains(selectedPawn) && !selectedPawn.Dead)
{
ArachnaeLog.Debug($"Forcing removal of pawn {selectedPawn} from RefuelingVat");
Log.Message($"Forcing removal of pawn {selectedPawn} from RefuelingVat");
innerContainer.Remove(selectedPawn);
GenPlace.TryPlaceThing(selectedPawn, this.Position, base.Map, ThingPlaceMode.Near);
ejected = true;
@@ -435,16 +523,16 @@ namespace ArachnaeSwarm
if (ejected)
{
ArachnaeLog.Debug($"Successfully ejected {selectedPawn} using method: {ejectionMethod}");
Log.Message($"Successfully ejected {selectedPawn} using method: {ejectionMethod}");
}
else if (!selectedPawn.Dead) // 只有活着的pawn弹出失败才报错
{
ArachnaeLog.Debug($"Failed to eject {selectedPawn} from RefuelingVat");
Log.Message($"Failed to eject {selectedPawn} from RefuelingVat");
}
}
catch (Exception ex)
{
ArachnaeLog.Debug($"Error during Finish() for {selectedPawn}: {ex}");
Log.Error($"Error during Finish() for {selectedPawn}: {ex}");
}
finally
{
@@ -463,7 +551,7 @@ namespace ArachnaeSwarm
// 确保pawn不在容器中除非是被建筑杀死的
if (innerContainer.Contains(selectedPawn) && !(selectedPawn.Dead && pawnsKilledByVat.Contains(selectedPawn)))
{
ArachnaeLog.Debug($"Pawn {selectedPawn} still in container during OnStop, forcing removal.");
Log.Message($"Pawn {selectedPawn} still in container during OnStop, forcing removal.");
innerContainer.Remove(selectedPawn);
}
}
@@ -476,6 +564,7 @@ namespace ArachnaeSwarm
// 可以在这里添加音效
}
// === 修改添加取消Gizmo ===
public override IEnumerable<Gizmo> GetGizmos()
{
// 原有的基础Gizmos
@@ -483,84 +572,77 @@ namespace ArachnaeSwarm
{
yield return gizmo;
}
if (base.Working)
// 选择殖民者的操作
var command_Action = new Command_Action
{
}
else
defaultLabel = "InsertPerson".Translate() + "...",
defaultDesc = "InsertPersonRefuelingVatDesc".Translate(),
icon = Building_GrowthVat.InsertPawnIcon.Texture,
action = () =>
{
List<FloatMenuOption> list = new List<FloatMenuOption>();
foreach (Pawn p in base.Map.mapPawns.AllPawnsSpawned)
{
if (p != null && !p.Destroyed && CanAcceptPawn(p).Accepted)
{
list.Add(new FloatMenuOption(p.LabelCap, () => SelectPawn(p), p, Color.white));
}
}
if (!list.Any())
{
list.Add(new FloatMenuOption("NoViablePawns".Translate(), null));
}
Find.WindowStack.Add(new FloatMenu(list));
}
};
if (!base.AnyAcceptablePawns)
{
// 选择殖民者的操作
var command_Action = new Command_Action
{
defaultLabel = "InsertPerson".Translate() + "...",
defaultDesc = "InsertPersonRefuelingVatDesc".Translate(),
icon = Building_GrowthVat.InsertPawnIcon.Texture,
action = () =>
{
List<FloatMenuOption> list = new List<FloatMenuOption>();
foreach (Pawn p in base.Map.mapPawns.AllPawnsSpawned)
{
if (p != null && !p.Destroyed && CanAcceptPawn(p).Accepted)
{
list.Add(new FloatMenuOption(p.LabelCap, () => SelectPawn(p), p, Color.white));
}
}
if (!list.Any())
{
list.Add(new FloatMenuOption("NoViablePawns".Translate(), null));
}
Find.WindowStack.Add(new FloatMenu(list));
}
};
if (!base.AnyAcceptablePawns)
{
command_Action.Disable("NoViablePawns".Translate());
}
yield return command_Action;
// 指派搬运囚犯/奴隶的操作
var command_CarryPrisoner = new Command_Action
{
defaultLabel = "AssignCarryPrisoner".Translate() + "...",
defaultDesc = "AssignCarryPrisonerDesc".Translate(),
icon = ContentFinder<Texture2D>.Get("UI/Commands/Attack"),
action = () =>
{
List<FloatMenuOption> list = new List<FloatMenuOption>();
// 获取所有可接受的囚犯和奴隶
foreach (Pawn p in base.Map.mapPawns.AllPawnsSpawned)
{
if (p != null && !p.Destroyed && CanAcceptPawn(p).Accepted && (p.IsPrisonerOfColony || p.IsSlaveOfColony))
{
list.Add(new FloatMenuOption(
p.LabelCap + " (" + (p.IsPrisonerOfColony ? "Prisoner" : "Slave") + ")",
() => AssignCarrierForPrisoner(p),
p,
Color.white
));
}
}
if (!list.Any())
{
list.Add(new FloatMenuOption("NoPrisonersOrSlaves".Translate(), null));
}
Find.WindowStack.Add(new FloatMenu(list));
}
};
// 检查是否有可用的囚犯/奴隶
bool hasPrisonersOrSlaves = base.Map.mapPawns.AllPawnsSpawned
.Any(p => p != null && !p.Destroyed && CanAcceptPawn(p).Accepted && (p.IsPrisonerOfColony || p.IsSlaveOfColony));
if (!hasPrisonersOrSlaves)
{
command_CarryPrisoner.Disable("NoPrisonersOrSlaves".Translate());
}
yield return command_CarryPrisoner;
command_Action.Disable("NoViablePawns".Translate());
}
yield return command_Action;
// 指派搬运囚犯/奴隶的操作
var command_CarryPrisoner = new Command_Action
{
defaultLabel = "AssignCarryPrisoner".Translate() + "...",
defaultDesc = "AssignCarryPrisonerDesc".Translate(),
icon = ContentFinder<Texture2D>.Get("UI/Commands/Attack"),
action = () =>
{
List<FloatMenuOption> list = new List<FloatMenuOption>();
// 获取所有可接受的囚犯和奴隶
foreach (Pawn p in base.Map.mapPawns.AllPawnsSpawned)
{
if (p != null && !p.Destroyed && CanAcceptPawn(p).Accepted && (p.IsPrisonerOfColony || p.IsSlaveOfColony))
{
list.Add(new FloatMenuOption(
p.LabelCap + " (" + (p.IsPrisonerOfColony ? "Prisoner" : "Slave") + ")",
() => AssignCarrierForPrisoner(p),
p,
Color.white
));
}
}
if (!list.Any())
{
list.Add(new FloatMenuOption("NoPrisonersOrSlaves".Translate(), null));
}
Find.WindowStack.Add(new FloatMenu(list));
}
};
// 检查是否有可用的囚犯/奴隶
bool hasPrisonersOrSlaves = base.Map.mapPawns.AllPawnsSpawned
.Any(p => p != null && !p.Destroyed && CanAcceptPawn(p).Accepted && (p.IsPrisonerOfColony || p.IsSlaveOfColony));
if (!hasPrisonersOrSlaves)
{
command_CarryPrisoner.Disable("NoPrisonersOrSlaves".Translate());
}
yield return command_CarryPrisoner;
}
public override string GetInspectString()
@@ -568,7 +650,12 @@ namespace ArachnaeSwarm
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append(base.GetInspectString());
if (base.Working && selectedPawn != null && !selectedPawn.Destroyed)
if (selfDestructInitiated)
{
stringBuilder.AppendLineIfNotEmpty().Append("RefuelingVat_SelfDestructActive".Translate());
stringBuilder.AppendLineIfNotEmpty().Append("RefuelingVat_SelfDestructCountdown".Translate((MissingTicksBeforeDestruction - pawnMissingTickCount) / 60f));
}
else if (base.Working && selectedPawn != null && !selectedPawn.Destroyed)
{
stringBuilder.AppendLineIfNotEmpty().Append("CasketContains".Translate().ToString() + ": " + selectedPawn.NameShortColored.Resolve());
@@ -668,7 +755,7 @@ namespace ArachnaeSwarm
JobDef carryJobDef = DefDatabase<JobDef>.GetNamed("ARA_CarryPrisonerToRefuelingVat");
if (carryJobDef == null)
{
ArachnaeLog.Debug("ARA_CarryPrisonerToRefuelingVat JobDef not found!");
Log.Error("ARA_CarryPrisonerToRefuelingVat JobDef not found!");
return null;
}
Job job = JobMaker.MakeJob(carryJobDef, prisoner, this);
@@ -749,6 +836,8 @@ namespace ArachnaeSwarm
base.ExposeData();
Scribe_Collections.Look(ref pawnTickCounters, "pawnTickCounters", LookMode.Reference, LookMode.Value);
Scribe_Collections.Look(ref pawnsKilledByVat, "pawnsKilledByVat", LookMode.Reference);
Scribe_Values.Look(ref selfDestructInitiated, "selfDestructInitiated", false);
Scribe_Values.Look(ref pawnMissingTickCount, "pawnMissingTickCount", 0);
// 确保集合不为null
if (Scribe.mode == LoadSaveMode.PostLoadInit)

View File

@@ -74,7 +74,7 @@ namespace ArachnaeSwarm
new QualityHediffReward(0.30f, 1, false, "ARA_QualityReward_1Hediff"),
new QualityHediffReward(0.50f, 2, false, "ARA_QualityReward_2Hediff"),
new QualityHediffReward(0.85f, 3, false, "ARA_QualityReward_3Hediff"),
new QualityHediffReward(0.99f, 4, true, "ARA_QualityReward_AllHediff")
new QualityHediffReward(0.99f, 4, false, "ARA_QualityReward_4Hediff")
};
}
@@ -141,14 +141,7 @@ namespace ArachnaeSwarm
if (reward.qualityThreshold > 0 && reward.hediffCount > 0)
{
string rewardText = $" {reward.qualityThreshold:P0}: ";
if (reward.giveAllHediffs)
{
rewardText += "AllHediffsReward".Translate();
}
else
{
rewardText += "HediffCountReward".Translate(reward.hediffCount);
}
rewardText += "HediffCountReward".Translate(reward.hediffCount);
builder.AppendLine(rewardText);
}
}

View File

@@ -193,7 +193,7 @@ namespace ArachnaeSwarm
// 显示剩余时间
Rect timeRect = new Rect(0f, curY, viewRect.width, SmallLabelHeight);
string timeText = "TimeRemaining".Translate() + ": " + daysRemaining.ToString("F1") + " " + "Days".Translate();
string timeText = "ARA_OothecaIncubator.TimeRemaining".Translate() + ": " + daysRemaining.ToString("F1") + " " + "Days".Translate();
if (hoursRemaining > 0.1f && daysRemaining < 1f)
{
timeText += " (" + hoursRemaining.ToString("F1") + " " + "Hours".Translate() + ")";