diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll
index 7409190..cc15259 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_WormholeDefs.xml b/1.6/1.6/Defs/Thing_building/ARA_WormholeDefs.xml
new file mode 100644
index 0000000..b48046f
--- /dev/null
+++ b/1.6/1.6/Defs/Thing_building/ARA_WormholeDefs.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+ ARA_WormholePortal_A
+
+ The primary control unit of a wormhole network. It can launch a secondary portal to a distant location, establishing a stable connection.
+ ArachnaeSwarm.Building_WormholePortal_A
+
+ Things/Building/Misc/LongRangeMineralScanner
+ Graphic_Multi
+ (4,4)
+
+ Damage/Corner
+ Damage/Corner
+ Damage/Corner
+ Damage/Corner
+
+
+ Building
+ Impassable
+ Normal
+ Building
+ 50
+ 0.5
+
+ 250
+ 8000
+ 0.5
+ 100
+
+ (2,2)
+
+ 100
+ 6
+
+
+
+ CompPowerTrader
+ 500
+
+
+
+ 500.0
+
+
+ ARA_InsectJelly
+
+
+ 虫蜜
+ true
+ true
+
+
+ 50
+ 100
+
+
+ Misc
+
+ false
+
+
+
+
+
+ ARA_WormholePortal_B
+
+ A remotely deployed secondary portal. It is linked to a primary portal (A) and allows for two-way travel.
+ ArachnaeSwarm.Building_WormholePortal_B
+
+ Things/Building/Misc/LongRangeMineralScanner
+ Graphic_Multi
+ (150, 150, 250)
+ (4,4)
+
+ Building
+ Impassable
+
+ 250
+ 0.5
+
+ (2,2)
+
+
+ CompPowerTrader
+ 200
+
+
+
+ None
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
index 6e473cc..b488458 100644
--- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
+++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
@@ -205,6 +205,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/Source/ArachnaeSwarm/HarmonyPatches/Patch_Game_DeinitAndRemoveMap.cs b/Source/ArachnaeSwarm/HarmonyPatches/Patch_Game_DeinitAndRemoveMap.cs
new file mode 100644
index 0000000..0cbbb94
--- /dev/null
+++ b/Source/ArachnaeSwarm/HarmonyPatches/Patch_Game_DeinitAndRemoveMap.cs
@@ -0,0 +1,23 @@
+using HarmonyLib;
+using Verse;
+using System.Linq;
+
+namespace ArachnaeSwarm
+{
+ [HarmonyPatch(typeof(Game), "DeinitAndRemoveMap")]
+ public static class Patch_Game_DeinitAndRemoveMap
+ {
+ [HarmonyPrefix]
+ public static bool Prefix(Map map)
+ {
+ // 如果地图上存在B端传送门,则阻止该地图被销毁
+ if (map != null && map.listerBuildings.AllBuildingsColonistOfClass().Any())
+ {
+ return false; // 返回 false, 阻止原版方法执行
+ }
+
+ // 否则,正常执行原版方法
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/HarmonyPatches/Patch_SettlementDefeatUtility_CheckDefeated.cs b/Source/ArachnaeSwarm/HarmonyPatches/Patch_SettlementDefeatUtility_CheckDefeated.cs
new file mode 100644
index 0000000..ebc7951
--- /dev/null
+++ b/Source/ArachnaeSwarm/HarmonyPatches/Patch_SettlementDefeatUtility_CheckDefeated.cs
@@ -0,0 +1,25 @@
+using HarmonyLib;
+using RimWorld;
+using RimWorld.Planet;
+using Verse;
+using System.Linq;
+
+namespace ArachnaeSwarm
+{
+ [HarmonyPatch(typeof(SettlementDefeatUtility), "CheckDefeated")]
+ public static class Patch_SettlementDefeatUtility_CheckDefeated
+ {
+ [HarmonyPrefix]
+ public static bool Prefix(Settlement factionBase)
+ {
+ // 如果目标没有地图,或者地图上存在B端传送门,则跳过原版的失败检查
+ if (!factionBase.HasMap || factionBase.Map.listerBuildings.AllBuildingsColonistOfClass().Any())
+ {
+ return false; // 返回 false, 阻止原版方法执行
+ }
+
+ // 否则,正常执行原版方法
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/HarmonyPatches/Patch_Site_ShouldRemoveMapNow.cs b/Source/ArachnaeSwarm/HarmonyPatches/Patch_Site_ShouldRemoveMapNow.cs
new file mode 100644
index 0000000..fdf8f28
--- /dev/null
+++ b/Source/ArachnaeSwarm/HarmonyPatches/Patch_Site_ShouldRemoveMapNow.cs
@@ -0,0 +1,27 @@
+using HarmonyLib;
+using RimWorld.Planet;
+using Verse;
+using System.Linq;
+
+namespace ArachnaeSwarm
+{
+ [HarmonyPatch(typeof(Site), "ShouldRemoveMapNow")]
+ public static class Patch_Site_ShouldRemoveMapNow
+ {
+ [HarmonyPostfix]
+ public static void Postfix(MapParent __instance, ref bool __result)
+ {
+ // 如果原方法已经决定不移除,我们就不需要干预
+ if (!__result)
+ {
+ return;
+ }
+
+ // 如果地图上存在B端传送门,则推翻原方法的决定,阻止地图被移除
+ if (__instance.HasMap && __instance.Map.listerBuildings.AllBuildingsColonistOfClass().Any())
+ {
+ __result = false;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/Wormhole/Building_WormholePortal_A.cs b/Source/ArachnaeSwarm/Wormhole/Building_WormholePortal_A.cs
new file mode 100644
index 0000000..4a51ba4
--- /dev/null
+++ b/Source/ArachnaeSwarm/Wormhole/Building_WormholePortal_A.cs
@@ -0,0 +1,108 @@
+using RimWorld;
+using RimWorld.Planet;
+using System.Collections.Generic;
+using Verse;
+
+namespace ArachnaeSwarm
+{
+ public enum WormholePortalStatus
+ {
+ Idle,
+ Linked
+ }
+
+ public class Building_WormholePortal_A : Building
+ {
+ private Building_WormholePortal_B linkedPortalB;
+ public WormholePortalStatus status = WormholePortalStatus.Idle;
+
+ private CompRefuelable refuelableComp;
+
+ public Building_WormholePortal_B LinkedPortal => linkedPortalB;
+
+ public override void ExposeData()
+ {
+ base.ExposeData();
+ Scribe_References.Look(ref linkedPortalB, "linkedPortalB");
+ Scribe_Values.Look(ref status, "status", WormholePortalStatus.Idle);
+ }
+
+ public override void SpawnSetup(Map map, bool respawningAfterLoad)
+ {
+ base.SpawnSetup(map, respawningAfterLoad);
+ refuelableComp = GetComp();
+ }
+
+ public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish)
+ {
+ if (linkedPortalB != null && !linkedPortalB.Destroyed)
+ {
+ linkedPortalB.Notify_A_Destroyed();
+ linkedPortalB.Destroy(DestroyMode.Vanish);
+ }
+ base.DeSpawn(mode);
+ }
+
+ public void SetLinkedPortal(Building_WormholePortal_B portalB)
+ {
+ if (portalB == null)
+ {
+ Notify_B_Destroyed();
+ return;
+ }
+ linkedPortalB = portalB;
+ status = WormholePortalStatus.Linked;
+ Messages.Message("WormholePortalLinked".Translate(this.Label, portalB.Map.Parent.LabelCap), this, MessageTypeDefOf.PositiveEvent);
+ }
+
+ public void Notify_B_Destroyed()
+ {
+ linkedPortalB = null;
+ status = WormholePortalStatus.Idle;
+ Messages.Message("WormholePortalB_Destroyed".Translate(this.Label), this, MessageTypeDefOf.NegativeEvent);
+ }
+
+ public override IEnumerable GetGizmos()
+ {
+ foreach (Gizmo g in base.GetGizmos())
+ {
+ yield return g;
+ }
+
+ if (status == WormholePortalStatus.Linked)
+ {
+ if (linkedPortalB == null || linkedPortalB.Destroyed)
+ {
+ // 安全检查,处理幽灵链接
+ Notify_B_Destroyed();
+ yield break;
+ }
+
+ Command_Action enterCommand = new Command_Action
+ {
+ defaultLabel = "EnterWormhole".Translate(),
+ defaultDesc = "EnterWormholeDesc".Translate(),
+ icon = ContentFinder.Get("UI/Commands/EnterCave"),
+ action = BeginTeleportation
+ };
+ yield return enterCommand;
+ }
+ }
+
+ public override string GetInspectString()
+ {
+ string text = base.GetInspectString();
+ text += "\n" + "Status".Translate() + ": " + status.ToString().Translate();
+ if (linkedPortalB != null && !linkedPortalB.Destroyed)
+ {
+ text += "\n" + "LinkedTo".Translate() + ": " + linkedPortalB.Map.Parent.LabelCap;
+ }
+ return text;
+ }
+
+ private void BeginTeleportation()
+ {
+ Find.WindowStack.Add(new Dialog_WormholeTransfer(this, this.LinkedPortal));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/Wormhole/Building_WormholePortal_B.cs b/Source/ArachnaeSwarm/Wormhole/Building_WormholePortal_B.cs
new file mode 100644
index 0000000..bee7f92
--- /dev/null
+++ b/Source/ArachnaeSwarm/Wormhole/Building_WormholePortal_B.cs
@@ -0,0 +1,79 @@
+using RimWorld.Planet;
+using System.Collections.Generic;
+using Verse;
+
+namespace ArachnaeSwarm
+{
+ public class Building_WormholePortal_B : Building
+ {
+ private Building_WormholePortal_A linkedPortalA;
+
+ public Building_WormholePortal_A LinkedPortal => linkedPortalA;
+
+ public override void ExposeData()
+ {
+ base.ExposeData();
+ Scribe_References.Look(ref linkedPortalA, "linkedPortalA");
+ }
+
+ public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish)
+ {
+ // 如果B被摧毁,通知A
+ if (linkedPortalA != null && !linkedPortalA.Destroyed)
+ {
+ linkedPortalA.Notify_B_Destroyed();
+ }
+ base.DeSpawn(mode);
+ }
+
+ // 这个方法在A端被摧毁时由A端调用,避免B端重复通知
+ public void Notify_A_Destroyed()
+ {
+ linkedPortalA = null;
+ }
+
+ public void SetLinkedPortal(Building_WormholePortal_A portalA)
+ {
+ linkedPortalA = portalA;
+ }
+
+ public override IEnumerable GetGizmos()
+ {
+ foreach (Gizmo g in base.GetGizmos())
+ {
+ yield return g;
+ }
+
+ if (linkedPortalA != null && !linkedPortalA.Destroyed)
+ {
+ Command_Action enterCommand = new Command_Action
+ {
+ defaultLabel = "EnterWormhole".Translate(),
+ defaultDesc = "EnterWormholeDesc".Translate(),
+ icon = ContentFinder.Get("UI/Commands/EnterCave"),
+ action = BeginTeleportation
+ };
+ yield return enterCommand;
+ }
+ }
+
+ public override string GetInspectString()
+ {
+ string text = base.GetInspectString();
+ if (linkedPortalA != null && !linkedPortalA.Destroyed)
+ {
+ text += "\n" + "LinkedTo".Translate() + ": " + linkedPortalA.Map.Parent.LabelCap;
+ }
+ else
+ {
+ text += "\n" + "ConnectionLost".Translate();
+ }
+ return text;
+ }
+
+ private void BeginTeleportation()
+ {
+ Find.WindowStack.Add(new Dialog_WormholeTransfer(this, this.LinkedPortal));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/Wormhole/CompLaunchableWormhole.cs b/Source/ArachnaeSwarm/Wormhole/CompLaunchableWormhole.cs
new file mode 100644
index 0000000..9b25342
--- /dev/null
+++ b/Source/ArachnaeSwarm/Wormhole/CompLaunchableWormhole.cs
@@ -0,0 +1,115 @@
+using System.Collections.Generic;
+using Verse;
+using RimWorld;
+using RimWorld.Planet;
+using UnityEngine;
+
+namespace ArachnaeSwarm
+{
+ public class CompLaunchableWormhole : ThingComp
+ {
+ private CompRefuelableNutrition refuelableComp;
+
+ public Building_WormholePortal_A PortalA => this.parent as Building_WormholePortal_A;
+ public CompProperties_LaunchableWormhole Props => (CompProperties_LaunchableWormhole)props;
+
+ public override void Initialize(CompProperties props)
+ {
+ base.Initialize(props);
+ this.refuelableComp = this.parent.GetComp();
+ }
+
+ public override IEnumerable CompGetGizmosExtra()
+ {
+ if (PortalA?.status == WormholePortalStatus.Linked)
+ {
+ yield break;
+ }
+
+ Command_Action launchCommand = new Command_Action();
+ launchCommand.defaultLabel = "CommandDeployWormholePortalB".Translate();
+ launchCommand.defaultDesc = "CommandDeployWormholePortalBDesc".Translate();
+ launchCommand.icon = ContentFinder.Get("UI/Commands/LaunchShip");
+
+ if (refuelableComp.Fuel < this.Props.fuelNeededToLaunch)
+ {
+ launchCommand.Disable("NotEnoughFuel".Translate());
+ }
+
+ launchCommand.action = delegate
+ {
+ StartChoosingDestination();
+ };
+ yield return launchCommand;
+ }
+
+ public void StartChoosingDestination()
+ {
+ CameraJumper.TryJump(CameraJumper.GetWorldTarget(this.parent));
+ Find.WorldSelector.ClearSelection();
+ int tile = this.parent.Map.Tile;
+ Find.WorldTargeter.BeginTargeting(ChoseWorldTarget, true, CompLaunchable.TargeterMouseAttachment, true, delegate
+ {
+ GenDraw.DrawWorldRadiusRing(tile, this.Props.maxLaunchDistance);
+ }, (GlobalTargetInfo t) => "Select target tile");
+ }
+
+ private bool ChoseWorldTarget(GlobalTargetInfo t)
+ {
+ if (!t.IsValid)
+ {
+ Messages.Message("MessageTransportPodsDestinationIsInvalid".Translate(), MessageTypeDefOf.RejectInput);
+ return false;
+ }
+ if (Find.World.Impassable(t.Tile))
+ {
+ Messages.Message("MessageTransportPodsDestinationIsImpassable".Translate(), MessageTypeDefOf.RejectInput);
+ return false;
+ }
+
+ MapParent mapParent = Find.World.worldObjects.MapParentAt(t.Tile);
+ if (mapParent?.HasMap ?? false)
+ {
+ Deploy(mapParent, t);
+ }
+ else
+ {
+ LongEventHandler.QueueLongEvent(delegate
+ {
+ var newMap = GetOrGenerateMapUtility.GetOrGenerateMap(t.Tile, WorldObjectDefOf.Camp);
+ Deploy(newMap.Parent, t);
+ }, "GeneratingMap", doAsynchronously: false, null);
+ }
+
+ return true;
+ }
+
+
+
+ private void Deploy(MapParent mapParent, GlobalTargetInfo t)
+ {
+ refuelableComp.ConsumeFuel(this.Props.fuelNeededToLaunch);
+ EffecterDefOf.Skip_Entry.Spawn(this.parent.Position, this.parent.Map);
+
+ Building_WormholePortal_B portalB = (Building_WormholePortal_B)ThingMaker.MakeThing(ThingDef.Named("ARA_WormholePortal_B"));
+ IntVec3 cell = DropCellFinder.RandomDropSpot(mapParent.Map);
+ GenSpawn.Spawn(portalB, cell, mapParent.Map, WipeMode.Vanish);
+
+ EffecterDefOf.Skip_Exit.Spawn(cell, mapParent.Map);
+
+ PortalA.SetLinkedPortal(portalB);
+ portalB.SetLinkedPortal(PortalA);
+ }
+ }
+
+ public class CompProperties_LaunchableWormhole : CompProperties
+ {
+ public float fuelNeededToLaunch;
+ public int maxLaunchDistance;
+
+ public CompProperties_LaunchableWormhole()
+ {
+ this.compClass = typeof(CompLaunchableWormhole);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/Wormhole/Dialog_WormholeTransfer.cs b/Source/ArachnaeSwarm/Wormhole/Dialog_WormholeTransfer.cs
new file mode 100644
index 0000000..1eeeba8
--- /dev/null
+++ b/Source/ArachnaeSwarm/Wormhole/Dialog_WormholeTransfer.cs
@@ -0,0 +1,214 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using RimWorld;
+using RimWorld.Planet;
+using UnityEngine;
+using Verse;
+using Verse.Sound;
+
+namespace ArachnaeSwarm
+{
+ public class Dialog_WormholeTransfer : Window
+ {
+ private enum Tab
+ {
+ Pawns,
+ Items
+ }
+
+ private const float TitleRectHeight = 35f;
+ private const float BottomAreaHeight = 55f;
+ private readonly Vector2 BottomButtonSize = new Vector2(160f, 40f);
+
+ private Building sourcePortal; // 通用源传送门
+ private Building destinationPortal; // 通用目标传送门
+
+ private List transferables;
+ private TransferableOneWayWidget pawnsTransfer;
+ private TransferableOneWayWidget itemsTransfer;
+ private Tab tab;
+
+ private static List tabsList = new List();
+
+ public override Vector2 InitialSize => new Vector2(1024f, UI.screenHeight);
+ protected override float Margin => 0f;
+
+ public Dialog_WormholeTransfer(Building sourcePortal, Building destinationPortal)
+ {
+ this.sourcePortal = sourcePortal;
+ this.destinationPortal = destinationPortal;
+ forcePause = true;
+ absorbInputAroundWindow = true;
+ }
+
+ public override void PostOpen()
+ {
+ base.PostOpen();
+ CalculateAndRecacheTransferables();
+ }
+
+ public override void DoWindowContents(Rect inRect)
+ {
+ Rect rect = new Rect(0f, 0f, inRect.width, TitleRectHeight);
+ Text.Font = GameFont.Medium;
+ Text.Anchor = TextAnchor.MiddleCenter;
+ Widgets.Label(rect, "EnterWormhole".Translate());
+ Text.Font = GameFont.Small;
+ Text.Anchor = TextAnchor.UpperLeft;
+
+ tabsList.Clear();
+ tabsList.Add(new TabRecord("PawnsTab".Translate(), () => tab = Tab.Pawns, tab == Tab.Pawns));
+ tabsList.Add(new TabRecord("ItemsTab".Translate(), () => tab = Tab.Items, tab == Tab.Items));
+
+ inRect.yMin += 67f;
+ Widgets.DrawMenuSection(inRect);
+ TabDrawer.DrawTabs(inRect, tabsList);
+ inRect = inRect.ContractedBy(17f);
+
+ Widgets.BeginGroup(inRect);
+ Rect rect2 = inRect.AtZero();
+ DoBottomButtons(rect2);
+ Rect inRect2 = rect2;
+ inRect2.yMax -= 76f;
+
+ bool anythingChanged = false;
+ switch (tab)
+ {
+ case Tab.Pawns:
+ pawnsTransfer.OnGUI(inRect2, out anythingChanged);
+ break;
+ case Tab.Items:
+ itemsTransfer.OnGUI(inRect2, out anythingChanged);
+ break;
+ }
+ if (anythingChanged)
+ {
+ // 可以添加一些计数或质量更新的逻辑
+ }
+ Widgets.EndGroup();
+ }
+
+ private void DoBottomButtons(Rect rect)
+ {
+ float buttonY = rect.height - BottomAreaHeight + 17;
+
+ if (Widgets.ButtonText(new Rect(rect.width / 2f - BottomButtonSize.x / 2f, buttonY, BottomButtonSize.x, BottomButtonSize.y), "ResetButton".Translate()))
+ {
+ SoundDefOf.Tick_Low.PlayOneShotOnCamera();
+ CalculateAndRecacheTransferables();
+ }
+ if (Widgets.ButtonText(new Rect(0f, buttonY, BottomButtonSize.x, BottomButtonSize.y), "CancelButton".Translate()))
+ {
+ Close();
+ }
+ if (Widgets.ButtonText(new Rect(rect.width - BottomButtonSize.x, buttonY, BottomButtonSize.x, BottomButtonSize.y), "AcceptButton".Translate()))
+ {
+ if (TryAccept())
+ {
+ SoundDefOf.Tick_High.PlayOneShotOnCamera();
+ Close(doCloseSound: false);
+ }
+ }
+ }
+
+ private bool TryAccept()
+ {
+ List toTransfer = transferables.Where(x => x.CountToTransfer > 0).ToList();
+ if (!toTransfer.Any())
+ {
+ Messages.Message("NothingToTransfer".Translate(), MessageTypeDefOf.RejectInput);
+ return false;
+ }
+
+ foreach (var trans in toTransfer)
+ {
+ // 传送逻辑
+ var things = trans.things.Take(trans.CountToTransfer).ToList();
+ foreach (var thing in things)
+ {
+ Pawn pawn = thing as Pawn;
+ if (pawn != null)
+ {
+ pawn.DeSpawn();
+ GenSpawn.Spawn(pawn, CellFinder.RandomClosewalkCellNear(destinationPortal.Position, destinationPortal.Map, 5), destinationPortal.Map, WipeMode.Vanish);
+ }
+ else
+ {
+ thing.DeSpawn();
+ GenSpawn.Spawn(thing, CellFinder.RandomClosewalkCellNear(destinationPortal.Position, destinationPortal.Map, 5), destinationPortal.Map, WipeMode.Vanish);
+ }
+ }
+ }
+
+ // 切换视角
+ if (toTransfer.Any(x => x.ThingDef.category == ThingCategory.Pawn))
+ {
+ var firstPawn = toTransfer.First(x => x.ThingDef.category == ThingCategory.Pawn).AnyThing as Pawn;
+ CameraJumper.TryJump(new GlobalTargetInfo(destinationPortal.Position, destinationPortal.Map));
+ if (firstPawn != null)
+ {
+ CameraJumper.TrySelect(firstPawn);
+ }
+ }
+
+ Messages.Message("WormholeTransferComplete".Translate(), MessageTypeDefOf.PositiveEvent);
+ return true;
+ }
+
+ private void CalculateAndRecacheTransferables()
+ {
+ transferables = new List();
+ AddPawnsToTransferables();
+ AddItemsToTransferables();
+
+ pawnsTransfer = new TransferableOneWayWidget(transferables.Where(x => x.ThingDef.category == ThingCategory.Pawn), null, null, "TransferableCount".Translate(),
+ drawMass: true,
+ ignorePawnInventoryMass: IgnorePawnsInventoryMode.Ignore,
+ includePawnsMassInMassUsage: true,
+ availableMassGetter: () => float.MaxValue, // 无质量限制
+ extraHeaderSpace: 0f,
+ ignoreSpawnedCorpseGearAndInventoryMass: false,
+ tile: sourcePortal.Map.Tile,
+ drawMarketValue: true,
+ drawEquippedWeapon: true);
+
+ itemsTransfer = new TransferableOneWayWidget(transferables.Where(x => x.ThingDef.category != ThingCategory.Pawn), null, null, "TransferableCount".Translate(),
+ drawMass: true,
+ ignorePawnInventoryMass: IgnorePawnsInventoryMode.Ignore,
+ includePawnsMassInMassUsage: true,
+ availableMassGetter: () => float.MaxValue,
+ extraHeaderSpace: 0f,
+ ignoreSpawnedCorpseGearAndInventoryMass: false,
+ tile: sourcePortal.Map.Tile,
+ drawMarketValue: true);
+ }
+
+ private void AddToTransferables(Thing t)
+ {
+ var transferable = TransferableUtility.TransferableMatching(t, transferables, TransferAsOneMode.PodsOrCaravanPacking);
+ if (transferable == null)
+ {
+ transferable = new TransferableOneWay();
+ transferables.Add(transferable);
+ }
+ transferable.things.Add(t);
+ }
+
+ private void AddPawnsToTransferables()
+ {
+ foreach (Pawn p in sourcePortal.Map.mapPawns.AllPawnsSpawned.Where(p => p.Faction == Faction.OfPlayer))
+ {
+ AddToTransferables(p);
+ }
+ }
+
+ private void AddItemsToTransferables()
+ {
+ foreach (Thing t in sourcePortal.Map.listerThings.AllThings.Where(t => t.def.category == ThingCategory.Item && t.def.EverHaulable && t.Position.IsValid && !t.Position.Fogged(t.Map)))
+ {
+ AddToTransferables(t);
+ }
+ }
+ }
+}
\ No newline at end of file