暂存5
This commit is contained in:
Binary file not shown.
@@ -102,6 +102,7 @@
|
|||||||
<pawnExitSound>Shuttle_PawnExit</pawnExitSound>
|
<pawnExitSound>Shuttle_PawnExit</pawnExitSound>
|
||||||
<showMassInInspectString>true</showMassInInspectString>
|
<showMassInInspectString>true</showMassInInspectString>
|
||||||
</li>
|
</li>
|
||||||
|
<li Class="WulaFallenEmpire.CompProperties_PocketMapPortal"></li>
|
||||||
<li Class="CompProperties_Refuelable">
|
<li Class="CompProperties_Refuelable">
|
||||||
<fuelCapacity>500</fuelCapacity>
|
<fuelCapacity>500</fuelCapacity>
|
||||||
<targetFuelLevelConfigurable>true</targetFuelLevelConfigurable>
|
<targetFuelLevelConfigurable>true</targetFuelLevelConfigurable>
|
||||||
@@ -128,6 +129,7 @@
|
|||||||
<li Class="CompProperties_AmbientSound">
|
<li Class="CompProperties_AmbientSound">
|
||||||
<sound>ShuttleIdle_Ambience</sound>
|
<sound>ShuttleIdle_Ambience</sound>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
</comps>
|
</comps>
|
||||||
<modExtensions>
|
<modExtensions>
|
||||||
<li Class="WulaFallenEmpire.PocketMapProperties">
|
<li Class="WulaFallenEmpire.PocketMapProperties">
|
||||||
|
|||||||
@@ -8,6 +8,9 @@
|
|||||||
<WULA.PocketSpace.ItemCount>储存物品: {0}</WULA.PocketSpace.ItemCount>
|
<WULA.PocketSpace.ItemCount>储存物品: {0}</WULA.PocketSpace.ItemCount>
|
||||||
|
|
||||||
<!-- Gizmo 按钮文本 -->
|
<!-- Gizmo 按钮文本 -->
|
||||||
|
<WULA.PocketSpace.Initialize>初始化内部空间</WULA.PocketSpace.Initialize>
|
||||||
|
<WULA.PocketSpace.InitializeDesc>初始化穿梭机的内部口袋空间。这将在穿梭机内部创建维度储存空间。</WULA.PocketSpace.InitializeDesc>
|
||||||
|
|
||||||
<WULA.PocketSpace.Enter>进入内部空间</WULA.PocketSpace.Enter>
|
<WULA.PocketSpace.Enter>进入内部空间</WULA.PocketSpace.Enter>
|
||||||
<WULA.PocketSpace.EnterDesc>进入穿梭机的内部口袋空间。无需骇入即可直接访问。选中的殖民者将被传送到内部空间。</WULA.PocketSpace.EnterDesc>
|
<WULA.PocketSpace.EnterDesc>进入穿梭机的内部口袋空间。无需骇入即可直接访问。选中的殖民者将被传送到内部空间。</WULA.PocketSpace.EnterDesc>
|
||||||
|
|
||||||
@@ -18,6 +21,11 @@
|
|||||||
<WULA.PocketSpace.ManageStorageDesc>打开内部容器管理界面,可以查看和取出储存在内部空间的物品。</WULA.PocketSpace.ManageStorageDesc>
|
<WULA.PocketSpace.ManageStorageDesc>打开内部容器管理界面,可以查看和取出储存在内部空间的物品。</WULA.PocketSpace.ManageStorageDesc>
|
||||||
|
|
||||||
<!-- 消息文本 -->
|
<!-- 消息文本 -->
|
||||||
|
<WULA.PocketSpace.CannotInitialize>无法初始化内部空间。</WULA.PocketSpace.CannotInitialize>
|
||||||
|
<WULA.PocketSpace.AlreadyInitialized>内部空间已经初始化。</WULA.PocketSpace.AlreadyInitialized>
|
||||||
|
<WULA.PocketSpace.InitializeSuccess>内部空间初始化成功。</WULA.PocketSpace.InitializeSuccess>
|
||||||
|
<WULA.PocketSpace.InitializeFailed>内部空间初始化失败。</WULA.PocketSpace.InitializeFailed>
|
||||||
|
|
||||||
<WULA.PocketSpace.CannotEnter>无法进入内部空间。</WULA.PocketSpace.CannotEnter>
|
<WULA.PocketSpace.CannotEnter>无法进入内部空间。</WULA.PocketSpace.CannotEnter>
|
||||||
<WULA.PocketSpace.AccessDenied>访问被拒绝。</WULA.PocketSpace.AccessDenied>
|
<WULA.PocketSpace.AccessDenied>访问被拒绝。</WULA.PocketSpace.AccessDenied>
|
||||||
<WULA.PocketSpace.NotSpawned>穿梭机未部署。</WULA.PocketSpace.NotSpawned>
|
<WULA.PocketSpace.NotSpawned>穿梭机未部署。</WULA.PocketSpace.NotSpawned>
|
||||||
|
|||||||
@@ -8,6 +8,9 @@
|
|||||||
<WULA.PocketSpace.ItemCount>Stored items: {0}</WULA.PocketSpace.ItemCount>
|
<WULA.PocketSpace.ItemCount>Stored items: {0}</WULA.PocketSpace.ItemCount>
|
||||||
|
|
||||||
<!-- Gizmo button text -->
|
<!-- Gizmo button text -->
|
||||||
|
<WULA.PocketSpace.Initialize>Initialize pocket space</WULA.PocketSpace.Initialize>
|
||||||
|
<WULA.PocketSpace.InitializeDesc>Initialize the shuttle's internal pocket space. This will create the dimensional storage space inside the shuttle.</WULA.PocketSpace.InitializeDesc>
|
||||||
|
|
||||||
<WULA.PocketSpace.Enter>Enter pocket space</WULA.PocketSpace.Enter>
|
<WULA.PocketSpace.Enter>Enter pocket space</WULA.PocketSpace.Enter>
|
||||||
<WULA.PocketSpace.EnterDesc>Enter the shuttle's internal pocket space. Direct access without hacking required. Selected colonists will be transported to the internal space.</WULA.PocketSpace.EnterDesc>
|
<WULA.PocketSpace.EnterDesc>Enter the shuttle's internal pocket space. Direct access without hacking required. Selected colonists will be transported to the internal space.</WULA.PocketSpace.EnterDesc>
|
||||||
|
|
||||||
@@ -18,6 +21,11 @@
|
|||||||
<WULA.PocketSpace.ManageStorageDesc>Open internal container management interface to view and retrieve items stored in the pocket space.</WULA.PocketSpace.ManageStorageDesc>
|
<WULA.PocketSpace.ManageStorageDesc>Open internal container management interface to view and retrieve items stored in the pocket space.</WULA.PocketSpace.ManageStorageDesc>
|
||||||
|
|
||||||
<!-- Message text -->
|
<!-- Message text -->
|
||||||
|
<WULA.PocketSpace.CannotInitialize>Cannot initialize pocket space.</WULA.PocketSpace.CannotInitialize>
|
||||||
|
<WULA.PocketSpace.AlreadyInitialized>Pocket space already initialized.</WULA.PocketSpace.AlreadyInitialized>
|
||||||
|
<WULA.PocketSpace.InitializeSuccess>Pocket space initialized successfully.</WULA.PocketSpace.InitializeSuccess>
|
||||||
|
<WULA.PocketSpace.InitializeFailed>Pocket space initialization failed.</WULA.PocketSpace.InitializeFailed>
|
||||||
|
|
||||||
<WULA.PocketSpace.CannotEnter>Cannot enter pocket space.</WULA.PocketSpace.CannotEnter>
|
<WULA.PocketSpace.CannotEnter>Cannot enter pocket space.</WULA.PocketSpace.CannotEnter>
|
||||||
<WULA.PocketSpace.AccessDenied>Access denied.</WULA.PocketSpace.AccessDenied>
|
<WULA.PocketSpace.AccessDenied>Access denied.</WULA.PocketSpace.AccessDenied>
|
||||||
<WULA.PocketSpace.TransportDisabled>Transport functionality disabled (shuttle in flight).</WULA.PocketSpace.TransportDisabled>
|
<WULA.PocketSpace.TransportDisabled>Transport functionality disabled (shuttle in flight).</WULA.PocketSpace.TransportDisabled>
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ namespace WulaFallenEmpire
|
|||||||
{
|
{
|
||||||
#region 静态图标定义(使用原版MapPortal的图标)
|
#region 静态图标定义(使用原版MapPortal的图标)
|
||||||
|
|
||||||
/// <summary>查看口袋地图图标</summary>
|
|
||||||
private static readonly Texture2D ViewPocketMapTex = ContentFinder<Texture2D>.Get("UI/Commands/ViewCave");
|
|
||||||
|
|
||||||
/// <summary>取消进入图标</summary>
|
/// <summary>取消进入图标</summary>
|
||||||
private static readonly Texture2D CancelEnterTex = ContentFinder<Texture2D>.Get("UI/Designators/Cancel");
|
private static readonly Texture2D CancelEnterTex = ContentFinder<Texture2D>.Get("UI/Designators/Cancel");
|
||||||
@@ -797,28 +795,7 @@ namespace WulaFallenEmpire
|
|||||||
enterCommand.disabledReason = reason;
|
enterCommand.disabledReason = reason;
|
||||||
yield return enterCommand;
|
yield return enterCommand;
|
||||||
|
|
||||||
// 查看口袋地图按钮(模仿原版MapPortal)
|
|
||||||
if (pocketMap != null)
|
|
||||||
{
|
|
||||||
yield return new Command_Action
|
|
||||||
{
|
|
||||||
defaultLabel = "WULA.PocketSpace.ViewMap".Translate(),
|
|
||||||
defaultDesc = "WULA.PocketSpace.ViewMapDesc".Translate(),
|
|
||||||
icon = ViewPocketMapTex,
|
|
||||||
action = delegate
|
|
||||||
{
|
|
||||||
// 模仿原版,跳转到口袋地图并选中退出点
|
|
||||||
if (exit != null)
|
|
||||||
{
|
|
||||||
CameraJumper.TryJumpAndSelect(exit);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SwitchToPocketSpace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,106 +1,65 @@
|
|||||||
using RimWorld;
|
using RimWorld;
|
||||||
using Verse;
|
using Verse;
|
||||||
using Verse.AI;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace WulaFallenEmpire
|
namespace WulaFallenEmpire
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 口袋空间传送门组件 - 将Building_PocketMapExit的功能转换成可挂载的组件
|
/// 口袋空间传送门组件 - 只作为入口功能,附加在穿梭机上处理进入内部空间的逻辑
|
||||||
/// 直接挂载在穿梭机上处理进入内部空间的逻辑
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CompPocketMapPortal : ThingComp
|
public class CompPocketMapPortal : ThingComp
|
||||||
{
|
{
|
||||||
/// <summary>目标地图(口袋空间)</summary>
|
|
||||||
public Map targetMap;
|
|
||||||
|
|
||||||
/// <summary>目标位置(在口袋空间中的位置)</summary>
|
|
||||||
public IntVec3 targetPos;
|
|
||||||
|
|
||||||
/// <summary>父穿梭机引用</summary>
|
|
||||||
public Building_ArmedShuttleWithPocket parentShuttle;
|
|
||||||
|
|
||||||
/// <summary>组件属性</summary>
|
/// <summary>组件属性</summary>
|
||||||
public CompProperties_PocketMapPortal Props => (CompProperties_PocketMapPortal)props;
|
public CompProperties_PocketMapPortal Props => (CompProperties_PocketMapPortal)props;
|
||||||
|
|
||||||
/// <summary>父建筑(应该是穿梭机)</summary>
|
/// <summary>父建筑(必须是穿梭机)</summary>
|
||||||
public Building_ArmedShuttleWithPocket ParentShuttle
|
public Building_ArmedShuttleWithPocket ParentShuttle => parent as Building_ArmedShuttleWithPocket;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (parentShuttle == null && parent is Building_ArmedShuttleWithPocket shuttle)
|
|
||||||
{
|
|
||||||
parentShuttle = shuttle;
|
|
||||||
}
|
|
||||||
return parentShuttle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostExposeData()
|
/// <summary>MapPortal适配器,用于使用原版Dialog_EnterPortal</summary>
|
||||||
{
|
private ShuttlePortalAdapter portalAdapter;
|
||||||
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)
|
public override void PostSpawnSetup(bool respawningAfterLoad)
|
||||||
{
|
{
|
||||||
base.PostSpawnSetup(respawningAfterLoad);
|
base.PostSpawnSetup(respawningAfterLoad);
|
||||||
|
|
||||||
// 确保父穿梭机引用正确
|
// 检查父对象是否是穿梭机
|
||||||
if (parent is Building_ArmedShuttleWithPocket shuttle)
|
if (ParentShuttle == null)
|
||||||
{
|
|
||||||
parentShuttle = shuttle;
|
|
||||||
Log.Message($"[WULA] CompPocketMapPortal attached to shuttle: {parent.LabelShort}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
Log.Error($"[WULA] CompPocketMapPortal attached to non-shuttle building: {parent?.def?.defName}");
|
Log.Error($"[WULA] CompPocketMapPortal attached to non-shuttle building: {parent?.def?.defName}");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 创建MapPortal适配器,并设置其地图和位置信息
|
||||||
|
portalAdapter = new ShuttlePortalAdapter(ParentShuttle);
|
||||||
|
// 使用反射设置适配器的地图和位置,让Dialog_EnterPortal能正确访问
|
||||||
|
if (portalAdapter != null && ParentShuttle.Spawned)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 使用反射设置私有字段
|
||||||
|
var mapField = typeof(Thing).GetField("mapIndexOrState",
|
||||||
|
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||||
|
var positionField = typeof(Thing).GetField("positionInt",
|
||||||
|
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||||
|
|
||||||
|
if (mapField != null && positionField != null)
|
||||||
|
{
|
||||||
|
mapField.SetValue(portalAdapter, mapField.GetValue(ParentShuttle));
|
||||||
|
positionField.SetValue(portalAdapter, positionField.GetValue(ParentShuttle));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (System.Exception ex)
|
||||||
|
{
|
||||||
|
Log.Warning($"[WULA] Could not set adapter map/position via reflection: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置口袋空间目标(由穿梭机调用)
|
/// 检查穿梭机是否可以进入(仅作为入口功能)
|
||||||
/// </summary>
|
|
||||||
public void SetPocketSpaceTarget(Map pocketMap, IntVec3 exitPos)
|
|
||||||
{
|
|
||||||
targetMap = pocketMap;
|
|
||||||
targetPos = exitPos;
|
|
||||||
Log.Message($"[WULA] CompPocketMapPortal target set to pocket map: {pocketMap?.uniqueID} at {exitPos}");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取其他地图(口袋空间),模仿原版MapPortal.GetOtherMap
|
|
||||||
/// </summary>
|
|
||||||
public Map GetOtherMap()
|
|
||||||
{
|
|
||||||
// 如果没有目标地图,尝试从父穿梭机获取
|
|
||||||
if (targetMap == null && ParentShuttle != null)
|
|
||||||
{
|
|
||||||
targetMap = ParentShuttle.PocketMap;
|
|
||||||
}
|
|
||||||
return targetMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取目标位置(在口袋空间中的位置),模仿原版MapPortal.GetDestinationLocation
|
|
||||||
/// </summary>
|
|
||||||
public IntVec3 GetDestinationLocation()
|
|
||||||
{
|
|
||||||
// 如果没有目标位置,使用口袋地图中心
|
|
||||||
if (targetPos == IntVec3.Invalid && targetMap != null)
|
|
||||||
{
|
|
||||||
targetPos = targetMap.Center;
|
|
||||||
}
|
|
||||||
return targetPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 检查是否可以进入口袋空间,模仿原版MapPortal.IsEnterable
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsEnterable(out string reason)
|
public bool IsEnterable(out string reason)
|
||||||
{
|
{
|
||||||
@@ -122,10 +81,7 @@ namespace WulaFallenEmpire
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查父穿梭机的传送状态
|
// 检查穿梭机的传送状态
|
||||||
if (ParentShuttle != null)
|
|
||||||
{
|
|
||||||
// 使用反射获取 transportDisabled 字段值
|
|
||||||
var transportDisabledField = typeof(Building_ArmedShuttleWithPocket).GetField("transportDisabled",
|
var transportDisabledField = typeof(Building_ArmedShuttleWithPocket).GetField("transportDisabled",
|
||||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||||
|
|
||||||
@@ -138,11 +94,9 @@ namespace WulaFallenEmpire
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 检查目标地图是否存在
|
// 检查口袋地图是否存在
|
||||||
Map pocketMap = GetOtherMap();
|
if (ParentShuttle.PocketMap == null)
|
||||||
if (pocketMap == null)
|
|
||||||
{
|
{
|
||||||
reason = "WULA.PocketSpace.NoTargetMap".Translate();
|
reason = "WULA.PocketSpace.NoTargetMap".Translate();
|
||||||
return false;
|
return false;
|
||||||
@@ -152,165 +106,71 @@ namespace WulaFallenEmpire
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 处理进入事件,将Pawn传送到口袋空间,模仿原版MapPortal.OnEntered
|
/// 获取组件额外的Gizmo按钮(根据口袋空间初始化状态显示不同按钮)
|
||||||
|
/// 重写CompGetGizmosExtra方法,这样RimWorld会自动调用并显示按钮
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void OnEntered(Pawn pawn)
|
public override IEnumerable<Gizmo> CompGetGizmosExtra()
|
||||||
{
|
{
|
||||||
Map pocketMap = GetOtherMap();
|
if (ParentShuttle == null) yield break;
|
||||||
if (pocketMap == null || !pawn.Spawned) return;
|
|
||||||
|
|
||||||
try
|
// 检查口袋空间是否已初始化
|
||||||
|
bool pocketMapExists = ParentShuttle.PocketMap != null;
|
||||||
|
|
||||||
|
if (!pocketMapExists)
|
||||||
{
|
{
|
||||||
// 在口袋地图找一个安全位置
|
// 口袋空间未创建,显示初始化按钮
|
||||||
IntVec3 spawnPos = GetDestinationLocation();
|
Command_Action initializeCommand = new Command_Action();
|
||||||
if (spawnPos == IntVec3.Invalid)
|
initializeCommand.action = delegate
|
||||||
{
|
{
|
||||||
spawnPos = pocketMap.Center;
|
// 创建口袋空间
|
||||||
|
InitializePocketSpace();
|
||||||
|
};
|
||||||
|
initializeCommand.icon = ContentFinder<Texture2D>.Get("UI/Commands/LoadTransporter");
|
||||||
|
initializeCommand.defaultLabel = "WULA.PocketSpace.Initialize".Translate();
|
||||||
|
initializeCommand.defaultDesc = "WULA.PocketSpace.InitializeDesc".Translate();
|
||||||
|
|
||||||
|
// 检查是否可以初始化
|
||||||
|
if (!ParentShuttle.Spawned)
|
||||||
|
{
|
||||||
|
initializeCommand.Disabled = true;
|
||||||
|
initializeCommand.disabledReason = "WULA.PocketSpace.NotSpawned".Translate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 寻找可行走的位置
|
yield return initializeCommand;
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
Log.Error($"[WULA] Could not find valid spawn position in pocket space for {pawn.LabelShort}");
|
// 穿梭机已创建,显示装载按钮(使用原版Dialog_EnterPortal)
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (System.Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error($"[WULA] Error entering pocket space: {ex}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 处理从口袋空间退出到主地图的逻辑
|
|
||||||
/// </summary>
|
|
||||||
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}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取Gizmo按钮(进入口袋空间按钮)
|
|
||||||
/// </summary>
|
|
||||||
public IEnumerable<Gizmo> GetGizmos()
|
|
||||||
{
|
|
||||||
if (ParentShuttle == null || !ParentShuttle.AllowDirectAccess) yield break;
|
|
||||||
|
|
||||||
// 进入口袋空间按钮
|
|
||||||
Command_Action enterCommand = new Command_Action();
|
Command_Action enterCommand = new Command_Action();
|
||||||
enterCommand.action = delegate
|
enterCommand.action = delegate
|
||||||
{
|
{
|
||||||
// 使用穿梭机的殖民者选择对话框
|
// 使用和Building_PocketMapExit一模一样的Dialog_EnterPortal方法
|
||||||
|
if (portalAdapter != null && portalAdapter.shuttle != null)
|
||||||
|
{
|
||||||
|
var dialog = new Dialog_EnterPortal(portalAdapter);
|
||||||
|
Find.WindowStack.Add(dialog);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Error("[WULA] Portal adapter or shuttle is null, recreating adapter");
|
||||||
|
// 重新创建适配器
|
||||||
if (ParentShuttle != null)
|
if (ParentShuttle != null)
|
||||||
{
|
{
|
||||||
// 获取所有可用的殖民者
|
portalAdapter = new ShuttlePortalAdapter(ParentShuttle);
|
||||||
List<Pawn> availablePawns = ParentShuttle.Map.mapPawns.AllPawnsSpawned
|
var dialog = new Dialog_EnterPortal(portalAdapter);
|
||||||
.Where(p => p.IsColonist && !p.Downed && p.CanReach(ParentShuttle, PathEndMode.Touch, Danger.Deadly))
|
Find.WindowStack.Add(dialog);
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (availablePawns.Count == 0)
|
|
||||||
{
|
|
||||||
Messages.Message("WULA.PocketSpace.NoPawnsAvailable".Translate(), ParentShuttle, MessageTypeDefOf.RejectInput);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
// 创建选项列表
|
|
||||||
List<FloatMenuOption> options = new List<FloatMenuOption>();
|
|
||||||
|
|
||||||
// 添加单个殖民者选项
|
|
||||||
foreach (Pawn pawn in availablePawns)
|
|
||||||
{
|
{
|
||||||
FloatMenuOption option = new FloatMenuOption(
|
Messages.Message("内部错误:穿梭机引用丢失", ParentShuttle, MessageTypeDefOf.RejectInput);
|
||||||
$"{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<Texture2D>.Get("UI/Commands/LoadTransporter");
|
enterCommand.icon = ContentFinder<Texture2D>.Get(Props.buttonIconPath);
|
||||||
enterCommand.defaultLabel = "WULA.PocketSpace.Enter".Translate() + "...";
|
enterCommand.defaultLabel = Props.enterButtonTextKey.Translate() + "...";
|
||||||
enterCommand.defaultDesc = "WULA.PocketSpace.EnterDesc".Translate();
|
enterCommand.defaultDesc = Props.enterButtonDescKey.Translate();
|
||||||
|
|
||||||
// 检查是否可以进入
|
// 检查是否可以进入
|
||||||
string reason;
|
string reason;
|
||||||
@@ -319,9 +179,6 @@ namespace WulaFallenEmpire
|
|||||||
yield return enterCommand;
|
yield return enterCommand;
|
||||||
|
|
||||||
// 查看口袋地图按钮
|
// 查看口袋地图按钮
|
||||||
Map pocketMap = GetOtherMap();
|
|
||||||
if (pocketMap != null)
|
|
||||||
{
|
|
||||||
yield return new Command_Action
|
yield return new Command_Action
|
||||||
{
|
{
|
||||||
defaultLabel = "WULA.PocketSpace.SwitchTo".Translate(),
|
defaultLabel = "WULA.PocketSpace.SwitchTo".Translate(),
|
||||||
@@ -329,41 +186,55 @@ namespace WulaFallenEmpire
|
|||||||
icon = ContentFinder<Texture2D>.Get("UI/Commands/ViewCave"),
|
icon = ContentFinder<Texture2D>.Get("UI/Commands/ViewCave"),
|
||||||
action = delegate
|
action = delegate
|
||||||
{
|
{
|
||||||
Current.Game.CurrentMap = pocketMap;
|
Current.Game.CurrentMap = ParentShuttle.PocketMap;
|
||||||
Find.CameraDriver.JumpToCurrentMapLoc(GetDestinationLocation());
|
Find.CameraDriver.JumpToCurrentMapLoc(ParentShuttle.PocketMap.Center);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取检视字符串信息
|
/// 初始化口袋空间
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string GetInspectString()
|
private void InitializePocketSpace()
|
||||||
{
|
{
|
||||||
if (ParentShuttle == null) return "";
|
if (ParentShuttle == null || !ParentShuttle.Spawned)
|
||||||
|
|
||||||
List<string> info = new List<string>();
|
|
||||||
|
|
||||||
// 口袋空间状态
|
|
||||||
if (targetMap != null)
|
|
||||||
{
|
{
|
||||||
info.Add("WULA.PocketSpace.Status".Translate() + ": " + "WULA.PocketSpace.Ready".Translate());
|
Messages.Message("WULA.PocketSpace.CannotInitialize".Translate(), ParentShuttle, MessageTypeDefOf.RejectInput);
|
||||||
|
return;
|
||||||
// 显示口袋空间中的人员数量
|
|
||||||
int pawnCount = targetMap.mapPawns.AllPawnsSpawned.Where(p => p.IsColonist).Count();
|
|
||||||
if (pawnCount > 0)
|
|
||||||
{
|
|
||||||
info.Add("WULA.PocketSpace.PawnCount".Translate(pawnCount));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ParentShuttle.PocketMap != null)
|
||||||
|
{
|
||||||
|
Messages.Message("WULA.PocketSpace.AlreadyInitialized".Translate(), ParentShuttle, MessageTypeDefOf.RejectInput);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Log.Message("[WULA] Starting pocket space initialization via component");
|
||||||
|
|
||||||
|
// 使用穿梭机的SwitchToPocketSpace方法,它会自动创建口袋空间
|
||||||
|
ParentShuttle.SwitchToPocketSpace();
|
||||||
|
|
||||||
|
if (ParentShuttle.PocketMap != null)
|
||||||
|
{
|
||||||
|
Messages.Message("WULA.PocketSpace.InitializeSuccess".Translate(), ParentShuttle, MessageTypeDefOf.PositiveEvent);
|
||||||
|
Log.Message("[WULA] Pocket space initialization completed successfully");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info.Add("WULA.PocketSpace.Status".Translate() + ": " + "WULA.PocketSpace.NotGenerated".Translate());
|
Messages.Message("WULA.PocketSpace.InitializeFailed".Translate(), ParentShuttle, MessageTypeDefOf.RejectInput);
|
||||||
|
Log.Error("[WULA] Pocket space initialization failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (System.Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error($"[WULA] Error during pocket space initialization: {ex}");
|
||||||
|
Messages.Message("WULA.PocketSpace.InitializeFailed".Translate(), ParentShuttle, MessageTypeDefOf.RejectInput);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Join("\n", info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -371,9 +242,138 @@ namespace WulaFallenEmpire
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class CompProperties_PocketMapPortal : CompProperties
|
public class CompProperties_PocketMapPortal : CompProperties
|
||||||
{
|
{
|
||||||
|
/// <summary>进入按钮文本键</summary>
|
||||||
|
public string enterButtonTextKey = "WULA.PocketSpace.Enter";
|
||||||
|
|
||||||
|
/// <summary>进入按钮描述键</summary>
|
||||||
|
public string enterButtonDescKey = "WULA.PocketSpace.EnterDesc";
|
||||||
|
|
||||||
|
/// <summary>按钮图标路径</summary>
|
||||||
|
public string buttonIconPath = "UI/Commands/LoadTransporter";
|
||||||
|
|
||||||
public CompProperties_PocketMapPortal()
|
public CompProperties_PocketMapPortal()
|
||||||
{
|
{
|
||||||
this.compClass = typeof(CompPocketMapPortal);
|
this.compClass = typeof(CompPocketMapPortal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// MapPortal适配器类,将Building_ArmedShuttleWithPocket适配为MapPortal接口
|
||||||
|
/// 完全模仿Building_PocketMapExit的实现方式
|
||||||
|
/// </summary>
|
||||||
|
public class ShuttlePortalAdapter : MapPortal
|
||||||
|
{
|
||||||
|
/// <summary>关联的穿梭机</summary>
|
||||||
|
public Building_ArmedShuttleWithPocket shuttle;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 默认构造函数(RimWorld组件系统要求)
|
||||||
|
/// </summary>
|
||||||
|
public ShuttlePortalAdapter()
|
||||||
|
{
|
||||||
|
// 为空,在PostSpawnSetup中初始化
|
||||||
|
}
|
||||||
|
|
||||||
|
public ShuttlePortalAdapter(Building_ArmedShuttleWithPocket shuttle)
|
||||||
|
{
|
||||||
|
this.shuttle = shuttle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重写获取其他地图,返回口袋空间(模仿Building_PocketMapExit.GetOtherMap)
|
||||||
|
/// </summary>
|
||||||
|
public override Map GetOtherMap()
|
||||||
|
{
|
||||||
|
if (shuttle?.PocketMap == null)
|
||||||
|
{
|
||||||
|
// 如果口袋空间还没创建,先创建它
|
||||||
|
shuttle?.SwitchToPocketSpace();
|
||||||
|
}
|
||||||
|
return shuttle?.PocketMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重写获取目标位置,返回口袋空间中心(模仿Building_PocketMapExit.GetDestinationLocation)
|
||||||
|
/// </summary>
|
||||||
|
public override IntVec3 GetDestinationLocation()
|
||||||
|
{
|
||||||
|
return shuttle?.PocketMap?.Center ?? IntVec3.Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重写是否可进入,检查穿梭机状态(模仿Building_PocketMapExit.IsEnterable)
|
||||||
|
/// </summary>
|
||||||
|
public override bool IsEnterable(out string reason)
|
||||||
|
{
|
||||||
|
if (shuttle == null || !shuttle.Spawned)
|
||||||
|
{
|
||||||
|
reason = "WULA.PocketSpace.NotSpawned".Translate();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!shuttle.AllowDirectAccess)
|
||||||
|
{
|
||||||
|
reason = "WULA.PocketSpace.AccessDenied".Translate();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查穿梭机的传送状态
|
||||||
|
var transportDisabledField = typeof(Building_ArmedShuttleWithPocket).GetField("transportDisabled",
|
||||||
|
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||||
|
|
||||||
|
if (transportDisabledField != null)
|
||||||
|
{
|
||||||
|
bool transportDisabled = (bool)transportDisabledField.GetValue(shuttle);
|
||||||
|
if (transportDisabled)
|
||||||
|
{
|
||||||
|
reason = "WULA.PocketSpace.TransportDisabled".Translate();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reason = "";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重写进入事件,处理进入口袋空间(模仿Building_PocketMapExit.OnEntered)
|
||||||
|
/// </summary>
|
||||||
|
public override void OnEntered(Pawn pawn)
|
||||||
|
{
|
||||||
|
// 通知穿梭机有物品被添加(用于统计和管理)
|
||||||
|
shuttle?.Notify_ThingAdded(pawn);
|
||||||
|
|
||||||
|
// 播放传送音效(如果存在)
|
||||||
|
if (Find.CurrentMap == shuttle?.Map)
|
||||||
|
{
|
||||||
|
// 可以在这里添加音效播放
|
||||||
|
// def.portal?.traverseSound?.PlayOneShot(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重写进入按钮文本
|
||||||
|
/// </summary>
|
||||||
|
public override string EnterString => "WULA.PocketSpace.Enter".Translate();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重写进入按钮图标,使用装载按钮的贴图
|
||||||
|
/// </summary>
|
||||||
|
protected override Texture2D EnterTex => ContentFinder<Texture2D>.Get("UI/Commands/LoadTransporter");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取地图引用(用于Dialog_EnterPortal)
|
||||||
|
/// </summary>
|
||||||
|
public new Map Map => shuttle?.Map;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取位置引用(用于Dialog_EnterPortal)
|
||||||
|
/// </summary>
|
||||||
|
public new IntVec3 Position => shuttle?.Position ?? IntVec3.Invalid;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取定义引用(用于Dialog_EnterPortal)
|
||||||
|
/// </summary>
|
||||||
|
public new ThingDef def => shuttle?.def;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user