diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll
index 4dc662f..e90b4a1 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_HiveShip.xml b/1.6/1.6/Defs/Thing_building/ARA_HiveShip.xml
index a1c5279..61d6189 100644
--- a/1.6/1.6/Defs/Thing_building/ARA_HiveShip.xml
+++ b/1.6/1.6/Defs/Thing_building/ARA_HiveShip.xml
@@ -3,15 +3,16 @@
ARA_HiveShip_Heart
猎手虫巢舰-心脏
- 一艘阿拉克涅虫群猎手虫巢舰的心脏。其功能和人类的逆重引擎类似
+ 一艘阿拉克涅虫群猎手虫巢舰的心脏,其功能和人类的逆重引擎类似。
ArachnaeSwarm.Building_ArachnaeGravEngine
RealtimeOnly
Normal
MinifiedThing
+ ArachnaeSwarm/Building/ARA_HiveShip_Heart_Icon
Graphic_Single
- Things/Building/GravEngine/GravEngine
- (3,3)
+ ArachnaeSwarm/Building/ARA_HiveShip_Heart_Pedestal
+ (3.25,3.25)
true
@@ -24,17 +25,15 @@
- UI/Commands/ArachnaeInspect
- Things/Building/ArachnaeGravEngine/ArachnaeGravEngine_Orb
- Things/Building/ArachnaeGravEngine/ArachnaeGravEngine_Cooldown
- UI/Icons/ArachnaeSwarm
+ UI/Commands/Inspect
+ ArachnaeSwarm/Building/ARA_HiveShip_Heart
+ ArachnaeSwarm/Building/ARA_HiveShip_Heart
(3,3)
true
0.6
- PassThroughOnly
- 20
+ Impassable
false
true
@@ -48,20 +47,18 @@
8
- (0,218,255,0)
+ (199,136,114,0)
- GravFieldExtender
- PilotConsole
- ChemfuelTank
- LargeChemfuelTank
- SmallThruster
- LargeThruster
+ GravFieldExtender
+ PilotConsole
+ ARA_HiveShip_Stomach
+ ARA_HiveShip_Tail
FuelOptimizer
SignalJammer
PilotSubpersonaCore
@@ -73,4 +70,114 @@
+
+ ARA_HiveShip_Stomach
+ 猎手虫巢舰-胃囊
+ 阿拉克涅虫群猎手虫巢舰的胃囊,它可以储存供虫巢舰进行移动的生物质。
+
+ Graphic_Multi
+ Things/Building/ChemfuelTank/ChemfuelTank
+ (2, 2)
+
+
+ 200
+ 30
+ 1
+ -10
+ 2000
+
+ (2, 2)
+
+ 120
+
+
+ BasicGravtech
+
+
+
+ 250
+ true
+ 250
+
+
+ Chemfuel
+
+
+ Chemfuel
+ Chemfuel
+ true
+ 1
+ true
+ false
+ true
+ true
+ false
+
+
+
+
+ ARA_HiveShip_Tail
+ small thruster
+ A chemfuel thruster that increases the range of a gravship. Thrusters require an unobstructed area free of large buildings and gravship substructure.\n\nA gravship can support up to four small thrusters.
+
+ Graphic_Multi
+ Things/Building/SmallThruster/SmallThruster
+ (1.1, 2.2)
+
+ (1, 1, 2)
+
+
+
+ 250
+ 0
+ -10
+ 10000
+ 20
+
+ (1, 2)
+ 4
+
+ 180
+ 4
+
+
+ BasicGravtech
+
+
+
+
+ 10
+
+ Thruster
+ (1, 0, 5)
+ (0, 0, -5)
+ 20
+ 4.0
+
+ (0, 0, 0.5)
+ (0, 0, 0.5)
+ (0, 0, 0.5)
+ (0, 0, 0.5)
+
+ MoteGlow
+
+ <_MainTex>/Things/Mote/SmallThruster_Burn
+
+ false
+ 4
+ 500
+
+ GravshipThrusterExhaust
+ 40.0
+ 0.0~0.5
+ (0.0,0.0,-20.0)
+ -10.0~10.0
+ 0.8~1.2
+ -180.0~180.0
+ 1.5~3.0
+
+
+
+
+
\ No newline at end of file
diff --git a/Content/Textures/ArachnaeSwarm/Building/ARA_HiveShip_Heart.png b/Content/Textures/ArachnaeSwarm/Building/ARA_HiveShip_Heart.png
new file mode 100644
index 0000000..9098272
Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Building/ARA_HiveShip_Heart.png differ
diff --git a/Content/Textures/ArachnaeSwarm/Building/ARA_HiveShip_Heart_Cooldown.png b/Content/Textures/ArachnaeSwarm/Building/ARA_HiveShip_Heart_Cooldown.png
new file mode 100644
index 0000000..9098272
Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Building/ARA_HiveShip_Heart_Cooldown.png differ
diff --git a/Content/Textures/ArachnaeSwarm/Building/ARA_HiveShip_Heart_Icon.png b/Content/Textures/ArachnaeSwarm/Building/ARA_HiveShip_Heart_Icon.png
new file mode 100644
index 0000000..215ebdb
Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Building/ARA_HiveShip_Heart_Icon.png differ
diff --git a/Content/Textures/ArachnaeSwarm/Building/ARA_HiveShip_Heart_Pedestal.png b/Content/Textures/ArachnaeSwarm/Building/ARA_HiveShip_Heart_Pedestal.png
new file mode 100644
index 0000000..bdc47e0
Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Building/ARA_HiveShip_Heart_Pedestal.png differ
diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo
index 61921df..b0d8646 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 f7dbf27..581d4ba 100644
--- a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json
+++ b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json
@@ -1,25 +1,17 @@
{
"Version": 1,
- "WorkspaceRootPath": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
+ "WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
"Documents": [
{
- "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\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\\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|e:\\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|E:\\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|E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\hediffs\\ara_hediffterrainspawn\\comphediffterrainspawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_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|E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\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\\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}"
}
],
@@ -40,59 +32,35 @@
"$type": "Document",
"DocumentIndex": 0,
"Title": "Building_ArachnaeGravEngine.cs",
- "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ArachnaeGravEngine.cs",
+ "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ArachnaeGravEngine.cs",
"RelativeDocumentMoniker": "Buildings\\Building_ArachnaeGravEngine.cs",
- "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ArachnaeGravEngine.cs",
+ "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ArachnaeGravEngine.cs",
"RelativeToolTip": "Buildings\\Building_ArachnaeGravEngine.cs",
- "ViewState": "AgIAAAAAAAAAAAAAAADwvw0AAAAmAAAAAAAAAA==",
+ "ViewState": "AgIAAK0AAAAAAAAAAAAUwL4AAAANAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2025-10-23T12:04:20.765Z",
+ "WhenOpened": "2025-10-24T02:30:45.288Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 1,
- "Title": "CompSpawnPawnFromList.cs",
- "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SpawnPawnFromList\\CompSpawnPawnFromList.cs",
- "RelativeDocumentMoniker": "Building_Comps\\ARA_SpawnPawnFromList\\CompSpawnPawnFromList.cs",
- "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SpawnPawnFromList\\CompSpawnPawnFromList.cs",
- "RelativeToolTip": "Building_Comps\\ARA_SpawnPawnFromList\\CompSpawnPawnFromList.cs",
- "ViewState": "AgIAAHQAAAAAAAAAAAAgwKAAAAA/AAAAAAAAAA==",
+ "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-23T10:44:55.813Z",
+ "WhenOpened": "2025-10-23T08:00:28.236Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 2,
- "Title": "CompProperties_SpawnPawnFromList.cs",
- "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SpawnPawnFromList\\CompProperties_SpawnPawnFromList.cs",
- "RelativeDocumentMoniker": "Building_Comps\\ARA_SpawnPawnFromList\\CompProperties_SpawnPawnFromList.cs",
- "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SpawnPawnFromList\\CompProperties_SpawnPawnFromList.cs",
- "RelativeToolTip": "Building_Comps\\ARA_SpawnPawnFromList\\CompProperties_SpawnPawnFromList.cs",
- "ViewState": "AgIAAAAAAAAAAAAAAADwvwAAAAAAAAAAAAAAAA==",
- "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2025-10-23T10:44:53.422Z"
- },
- {
- "$type": "Document",
- "DocumentIndex": 3,
- "Title": "CompHediffTerrainSpawn.cs",
- "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HediffTerrainSpawn\\CompHediffTerrainSpawn.cs",
- "RelativeDocumentMoniker": "Hediffs\\ARA_HediffTerrainSpawn\\CompHediffTerrainSpawn.cs",
- "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_HediffTerrainSpawn\\CompHediffTerrainSpawn.cs",
- "RelativeToolTip": "Hediffs\\ARA_HediffTerrainSpawn\\CompHediffTerrainSpawn.cs",
- "ViewState": "AgIAAF4AAAAAAAAAAAAAAG4AAAAAAAAAAAAAAA==",
- "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2025-10-23T08:00:28.236Z"
- },
- {
- "$type": "Document",
- "DocumentIndex": 4,
"Title": "CompAbilityEffect_RandomHediff.cs",
- "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\CompAbilityEffect_RandomHediff.cs",
+ "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\CompAbilityEffect_RandomHediff.cs",
"RelativeDocumentMoniker": "Abilities\\CompAbilityEffect_RandomHediff.cs",
- "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\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|",
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 110c48f..61bd1e4 100644
--- a/Source/ArachnaeSwarm/Building_Comps/ARA_Building_RefuelingVat/Building_RefuelingVat.cs
+++ b/Source/ArachnaeSwarm/Building_Comps/ARA_Building_RefuelingVat/Building_RefuelingVat.cs
@@ -114,7 +114,8 @@ namespace ArachnaeSwarm
{
if (selectedPawn != null && innerContainer.Contains(selectedPawn))
{
- Notify_PawnRemoved();
+ Log.Warning($"RefuelingVat despawned with pawn inside, forcing ejection.");
+ Finish(); // 使用修改后的Finish方法
}
}
base.DeSpawn(mode);
@@ -172,6 +173,13 @@ namespace ArachnaeSwarm
if (base.Working && selectedPawn != null)
{
+ // 检查俘虏是否死亡 - 增加更严格的检查
+ if (selectedPawn.Dead || selectedPawn.Destroyed)
+ {
+ Finish();
+ return;
+ }
+
// 酸蚀伤害逻辑
if (pawnTickCounters.TryGetValue(selectedPawn, out int tickCount))
{
@@ -195,13 +203,6 @@ namespace ArachnaeSwarm
float fuelToAdd = FuelProductionPerTick;
RefuelableComp.Refuel(fuelToAdd);
}
-
- // 检查俘虏是否死亡
- if (selectedPawn.Dead)
- {
- Finish();
- return;
- }
}
}
@@ -254,11 +255,61 @@ namespace ArachnaeSwarm
private void Finish()
{
- if (selectedPawn != null && innerContainer.Contains(selectedPawn))
+ if (selectedPawn != null)
{
- Notify_PawnRemoved();
- innerContainer.TryDrop(selectedPawn, InteractionCell, base.Map, ThingPlaceMode.Near, 1, out var _);
- OnStop();
+ try
+ {
+ Notify_PawnRemoved();
+
+ bool ejected = false;
+ string ejectionMethod = "None";
+
+ // 方法1:标准弹出 - 在交互单元格附近
+ if (innerContainer.Contains(selectedPawn))
+ {
+ ejected = innerContainer.TryDrop(selectedPawn, InteractionCell, base.Map, ThingPlaceMode.Near, 1, out var _);
+ if (ejected) ejectionMethod = "Standard";
+ }
+
+ // 方法2:尝试随机相邻单元格
+ if (!ejected && innerContainer.Contains(selectedPawn))
+ {
+ var adjacentCells = GenAdj.CellsAdjacent8Way(this).Where(c => c.Walkable(base.Map) && c.InBounds(base.Map)).ToList();
+ if (adjacentCells.Count > 0)
+ {
+ IntVec3 randomCell = adjacentCells.RandomElement();
+ ejected = innerContainer.TryDrop(selectedPawn, randomCell, base.Map, ThingPlaceMode.Direct, 1, out var _);
+ if (ejected) ejectionMethod = "Adjacent";
+ }
+ }
+
+ // 方法3:强制移除
+ if (!ejected && innerContainer.Contains(selectedPawn))
+ {
+ Log.Warning($"Forcing removal of dead pawn {selectedPawn} from RefuelingVat");
+ innerContainer.Remove(selectedPawn);
+ GenPlace.TryPlaceThing(selectedPawn, this.Position, base.Map, ThingPlaceMode.Near);
+ ejected = true;
+ ejectionMethod = "Forced";
+ }
+
+ if (ejected)
+ {
+ Log.Message($"Successfully ejected {selectedPawn} using method: {ejectionMethod}");
+ }
+ else
+ {
+ Log.Error($"Failed to eject {selectedPawn} from RefuelingVat");
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error($"Error during Finish() for {selectedPawn}: {ex}");
+ }
+ finally
+ {
+ OnStop();
+ }
}
}
@@ -267,6 +318,13 @@ namespace ArachnaeSwarm
if (selectedPawn != null)
{
pawnTickCounters.Remove(selectedPawn);
+
+ // 确保pawn不在容器中
+ if (innerContainer.Contains(selectedPawn))
+ {
+ Log.Warning($"Pawn {selectedPawn} still in container during OnStop, forcing removal.");
+ innerContainer.Remove(selectedPawn);
+ }
}
selectedPawn = null;
startTick = -1;
diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_NutrientVat/Building_NutrientVat.cs b/Source/ArachnaeSwarm/Building_Comps/ARA_NutrientVat/Building_NutrientVat.cs
index 8e2ef16..b1ba301 100644
--- a/Source/ArachnaeSwarm/Building_Comps/ARA_NutrientVat/Building_NutrientVat.cs
+++ b/Source/ArachnaeSwarm/Building_Comps/ARA_NutrientVat/Building_NutrientVat.cs
@@ -88,6 +88,10 @@ namespace ArachnaeSwarm
}
}
+ // 酸蚀伤害间隔(每6000 tick约1/10天)
+ private const int AcidDamageInterval = 6000;
+ private Dictionary pawnTickCounters = new Dictionary();
+
public override void SpawnSetup(Map map, bool respawningAfterLoad)
{
base.SpawnSetup(map, respawningAfterLoad);
@@ -100,19 +104,13 @@ namespace ArachnaeSwarm
{
if (selectedPawn != null && innerContainer.Contains(selectedPawn))
{
- Notify_PawnRemoved();
+ Log.Warning($"NutrientVat despawned with pawn inside, forcing ejection.");
+ Finish(); // 使用修改后的Finish方法
}
}
base.DeSpawn(mode);
}
- //ĵ㣺Աʴ˺
- private Dictionary pawnTickCounters = new Dictionary();
- private BodyPartRecord GetRandomBodyPart(Pawn pawn)
- {
- var parts = pawn.health.hediffSet.GetNotMissingParts().ToList();
- return parts.Count > 0 ? parts.RandomElement() : pawn.RaceProps.body.corePart;
- }
private void ApplyAcidDamage(Pawn pawn)
{
try
@@ -123,14 +121,14 @@ namespace ArachnaeSwarm
DamageInfo acidDamage = new DamageInfo(
acidDamageDef,
- 3f, // ÿ3˺
- 2f, // ״
- -1f, // Ƕ
+ 3f, // 每次3点伤害
+ 2f, // 护甲穿透
+ -1f, // 随机角度
instigator: null,
hitPart: targetPart
);
- // Ӧ˺
+ // 应用伤害
pawn.TakeDamage(acidDamage);
}
catch (Exception ex)
@@ -138,9 +136,10 @@ namespace ArachnaeSwarm
Log.Error($"Error applying acid damage to {pawn}: {ex.Message}");
}
}
+
private BodyPartRecord GetRandomVulnerablePart(Pawn pawn)
{
- // ѡⲿ岿λ
+ // 优先选择外部身体部位
var vulnerableParts = pawn.health.hediffSet.GetNotMissingParts()
.Where(part => part.depth == BodyPartDepth.Outside &&
!part.def.conceptual &&
@@ -164,24 +163,23 @@ namespace ArachnaeSwarm
if (base.Working && selectedPawn != null)
{
- //ĵ㣺Աʴ˺
+ // 检查俘虏是否死亡 - 增加更严格的检查
+ if (selectedPawn.Dead || selectedPawn.Destroyed)
+ {
+ Finish();
+ return;
+ }
+
+ // 酸蚀伤害逻辑
if (pawnTickCounters.TryGetValue(selectedPawn, out int tickCount))
{
tickCount++;
pawnTickCounters[selectedPawn] = tickCount;
- if (tickCount >= 6000)
+ if (tickCount >= AcidDamageInterval)
{
- DamageInfo acidDamage = new DamageInfo(
- DefDatabase.GetNamed("AcidBurn") ?? DamageDefOf.Burn,
- 1f,
- 100f, // ȫ״
- -1f,
- instigator: null,
- hitPart: GetRandomBodyPart(selectedPawn)
- );
- pawnTickCounters[selectedPawn] = 0;
ApplyAcidDamage(selectedPawn);
+ pawnTickCounters[selectedPawn] = 0;
}
}
else
@@ -242,24 +240,26 @@ namespace ArachnaeSwarm
{
return "PawnBiostarving".Translate(pawn.Named("PAWN"));
}
- //ĵ㣺ֹȺԱ
- if (pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindMaster) || pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindDrone) || pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindWorker))
+ // 禁止置入虫群成员
+ if (pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindMaster) ||
+ pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindDrone) ||
+ pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindWorker))
{
return "PawnIsHiveMember".Translate(pawn.Named("PAWN"));
}
- //ĵ㣺ֳߡū
+ // 允许殖民者、囚犯和奴隶
bool isColonist = pawn.IsColonist;
bool isPrisoner = pawn.IsPrisonerOfColony;
bool isSlave = pawn.IsSlaveOfColony;
- // ֳߡū
+ // 允许殖民者、囚犯或奴隶,但不能是任务寄宿者
return (isColonist || isPrisoner || isSlave) && !pawn.IsQuestLodger();
}
public override void TryAcceptPawn(Pawn pawn)
{
- if (!CanAcceptPawn(pawn))
+ if (!CanAcceptPawn(pawn).Accepted)
{
return;
}
@@ -269,6 +269,7 @@ namespace ArachnaeSwarm
if (innerContainer.TryAddOrTransfer(pawn))
{
startTick = Find.TickManager.TicksGame;
+ pawnTickCounters[pawn] = 0; // 初始化伤害计数器
}
if (deselected)
{
@@ -278,28 +279,143 @@ namespace ArachnaeSwarm
private void Finish()
{
- if (selectedPawn != null && innerContainer.Contains(selectedPawn))
+ if (selectedPawn != null)
{
- Notify_PawnRemoved();
- innerContainer.TryDrop(selectedPawn, InteractionCell, base.Map, ThingPlaceMode.Near, 1, out var _);
- OnStop();
+ try
+ {
+ Notify_PawnRemoved();
+
+ bool ejected = false;
+ string ejectionMethod = "None";
+
+ // 方法1:标准弹出 - 在交互单元格附近
+ if (innerContainer.Contains(selectedPawn))
+ {
+ ejected = innerContainer.TryDrop(selectedPawn, InteractionCell, base.Map, ThingPlaceMode.Near, 1, out var _);
+ if (ejected) ejectionMethod = "Standard";
+ }
+
+ // 方法2:尝试随机相邻单元格
+ if (!ejected && innerContainer.Contains(selectedPawn))
+ {
+ var adjacentCells = GenAdj.CellsAdjacent8Way(this).Where(c => c.Walkable(base.Map) && c.InBounds(base.Map)).ToList();
+ if (adjacentCells.Count > 0)
+ {
+ IntVec3 randomCell = adjacentCells.RandomElement();
+ ejected = innerContainer.TryDrop(selectedPawn, randomCell, base.Map, ThingPlaceMode.Direct, 1, out var _);
+ if (ejected) ejectionMethod = "Adjacent";
+ }
+ }
+
+ // 方法3:强制移除
+ if (!ejected && innerContainer.Contains(selectedPawn))
+ {
+ Log.Warning($"Forcing removal of pawn {selectedPawn} from NutrientVat");
+ innerContainer.Remove(selectedPawn);
+ GenPlace.TryPlaceThing(selectedPawn, this.Position, base.Map, ThingPlaceMode.Near);
+ ejected = true;
+ ejectionMethod = "Forced";
+ }
+
+ if (ejected)
+ {
+ Log.Message($"Successfully ejected {selectedPawn} using method: {ejectionMethod}");
+ }
+ else
+ {
+ Log.Error($"Failed to eject {selectedPawn} from NutrientVat");
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error($"Error during Finish() for {selectedPawn}: {ex}");
+ }
+ finally
+ {
+ OnStop();
+ }
}
}
private void Fail()
{
- if (selectedPawn != null && innerContainer.Contains(selectedPawn))
+ if (selectedPawn != null)
{
- Notify_PawnRemoved();
- innerContainer.TryDrop(selectedPawn, InteractionCell, base.Map, ThingPlaceMode.Near, 1, out var _);
- Hediff firstHediffOfDef = selectedPawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.BioStarvation);
- selectedPawn.Kill(null, firstHediffOfDef);
+ try
+ {
+ Notify_PawnRemoved();
+
+ bool ejected = false;
+ string ejectionMethod = "None";
+
+ // 方法1:标准弹出 - 在交互单元格附近
+ if (innerContainer.Contains(selectedPawn))
+ {
+ ejected = innerContainer.TryDrop(selectedPawn, InteractionCell, base.Map, ThingPlaceMode.Near, 1, out var _);
+ if (ejected) ejectionMethod = "Standard";
+ }
+
+ // 方法2:尝试随机相邻单元格
+ if (!ejected && innerContainer.Contains(selectedPawn))
+ {
+ var adjacentCells = GenAdj.CellsAdjacent8Way(this).Where(c => c.Walkable(base.Map) && c.InBounds(base.Map)).ToList();
+ if (adjacentCells.Count > 0)
+ {
+ IntVec3 randomCell = adjacentCells.RandomElement();
+ ejected = innerContainer.TryDrop(selectedPawn, randomCell, base.Map, ThingPlaceMode.Direct, 1, out var _);
+ if (ejected) ejectionMethod = "Adjacent";
+ }
+ }
+
+ // 方法3:强制移除
+ if (!ejected && innerContainer.Contains(selectedPawn))
+ {
+ Log.Warning($"Forcing removal of failed pawn {selectedPawn} from NutrientVat");
+ innerContainer.Remove(selectedPawn);
+ GenPlace.TryPlaceThing(selectedPawn, this.Position, base.Map, ThingPlaceMode.Near);
+ ejected = true;
+ ejectionMethod = "Forced";
+ }
+
+ if (ejected)
+ {
+ Log.Message($"Successfully ejected failed pawn {selectedPawn} using method: {ejectionMethod}");
+ // 在成功弹出后杀死俘虏
+ Hediff firstHediffOfDef = selectedPawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.BioStarvation);
+ selectedPawn.Kill(null, firstHediffOfDef);
+ }
+ else
+ {
+ Log.Error($"Failed to eject failed pawn {selectedPawn} from NutrientVat");
+ // 即使弹出失败也要杀死俘虏
+ Hediff firstHediffOfDef = selectedPawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.BioStarvation);
+ selectedPawn.Kill(null, firstHediffOfDef);
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error($"Error during Fail() for {selectedPawn}: {ex}");
+ }
+ finally
+ {
+ OnStop();
+ }
}
- OnStop();
}
private void OnStop()
{
+ if (selectedPawn != null)
+ {
+ pawnTickCounters.Remove(selectedPawn);
+
+ // 确保pawn不在容器中
+ if (innerContainer.Contains(selectedPawn))
+ {
+ Log.Warning($"Pawn {selectedPawn} still in container during OnStop, forcing removal.");
+ innerContainer.Remove(selectedPawn);
+ }
+ }
selectedPawn = null;
startTick = -1;
if (RefuelableComp != null)
@@ -312,22 +428,22 @@ namespace ArachnaeSwarm
{
// You can add sound effects here if you want, e.g., SoundDefOf.GrowthVat_Open.PlayOneShot(SoundInfo.InMap(this));
}
+
public override IEnumerable GetGizmos()
{
- // ԭеĻGizmos
+ // 原有的基础Gizmos
foreach (Gizmo gizmo in base.GetGizmos())
{
yield return gizmo;
}
- // ĵ㣺ɾ˵
if (base.Working)
{
- // ԭеĹ״̬µGizmos
+ // 原有的工作状态下的Gizmos
}
else
{
- // ԭеѡֳߵIJ
+ // 原有的选择殖民者的操作
var command_Action = new Command_Action
{
defaultLabel = "InsertPerson".Translate() + "...",
@@ -338,7 +454,7 @@ namespace ArachnaeSwarm
List list = new List();
foreach (Pawn p in base.Map.mapPawns.AllPawnsSpawned)
{
- if ((bool)CanAcceptPawn(p))
+ if (CanAcceptPawn(p).Accepted)
{
list.Add(new FloatMenuOption(p.LabelCap, () => SelectPawn(p), p, Color.white));
}
@@ -356,7 +472,7 @@ namespace ArachnaeSwarm
}
yield return command_Action;
- // ָɰ/ūIJ
+ // 指派搬运囚犯/奴隶的操作
var command_CarryPrisoner = new Command_Action
{
defaultLabel = "AssignCarryPrisoner".Translate() + "...",
@@ -366,10 +482,10 @@ namespace ArachnaeSwarm
{
List list = new List();
- // ȡпɽܵū
+ // 获取所有可接受的囚犯和奴隶
foreach (Pawn p in base.Map.mapPawns.AllPawnsSpawned)
{
- if ((bool)CanAcceptPawn(p) && (p.IsPrisonerOfColony || p.IsSlaveOfColony))
+ if (CanAcceptPawn(p).Accepted && (p.IsPrisonerOfColony || p.IsSlaveOfColony))
{
list.Add(new FloatMenuOption(
p.LabelCap + " (" + (p.IsPrisonerOfColony ? "Prisoner" : "Slave") + ")",
@@ -388,9 +504,9 @@ namespace ArachnaeSwarm
}
};
- // Ƿпõ/ū
+ // 检查是否有可用的囚犯/奴隶
bool hasPrisonersOrSlaves = base.Map.mapPawns.AllPawnsSpawned
- .Any(p => (bool)CanAcceptPawn(p) && (p.IsPrisonerOfColony || p.IsSlaveOfColony));
+ .Any(p => CanAcceptPawn(p).Accepted && (p.IsPrisonerOfColony || p.IsSlaveOfColony));
if (!hasPrisonersOrSlaves)
{
@@ -416,6 +532,13 @@ namespace ArachnaeSwarm
string text = ((BiostarvationDailyOffset >= 0f) ? "+" : string.Empty);
stringBuilder.AppendLineIfNotEmpty().Append(string.Format("{0}: {1} ({2})", "Biostarvation".Translate(), biostarvation.Severity.ToStringPercent(), "PerDay".Translate(text + BiostarvationDailyOffset.ToStringPercent())));
}
+
+ // 显示酸蚀伤害信息
+ if (pawnTickCounters.TryGetValue(selectedPawn, out int tickCount))
+ {
+ float damageProgress = (float)tickCount / AcidDamageInterval;
+ stringBuilder.AppendLineIfNotEmpty().Append("AcidDamageProgress".Translate() + ": " + damageProgress.ToStringPercent());
+ }
}
else if (selectedPawn != null)
{
@@ -466,13 +589,14 @@ namespace ArachnaeSwarm
TopGraphic.Draw(DrawPos + Altitudes.AltIncVect * 2f, base.Rotation, this);
}
}
+
public Job CreateCarryJobForPrisoner(Pawn prisoner, Pawn carrier)
{
if (prisoner == null || carrier == null)
return null;
if (!CanAcceptPawn(prisoner).Accepted)
return null;
- // ˹
+ // 创建搬运工作定义
JobDef carryJobDef = DefDatabase.GetNamed("ARA_CarryPrisonerToNutrientVat");
if (carryJobDef == null)
return null;
@@ -480,16 +604,17 @@ namespace ArachnaeSwarm
job.count = 1;
return job;
}
+
public IEnumerable GetAvailableCarriers()
{
foreach (Pawn pawn in base.Map.mapPawns.AllPawnsSpawned)
{
- // ǷdzȺԱӵARA_HiveMindDrone
+ // 检查是否是虫群成员
if (pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindDrone) ||
pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindWorker) ||
pawn.health.hediffSet.HasHediff(ARA_HediffDefOf.ARA_HiveMindMaster))
{
- // ǷܹҲ
+ // 检查是否能够工作且不是囚犯
if (pawn.workSettings != null && pawn.workSettings.WorkIsActive(WorkTypeDefOf.Hauling) &&
!pawn.Downed && !pawn.IsPrisoner && pawn.CanReach(this, PathEndMode.InteractionCell, Danger.Some))
{
@@ -498,11 +623,12 @@ namespace ArachnaeSwarm
}
}
}
+
public void AssignCarrierForPrisoner(Pawn prisoner)
{
if (prisoner == null)
return;
- // ȡõİ
+ // 获取可用的搬运者
var availableCarriers = GetAvailableCarriers().ToList();
if (!availableCarriers.Any())
@@ -510,7 +636,7 @@ namespace ArachnaeSwarm
Messages.Message("NoAvailableHiveCarriers".Translate(), MessageTypeDefOf.RejectInput);
return;
}
- // ˵ѡ
+ // 创建浮动菜单选择搬运者
List options = new List();
foreach (Pawn carrier in availableCarriers)
@@ -539,5 +665,12 @@ namespace ArachnaeSwarm
Messages.Message("NoAvailableCarriers".Translate(), MessageTypeDefOf.RejectInput);
}
}
+
+ // 保存和加载数据
+ public override void ExposeData()
+ {
+ base.ExposeData();
+ Scribe_Collections.Look(ref pawnTickCounters, "pawnTickCounters", LookMode.Reference, LookMode.Value);
+ }
}
-}
\ No newline at end of file
+}
diff --git a/Source/ArachnaeSwarm/Buildings/Building_ArachnaeGravEngine.cs b/Source/ArachnaeSwarm/Buildings/Building_ArachnaeGravEngine.cs
index 0180cba..a5f2776 100644
--- a/Source/ArachnaeSwarm/Buildings/Building_ArachnaeGravEngine.cs
+++ b/Source/ArachnaeSwarm/Buildings/Building_ArachnaeGravEngine.cs
@@ -174,12 +174,22 @@ namespace ArachnaeSwarm
Messages.Message("ArachnaeSwarmActivated".Translate(), this, MessageTypeDefOf.PositiveEvent);
}
- // 重写 DrawAt 方法以使用自定义材质
+ // 重写 DrawAt 方法以完全控制绘制过程
protected override void DrawAt(Vector3 drawLoc, bool flip = false)
{
- base.DrawAt(drawLoc, flip);
+ // 不调用 base.DrawAt,而是直接绘制建筑主体
+ // 复制父类 Building 的 DrawAt 逻辑,但不包括 orb 的绘制
+ if (def.graphicData != null)
+ {
+ Graphic graphic = Graphic;
+ if (graphic != null)
+ {
+ graphic.Draw(drawLoc, flip ? base.Rotation.Opposite : base.Rotation, this, 0f);
+ }
+ }
if (base.Spawned)
{
+ // 应用浮动效果(与父类相同)
if (Find.TickManager.TicksGame >= cooldownCompleteTick)
{
// 使用 Mathf 替代 MathF
@@ -187,8 +197,8 @@ namespace ArachnaeSwarm
}
drawLoc.y += 0.03658537f;
Vector3 s = new Vector3(def.graphicData.drawSize.x, 1f, def.graphicData.drawSize.y);
-
- // 使用自定义的球体材质
+
+ // 只使用自定义的球体材质,不绘制默认 orb
Graphics.DrawMesh(MeshPool.plane10Back, Matrix4x4.TRS(drawLoc, base.Rotation.AsQuat, s), CustomOrbMat.Material, 0, null, 0);
}
}
@@ -217,6 +227,5 @@ namespace ArachnaeSwarm
public string inspectCommandTexPath;
public string orbTexPath;
public string cooldownTexPath;
- public string swarmIconPath;
}
}
diff --git a/非公开资源/Content/Textures/Building/ARA_HiveShip_Heart.sai2 b/非公开资源/Content/Textures/Building/ARA_HiveShip_Heart.sai2
index 213bc1b..6d13f5f 100644
Binary files a/非公开资源/Content/Textures/Building/ARA_HiveShip_Heart.sai2 and b/非公开资源/Content/Textures/Building/ARA_HiveShip_Heart.sai2 differ