using System.Collections.Generic; using System.Reflection.Emit; using BepInEx.Configuration; using HarmonyLib; namespace UXAssist; public static class PlayerPatch { public static ConfigEntry EnhancedMechaForgeCountControlEnabled; public static void Init() { EnhancedMechaForgeCountControlEnabled.SettingChanged += (_, _) => EnhancedMechaForgeCountControl.Enable(EnhancedMechaForgeCountControlEnabled.Value); EnhancedMechaForgeCountControl.Enable(EnhancedMechaForgeCountControlEnabled.Value); } public static void Uninit() { EnhancedMechaForgeCountControl.Enable(false); } private static class EnhancedMechaForgeCountControl { private static Harmony _patch; public static void Enable(bool on) { if (on) { _patch ??= Harmony.CreateAndPatchAll(typeof(EnhancedMechaForgeCountControl)); } else { _patch?.UnpatchSelf(); _patch = null; } } [HarmonyTranspiler] [HarmonyPatch(typeof(UIReplicatorWindow), nameof(UIReplicatorWindow.OnOkButtonClick))] private static IEnumerable UIReplicatorWindow_OnOkButtonClick_Transpiler(IEnumerable instructions, ILGenerator generator) { var matcher = new CodeMatcher(instructions, generator); matcher.MatchForward(false, new CodeMatch(ci => ci.opcode == OpCodes.Ldc_I4_S && ci.OperandIs(10)) ); matcher.Repeat(m => m.SetAndAdvance(OpCodes.Ldc_I4, 1000)); return matcher.InstructionEnumeration(); } [HarmonyTranspiler] [HarmonyPatch(typeof(UIReplicatorWindow), nameof(UIReplicatorWindow.OnPlusButtonClick))] [HarmonyPatch(typeof(UIReplicatorWindow), nameof(UIReplicatorWindow.OnMinusButtonClick))] private static IEnumerable UIReplicatorWindow_OnPlusButtonClick_Transpiler(IEnumerable instructions, ILGenerator generator) { var label1 = generator.DefineLabel(); var label2 = generator.DefineLabel(); var label3 = generator.DefineLabel(); var label4 = generator.DefineLabel(); var matcher = new CodeMatcher(instructions, generator); matcher.MatchForward(false, new CodeMatch(OpCodes.Ldloc_0), new CodeMatch(OpCodes.Ldc_I4_1), new CodeMatch(o => o.opcode == OpCodes.Add || o.opcode == OpCodes.Sub) ).Advance(1).RemoveInstruction().InsertAndAdvance( new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(VFInput), nameof(VFInput.control))), new CodeInstruction(OpCodes.Brfalse_S, label1), new CodeInstruction(OpCodes.Ldc_I4_S, 10), new CodeInstruction(OpCodes.Br_S, label4), new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(VFInput), nameof(VFInput.shift))).WithLabels(label1), new CodeInstruction(OpCodes.Brfalse_S, label2), new CodeInstruction(OpCodes.Ldc_I4_S, 100), new CodeInstruction(OpCodes.Br_S, label4), new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(VFInput), nameof(VFInput.alt))).WithLabels(label2), new CodeInstruction(OpCodes.Brfalse_S, label3), new CodeInstruction(OpCodes.Ldc_I4, 1000), new CodeInstruction(OpCodes.Br_S, label4), new CodeInstruction(OpCodes.Ldc_I4_1).WithLabels(label3) ).Labels.Add(label4); matcher.MatchForward(false, new CodeMatch(ci => ci.opcode == OpCodes.Ldc_I4_S && ci.OperandIs(10)) ); matcher.Repeat(m => m.SetAndAdvance(OpCodes.Ldc_I4, 1000)); return matcher.InstructionEnumeration(); } } }