diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll
index ee4c8bd8..7c1049f1 100644
Binary files a/1.6/1.6/Assemblies/WulaFallenEmpire.dll and b/1.6/1.6/Assemblies/WulaFallenEmpire.dll differ
diff --git a/Source/WulaFallenEmpire/WULA_Shuttle/CompPocketMapPortal.cs b/Source/WulaFallenEmpire/WULA_Shuttle/CompPocketMapPortal.cs
new file mode 100644
index 00000000..971bdf1b
--- /dev/null
+++ b/Source/WulaFallenEmpire/WULA_Shuttle/CompPocketMapPortal.cs
@@ -0,0 +1,379 @@
+using RimWorld;
+using Verse;
+using Verse.AI;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using System.Reflection;
+
+namespace WulaFallenEmpire
+{
+ ///
+ /// 口袋空间传送门组件 - 将Building_PocketMapExit的功能转换成可挂载的组件
+ /// 直接挂载在穿梭机上处理进入内部空间的逻辑
+ ///
+ public class CompPocketMapPortal : ThingComp
+ {
+ /// 目标地图(口袋空间)
+ public Map targetMap;
+
+ /// 目标位置(在口袋空间中的位置)
+ public IntVec3 targetPos;
+
+ /// 父穿梭机引用
+ public Building_ArmedShuttleWithPocket parentShuttle;
+
+ /// 组件属性
+ public CompProperties_PocketMapPortal Props => (CompProperties_PocketMapPortal)props;
+
+ /// 父建筑(应该是穿梭机)
+ public Building_ArmedShuttleWithPocket ParentShuttle
+ {
+ get
+ {
+ if (parentShuttle == null && parent is Building_ArmedShuttleWithPocket shuttle)
+ {
+ parentShuttle = shuttle;
+ }
+ return parentShuttle;
+ }
+ }
+
+ public override void PostExposeData()
+ {
+ base.PostExposeData();
+ Scribe_References.Look(ref targetMap, "targetMap");
+ Scribe_Values.Look(ref targetPos, "targetPos");
+ Scribe_References.Look(ref parentShuttle, "parentShuttle");
+ }
+
+ public override void PostSpawnSetup(bool respawningAfterLoad)
+ {
+ base.PostSpawnSetup(respawningAfterLoad);
+
+ // 确保父穿梭机引用正确
+ if (parent is Building_ArmedShuttleWithPocket shuttle)
+ {
+ parentShuttle = shuttle;
+ Log.Message($"[WULA] CompPocketMapPortal attached to shuttle: {parent.LabelShort}");
+ }
+ else
+ {
+ Log.Error($"[WULA] CompPocketMapPortal attached to non-shuttle building: {parent?.def?.defName}");
+ }
+ }
+
+ ///
+ /// 设置口袋空间目标(由穿梭机调用)
+ ///
+ public void SetPocketSpaceTarget(Map pocketMap, IntVec3 exitPos)
+ {
+ targetMap = pocketMap;
+ targetPos = exitPos;
+ Log.Message($"[WULA] CompPocketMapPortal target set to pocket map: {pocketMap?.uniqueID} at {exitPos}");
+ }
+
+ ///
+ /// 获取其他地图(口袋空间),模仿原版MapPortal.GetOtherMap
+ ///
+ public Map GetOtherMap()
+ {
+ // 如果没有目标地图,尝试从父穿梭机获取
+ if (targetMap == null && ParentShuttle != null)
+ {
+ targetMap = ParentShuttle.PocketMap;
+ }
+ return targetMap;
+ }
+
+ ///
+ /// 获取目标位置(在口袋空间中的位置),模仿原版MapPortal.GetDestinationLocation
+ ///
+ public IntVec3 GetDestinationLocation()
+ {
+ // 如果没有目标位置,使用口袋地图中心
+ if (targetPos == IntVec3.Invalid && targetMap != null)
+ {
+ targetPos = targetMap.Center;
+ }
+ return targetPos;
+ }
+
+ ///
+ /// 检查是否可以进入口袋空间,模仿原版MapPortal.IsEnterable
+ ///
+ public bool IsEnterable(out string reason)
+ {
+ if (ParentShuttle == null)
+ {
+ reason = "WULA.PocketSpace.NotSpawned".Translate();
+ return false;
+ }
+
+ if (!ParentShuttle.AllowDirectAccess)
+ {
+ reason = "WULA.PocketSpace.AccessDenied".Translate();
+ return false;
+ }
+
+ if (!ParentShuttle.Spawned)
+ {
+ reason = "WULA.PocketSpace.NotSpawned".Translate();
+ return false;
+ }
+
+ // 检查父穿梭机的传送状态
+ if (ParentShuttle != null)
+ {
+ // 使用反射获取 transportDisabled 字段值
+ var transportDisabledField = typeof(Building_ArmedShuttleWithPocket).GetField("transportDisabled",
+ System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
+
+ if (transportDisabledField != null)
+ {
+ bool transportDisabled = (bool)transportDisabledField.GetValue(ParentShuttle);
+ if (transportDisabled)
+ {
+ reason = "WULA.PocketSpace.TransportDisabled".Translate();
+ return false;
+ }
+ }
+ }
+
+ // 检查目标地图是否存在
+ Map pocketMap = GetOtherMap();
+ if (pocketMap == null)
+ {
+ reason = "WULA.PocketSpace.NoTargetMap".Translate();
+ return false;
+ }
+
+ reason = "";
+ return true;
+ }
+
+ ///
+ /// 处理进入事件,将Pawn传送到口袋空间,模仿原版MapPortal.OnEntered
+ ///
+ public void OnEntered(Pawn pawn)
+ {
+ Map pocketMap = GetOtherMap();
+ if (pocketMap == null || !pawn.Spawned) return;
+
+ try
+ {
+ // 在口袋地图找一个安全位置
+ IntVec3 spawnPos = GetDestinationLocation();
+ if (spawnPos == IntVec3.Invalid)
+ {
+ spawnPos = pocketMap.Center;
+ }
+
+ // 寻找可行走的位置
+ spawnPos = CellFinder.RandomClosewalkCellNear(spawnPos, pocketMap, 10,
+ p => p.Standable(pocketMap) && !p.GetThingList(pocketMap).Any(t => t is Pawn));
+
+ if (spawnPos.IsValid)
+ {
+ // 传送人员到口袋空间
+ pawn.DeSpawn();
+ GenPlace.TryPlaceThing(pawn, spawnPos, pocketMap, ThingPlaceMode.Near);
+
+ // 通知父穿梭机有物品被添加
+ if (ParentShuttle != null)
+ {
+ ParentShuttle.Notify_ThingAdded(pawn);
+ }
+
+ // 如果是玩家控制的殖民者,切换到口袋地图
+ if (pawn.IsColonistPlayerControlled)
+ {
+ Current.Game.CurrentMap = pocketMap;
+ Find.CameraDriver.JumpToCurrentMapLoc(spawnPos);
+ }
+
+ Messages.Message("WULA.PocketSpace.TransferSuccess".Translate(1), MessageTypeDefOf.PositiveEvent);
+ Log.Message($"[WULA] Transferred {pawn.LabelShort} to pocket space at {spawnPos}");
+ }
+ else
+ {
+ Log.Error($"[WULA] Could not find valid spawn position in pocket space for {pawn.LabelShort}");
+ }
+ }
+ catch (System.Exception ex)
+ {
+ Log.Error($"[WULA] Error entering pocket space: {ex}");
+ }
+ }
+
+ ///
+ /// 处理从口袋空间退出到主地图的逻辑
+ ///
+ public void ExitPocketSpace(Pawn pawn)
+ {
+ if (ParentShuttle == null || !ParentShuttle.Spawned || !pawn.Spawned) return;
+
+ try
+ {
+ // 在主地图找一个安全位置(穿梭机附近)
+ IntVec3 exitPos = CellFinder.RandomClosewalkCellNear(ParentShuttle.Position, ParentShuttle.Map, 3,
+ p => p.Standable(ParentShuttle.Map) && !p.GetThingList(ParentShuttle.Map).Any(t => t is Pawn));
+
+ if (exitPos.IsValid)
+ {
+ // 传送人员回主地图
+ pawn.DeSpawn();
+ GenPlace.TryPlaceThing(pawn, exitPos, ParentShuttle.Map, ThingPlaceMode.Near);
+
+ // 如果是玩家控制的殖民者,切换到主地图
+ if (pawn.IsColonistPlayerControlled)
+ {
+ Current.Game.CurrentMap = ParentShuttle.Map;
+ Find.CameraDriver.JumpToCurrentMapLoc(exitPos);
+ }
+
+ Messages.Message("WULA.PocketSpace.ExitSuccess".Translate(pawn.LabelShort), MessageTypeDefOf.PositiveEvent);
+ Log.Message($"[WULA] {pawn.LabelShort} exited pocket space to main map at {exitPos}");
+ }
+ else
+ {
+ Log.Error($"[WULA] Could not find valid exit position for {pawn.LabelShort}");
+ }
+ }
+ catch (System.Exception ex)
+ {
+ Log.Error($"[WULA] Error exiting pocket space: {ex}");
+ }
+ }
+
+ ///
+ /// 获取Gizmo按钮(进入口袋空间按钮)
+ ///
+ public IEnumerable GetGizmos()
+ {
+ if (ParentShuttle == null || !ParentShuttle.AllowDirectAccess) yield break;
+
+ // 进入口袋空间按钮
+ Command_Action enterCommand = new Command_Action();
+ enterCommand.action = delegate
+ {
+ // 使用穿梭机的殖民者选择对话框
+ if (ParentShuttle != null)
+ {
+ // 获取所有可用的殖民者
+ List availablePawns = ParentShuttle.Map.mapPawns.AllPawnsSpawned
+ .Where(p => p.IsColonist && !p.Downed && p.CanReach(ParentShuttle, PathEndMode.Touch, Danger.Deadly))
+ .ToList();
+
+ if (availablePawns.Count == 0)
+ {
+ Messages.Message("WULA.PocketSpace.NoPawnsAvailable".Translate(), ParentShuttle, MessageTypeDefOf.RejectInput);
+ return;
+ }
+
+ // 创建选项列表
+ List options = new List();
+
+ // 添加单个殖民者选项
+ foreach (Pawn pawn in availablePawns)
+ {
+ FloatMenuOption option = new FloatMenuOption(
+ $"{pawn.LabelShort}",
+ delegate
+ {
+ OnEntered(pawn);
+ }
+ );
+ options.Add(option);
+ }
+
+ // 添加"全部殖民者"选项
+ if (availablePawns.Count > 1)
+ {
+ FloatMenuOption allOption = new FloatMenuOption(
+ "WULA.PocketSpace.AllColonists".Translate(availablePawns.Count),
+ delegate
+ {
+ foreach (Pawn pawn in availablePawns)
+ {
+ OnEntered(pawn);
+ }
+ }
+ );
+ options.Add(allOption);
+ }
+
+ // 显示浮动菜单
+ FloatMenu floatMenu = new FloatMenu(options);
+ Find.WindowStack.Add(floatMenu);
+ }
+ };
+ enterCommand.icon = ContentFinder.Get("UI/Commands/LoadTransporter");
+ enterCommand.defaultLabel = "WULA.PocketSpace.Enter".Translate() + "...";
+ enterCommand.defaultDesc = "WULA.PocketSpace.EnterDesc".Translate();
+
+ // 检查是否可以进入
+ string reason;
+ enterCommand.Disabled = !IsEnterable(out reason);
+ enterCommand.disabledReason = reason;
+ yield return enterCommand;
+
+ // 查看口袋地图按钮
+ Map pocketMap = GetOtherMap();
+ if (pocketMap != null)
+ {
+ yield return new Command_Action
+ {
+ defaultLabel = "WULA.PocketSpace.SwitchTo".Translate(),
+ defaultDesc = "WULA.PocketSpace.SwitchToDesc".Translate(),
+ icon = ContentFinder.Get("UI/Commands/ViewCave"),
+ action = delegate
+ {
+ Current.Game.CurrentMap = pocketMap;
+ Find.CameraDriver.JumpToCurrentMapLoc(GetDestinationLocation());
+ }
+ };
+ }
+ }
+
+ ///
+ /// 获取检视字符串信息
+ ///
+ public string GetInspectString()
+ {
+ if (ParentShuttle == null) return "";
+
+ List info = new List();
+
+ // 口袋空间状态
+ if (targetMap != null)
+ {
+ info.Add("WULA.PocketSpace.Status".Translate() + ": " + "WULA.PocketSpace.Ready".Translate());
+
+ // 显示口袋空间中的人员数量
+ int pawnCount = targetMap.mapPawns.AllPawnsSpawned.Where(p => p.IsColonist).Count();
+ if (pawnCount > 0)
+ {
+ info.Add("WULA.PocketSpace.PawnCount".Translate(pawnCount));
+ }
+ }
+ else
+ {
+ info.Add("WULA.PocketSpace.Status".Translate() + ": " + "WULA.PocketSpace.NotGenerated".Translate());
+ }
+
+ return string.Join("\n", info);
+ }
+ }
+
+ ///
+ /// 口袋空间传送门组件属性
+ ///
+ public class CompProperties_PocketMapPortal : CompProperties
+ {
+ public CompProperties_PocketMapPortal()
+ {
+ this.compClass = typeof(CompPocketMapPortal);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
index ebb33551..2897858b 100644
--- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
+++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
@@ -171,6 +171,7 @@
+