From 20ca007969bd316ca29989519fc526fbc8a24394 Mon Sep 17 00:00:00 2001 From: Tyfon <29051038+tyfon7@users.noreply.github.com> Date: Wed, 24 Apr 2024 14:50:21 -0700 Subject: [PATCH] Future-proofing swappatch, add mouse scroll multi --- Patches/DisabledActionsPatch.cs | 4 +- Patches/ScrollPatches.cs | 16 +++++ Patches/SwapPatch.cs | 119 +++++++++++++++++++++++--------- Settings.cs | 2 + 4 files changed, 107 insertions(+), 34 deletions(-) diff --git a/Patches/DisabledActionsPatch.cs b/Patches/DisabledActionsPatch.cs index 945ac8d..522b4b3 100644 --- a/Patches/DisabledActionsPatch.cs +++ b/Patches/DisabledActionsPatch.cs @@ -8,6 +8,7 @@ namespace UIFixes { public class DisabledActionsPatch : ModulePatch { + private static string[] UnimplementedActions = ["Bang & clear", "Flash & clear", "Move in"]; protected override MethodBase GetTargetMethod() { Type type = typeof(GetActionsClass); @@ -25,7 +26,8 @@ namespace UIFixes { for (int i = __result.Actions.Count - 1; i >= 0; i--) { - if (__result.Actions[i].Disabled) + // if (__result.Actions[i].Disabled) + if (UnimplementedActions.Contains(__result.Actions[i].Name)) { __result.Actions.RemoveAt(i); } diff --git a/Patches/ScrollPatches.cs b/Patches/ScrollPatches.cs index 999bd43..89975e5 100644 --- a/Patches/ScrollPatches.cs +++ b/Patches/ScrollPatches.cs @@ -21,6 +21,7 @@ namespace UIFixes new TraderDealScreenPatch().Enable(); new OfferViewListPatch().Enable(); new MessagesContainerPatch().Enable(); + new MouseScrollSpeedPatch().Enable(); } protected static void HandleInput(ScrollRect scrollRect) @@ -229,5 +230,20 @@ namespace UIFixes return instructions; } } + + public class MouseScrollSpeedPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + Type type = typeof(ScrollRectNoDrag); + return type.GetMethod("OnScroll"); + } + + [PatchPrefix] + private static void Prefix(PointerEventData data) + { + data.scrollDelta *= Settings.MouseScrollMulti.Value; + } + } } } diff --git a/Patches/SwapPatch.cs b/Patches/SwapPatch.cs index 9436d0f..6eadc95 100644 --- a/Patches/SwapPatch.cs +++ b/Patches/SwapPatch.cs @@ -15,8 +15,41 @@ namespace UIFixes { public class SwapPatch { + // Types needed + private static Type GridItemAddressType; // GClass2769 + private static FieldInfo GridItemAddressLocationInGridField; + private static PropertyInfo GridItemAddressGridProperty; + + private static Type SlotItemAddressType; // GClass2767 + private static FieldInfo SlotItemAddressSlotField; + + private static Type CanAcceptOperationType; // GStruct413 + private static PropertyInfo CanAcceptOperationSucceededProperty; + private static PropertyInfo CanAcceptOperationErrorProperty; + + private static Type SwapOperationType; + private static MethodInfo SwapOperationToCanAcceptOperationOperator; +/* + private static Type CannotApplyErrorType; // GClass3300 + private static Type CannotAddErrorType; // GClass3296 + private static Type NoActionsErrorType; // GClass3293 +*/ public static void Enable() { + GridItemAddressType = PatchConstants.EftTypes.First(t => typeof(ItemAddress).IsAssignableFrom(t) && AccessTools.Property(t, "Grid") != null); + GridItemAddressLocationInGridField = AccessTools.Field(GridItemAddressType, "LocationInGrid"); + GridItemAddressGridProperty = AccessTools.Property(GridItemAddressType, "Grid"); + + SlotItemAddressType = PatchConstants.EftTypes.First(t => typeof(ItemAddress).IsAssignableFrom(t) && AccessTools.Field(t, "Slot") != null); + SlotItemAddressSlotField = AccessTools.Field(SlotItemAddressType, "Slot"); + + CanAcceptOperationType = AccessTools.Method(typeof(GridView), "CanAccept").GetParameters()[2].ParameterType.GetElementType(); // parameter is a ref type, get underlying type + CanAcceptOperationSucceededProperty = AccessTools.Property(CanAcceptOperationType, "Succeeded"); + CanAcceptOperationErrorProperty = AccessTools.Property(CanAcceptOperationType, "Error"); + + SwapOperationType = AccessTools.Method(typeof(InteractionsHandlerClass), "Swap").ReturnType; + SwapOperationToCanAcceptOperationOperator = SwapOperationType.GetMethods().First(m => m.Name == "op_Implicit" && m.ReturnType == CanAcceptOperationType); + new GridViewCanAcceptPatch().Enable(); new GetHightLightColorPatch().Enable(); new SlotViewCanAcceptPatch().Enable(); @@ -26,9 +59,14 @@ namespace UIFixes public class GridViewCanAcceptPatch : ModulePatch { + private static FieldInfo GridViewTraderControllerClassField; + protected override MethodBase GetTargetMethod() { Type type = typeof(GridView); + + GridViewTraderControllerClassField = AccessTools.GetDeclaredFields(type).First(f => f.FieldType == typeof(TraderControllerClass)); + return type.GetMethod("CanAccept"); } @@ -41,13 +79,14 @@ namespace UIFixes return false; } - if (itemAddressA is GClass2769 && itemAddressB is GClass2769) + //if (itemAddressA is GClass2769 && itemAddressB is GClass2769) + if (GridItemAddressType.IsInstanceOfType(itemAddressA) && GridItemAddressType.IsInstanceOfType(itemAddressB)) { - LocationInGrid locationA = (itemAddressA as GClass2769).LocationInGrid; - LocationInGrid locationB = (itemAddressB as GClass2769).LocationInGrid; - StashGridClass grid = (itemAddressA as GClass2769).Grid; + LocationInGrid locationA = GridItemAddressLocationInGridField.GetValue(itemAddressA) as LocationInGrid; // (itemAddressA as GClass2769).LocationInGrid; + LocationInGrid locationB = GridItemAddressLocationInGridField.GetValue(itemAddressB) as LocationInGrid; // (itemAddressB as GClass2769).LocationInGrid; + StashGridClass grid = GridItemAddressGridProperty.GetValue(itemAddressA) as StashGridClass; //(itemAddressA as GClass2769).Grid; - GStruct24 itemASize = itemA.CalculateRotatedSize(locationA.r); + var itemASize = itemA.CalculateRotatedSize(locationA.r); var itemASlots = new List(); for (int y = 0; y < itemASize.Y; y++) { @@ -57,7 +96,7 @@ namespace UIFixes } } - GStruct24 itemBSize = itemB.CalculateRotatedSize(locationB.r); + var itemBSize = itemB.CalculateRotatedSize(locationB.r); for (int y = 0; y < itemBSize.Y; y++) { for (int x = 0; x < itemBSize.X; x++) @@ -75,14 +114,14 @@ namespace UIFixes } [PatchPostfix] - private static void Postfix(GridView __instance, ItemContextClass itemContext, ItemContextAbstractClass targetItemContext, ref GStruct413 operation, ref bool __result, TraderControllerClass ___gclass2758_0) + private static void Postfix(GridView __instance, ItemContextClass itemContext, ItemContextAbstractClass targetItemContext, ref object operation, ref bool __result) { if (!Settings.SwapItems.Value) { return; } - if (InHighlight || itemContext == null || targetItemContext == null) + if (InHighlight || itemContext == null || targetItemContext == null || (bool)CanAcceptOperationSucceededProperty.GetValue(operation) == true) { return; } @@ -92,10 +131,16 @@ namespace UIFixes // 3300 cannot apply a to b // 3293 no possible actions - if (item != targetItem && (operation.Error is GClass3300 || operation.Error is GClass3293)) + if (item == targetItem) + { + return; + } + + string error = CanAcceptOperationErrorProperty.GetValue(operation).ToString(); // operation.Error.ToString(); + if (error.StartsWith("Cannot add") || error.StartsWith("Cannot apply") || error == "InventoryError/NoPossibleActions") { ItemAddress itemAddress = item.Parent; - GClass2769 targetAddress = targetItem.Parent as GClass2769; + ItemAddress targetAddress = targetItem.Parent; if (targetAddress == null) { @@ -103,51 +148,57 @@ namespace UIFixes } LocationInGrid itemToLocation = __instance.CalculateItemLocation(itemContext); // This is the location you're dragging it over, including rotation - var itemToAddress = new GClass2769(targetAddress.Grid, itemToLocation); // This is a grid because we're in the GridView patch, i.e. you're dragging it over a grid + ItemAddress itemToAddress = Activator.CreateInstance(GridItemAddressType, [GridItemAddressGridProperty.GetValue(targetAddress), itemToLocation]) as ItemAddress; //new GClass2769(targetAddress.Grid, itemToLocation); // This is a grid because we're in the GridView patch, i.e. you're dragging it over a grid ItemAddress targetToAddress; - if (itemAddress is GClass2769) // The item source is a grid + //if (itemAddress is GClass2769) // The item source is a grid + if (GridItemAddressType.IsInstanceOfType(itemAddress)) { - var itemGridAddress = itemAddress as GClass2769; + LocationInGrid targetToLocation = (GridItemAddressLocationInGridField.GetValue(itemAddress) as LocationInGrid).Clone(); //itemGridAddress.LocationInGrid.Clone(); + targetToLocation.r = (GridItemAddressLocationInGridField.GetValue(targetAddress) as LocationInGrid).r; - LocationInGrid targetToLocation = itemGridAddress.LocationInGrid.Clone(); - targetToLocation.r = targetAddress.LocationInGrid.r; - targetToAddress = new GClass2769(itemGridAddress.Grid, targetToLocation); + StashGridClass grid = GridItemAddressGridProperty.GetValue(itemAddress) as StashGridClass; //(itemAddressA as GClass2769).Grid; + targetToAddress = Activator.CreateInstance(GridItemAddressType, [grid, targetToLocation]) as ItemAddress; //new GClass2769(itemGridAddress.Grid, targetToLocation); } - else if (itemAddress is GClass2767) // The item source is a slot + //else if (itemAddress is GClass2767) // The item source is a slot + else if (SlotItemAddressType.IsInstanceOfType(itemAddress)) { - var itemSlotAddress = itemAddress as GClass2767; - targetToAddress = new GClass2767(itemSlotAddress.Slot); + //var itemSlotAddress = itemAddress as GClass2767; + targetToAddress = Activator.CreateInstance(SlotItemAddressType, [SlotItemAddressSlotField.GetValue(itemAddress)]) as ItemAddress; //new GClass2767(itemSlotAddress.Slot); } else { return; } + // Get the TraderControllerClass + TraderControllerClass traderControllerClass = GridViewTraderControllerClassField.GetValue(__instance) as TraderControllerClass; + // Check that the destinations won't overlap (Swap won't check this) if (!ItemsOverlap(item, itemToAddress, targetItem, targetToAddress)) { // Try original rotations - var result = InteractionsHandlerClass.Swap(item, itemToAddress, targetItem, targetToAddress, ___gclass2758_0, true); + var result = InteractionsHandlerClass.Swap(item, itemToAddress, targetItem, targetToAddress, traderControllerClass, true); if (result.Succeeded) { - operation = result; - __result = operation.Succeeded; + // operation = result; + operation = SwapOperationToCanAcceptOperationOperator.Invoke(null, [result]); + __result = true; return; } } // If we're coming from a grid, try rotating the target object - if (targetToAddress is GClass2769) + if (GridItemAddressType.IsInstanceOfType(itemAddress)) { - var targetToLocation = (targetToAddress as GClass2769).LocationInGrid; + var targetToLocation = GridItemAddressLocationInGridField.GetValue(targetToAddress) as LocationInGrid; // (targetToAddress as GClass2769).LocationInGrid; targetToLocation.r = targetToLocation.r == ItemRotation.Horizontal ? ItemRotation.Vertical : ItemRotation.Horizontal; if (!ItemsOverlap(item, itemToAddress, targetItem, targetToAddress)) { - var result = InteractionsHandlerClass.Swap(item, itemToAddress, targetItem, targetToAddress, ___gclass2758_0, true); + var result = InteractionsHandlerClass.Swap(item, itemToAddress, targetItem, targetToAddress, traderControllerClass, true); if (result.Succeeded) { - operation = result; - __result = operation.Succeeded; + operation = SwapOperationToCanAcceptOperationOperator.Invoke(null, [result]); + __result = true; return; } } @@ -167,33 +218,35 @@ namespace UIFixes } [PatchPostfix] - private static void Postfix(SlotView __instance, ItemContextClass itemContext, ItemContextAbstractClass targetItemContext, ref GStruct413 operation, InventoryControllerClass ___InventoryController, ref bool __result) + private static void Postfix(SlotView __instance, ItemContextClass itemContext, ItemContextAbstractClass targetItemContext, ref object operation, InventoryControllerClass ___InventoryController, ref bool __result) { if (!@Settings.SwapItems.Value) { return; } - if (InHighlight || itemContext == null || targetItemContext == null) + if (InHighlight || itemContext == null || targetItemContext == null || (bool)CanAcceptOperationSucceededProperty.GetValue(operation) == true) { return; } // 3300 cannot apply a to b // 3293 no possible actions - if (operation.Error is GClass3300 || operation.Error is GClass3293) + //if (operation.Error is GClass3300 || operation.Error is GClass3293) + string error = CanAcceptOperationErrorProperty.GetValue(operation).ToString(); // operation.Error.ToString(); + if (error.StartsWith("Cannot add") || error.StartsWith("Cannot apply") || error == "InventoryError/NoPossibleActions") { var item = itemContext.Item; var targetItem = targetItemContext.Item; - var itemToAddress = new GClass2767(__instance.Slot); + var itemToAddress = Activator.CreateInstance(SlotItemAddressType, [__instance.Slot]) as ItemAddress; // new GClass2767(__instance.Slot); var targetToAddress = item.Parent; var result = InteractionsHandlerClass.Swap(item, itemToAddress, targetItem, targetToAddress, ___InventoryController, true); if (result.Succeeded) { - operation = result; - __result = operation.Succeeded; + operation = SwapOperationToCanAcceptOperationOperator.Invoke(null, [result]); + __result = true; } } } diff --git a/Settings.cs b/Settings.cs index af4cab7..9451d83 100644 --- a/Settings.cs +++ b/Settings.cs @@ -9,6 +9,7 @@ namespace UIFixes public static ConfigEntry TransferConfirmOnClose { get; set; } public static ConfigEntry UseHomeEnd { get; set; } public static ConfigEntry RebindPageUpDown { get; set; } + public static ConfigEntry MouseScrollMulti { get; set; } public static ConfigEntry RemoveDisabledActions { get; set; } public static ConfigEntry SwapItems { get; set; } @@ -19,6 +20,7 @@ namespace UIFixes TransferConfirmOnClose = config.Bind("Transfer Items", "Confirm untransfered items", false, "Whether to pointlessly confirm that you're leaving the item transfer with literally no consequences"); UseHomeEnd = config.Bind("Keybinds", "Add support for Home and End", true, "Home and End will scroll to the top and bottom of lists"); RebindPageUpDown = config.Bind("Keybinds", "Use normal PageUp and PageDown (requires restart)", true, "Changes PageUp and PageDown to simply page up and down, not scroll all the way to top and bottom"); + MouseScrollMulti = config.Bind("Keybinds", "Mousewheel scrolling multiplier", 1, "How many rows to scroll with the mousewheel"); RemoveDisabledActions = config.Bind("In Raid", "Hide unimplemented actions", false, "Hides actions you can't actually do, like \"Bang and Clear\", etc from locked doors and other interactable objects"); SwapItems = config.Bind("Enhancements", "Enable item swapping", true); }