zc6
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,51 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
using RimWorld;
|
||||||
|
using Verse;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
|
||||||
|
namespace WulaFallenEmpire
|
||||||
|
{
|
||||||
|
[HarmonyPatch(typeof(Dialog_EnterPortal), "CalculateAndRecacheTransferables")]
|
||||||
|
public static class DialogEnterPortal_CalculateAndRecacheTransferables_Patch
|
||||||
|
{
|
||||||
|
// Transpiler 负责修改方法的 IL 代码
|
||||||
|
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
|
||||||
|
{
|
||||||
|
var codes = new List<CodeInstruction>(instructions);
|
||||||
|
// 找到 MapPortal.Map 属性的 getter 方法
|
||||||
|
var mapPropertyGetter = AccessTools.PropertyGetter(typeof(MapPortal), "Map");
|
||||||
|
// 找到我们自定义的静态方法,它将返回正确的 Map
|
||||||
|
var getShuttleMapMethod = AccessTools.Method(typeof(DialogEnterPortal_CalculateAndRecacheTransferables_Patch), nameof(GetShuttleMap));
|
||||||
|
|
||||||
|
for (int i = 0; i < codes.Count; i++)
|
||||||
|
{
|
||||||
|
// 查找对 MapPortal.Map 的 get 访问
|
||||||
|
if (codes[i].opcode == OpCodes.Callvirt && codes[i].operand is MethodInfo method && method == mapPropertyGetter)
|
||||||
|
{
|
||||||
|
// 替换为调用我们的静态方法
|
||||||
|
yield return new CodeInstruction(OpCodes.Call, getShuttleMapMethod);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yield return codes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 这个静态方法将由 Transpiler 注入,用于返回正确的 Map
|
||||||
|
// 参数 portalInstance 是原始方法中对 MapPortal 实例的引用
|
||||||
|
public static Map GetShuttleMap(MapPortal portalInstance)
|
||||||
|
{
|
||||||
|
if (portalInstance is ShuttlePortalAdapter adapter && adapter.shuttle != null)
|
||||||
|
{
|
||||||
|
return adapter.shuttle.Map;
|
||||||
|
}
|
||||||
|
// 如果不是我们的适配器或者 shuttle 为空,则返回原始 MapPortal 的 Map
|
||||||
|
// 我们需要直接访问 Thing 类的 Map 属性,这是 MapPortal 继承的
|
||||||
|
var originalMapGetter = AccessTools.PropertyGetter(typeof(Thing), "Map");
|
||||||
|
return (Map)originalMapGetter.Invoke(portalInstance, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,27 +33,12 @@ namespace WulaFallenEmpire
|
|||||||
{
|
{
|
||||||
// 创建MapPortal适配器,并设置其地图和位置信息
|
// 创建MapPortal适配器,并设置其地图和位置信息
|
||||||
portalAdapter = new ShuttlePortalAdapter(ParentShuttle);
|
portalAdapter = new ShuttlePortalAdapter(ParentShuttle);
|
||||||
// 使用反射设置适配器的地图和位置,让Dialog_EnterPortal能正确访问
|
// 确保 portalAdapter 的 shuttle 引用被正确设置
|
||||||
if (portalAdapter != null && ParentShuttle.Spawned)
|
// 并在 PostSpawnSetup 中设置 MapPortal 基类的地图和位置信息
|
||||||
|
// 确保 portalAdapter 的 shuttle 引用被正确设置
|
||||||
|
if (portalAdapter != null)
|
||||||
{
|
{
|
||||||
try
|
portalAdapter.shuttle = ParentShuttle;
|
||||||
{
|
|
||||||
// 使用反射设置私有字段
|
|
||||||
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}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,25 +132,39 @@ namespace WulaFallenEmpire
|
|||||||
enterCommand.action = delegate
|
enterCommand.action = delegate
|
||||||
{
|
{
|
||||||
// 使用和Building_PocketMapExit一模一样的Dialog_EnterPortal方法
|
// 使用和Building_PocketMapExit一模一样的Dialog_EnterPortal方法
|
||||||
if (portalAdapter != null && portalAdapter.shuttle != null)
|
if (portalAdapter == null || portalAdapter.shuttle != ParentShuttle)
|
||||||
|
{
|
||||||
|
// 重新创建并设置适配器,确保其指向正确的穿梭机
|
||||||
|
portalAdapter = new ShuttlePortalAdapter(ParentShuttle);
|
||||||
|
// 再次尝试设置 MapPortal 基类的地图和位置信息
|
||||||
|
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 && ParentShuttle.Spawned)
|
||||||
|
{
|
||||||
|
mapField.SetValue(portalAdapter, (sbyte)ParentShuttle.Map.Index); // 显式转换为 sbyte
|
||||||
|
positionField.SetValue(portalAdapter, ParentShuttle.Position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (System.Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error($"[WULA] Error setting MapPortal base fields during Gizmo click: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (portalAdapter != null)
|
||||||
{
|
{
|
||||||
var dialog = new Dialog_EnterPortal(portalAdapter);
|
var dialog = new Dialog_EnterPortal(portalAdapter);
|
||||||
Find.WindowStack.Add(dialog);
|
Find.WindowStack.Add(dialog);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.Error("[WULA] Portal adapter or shuttle is null, recreating adapter");
|
Messages.Message("WULA.PocketSpace.AdapterError".Translate(), ParentShuttle, MessageTypeDefOf.RejectInput);
|
||||||
// 重新创建适配器
|
Log.Error("[WULA] Portal adapter is null after recreation attempt.");
|
||||||
if (ParentShuttle != null)
|
|
||||||
{
|
|
||||||
portalAdapter = new ShuttlePortalAdapter(ParentShuttle);
|
|
||||||
var dialog = new Dialog_EnterPortal(portalAdapter);
|
|
||||||
Find.WindowStack.Add(dialog);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Messages.Message("内部错误:穿梭机引用丢失", ParentShuttle, MessageTypeDefOf.RejectInput);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
enterCommand.icon = ContentFinder<Texture2D>.Get(Props.buttonIconPath);
|
enterCommand.icon = ContentFinder<Texture2D>.Get(Props.buttonIconPath);
|
||||||
@@ -271,7 +270,7 @@ namespace WulaFallenEmpire
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ShuttlePortalAdapter()
|
public ShuttlePortalAdapter()
|
||||||
{
|
{
|
||||||
// 为空,在PostSpawnSetup中初始化
|
// 在这里不初始化 shuttle,因为它将在 PostSpawnSetup 中设置
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShuttlePortalAdapter(Building_ArmedShuttleWithPocket shuttle)
|
public ShuttlePortalAdapter(Building_ArmedShuttleWithPocket shuttle)
|
||||||
@@ -286,7 +285,7 @@ namespace WulaFallenEmpire
|
|||||||
{
|
{
|
||||||
if (shuttle?.PocketMap == null)
|
if (shuttle?.PocketMap == null)
|
||||||
{
|
{
|
||||||
// 如果口袋空间还没创建,先创建它
|
// 如口袋空间还没创建,先创建它
|
||||||
shuttle?.SwitchToPocketSpace();
|
shuttle?.SwitchToPocketSpace();
|
||||||
}
|
}
|
||||||
return shuttle?.PocketMap;
|
return shuttle?.PocketMap;
|
||||||
@@ -361,19 +360,8 @@ namespace WulaFallenEmpire
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected override Texture2D EnterTex => ContentFinder<Texture2D>.Get("UI/Commands/LoadTransporter");
|
protected override Texture2D EnterTex => ContentFinder<Texture2D>.Get("UI/Commands/LoadTransporter");
|
||||||
|
|
||||||
/// <summary>
|
// 移除了 new 关键字的 Map, Position, def 属性,因为它们在 MapPortal 基类中可能不是 virtual 的
|
||||||
/// 获取地图引用(用于Dialog_EnterPortal)
|
// 并且我们依赖 PostSpawnSetup 中的反射来设置 MapPortal 基类的私有字段
|
||||||
/// </summary>
|
// 这确保了 Dialog_EnterPortal 能够直接访问到正确的地图和位置信息。
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,6 +96,7 @@
|
|||||||
<Compile Include="EventSystem\EventUIConfigDef.cs" />
|
<Compile Include="EventSystem\EventUIConfigDef.cs" />
|
||||||
<Compile Include="EventSystem\Letter_EventChoice.cs" />
|
<Compile Include="EventSystem\Letter_EventChoice.cs" />
|
||||||
<Compile Include="EventSystem\QuestNode_Root_EventLetter.cs" />
|
<Compile Include="EventSystem\QuestNode_Root_EventLetter.cs" />
|
||||||
|
<Compile Include="HarmonyPatches\DialogEnterPortal_MapPatch.cs" />
|
||||||
<Compile Include="HarmonyPatches\Caravan_NeedsTracker_TrySatisfyPawnNeeds_Patch.cs" />
|
<Compile Include="HarmonyPatches\Caravan_NeedsTracker_TrySatisfyPawnNeeds_Patch.cs" />
|
||||||
<Compile Include="HarmonyPatches\DamageInfo_Constructor_Patch.cs" />
|
<Compile Include="HarmonyPatches\DamageInfo_Constructor_Patch.cs" />
|
||||||
<Compile Include="HarmonyPatches\FloatMenuOptionProvider_Ingest_Patch.cs" />
|
<Compile Include="HarmonyPatches\FloatMenuOptionProvider_Ingest_Patch.cs" />
|
||||||
|
|||||||
Reference in New Issue
Block a user