diff --git a/Source/ProjectRimFactory/Common/ConditionalPatchHelper.cs b/Source/ProjectRimFactory/Common/ConditionalPatchHelper.cs index fbceb2ec..2cd05ae1 100644 --- a/Source/ProjectRimFactory/Common/ConditionalPatchHelper.cs +++ b/Source/ProjectRimFactory/Common/ConditionalPatchHelper.cs @@ -92,11 +92,6 @@ public void PatchHandler(bool patch) AccessTools.Method(typeof(HarmonyPatches.Patch_Building_Storage_Accepts), "Prefix") ); - private static readonly TogglePatch PatchStorageSettingsAllowedToAccept = new( - AccessTools.Method(typeof(StorageSettings), "AllowedToAccept", new Type[] { typeof(Thing) }), - AccessTools.Method(typeof(HarmonyPatches.Patch_StorageSettings_AllowedToAccept), "Prefix") - ); - private static readonly TogglePatch PatchForbidUtilityIsForbidden = new( AccessTools.Method(typeof(ForbidUtility), "IsForbidden", new Type[] { typeof(Thing), typeof(Pawn) }), AccessTools.Method(typeof(HarmonyPatches.Patch_ForbidUtility_IsForbidden), "Prefix") @@ -119,7 +114,6 @@ private static void UpdatePatchStorage() PatchFloatMenuMakerMapChoicesAtFor.PatchHandler(state); PatchBuildingStorageAccepts.PatchHandler(state); PatchForbidUtilityIsForbidden.PatchHandler(state); - PatchStorageSettingsAllowedToAccept.PatchHandler(state); } public static void Register(Building_MassStorageUnit building) diff --git a/Source/ProjectRimFactory/Common/HarmonyPatches/PatchStorage.cs b/Source/ProjectRimFactory/Common/HarmonyPatches/PatchStorage.cs index 06a09d5c..1b363340 100644 --- a/Source/ProjectRimFactory/Common/HarmonyPatches/PatchStorage.cs +++ b/Source/ProjectRimFactory/Common/HarmonyPatches/PatchStorage.cs @@ -46,31 +46,6 @@ static bool Prefix(Building_Storage __instance, Thing t, out bool __result) } } - // 1.5 Stuff - class Patch_StorageSettings_AllowedToAccept - { - // ReSharper disable once UnusedMember.Local - static bool Prefix(IStoreSettingsParent ___owner, Thing t, out bool __result) - { - __result = false; - if (___owner is Building_Storage storage) - { - //Check if pawn input is forbidden - if (!PatchStorageUtil.SkippAcceptsPatch && ((storage as IForbidPawnInputItem)?.ForbidPawnInput ?? false)) - { - //#699 #678 - //This check is needed to support the use of the Limit function for the IO Ports - if (storage.Position != t.Position) - { - return false; - } - } - } - - - return true; - } - } class Patch_FloatMenuMakerMap_GetOptions { diff --git a/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_StorageSettings_AllowedToAccept.cs b/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_StorageSettings_AllowedToAccept.cs new file mode 100644 index 00000000..76383721 --- /dev/null +++ b/Source/ProjectRimFactory/Common/HarmonyPatches/Patch_StorageSettings_AllowedToAccept.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Reflection.Emit; +using HarmonyLib; +using RimWorld; +using Verse; +// ReSharper disable UnusedType.Global +// ReSharper disable UnusedMember.Local +// ReSharper disable ArrangeTypeModifiers +// ReSharper disable ArrangeTypeMemberModifiers + +namespace ProjectRimFactory.Common.HarmonyPatches; + +/// +/// Required for the IO Port Limit Function +/// See: #699 #678 for reference +/// +/// +[HarmonyPatch(typeof(StorageSettings), "AllowedToAccept", typeof(Thing))] +class Patch_StorageSettings_AllowedToAccept +{ + + + private static bool patchDone = false; + private static bool foundStart = false; + private static object jumpMarker; + + /// + /// Equivalent to the Following Prefix + /// static bool Prefix(IStoreSettingsParent ___owner, Thing t, out bool __result) + ///{ + /// __result = false; + /// if (___owner is not IForbidPawnInputItem storage) return true; + /// if (PatchStorageUtil.SkippAcceptsPatch || !storage.ForbidPawnInput || storage.Position == t.Position) + /// { + /// return true; + /// } + /// return false; + ///} + /// + static IEnumerable Transpiler(IEnumerable instructions) + { + + foreach (var instruction in instructions) + { + + if (!foundStart && !patchDone) + { + if (instruction.opcode == OpCodes.Brfalse_S) + { + jumpMarker = instruction.operand; + } + if (instruction.opcode == OpCodes.Ldc_I4_1) + { + foundStart = true; + } + } + + if (foundStart && !patchDone) + { + // Insert Patch Here + // We are Just before the Return True + yield return new CodeInstruction(OpCodes.Ldarg_0); + yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(StorageSettings), "owner")); + yield return new CodeInstruction(OpCodes.Isinst, typeof(IForbidPawnInputItem)); + yield return new CodeInstruction(OpCodes.Brfalse_S, jumpMarker); // if not IForbidPawnInputItem return + + yield return new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PatchStorageUtil), "SkippAcceptsPatch")); + yield return new CodeInstruction(OpCodes.Brtrue_S, jumpMarker); // Skip if SkippAcceptsPatch + + + // I Hope that's right + yield return new CodeInstruction(OpCodes.Ldarg_0); + yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(StorageSettings), "owner")); + yield return new CodeInstruction(OpCodes.Isinst, typeof(IForbidPawnInputItem)); + yield return new CodeInstruction(OpCodes.Callvirt, + AccessTools.PropertyGetter(typeof(IForbidPawnInputItem), "ForbidPawnInput")); + yield return new CodeInstruction(OpCodes.Brfalse_S, jumpMarker); // if not ForbidPawnInput return + + // now the Position check + // I Hope that's right + yield return new CodeInstruction(OpCodes.Ldarg_0); + yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(StorageSettings), "owner")); + yield return new CodeInstruction(OpCodes.Isinst, typeof(IForbidPawnInputItem)); + yield return new CodeInstruction(OpCodes.Callvirt, AccessTools.Method(typeof(IHaulDestination), "get_Position")); + + + //yield return new CodeInstruction(OpCodes.Ldarg_1); // This should be the thing + //yield return new CodeInstruction(OpCodes.Callvirt, AccessTools.Method(typeof(Thing), "get_Position")); + + yield return new CodeInstruction(OpCodes.Ldarg_1); // This should be the thing + yield return new CodeInstruction(OpCodes.Callvirt, AccessTools.Method(typeof(Thing), "get_Position")); + + + yield return new CodeInstruction(OpCodes.Call, + AccessTools.Method(typeof(IntVec3), "op_Equality", new Type[] { typeof(IntVec3), typeof(IntVec3) })); + yield return new CodeInstruction(OpCodes.Brtrue_S, jumpMarker); // Skip if pos is the same + + yield return new CodeInstruction(OpCodes.Ldc_I4_0); + yield return new CodeInstruction(OpCodes.Ret); + + patchDone = true; + } + + yield return instruction; + } + } + +} \ No newline at end of file