From cd5527827adc70674081b294a94a4968dec6f0d9 Mon Sep 17 00:00:00 2001 From: Tyfon <29051038+tyfon7@users.noreply.github.com> Date: Sun, 2 Jun 2024 14:50:54 -0700 Subject: [PATCH] Confirm split with space; fix armor tooltip; remember repairer --- Patches/ConfirmationDialogKeysPatch.cs | 57 ++++++++++++++++++++------ Patches/FixTooltipPatch.cs | 50 ++++++++++++++++++---- Patches/InspectWindowStatsPatches.cs | 2 +- Patches/RememberRepairerPatch.cs | 29 +++++++++++++ Patches/TradingAutoSwitchPatches.cs | 2 +- Plugin.cs | 5 ++- R.cs | 47 ++++++++++++++------- 7 files changed, 155 insertions(+), 37 deletions(-) create mode 100644 Patches/RememberRepairerPatch.cs diff --git a/Patches/ConfirmationDialogKeysPatch.cs b/Patches/ConfirmationDialogKeysPatch.cs index b4dc2b5..cbbe71d 100644 --- a/Patches/ConfirmationDialogKeysPatch.cs +++ b/Patches/ConfirmationDialogKeysPatch.cs @@ -1,31 +1,64 @@ using Aki.Reflection.Patching; +using EFT.InputSystem; +using EFT.UI; using HarmonyLib; using System.Reflection; using UnityEngine; namespace UIFixes { - public class ConfirmationDialogKeysPatch : ModulePatch + public static class ConfirmDialogKeysPatches { - protected override MethodBase GetTargetMethod() + public static void Enable() { - return AccessTools.Method(R.DialogWindow.Type, "Update"); + new DialogWindowPatch().Enable(); + new SplitDialogPatch().Enable(); } - [PatchPostfix] - public static void Postfix(object __instance, bool ___bool_0) + public class DialogWindowPatch : ModulePatch { - var instance = new R.DialogWindow(__instance); - - if (!___bool_0) + protected override MethodBase GetTargetMethod() { - return; + return AccessTools.Method(R.DialogWindow.Type, "Update"); } - if (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter) || Input.GetKeyDown(KeyCode.Space)) + [PatchPostfix] + public static void Postfix(object __instance, bool ___bool_0) { - instance.Accept(); - return; + var instance = new R.DialogWindow(__instance); + + if (!___bool_0) + { + return; + } + + if (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter) || Input.GetKeyDown(KeyCode.Space)) + { + instance.Accept(); + return; + } + } + } + + public class SplitDialogPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(ItemUiContext), nameof(ItemUiContext.TranslateCommand)); + } + + [PatchPrefix] + public static bool Prefix(ECommand command, ref InputNode.ETranslateResult __result, SplitDialog ___splitDialog_0) + { + // It's wild to me that they implement UI keyboard shortcuts via the in-raid movement keybinds + if (___splitDialog_0 != null && ___splitDialog_0.gameObject.activeSelf && command == ECommand.Jump) + { + ___splitDialog_0.Accept(); + __result = InputNode.ETranslateResult.Block; + return false; + } + + return true; } } } diff --git a/Patches/FixTooltipPatch.cs b/Patches/FixTooltipPatch.cs index 9544bdc..cc5230b 100644 --- a/Patches/FixTooltipPatch.cs +++ b/Patches/FixTooltipPatch.cs @@ -1,22 +1,58 @@ using Aki.Reflection.Patching; +using EFT.UI; using EFT.UI.DragAndDrop; using HarmonyLib; using System.Reflection; +using TMPro; namespace UIFixes { - public class FixTooltipPatch : ModulePatch + public static class FixTooltipPatches { - protected override MethodBase GetTargetMethod() + public static void Enable() { - return AccessTools.Method(typeof(QuestItemViewPanel), nameof(QuestItemViewPanel.method_2)); + new QuestTooltipPatch().Enable(); + new ArmorTooltipPatch().Enable(); } - [PatchPostfix] - public static void Postfix(QuestItemViewPanel __instance) + public class QuestTooltipPatch : ModulePatch { - GridItemView parent = __instance.GetComponentInParent(); - parent?.ShowTooltip(); + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(QuestItemViewPanel), nameof(QuestItemViewPanel.method_2)); + } + + [PatchPostfix] + public static void Postfix(QuestItemViewPanel __instance) + { + GridItemView parent = __instance.GetComponentInParent(); + parent?.ShowTooltip(); + } + } + + public class ArmorTooltipPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(GridItemView), nameof(GridItemView.NewGridItemView)); + } + + // BSG loves to implement the same stuff in totally different ways, and this way is bad and also wrong + [PatchPostfix] + public static void Postfix(GridItemView __instance, TextMeshProUGUI ___ItemValue, PointerEventsProxy ____valuePointerEventsProxy) + { + // Add hover events to the correct place + HoverTrigger trigger = ___ItemValue.GetOrAddComponent(); + trigger.OnHoverStart += eventData => __instance.method_31(); + trigger.OnHoverEnd += eventData => + { + __instance.method_32(); + __instance.ShowTooltip(); + }; + + // Remove them from the wrong place + UnityEngine.Object.Destroy(____valuePointerEventsProxy); + } } } } diff --git a/Patches/InspectWindowStatsPatches.cs b/Patches/InspectWindowStatsPatches.cs index 0d3aee5..e2ff332 100644 --- a/Patches/InspectWindowStatsPatches.cs +++ b/Patches/InspectWindowStatsPatches.cs @@ -192,7 +192,7 @@ namespace UIFixes contextInteractions.OnRedrawRequired += createButton; // And unsubscribe when the window goes away - buttonsContainer.AddDisposable(() => + buttonsContainer.UI.AddDisposable(() => { contextInteractions.OnRedrawRequired -= createButton; Settings.ShowModStats.SettingChanged -= onSettingChanged; diff --git a/Patches/RememberRepairerPatch.cs b/Patches/RememberRepairerPatch.cs new file mode 100644 index 0000000..5496954 --- /dev/null +++ b/Patches/RememberRepairerPatch.cs @@ -0,0 +1,29 @@ +using Aki.Reflection.Patching; +using EFT.UI; +using HarmonyLib; +using System.Reflection; +using UnityEngine; + +namespace UIFixes +{ + public class RememberRepairerPatch : ModulePatch + { + private static readonly string PlayerPrefKey = "UIFixes.Repair.CurrentRepairerIndex"; + + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(RepairerParametersPanel), nameof(RepairerParametersPanel.Show)); + } + + [PatchPostfix] + public static void Postfix(RepairerParametersPanel __instance, DropDownBox ____tradersDropDown) + { + __instance.R().UI.AddDisposable(____tradersDropDown.OnValueChanged.Subscribe(index => PlayerPrefs.SetInt(PlayerPrefKey, index))); + + if (PlayerPrefs.HasKey(PlayerPrefKey)) + { + ____tradersDropDown.UpdateValue(PlayerPrefs.GetInt(PlayerPrefKey)); + } + } + } +} diff --git a/Patches/TradingAutoSwitchPatches.cs b/Patches/TradingAutoSwitchPatches.cs index aaa9d3c..5fb848f 100644 --- a/Patches/TradingAutoSwitchPatches.cs +++ b/Patches/TradingAutoSwitchPatches.cs @@ -35,7 +35,7 @@ namespace UIFixes BuyTab = wrappedInstance.BuyTab; SellTab = wrappedInstance.SellTab; - wrappedInstance.AddDisposable(() => + wrappedInstance.UI.AddDisposable(() => { BuyTab = null; SellTab = null; diff --git a/Plugin.cs b/Plugin.cs index 3dfa222..87567e5 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -13,9 +13,9 @@ namespace UIFixes R.Init(); - new ConfirmationDialogKeysPatch().Enable(); + ConfirmDialogKeysPatches.Enable(); new FixMailRecieveAllPatch().Enable(); - new FixTooltipPatch().Enable(); + FixTooltipPatches.Enable(); new FixWeaponBindsDisplayPatch().Enable(); FocusFleaOfferNumberPatches.Enable(); HideoutSearchPatches.Enable(); @@ -42,6 +42,7 @@ namespace UIFixes AddOfferRememberAutoselectPatches.Enable(); KeepMessagesOpenPatches.Enable(); new FocusTradeQuantityPatch().Enable(); + new RememberRepairerPatch().Enable(); } public static bool InRaid() diff --git a/R.cs b/R.cs index d893029..b816656 100644 --- a/R.cs +++ b/R.cs @@ -23,6 +23,8 @@ namespace UIFixes public static void Init() { // Order is significant, as some reference each other + UIElement.InitUITypes(); + UIContext.InitTypes(); DialogWindow.InitTypes(); ControlSettings.InitTypes(); ProductionPanel.InitTypes(); @@ -58,6 +60,32 @@ namespace UIFixes public object Value { get; protected set; } = value; } + public class UIElement(object value) : Wrapper(value) + { + private static FieldInfo UIField; + + public static void InitUITypes() + { + UIField = AccessTools.Field(typeof(EFT.UI.UIElement), "UI"); + } + + public UIContext UI { get { return new UIContext(UIField.GetValue(Value)); } } + } + + public class UIContext(object value) : Wrapper(value) + { + public static Type Type { get; private set; } + private static MethodInfo AddDisposableActionMethod; + + public static void InitTypes() + { + Type = AccessTools.Field(typeof(EFT.UI.UIElement), "UI").FieldType; + AddDisposableActionMethod = AccessTools.Method(Type, "AddDisposable", [typeof(Action)]); + } + + public void AddDisposable(Action destroy) => AddDisposableActionMethod.Invoke(Value, [destroy]); + } + public class DialogWindow(object value) : Wrapper(value) { public static Type Type { get; private set; } @@ -288,27 +316,21 @@ namespace UIFixes public object ToGridViewCanAcceptOperation() => ImplicitCastToGridViewCanAcceptOperationMethod.Invoke(null, [Value]); } - public class InteractionButtonsContainer(object value) : Wrapper(value) + public class InteractionButtonsContainer(object value) : UIElement(value) { public static Type Type { get; private set; } private static FieldInfo ButtonTemplateField; private static FieldInfo ContainerField; - private static FieldInfo UIField; - private static MethodInfo UIAddDisposableMethod; public static void InitTypes() { Type = typeof(EFT.UI.InteractionButtonsContainer); ButtonTemplateField = AccessTools.Field(Type, "_buttonTemplate"); ContainerField = AccessTools.Field(Type, "_buttonsContainer"); - UIField = AccessTools.Field(Type, "UI"); // GClass767 - UIAddDisposableMethod = AccessTools.Method(UIField.FieldType, "AddDisposable", [typeof(Action)]); } public SimpleContextMenuButton ButtonTemplate { get { return (SimpleContextMenuButton)ButtonTemplateField.GetValue(Value); } } public Transform Container { get { return (Transform)ContainerField.GetValue(Value); } } - public object UI { get { return UIField.GetValue(Value); } } - public void AddDisposable(Action action) => UIAddDisposableMethod.Invoke(UI, [action]); } public class ContextMenuButton(object value) : Wrapper(value) @@ -488,25 +510,19 @@ namespace UIFixes public static Dictionary GetMoneySums(IEnumerable items) => (Dictionary)GetMoneySumsMethod.Invoke(null, [items]); } - public class TraderScreensGroup(object value) : Wrapper(value) + public class TraderScreensGroup(object value) : UIElement(value) { public static Type Type { get; private set; } - private static FieldInfo UIField; - private static MethodInfo UIAddDisposableMethod; private static FieldInfo BuyTabField; private static FieldInfo SellTabField; public static void InitTypes() { Type = typeof(EFT.UI.TraderScreensGroup); - UIField = AccessTools.Field(Type, "UI"); - UIAddDisposableMethod = AccessTools.Method(UIField.FieldType, "AddDisposable", [typeof(Action)]); BuyTabField = AccessTools.Field(Type, "_buyTab"); SellTabField = AccessTools.Field(Type, "_sellTab"); } - public object UI { get { return UIField.GetValue(Value); } } - public void AddDisposable(Action action) => UIAddDisposableMethod.Invoke(UI, [action]); public Tab BuyTab { get { return (Tab)BuyTabField.GetValue(Value); } } public Tab SellTab { get { return (Tab)SellTabField.GetValue(Value); } } } @@ -552,6 +568,8 @@ namespace UIFixes public Button Button { get { return (Button)ButtonField.GetValue(Value); } } } + + public class RepairerParametersPanel(object value) : UIElement(value) { } } public static class RExtentensions @@ -574,5 +592,6 @@ namespace UIFixes public static R.TradingItemView R(this TradingItemView value) => new(value); public static R.GridWindow R(this GridWindow value) => new(value); public static R.GridSortPanel R(this GridSortPanel value) => new(value); + public static R.RepairerParametersPanel R(this RepairerParametersPanel value) => new(value); } }