Files
WulaFallenEmpireRW/Source/WulaFallenEmpire/WULA_Shuttle/Building_PocketMapExit.cs
2025-08-25 12:02:20 +08:00

319 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using RimWorld;
using Verse;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace WulaFallenEmpire
{
/// <summary>
/// 口袋空间退出点建筑 - 继承自MapPortal以获得完整的双向传送功能
/// </summary>
public class Building_PocketMapExit : MapPortal
{
/// <summary>目标地图</summary>
public Map targetMap;
/// <summary>目标位置</summary>
public IntVec3 targetPos;
/// <summary>父穿梭机</summary>
public Building_ArmedShuttleWithPocket parentShuttle;
public override void ExposeData()
{
base.ExposeData();
Scribe_References.Look(ref targetMap, "targetMap");
Scribe_Values.Look(ref targetPos, "targetPos");
Scribe_References.Look(ref parentShuttle, "parentShuttle");
}
/// <summary>
/// 重写获取其他地图返回主地图模仿原版MapPortal.GetOtherMap
/// </summary>
public override Map GetOtherMap()
{
// 动态更新目标地图,处理穿梭机移动的情况
UpdateTargetFromParentShuttle();
return targetMap;
}
/// <summary>
/// 重写获取目标位置返回主地图上的穿梭机位置模仿原版MapPortal.GetDestinationLocation
/// </summary>
public override IntVec3 GetDestinationLocation()
{
// 动态更新目标位置,处理穿梭机移动的情况
UpdateTargetFromParentShuttle();
return targetPos;
}
/// <summary>
/// 从父穿梭机动态更新目标位置,处理穿梭机移动的情况
/// </summary>
private void UpdateTargetFromParentShuttle()
{
if (parentShuttle != null && parentShuttle.Spawned)
{
// 如果穿梭机还在地图上,更新目标位置
if (targetMap != parentShuttle.Map || targetPos != parentShuttle.Position)
{
targetMap = parentShuttle.Map;
targetPos = parentShuttle.Position;
Log.Message($"[WULA] Updated exit target to shuttle location: {targetMap?.uniqueID} at {targetPos}");
}
}
else if (parentShuttle != null && !parentShuttle.Spawned)
{
// 穿梭机不在地图上(可能在飞行中)
// 保持原有目标,但记录警告
if (this.IsHashIntervalTick(2500)) // 每隔一段时间检查一次
{
Log.Warning($"[WULA] Parent shuttle is not spawned, exit target may be outdated. Last known: {targetMap?.uniqueID} at {targetPos}");
}
}
}
/// <summary>
/// 重写是否可进入检查目标地图是否存在模仿原版MapPortal.IsEnterable
/// </summary>
public override bool IsEnterable(out string reason)
{
if (targetMap == null)
{
reason = "WULA.PocketSpace.NoTargetMap".Translate();
return false;
}
reason = "";
return true;
}
/// <summary>
/// 重写进入事件处理从口袋空间退出到主地图模仿原版MapPortal.OnEntered
/// </summary>
public override void OnEntered(Pawn pawn)
{
// 不调用 base.OnEntered因为我们不需要原版的通知机制
// 直接处理退出逻辑
if (targetMap != null && pawn.Spawned)
{
ExitPocketSpace(pawn);
}
}
/// <summary>
/// 重写进入按钮文本
/// </summary>
public override string EnterString => "WULA.PocketSpace.ExitToMainMap".Translate();
/// <summary>
/// 重写进入按钮图标使用原版的ViewCave图标
/// </summary>
protected override Texture2D EnterTex => ContentFinder<Texture2D>.Get("UI/Commands/ViewCave");
/// <summary>
/// 重写GetGizmos方法添加穿梭机装载相关按钮
/// </summary>
public override IEnumerable<Gizmo> GetGizmos()
{
// 获取基类的按钮(退出空间和查看地图按钮)
foreach (Gizmo gizmo in base.GetGizmos())
{
yield return gizmo;
}
// 如果有父穿梭机,添加穿梭机相关的装载按钮
if (parentShuttle != null)
{
// 查看主地图按钮
yield return new Command_Action
{
defaultLabel = "WULA.PocketSpace.ViewMainMap".Translate(),
defaultDesc = "WULA.PocketSpace.ViewMainMapDesc".Translate(),
icon = ContentFinder<Texture2D>.Get("UI/Commands/ViewWorld"),
action = delegate
{
if (targetMap != null)
{
Current.Game.CurrentMap = targetMap;
if (parentShuttle != null && parentShuttle.Spawned)
{
Find.CameraDriver.JumpToCurrentMapLoc(parentShuttle.Position);
Find.Selector.Select(parentShuttle);
}
else
{
Find.CameraDriver.JumpToCurrentMapLoc(targetPos);
}
}
}
};
// 穿梭机装载管理按钮
if (parentShuttle.Spawned)
{
// 获取穿梭机的CompTransporter组件
CompTransporter transporter = parentShuttle.GetComp<CompTransporter>();
if (transporter != null)
{
// 添加装载按钮模仿原版CompTransporter的功能
yield return new Command_Action
{
defaultLabel = "WULA.PocketSpace.LoadShuttle".Translate(),
defaultDesc = "WULA.PocketSpace.LoadShuttleDesc".Translate(),
icon = ContentFinder<Texture2D>.Get("UI/Commands/LoadTransporter"),
action = delegate
{
OpenShuttleLoadingDialog(transporter);
}
};
// 如果正在装载,添加取消装载按钮
if (transporter.LoadingInProgress)
{
yield return new Command_Action
{
defaultLabel = "WULA.PocketSpace.CancelLoading".Translate(),
defaultDesc = "WULA.PocketSpace.CancelLoadingDesc".Translate(),
icon = ContentFinder<Texture2D>.Get("UI/Designators/Cancel"),
action = delegate
{
transporter.CancelLoad();
}
};
}
}
// 添加穿梭机发射按钮(如果正在装载且可以发射)
CompLaunchable launchable = parentShuttle.GetComp<CompLaunchable>();
if (launchable != null && transporter != null && !transporter.LoadingInProgress)
{
foreach (Gizmo gizmo in launchable.CompGetGizmosExtra())
{
yield return gizmo;
}
}
}
// 穿梭机状态信息按钮
yield return new Command_Action
{
defaultLabel = "WULA.PocketSpace.ShuttleStatus".Translate(),
defaultDesc = "WULA.PocketSpace.ShuttleStatusDesc".Translate(),
icon = ContentFinder<Texture2D>.Get("UI/Commands/InfoCard"),
action = delegate
{
ShowShuttleStatusInfo();
}
};
}
}
/// <summary>
/// 单个人员退出口袋空间简化版本利用MapPortal功能
/// </summary>
private void ExitPocketSpace(Pawn pawn)
{
if (targetMap == null || !pawn.Spawned) return;
try
{
// 在目标地图找一个安全位置
IntVec3 exitPos = CellFinder.RandomClosewalkCellNear(targetPos, targetMap, 3, p => p.Standable(targetMap));
// 传送人员
pawn.DeSpawn();
GenPlace.TryPlaceThing(pawn, exitPos, targetMap, ThingPlaceMode.Near);
// 切换到主地图
if (pawn.IsColonistPlayerControlled)
{
Current.Game.CurrentMap = targetMap;
Find.CameraDriver.JumpToCurrentMapLoc(exitPos);
}
Messages.Message("WULA.PocketSpace.ExitSuccess".Translate(pawn.LabelShort), MessageTypeDefOf.PositiveEvent);
}
catch (System.Exception ex)
{
Log.Error($"[WULA] Error exiting pocket space: {ex}");
}
}
/// <summary>
/// 打开穿梭机装载对话框
/// </summary>
private void OpenShuttleLoadingDialog(CompTransporter transporter)
{
if (transporter == null) return;
try
{
// 使用原版的Dialog_LoadTransporters打开装载对话框
Find.WindowStack.Add(new Dialog_LoadTransporters(parentShuttle.Map, new List<CompTransporter> { transporter }));
}
catch (System.Exception ex)
{
Log.Error($"[WULA] Error opening shuttle loading dialog: {ex}");
Messages.Message("WULA.PocketSpace.LoadingDialogError".Translate(), MessageTypeDefOf.RejectInput);
}
}
/// <summary>
/// 显示穿梭机状态信息
/// </summary>
private void ShowShuttleStatusInfo()
{
if (parentShuttle == null) return;
StringBuilder statusText = new StringBuilder();
// 基本信息
statusText.AppendLine("WULA.PocketSpace.ShuttleInfo".Translate());
statusText.AppendLine($"• 状态: {(parentShuttle.Spawned ? "" : "")}");
if (parentShuttle.Spawned)
{
statusText.AppendLine($"• 位置: {targetMap?.Parent?.Label ?? ""} ({targetPos.x}, {targetPos.z})");
// 燃料信息
CompRefuelable fuel = parentShuttle.GetComp<CompRefuelable>();
if (fuel != null)
{
statusText.AppendLine($"• 燃料: {fuel.Fuel:F0}/{fuel.Props.fuelCapacity:F0}");
}
// 装载信息
CompTransporter transporter = parentShuttle.GetComp<CompTransporter>();
if (transporter != null)
{
statusText.AppendLine($"• 载重: {transporter.MassUsage:F1}/{transporter.Props.massCapacity:F1}");
if (transporter.LoadingInProgress)
{
statusText.AppendLine("• 装载状态: 正在装载...");
}
}
// 口袋空间信息
if (parentShuttle.pocketMapGenerated)
{
statusText.AppendLine($"• 内部空间: 已初始化");
if (parentShuttle.innerContainer.Count > 0)
{
statusText.AppendLine($"• 内部储存: {parentShuttle.innerContainer.Count} 件物品");
}
}
}
else
{
statusText.AppendLine("• 穿梭机正在飞行中,无法获取详细信息");
}
// 显示信息对话框
Find.WindowStack.Add(new Dialog_MessageBox(statusText.ToString(), "WULA.PocketSpace.ShuttleStatus".Translate()));
}
}
}