diff --git a/ContextMenus/RepairInteractions.cs b/ContextMenus/RepairInteractions.cs index dfe3af9..ffe84f2 100644 --- a/ContextMenus/RepairInteractions.cs +++ b/ContextMenus/RepairInteractions.cs @@ -41,7 +41,7 @@ namespace UIFixes { text = string.Format("{0}", repairer.LocalizedName); } - else if (repairer is GClass802 repairKit) + else if (repairer is GClass803 repairKit) { float pointsLeft = repairKit.GetRepairPoints(); double amount = repairStrategy.GetRepairPrice(repairAmount, repairKit); @@ -96,7 +96,7 @@ namespace UIFixes float repairAmount = GetClampedRepairAmount(repairStrategy); - if (repairer is GClass802 repairKit) + if (repairer is GClass803 repairKit) { float pointsLeft = repairKit.GetRepairPoints(); double amount = repairStrategy.GetRepairPrice(repairAmount, repairKit); diff --git a/Multiselect/MultiGrid.cs b/Multiselect/MultiGrid.cs index ecaf233..096c3bc 100644 --- a/Multiselect/MultiGrid.cs +++ b/Multiselect/MultiGrid.cs @@ -5,8 +5,6 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; -using GridItemAddress = GClass2769; - namespace UIFixes { public static class MultiGrid @@ -14,7 +12,7 @@ namespace UIFixes private static readonly Dictionary> GridOffsets = []; private static readonly Dictionary>> GridsByLocation = []; - public static LocationInGrid GetGridLocation(GridItemAddress realAddress) + public static LocationInGrid GetGridLocation(ItemAddressClass realAddress) { if (!IsMultiGrid(realAddress)) { @@ -25,7 +23,7 @@ namespace UIFixes return new LocationInGrid(realAddress.LocationInGrid.x + gridOffset.x, realAddress.LocationInGrid.y + gridOffset.y, realAddress.LocationInGrid.r); } - public static GridItemAddress GetRealAddress(StashGridClass originGrid, LocationInGrid multigridLocation) + public static ItemAddressClass GetRealAddress(StashGridClass originGrid, LocationInGrid multigridLocation) { if (!IsMultiGrid(originGrid.ParentItem)) { @@ -33,7 +31,7 @@ namespace UIFixes multigridLocation.x = Math.Max(0, Math.Min(originGrid.GridWidth.Value, multigridLocation.x)); multigridLocation.y = Math.Max(0, Math.Min(originGrid.GridHeight.Value, multigridLocation.y)); - return new GridItemAddress(originGrid, multigridLocation); + return new ItemAddressClass(originGrid, multigridLocation); } var gridsByLocation = GridsByLocation[originGrid.ParentItem]; @@ -54,7 +52,7 @@ namespace UIFixes Vector2Int offsets = GridOffsets[originGrid.ParentItem][grid]; LocationInGrid location = new(x - offsets.x, y - offsets.y, multigridLocation.r); - return new GridItemAddress(grid, location); + return new ItemAddressClass(grid, location); } public static void Cache(GridView initialGridView) @@ -108,25 +106,9 @@ namespace UIFixes GridOffsets.Add(parent, gridOffsets); GridsByLocation.Add(parent, gridsByLocation); - - // Best effort attempt at cleanup - IItemOwner owner = parent.Owner; - if (owner != null) - { - void onRemoveItem(GEventArgs3 eventArgs) - { - if (GridOffsets.ContainsKey(eventArgs.Item)) - { - GridOffsets.Remove(eventArgs.Item); - GridsByLocation.Remove(eventArgs.Item); - owner.RemoveItemEvent -= onRemoveItem; - } - }; - owner.RemoveItemEvent += onRemoveItem; - } } - private static bool IsMultiGrid(GridItemAddress itemAddress) + private static bool IsMultiGrid(ItemAddressClass itemAddress) { return IsMultiGrid(itemAddress.Container.ParentItem); } diff --git a/Multiselect/MultiSelect.cs b/Multiselect/MultiSelect.cs index ac55efa..6bfc3ab 100644 --- a/Multiselect/MultiSelect.cs +++ b/Multiselect/MultiSelect.cs @@ -7,8 +7,6 @@ using System.Threading.Tasks; using TMPro; using UnityEngine; -using GridItemAddress = GClass2769; - namespace UIFixes { public class MultiSelect @@ -202,9 +200,9 @@ namespace UIFixes var result = ItemContexts .Where(ic => first == null || ic.Item != first.Item) - .OrderByDescending(ic => ic.ItemAddress is GridItemAddress) + .OrderByDescending(ic => ic.ItemAddress is ItemAddressClass) .ThenByDescending(ic => first != null && first.ItemAddress.Container.ParentItem == ic.ItemAddress.Container.ParentItem) - .ThenBy(ic => ic.ItemAddress is GridItemAddress selectedGridAddress ? gridOrder(MultiGrid.GetGridLocation(selectedGridAddress)) : 0); + .ThenBy(ic => ic.ItemAddress is ItemAddressClass selectedGridAddress ? gridOrder(MultiGrid.GetGridLocation(selectedGridAddress)) : 0); return first != null && prepend ? result.Prepend(first) : result; } @@ -238,7 +236,7 @@ namespace UIFixes private static bool InteractionAvailable(ItemContextClass itemContext, EItemInfoButton interaction, ItemUiContext itemUiContext) { // Since itemContext is for "drag", no context actions are allowed. Get the underlying "inventory" context - ItemContextAbstractClass innerContext = itemContext.GClass2813_0; + ItemContextAbstractClass innerContext = itemContext.ItemContextAbstractClass; if (innerContext == null) { return false; @@ -283,7 +281,7 @@ namespace UIFixes var taskSerializer = itemUiContext.gameObject.AddComponent(); taskSerializer.Initialize( SortedItemContexts().Where(ic => InteractionAvailable(ic, EItemInfoButton.Unequip, itemUiContext)), - itemContext => itemUiContext.Uninstall(itemContext.GClass2813_0)); + itemContext => itemUiContext.Uninstall(itemContext.ItemContextAbstractClass)); itemUiContext.Tooltip?.Close(); } @@ -291,19 +289,23 @@ namespace UIFixes public static Task LoadAmmoAll(ItemUiContext itemUiContext, string ammoTemplateId, bool allOrNothing) { - StopLoading(); + StopLoading(true); if (!allOrNothing || InteractionCount(EItemInfoButton.LoadAmmo, itemUiContext) == Count) { - // Call Initialize() before setting UnloadSerializer so that the initial synchronous call to StopProcesses()->StopUnloading() doesn't immediately cancel this - var taskSerializer = itemUiContext.gameObject.AddComponent(); - Task result = taskSerializer.Initialize( - SortedItemContexts().Where(ic => ic.Item is MagazineClass && InteractionAvailable(ic, EItemInfoButton.LoadAmmo, itemUiContext)), - itemContext => itemUiContext.LoadAmmoByType(itemContext.Item as MagazineClass, ammoTemplateId, itemContext.UpdateView)); + LoadUnloadSerializer = itemUiContext.gameObject.AddComponent(); + Task result = LoadUnloadSerializer.Initialize( + SortedItemContexts() + .Where(ic => ic.Item is MagazineClass && InteractionAvailable(ic, EItemInfoButton.LoadAmmo, itemUiContext)) + .SelectMany(ic => ic.RepeatUntilFull()), + itemContext => + { + IgnoreStopLoading = true; + return itemUiContext.LoadAmmoByType(itemContext.Item as MagazineClass, ammoTemplateId, itemContext.UpdateView); + }); - LoadUnloadSerializer = taskSerializer; itemUiContext.Tooltip?.Close(); - return result; + return result.ContinueWith(t => LoadUnloadSerializer = null); } return Task.CompletedTask; @@ -311,12 +313,11 @@ namespace UIFixes public static void UnloadAmmoAll(ItemUiContext itemUiContext, bool allOrNothing) { - StopLoading(); + StopLoading(true); if (!allOrNothing || InteractionCount(EItemInfoButton.UnloadAmmo, itemUiContext) == Count) { - // Call Initialize() before setting UnloadSerializer so that the initial synchronous call to StopProcesses()->StopUnloading() doesn't immediately cancel this - var taskSerializer = itemUiContext.gameObject.AddComponent(); - taskSerializer.Initialize( + LoadUnloadSerializer = itemUiContext.gameObject.AddComponent(); + LoadUnloadSerializer.Initialize( SortedItemContexts().Where(ic => InteractionAvailable(ic, EItemInfoButton.UnloadAmmo, itemUiContext)), itemContext => { @@ -324,23 +325,33 @@ namespace UIFixes { Deselect(itemContext); } - return itemUiContext.UnloadAmmo(itemContext.Item); - }); - LoadUnloadSerializer = taskSerializer; + IgnoreStopLoading = true; + return itemUiContext.UnloadAmmo(itemContext.Item); + }).ContinueWith(t => LoadUnloadSerializer = null); + itemUiContext.Tooltip?.Close(); } } - public static void StopLoading() + private static bool IgnoreStopLoading = false; + + public static void StopLoading(bool force = false) { if (LoadUnloadSerializer == null) { return; } - LoadUnloadSerializer.Cancel(); - LoadUnloadSerializer = null; + if (!IgnoreStopLoading || force) + { + LoadUnloadSerializer.Cancel(); + LoadUnloadSerializer = null; + } + else + { + IgnoreStopLoading = false; + } } public static void UnpackAll(ItemUiContext itemUiContext, bool allOrNothing) @@ -402,21 +413,21 @@ namespace UIFixes public MultiSelectItemContext(ItemContextAbstractClass itemContext, ItemRotation rotation) : base(itemContext, rotation) { // Adjust event handlers - if (GClass2813_0 != null) + if (ItemContextAbstractClass != null) { // Listen for underlying context being disposed, it might mean the item is gone (merged, destroyed, etc) - GClass2813_0.OnDisposed += OnParentDispose; + ItemContextAbstractClass.OnDisposed += OnParentDispose; // This serves no purpose and causes stack overflows - GClass2813_0.OnCloseWindow -= CloseDependentWindows; + ItemContextAbstractClass.OnCloseWindow -= CloseDependentWindows; } } public override void Dispose() { base.Dispose(); - if (GClass2813_0 != null) + if (ItemContextAbstractClass != null) { - GClass2813_0.OnDisposed -= OnParentDispose; + ItemContextAbstractClass.OnDisposed -= OnParentDispose; } } @@ -433,9 +444,9 @@ namespace UIFixes // ItemContextClass (drag) defaults to None, but we want what the underlying item allows public override bool CanQuickMoveTo(ETargetContainer targetContainer) { - if (GClass2813_0 != null) + if (ItemContextAbstractClass != null) { - return GClass2813_0.CanQuickMoveTo(targetContainer); + return ItemContextAbstractClass.CanQuickMoveTo(targetContainer); } return base.CanQuickMoveTo(targetContainer); @@ -481,6 +492,18 @@ namespace UIFixes } } + public static IEnumerable RepeatUntilFull(this ItemContextClass itemContext) + { + if (itemContext.Item is MagazineClass magazine) + { + int ammoCount = -1; + while (magazine.Count > ammoCount && magazine.Count < magazine.MaxCount) + { + ammoCount = magazine.Count; + yield return itemContext; + } + } + } } } diff --git a/Patches/AddOfferClickablePricesPatches.cs b/Patches/AddOfferClickablePricesPatches.cs index dc4b1d6..daa2bcd 100644 --- a/Patches/AddOfferClickablePricesPatches.cs +++ b/Patches/AddOfferClickablePricesPatches.cs @@ -1,7 +1,7 @@ -using Aki.Reflection.Patching; -using EFT.UI.Ragfair; +using EFT.UI.Ragfair; using HarmonyLib; using JetBrains.Annotations; +using SPT.Reflection.Patching; using System.Linq; using System.Reflection; using TMPro; diff --git a/Patches/AddOfferRememberAutoselectPatches.cs b/Patches/AddOfferRememberAutoselectPatches.cs index 12b7e11..60a2e3e 100644 --- a/Patches/AddOfferRememberAutoselectPatches.cs +++ b/Patches/AddOfferRememberAutoselectPatches.cs @@ -1,7 +1,7 @@ -using Aki.Reflection.Patching; -using EFT.UI; +using EFT.UI; using EFT.UI.Ragfair; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; using UnityEngine; @@ -29,7 +29,7 @@ namespace UIFixes { protected override MethodBase GetTargetMethod() { - return AccessTools.Method(typeof(AddOfferWindow), nameof(AddOfferWindow.method_8)); + return AccessTools.Method(typeof(AddOfferWindow), nameof(AddOfferWindow.method_7)); } [PatchPostfix] diff --git a/Patches/AssortUnlocksPatch.cs b/Patches/AssortUnlocksPatch.cs index b467a13..f42ad1e 100644 --- a/Patches/AssortUnlocksPatch.cs +++ b/Patches/AssortUnlocksPatch.cs @@ -1,12 +1,13 @@ -using Aki.Common.Http; -using Aki.Reflection.Patching; -using EFT.UI; +using EFT.UI; using EFT.UI.Ragfair; using HarmonyLib; using Newtonsoft.Json; +using SPT.Common.Http; +using SPT.Reflection.Patching; using System; using System.Collections.Generic; using System.Reflection; +using System.Threading.Tasks; namespace UIFixes { @@ -32,20 +33,24 @@ namespace UIFixes { Loading = true; - string response = RequestHandler.GetJson("/uifixes/assortUnlocks"); - if (!String.IsNullOrEmpty(response)) + Task response = RequestHandler.GetJsonAsync("/uifixes/assortUnlocks"); + response.ContinueWith(task => { - try + string json = task.Result; + if (!String.IsNullOrEmpty(json)) { - AssortUnlocks = JsonConvert.DeserializeObject>(response); + try + { + AssortUnlocks = JsonConvert.DeserializeObject>(json); + } + catch (Exception ex) + { + Logger.LogError(ex); + } } - catch (Exception ex) - { - Logger.LogError(ex); - } - } - Loading = false; + Loading = false; + }); } if (__instance.Offer_0.Locked) diff --git a/Patches/AutofillQuestItemsPatch.cs b/Patches/AutofillQuestItemsPatch.cs index 3f9db85..2a3306b 100644 --- a/Patches/AutofillQuestItemsPatch.cs +++ b/Patches/AutofillQuestItemsPatch.cs @@ -1,6 +1,6 @@ -using Aki.Reflection.Patching; -using EFT.UI; +using EFT.UI; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; using UnityEngine; diff --git a/Patches/ConfirmationDialogKeysPatches.cs b/Patches/ConfirmationDialogKeysPatches.cs index aa8e9d4..e320391 100644 --- a/Patches/ConfirmationDialogKeysPatches.cs +++ b/Patches/ConfirmationDialogKeysPatches.cs @@ -1,7 +1,6 @@ -using Aki.Reflection.Patching; -using EFT.InputSystem; -using EFT.UI; +using EFT.UI; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; using UnityEngine; using UnityEngine.UI; diff --git a/Patches/ContextMenuPatches.cs b/Patches/ContextMenuPatches.cs index 5ff21d1..86fa881 100644 --- a/Patches/ContextMenuPatches.cs +++ b/Patches/ContextMenuPatches.cs @@ -1,9 +1,9 @@ -using Aki.Reflection.Patching; -using Aki.Reflection.Utils; -using Comfort.Common; +using Comfort.Common; using EFT.InventoryLogic; using EFT.UI; using HarmonyLib; +using SPT.Reflection.Patching; +using SPT.Reflection.Utils; using System; using System.Collections.Generic; using System.Linq; @@ -49,9 +49,9 @@ namespace UIFixes public static void Enable() { // The context menus in the inventory and the trading screen inventory are *completely different code* - InventoryRootInteractionsType = PatchConstants.EftTypes.Single(t => t.GetField("HIDEOUT_WEAPON_MODIFICATION_REQUIRED") != null); // GClass3023 + InventoryRootInteractionsType = PatchConstants.EftTypes.Single(t => t.GetField("HIDEOUT_WEAPON_MODIFICATION_REQUIRED") != null); // GClass3045 - // GClass3032 - this is nuts to find, have to inspect a static enum array + // GClass3054 - this is nuts to find, have to inspect a static enum array TradingRootInteractionsType = PatchConstants.EftTypes.Single(t => { var enumerableField = t.GetField("ienumerable_2", BindingFlags.NonPublic | BindingFlags.Static); @@ -414,7 +414,7 @@ namespace UIFixes if (selectedItem is BulletClass) { - __result = new MagazineBuildClass.Class3135(selectedItem); + __result = new MagazineBuildClass.Class3183(selectedItem); return false; } diff --git a/Patches/ContextMenuShortcutPatches.cs b/Patches/ContextMenuShortcutPatches.cs index 102d584..4b00092 100644 --- a/Patches/ContextMenuShortcutPatches.cs +++ b/Patches/ContextMenuShortcutPatches.cs @@ -1,8 +1,8 @@ -using Aki.Reflection.Patching; -using EFT.InventoryLogic; +using EFT.InventoryLogic; using EFT.UI; using EFT.UI.DragAndDrop; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; using TMPro; using UnityEngine.EventSystems; @@ -143,9 +143,9 @@ namespace UIFixes } [PatchPostfix] - public static void Postfix(ItemUiContext ___itemUiContext_0, ItemContextAbstractClass ___gclass2813_0) + public static void Postfix(ItemUiContext ___itemUiContext_0, ItemContextAbstractClass ___itemContextAbstractClass) { - ___itemUiContext_0.RegisterCurrentItemContext(___gclass2813_0); + ___itemUiContext_0.RegisterCurrentItemContext(___itemContextAbstractClass); } } @@ -157,9 +157,9 @@ namespace UIFixes } [PatchPostfix] - public static void Postfix(ItemUiContext ___itemUiContext_0, ItemContextAbstractClass ___gclass2813_0) + public static void Postfix(ItemUiContext ___itemUiContext_0, ItemContextAbstractClass ___itemContextAbstractClass) { - ___itemUiContext_0.UnregisterCurrentItemContext(___gclass2813_0); + ___itemUiContext_0.UnregisterCurrentItemContext(___itemContextAbstractClass); } } diff --git a/Patches/FixFleaPatches.cs b/Patches/FixFleaPatches.cs index 1c76278..8837479 100644 --- a/Patches/FixFleaPatches.cs +++ b/Patches/FixFleaPatches.cs @@ -1,6 +1,6 @@ -using Aki.Reflection.Patching; -using EFT.UI.Ragfair; +using EFT.UI.Ragfair; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; using TMPro; using UnityEngine; diff --git a/Patches/FixMailRecieveAllPatch.cs b/Patches/FixMailRecieveAllPatch.cs index 23dab60..7b6392d 100644 --- a/Patches/FixMailRecieveAllPatch.cs +++ b/Patches/FixMailRecieveAllPatch.cs @@ -1,6 +1,6 @@ -using Aki.Reflection.Patching; using EFT.UI.Chat; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; namespace UIFixes diff --git a/Patches/FixTooltipPatches.cs b/Patches/FixTooltipPatches.cs index 6aeff33..72eac2c 100644 --- a/Patches/FixTooltipPatches.cs +++ b/Patches/FixTooltipPatches.cs @@ -1,7 +1,7 @@ -using Aki.Reflection.Patching; -using EFT.UI; +using EFT.UI; using EFT.UI.DragAndDrop; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; using TMPro; using UnityEngine; diff --git a/Patches/FixTraderControllerSimulateFalsePatch.cs b/Patches/FixTraderControllerSimulateFalsePatch.cs index a5f63ff..06ef2ea 100644 --- a/Patches/FixTraderControllerSimulateFalsePatch.cs +++ b/Patches/FixTraderControllerSimulateFalsePatch.cs @@ -1,7 +1,7 @@ -using Aki.Reflection.Patching; -using Diz.LanguageExtensions; +using Diz.LanguageExtensions; using EFT.InventoryLogic; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; namespace UIFixes @@ -13,18 +13,18 @@ namespace UIFixes return AccessTools.Method(typeof(TraderControllerClass), nameof(TraderControllerClass.ExecutePossibleAction), [typeof(ItemContextAbstractClass), typeof(Item), typeof(bool), typeof(bool)]); } - // Recreatign this function to add the comment section, so calling this with simulate = false doesn't break everything + // Recreating this function to add the comment section, so calling this with simulate = false doesn't break everything [PatchPrefix] [HarmonyPriority(Priority.Last)] public static bool Prefix(TraderControllerClass __instance, ItemContextAbstractClass itemContext, Item targetItem, bool partialTransferOnly, bool simulate, ref GStruct413 __result) { - TraderControllerClass.Struct754 opStruct; + TraderControllerClass.Struct775 opStruct; opStruct.targetItem = targetItem; - opStruct.gclass2758_0 = __instance; + opStruct.traderControllerClass = __instance; opStruct.simulate = simulate; opStruct.item = itemContext.Item; - Error error = new GClass3293(opStruct.item); + Error error = new GClass3317(opStruct.item); bool mergeAvailable = itemContext.MergeAvailable; bool splitAvailable = itemContext.SplitAvailable; partialTransferOnly &= splitAvailable; @@ -45,7 +45,7 @@ namespace UIFixes } } - if (opStruct.targetItem is GInterface306 applicable) + if (opStruct.targetItem is GInterface321 applicable) { var operation = __instance.method_23(applicable, ref error, ref opStruct); if (operation.Succeeded) diff --git a/Patches/FixUnloadLastBulletPatch.cs b/Patches/FixUnloadLastBulletPatch.cs index 1581c0e..c52dad3 100644 --- a/Patches/FixUnloadLastBulletPatch.cs +++ b/Patches/FixUnloadLastBulletPatch.cs @@ -1,6 +1,6 @@ -using Aki.Reflection.Patching; -using EFT.InventoryLogic; +using EFT.InventoryLogic; using HarmonyLib; +using SPT.Reflection.Patching; using System.Collections.Generic; using System.Reflection; diff --git a/Patches/FleaPrevSearchPatches.cs b/Patches/FleaPrevSearchPatches.cs index 2b0ca8a..bcc7a7e 100644 --- a/Patches/FleaPrevSearchPatches.cs +++ b/Patches/FleaPrevSearchPatches.cs @@ -1,8 +1,8 @@ -using Aki.Reflection.Patching; -using EFT.UI; +using EFT.UI; using EFT.UI.Ragfair; using EFT.UI.Utilities.LightScroller; using HarmonyLib; +using SPT.Reflection.Patching; using System; using System.Collections.Generic; using System.Linq; @@ -197,7 +197,7 @@ namespace UIFixes private void ApplyFullFilter(FilterRule filterRule) { // Order impacts the order the filters show in the UI - var searches = new List(); + var searches = new List(); // This part was tricky to figure out. Adding OR removing any of these ID filters will clear the others, so you can only do one of them. // When going to a state with no id filter, you MUST remove something (or all to be safe) @@ -322,7 +322,7 @@ namespace UIFixes { protected override MethodBase GetTargetMethod() { - return AccessTools.Method(typeof(RagfairScreen), nameof(RagfairScreen.method_7)); + return AccessTools.Method(typeof(RagfairScreen), nameof(RagfairScreen.method_9)); } [PatchPostfix] diff --git a/Patches/FocusFleaOfferNumberPatches.cs b/Patches/FocusFleaOfferNumberPatches.cs index 08ea964..5293875 100644 --- a/Patches/FocusFleaOfferNumberPatches.cs +++ b/Patches/FocusFleaOfferNumberPatches.cs @@ -1,13 +1,10 @@ -using Aki.Reflection.Patching; -using EFT.InventoryLogic; -using EFT.UI.Ragfair; +using EFT.UI.Ragfair; using HarmonyLib; +using SPT.Reflection.Patching; using System; -using System.Linq; using System.Reflection; using TMPro; using UnityEngine; -using UnityEngine.UI; namespace UIFixes { diff --git a/Patches/FocusTradeQuantityPatch.cs b/Patches/FocusTradeQuantityPatch.cs index 54f9778..94a00f4 100644 --- a/Patches/FocusTradeQuantityPatch.cs +++ b/Patches/FocusTradeQuantityPatch.cs @@ -1,6 +1,6 @@ -using Aki.Reflection.Patching; -using EFT.UI; +using EFT.UI; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; using TMPro; diff --git a/Patches/GridWindowButtonsPatch.cs b/Patches/GridWindowButtonsPatch.cs index 356cb0c..9642751 100644 --- a/Patches/GridWindowButtonsPatch.cs +++ b/Patches/GridWindowButtonsPatch.cs @@ -1,7 +1,7 @@ -using Aki.Reflection.Patching; -using EFT.InventoryLogic; +using EFT.InventoryLogic; using EFT.UI; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; using UnityEngine; using UnityEngine.UI; diff --git a/Patches/HideoutLevelPatches.cs b/Patches/HideoutLevelPatches.cs index 3fa51db..4d9ac73 100644 --- a/Patches/HideoutLevelPatches.cs +++ b/Patches/HideoutLevelPatches.cs @@ -1,6 +1,6 @@ -using Aki.Reflection.Patching; -using EFT.Hideout; +using EFT.Hideout; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; namespace UIFixes diff --git a/Patches/HideoutSearchPatches.cs b/Patches/HideoutSearchPatches.cs index ed91fa4..d918a80 100644 --- a/Patches/HideoutSearchPatches.cs +++ b/Patches/HideoutSearchPatches.cs @@ -1,4 +1,4 @@ -using Aki.Reflection.Patching; +using SPT.Reflection.Patching; using EFT.Hideout; using EFT.UI; using HarmonyLib; @@ -34,7 +34,7 @@ namespace UIFixes { protected override MethodBase GetTargetMethod() { - return AccessTools.Method(R.ProductionPanelShowSubclass.Type, "method_6"); + return AccessTools.Method(R.ProductionPanelShowSubclass.Type, "method_2"); } [PatchPostfix] @@ -96,7 +96,7 @@ namespace UIFixes public static void Postfix(ProductionPanel __instance, ValidationInputField ____searchInputField) { // Force it to render immediately, at full height, even if the search filtering would reduce the number of children - if (__instance.method_4().Count() > 2) + if (__instance.method_9().Count() > 2) { AreaScreenSubstrate areaScreenSubstrate = __instance.GetComponentInParent(); LayoutElement layoutElement = areaScreenSubstrate.R().ContentLayout; @@ -109,21 +109,21 @@ namespace UIFixes } } - // method_4 gets the sorted list of products. If there's a search term, prioritize the matching items so they load first + // method_9 gets the sorted list of products. If there's a search term, prioritize the matching items so they load first public class FastHideoutSearchPatch : ModulePatch { protected override MethodBase GetTargetMethod() { - return AccessTools.Method(typeof(ProductionPanel), nameof(ProductionPanel.method_4)); + return AccessTools.Method(typeof(ProductionPanel), nameof(ProductionPanel.method_9)); } - // Copied directly from method_4. Working with GClasses directly here, because this would be a nightmare with reflection + // Copied directly from method_9. Working with GClasses directly here, because this would be a nightmare with reflection [PatchPrefix] - public static bool Prefix(ref IEnumerable __result, ProductionPanel __instance, GClass1922[] ___gclass1922_0, ValidationInputField ____searchInputField) + public static bool Prefix(ref IEnumerable __result, ProductionPanel __instance, ProductionBuildAbstractClass[] ___gclass1938_0, ValidationInputField ____searchInputField) { - __result = ___gclass1922_0.OfType().Where(scheme => !scheme.locked) + __result = ___gclass1938_0.OfType().Where(scheme => !scheme.locked) .OrderBy(scheme => scheme.endProduct.LocalizedName().Contains(____searchInputField.text) ? 0 : 1) // search-matching items first - .ThenBy(__instance.method_10) + .ThenBy(__instance.method_18) .ThenBy(scheme => scheme.FavoriteIndex) .ThenBy(scheme => scheme.Level); @@ -131,18 +131,18 @@ namespace UIFixes } } - // method_9 activates/deactivates the product game objects based on the search. Need to resort the list due to above patch + // method_14 activates/deactivates the product game objects based on the search. Need to resort the list due to above patch public class FixHideoutSearchAgainPatch : ModulePatch { protected override MethodBase GetTargetMethod() { - return AccessTools.Method(typeof(ProductionPanel), nameof(ProductionPanel.method_9)); + return AccessTools.Method(typeof(ProductionPanel), nameof(ProductionPanel.method_14)); } [PatchPrefix] public static void Prefix(ProductionPanel __instance) { - __instance.method_8(); // update sort order + __instance.method_13(); // update sort order } } diff --git a/Patches/InspectWindowResizePatches.cs b/Patches/InspectWindowResizePatches.cs index 5342c60..273b59d 100644 --- a/Patches/InspectWindowResizePatches.cs +++ b/Patches/InspectWindowResizePatches.cs @@ -1,8 +1,8 @@ -using Aki.Reflection.Patching; -using EFT.InputSystem; +using EFT.InputSystem; using EFT.InventoryLogic; using EFT.UI; using HarmonyLib; +using SPT.Reflection.Patching; using System.Collections.Generic; using System.Linq; using System.Reflection; diff --git a/Patches/InspectWindowStatsPatches.cs b/Patches/InspectWindowStatsPatches.cs index e9995b8..fcc1e3e 100644 --- a/Patches/InspectWindowStatsPatches.cs +++ b/Patches/InspectWindowStatsPatches.cs @@ -1,7 +1,7 @@ -using Aki.Reflection.Patching; -using EFT.InventoryLogic; +using EFT.InventoryLogic; using EFT.UI; using HarmonyLib; +using SPT.Reflection.Patching; using System; using System.Collections.Generic; using System.Globalization; @@ -304,7 +304,7 @@ namespace UIFixes // Bar width is currently set to durability/100, and that 100 is pretty much hardcoded by the client // Just clamp the bar to keep it from overflowing [PatchPostfix] - public static void Postfix(DurabilityPanel __instance, Image ___Current) + public static void Postfix(Image ___Current) { ___Current.rectTransform.anchorMax = new Vector2( Mathf.Min(___Current.rectTransform.anchorMax.x, 1f), diff --git a/Patches/KeepMessagesOpenPatches.cs b/Patches/KeepMessagesOpenPatches.cs index c32dfe3..ec2f546 100644 --- a/Patches/KeepMessagesOpenPatches.cs +++ b/Patches/KeepMessagesOpenPatches.cs @@ -1,8 +1,8 @@ -using Aki.Reflection.Patching; -using EFT.UI; +using EFT.UI; using EFT.UI.Chat; using EFT.UI.Screens; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; namespace UIFixes diff --git a/Patches/KeepOfferWindowOpenPatches.cs b/Patches/KeepOfferWindowOpenPatches.cs index 016b4e7..0ae8ab0 100644 --- a/Patches/KeepOfferWindowOpenPatches.cs +++ b/Patches/KeepOfferWindowOpenPatches.cs @@ -1,7 +1,9 @@ -using Aki.Reflection.Patching; -using EFT.InventoryLogic; -using EFT.UI.Ragfair; +using EFT.UI.Ragfair; using HarmonyLib; +using SPT.Reflection.Patching; +using System; +using System.Collections.Generic; +using System.Linq; using System.Reflection; using System.Threading.Tasks; @@ -11,13 +13,42 @@ namespace UIFixes { private static bool BlockClose = false; + private static TaskCompletionSource CompletionSource; + private static readonly List AddOfferTasks = []; + private static AddOfferWindow Window; + public static void Enable() { + new GetTaskCompletionSourcePatch().Enable(); new PlaceOfferClickPatch().Enable(); new ClosePatch().Enable(); new ManageTaskPatch().Enable(); } + public class GetTaskCompletionSourcePatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.DeclaredMethod(typeof(AddOfferWindow), nameof(AddOfferWindow.Show)); + } + + [PatchPostfix] + public static void Postfix(AddOfferWindow __instance, ref Task __result) + { + if (!Settings.KeepAddOfferOpen.Value) + { + return; + } + + Window = __instance; + AddOfferTasks.Clear(); + + // Use a different task to mark when everything is actually done + CompletionSource = new TaskCompletionSource(); + __result = CompletionSource.Task; + } + } + public class PlaceOfferClickPatch : ModulePatch { protected override MethodBase GetTargetMethod() @@ -26,10 +57,12 @@ namespace UIFixes } [PatchPrefix] - public static void Prefix(AddOfferWindow __instance) + public static void Prefix(AddOfferWindow __instance, TaskCompletionSource ___taskCompletionSource_0, ref TaskCompletionSource __state) { if (Settings.KeepAddOfferOpen.Value) { + __state = ___taskCompletionSource_0; + // Close the window if you're gonna hit max offers var ragfair = __instance.R().Ragfair; if (Settings.KeepAddOfferOpenIgnoreMaxOffers.Value || ragfair.MyOffersCount + 1 < ragfair.GetMaxOffersCount(ragfair.MyRating)) @@ -40,10 +73,13 @@ namespace UIFixes } [PatchPostfix] - public static void Postfix(RequirementView[] ____requirementViews, bool ___bool_2) + public static void Postfix(RequirementView[] ____requirementViews, TaskCompletionSource ___taskCompletionSource_0, ref TaskCompletionSource __state) { - if (Settings.KeepAddOfferOpen.Value && ___bool_2) + bool isAddingOffer = __state != ___taskCompletionSource_0; // If the taskCompletionSource member was changed, then it's adding an offer :S + if (Settings.KeepAddOfferOpen.Value && isAddingOffer) { + AddOfferTasks.Add(__state.Task); // This is the task completion source passed into the add offer call + // clear old prices foreach (var requirementView in ____requirementViews) { @@ -59,12 +95,20 @@ namespace UIFixes { protected override MethodBase GetTargetMethod() { - return AccessTools.Method(typeof(AddOfferWindow), nameof(AddOfferWindow.Close)); + return AccessTools.Method(typeof(AddOfferWindow), nameof(Window.Close)); } [PatchPrefix] public static bool Prefix() { + if (!BlockClose && AddOfferTasks.All(t => t.IsCompleted)) + { + CompletionSource.Complete(); + CompletionSource = null; + AddOfferTasks.Clear(); + Window = null; + } + return !BlockClose; } } @@ -75,21 +119,25 @@ namespace UIFixes { protected override MethodBase GetTargetMethod() { - return AccessTools.Method(typeof(AddOfferWindow), nameof(AddOfferWindow.method_16)); + Type type = typeof(AddOfferWindow).GetNestedTypes().Single(t => t.GetField("completionSource") != null); // AddOfferWindow.Class3068 + return AccessTools.Method(type, "method_0"); } [PatchPrefix] - public static bool Prefix(AddOfferWindow __instance, TaskCompletionSource ___taskCompletionSource_0, ref bool ___bool_2) + public static bool Prefix(TaskCompletionSource ___completionSource) { - if (!Settings.KeepAddOfferOpen.Value) + if (!Settings.KeepAddOfferOpen.Value || Window == null) { return true; } - ___bool_2 = false; - if (!__instance.gameObject.activeInHierarchy) + ___completionSource.Complete(); + if (!Window.gameObject.activeInHierarchy && AddOfferTasks.All(t => t.IsCompleted)) { - ___taskCompletionSource_0.SetResult(null); + CompletionSource.Complete(); + CompletionSource = null; + AddOfferTasks.Clear(); + Window = null; } return false; diff --git a/Patches/KeepWindowsOnScreenPatches.cs b/Patches/KeepWindowsOnScreenPatches.cs index bdba3d9..64c54c6 100644 --- a/Patches/KeepWindowsOnScreenPatches.cs +++ b/Patches/KeepWindowsOnScreenPatches.cs @@ -1,7 +1,7 @@ -using Aki.Reflection.Patching; -using EFT.InputSystem; +using EFT.InputSystem; using EFT.UI; using HarmonyLib; +using SPT.Reflection.Patching; using System.Collections.Generic; using System.Linq; using System.Reflection; diff --git a/Patches/LoadAmmoInRaidPatches.cs b/Patches/LoadAmmoInRaidPatches.cs index c6942ad..3d55379 100644 --- a/Patches/LoadAmmoInRaidPatches.cs +++ b/Patches/LoadAmmoInRaidPatches.cs @@ -1,8 +1,8 @@ -using Aki.Reflection.Patching; -using EFT.InventoryLogic; +using EFT.InventoryLogic; using EFT.UI; using EFT.UI.DragAndDrop; using HarmonyLib; +using SPT.Reflection.Patching; using System.Collections.Generic; using System.Linq; using System.Reflection; diff --git a/Patches/LoadMagPresetsPatch.cs b/Patches/LoadMagPresetsPatch.cs index 95f2123..a51a6c3 100644 --- a/Patches/LoadMagPresetsPatch.cs +++ b/Patches/LoadMagPresetsPatch.cs @@ -1,6 +1,6 @@ -using Aki.Reflection.Patching; -using EFT.InventoryLogic; +using EFT.InventoryLogic; using HarmonyLib; +using SPT.Reflection.Patching; using System; using System.Collections.Generic; using System.Reflection; @@ -11,8 +11,7 @@ namespace UIFixes { protected override MethodBase GetTargetMethod() { - Type type = AccessTools.Method(typeof(ISession), nameof(ISession.SaveMagBuild)).GetParameters()[0].ParameterType; - return AccessTools.Method(type, "smethod_0"); + return AccessTools.Method(typeof(MagazineBuildPresetClass), nameof(MagazineBuildPresetClass.smethod_0)); } // This method returns a list of places to search for ammo. For whatever reason, it only looks diff --git a/Patches/LoadMultipleMagazinesPatches.cs b/Patches/LoadMultipleMagazinesPatches.cs index 93bd4c0..3512103 100644 --- a/Patches/LoadMultipleMagazinesPatches.cs +++ b/Patches/LoadMultipleMagazinesPatches.cs @@ -1,7 +1,7 @@ -using Aki.Reflection.Patching; -using EFT.InventoryLogic; +using EFT.InventoryLogic; using EFT.UI; using HarmonyLib; +using SPT.Reflection.Patching; using System.Linq; using System.Reflection; using System.Threading.Tasks; @@ -53,7 +53,7 @@ namespace UIFixes { protected override MethodBase GetTargetMethod() { - return AccessTools.Method(typeof(GClass2510), nameof(GClass2510.CheckItemFilter)); + return AccessTools.Method(typeof(GClass2524), nameof(GClass2524.CheckItemFilter)); } [PatchPrefix] @@ -72,7 +72,7 @@ namespace UIFixes { protected override MethodBase GetTargetMethod() { - return AccessTools.Method(typeof(GClass3043), nameof(GClass3043.method_6)); + return AccessTools.Method(typeof(GClass3065), nameof(GClass3065.method_6)); } [PatchPrefix] @@ -92,7 +92,7 @@ namespace UIFixes { protected override MethodBase GetTargetMethod() { - return AccessTools.Method(typeof(GClass3044), nameof(GClass3044.method_7)); + return AccessTools.Method(typeof(GClass3066), nameof(GClass3066.method_7)); } [PatchPrefix] @@ -119,11 +119,11 @@ namespace UIFixes { protected override MethodBase GetTargetMethod() { - return AccessTools.Method(typeof(GClass3044), nameof(GClass3044.method_6)); + return AccessTools.Method(typeof(GClass3066), nameof(GClass3066.method_6)); } [PatchPrefix] - public static bool Prefix(GClass2092 preset, ItemUiContext ___itemUiContext_1) + public static bool Prefix(MagazineBuildPresetClass preset, ItemUiContext ___itemUiContext_1) { if (!MultiSelect.Active) { diff --git a/Patches/MoveTaskbarPatch.cs b/Patches/MoveTaskbarPatch.cs index 99eafff..3522cc6 100644 --- a/Patches/MoveTaskbarPatch.cs +++ b/Patches/MoveTaskbarPatch.cs @@ -1,6 +1,6 @@ -using Aki.Reflection.Patching; -using EFT.UI; +using EFT.UI; using HarmonyLib; +using SPT.Reflection.Patching; using System.Linq; using System.Reflection; using UnityEngine; diff --git a/Patches/MultiSelectPatches.cs b/Patches/MultiSelectPatches.cs index 788fc16..05beb35 100644 --- a/Patches/MultiSelectPatches.cs +++ b/Patches/MultiSelectPatches.cs @@ -1,5 +1,4 @@ -using Aki.Reflection.Patching; -using Comfort.Common; +using Comfort.Common; using EFT; using EFT.Communications; using EFT.InventoryLogic; @@ -7,28 +6,27 @@ using EFT.UI; using EFT.UI.DragAndDrop; using EFT.UI.Insurance; using HarmonyLib; +using SPT.Reflection.Patching; +using SPT.Reflection.Utils; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; -using System.Threading; using System.Threading.Tasks; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; +using BaseItemInfoInteractions = GClass3042; +using DestroyError = GClass3344; +using GenericItemContext = GClass2833; +using GridModificationsUnavailableError = StashGridClass.GClass3315; using ItemOperation = GStruct413; -using MoveOperation = GClass2786; -using GridItemAddress = GClass2769; -using GridFindExtensions = GClass2503; -using BaseItemInfoInteractions = GClass3021; -using GenericItemContext = GClass2817; -using Stackable = GClass2735; -using NoOpMove = GClass2779; -using DestroyError = GClass3320; -using NoRoomError = GClass3292; -using GridModificationsUnavailableError = StashGridClass.GClass3291; -using MoveSameSpaceError = InteractionsHandlerClass.GClass3329; +using MoveOperation = GClass2802; +using MoveSameSpaceError = InteractionsHandlerClass.GClass3353; +using NoOpMove = GClass2795; +using NoRoomError = GClass3316; +using Stackable = GClass2751; namespace UIFixes { @@ -41,7 +39,7 @@ namespace UIFixes private static readonly List Previews = []; // Point that various QuickFindPlace overrides should start at - private static GridItemAddress FindOrigin = null; + private static ItemAddressClass FindOrigin = null; private static bool FindVerticalFirst = false; // Prevents QuickFind from attempting a merge @@ -91,9 +89,9 @@ namespace UIFixes // Various location finding new FindSpotKeepRotationPatch().Enable(); - new FindLocationForItemPatch().Enable(); new FindPlaceToPutPatch().Enable(); new AdjustQuickFindFlagsPatch().Enable(); + new ReorderContainersPatch().Enable(); new AllowFindSameSpotPatch().Enable(); } @@ -331,9 +329,12 @@ namespace UIFixes } [PatchPostfix] - public static void Postfix() + public static void Postfix(Player.PlayerInventoryController __instance) { - MultiSelect.StopLoading(); + if (__instance.Profile == PatchConstants.BackEndSession.Profile) + { + MultiSelect.StopLoading(); + } } } @@ -485,7 +486,7 @@ namespace UIFixes return false; } - GridItemAddress hoveredAddress = new(__instance.Grid, hoveredLocation); + ItemAddressClass hoveredAddress = new(__instance.Grid, hoveredLocation); if (!item.CheckAction(hoveredAddress)) { return false; @@ -667,7 +668,7 @@ namespace UIFixes DisableMerge = targetItemContext == null; LocationInGrid hoveredLocation = __instance.CalculateItemLocation(itemContext); - GridItemAddress hoveredAddress = new(__instance.Grid, hoveredLocation); + ItemAddressClass hoveredAddress = new(__instance.Grid, hoveredLocation); if (__instance.Grid.ParentItem is SortingTableClass) { @@ -744,26 +745,6 @@ namespace UIFixes } } - public class AllowFindSameSpotPatch : ModulePatch - { - protected override MethodBase GetTargetMethod() - { - return AccessTools.Method(typeof(GridFindExtensions), nameof(GridFindExtensions.FindLocationForItem)); - } - - [PatchPrefix] - public static bool Prefix(IEnumerable grids, Item item, ref GridItemAddress __result) - { - if (!MultiSelect.Active) - { - return true; - } - - __result = grids.Select(g => g.FindLocationForItem(item)).FirstOrDefault(x => x != null); - return false; - } - } - public class GridViewPickTargetPatch : ModulePatch { public static Item FallbackResult = null; @@ -959,7 +940,7 @@ namespace UIFixes bool firstItem = true; LocationInGrid hoveredLocation = __instance.CalculateItemLocation(itemContext); - GridItemAddress hoveredAddress = new(__instance.Grid, hoveredLocation); + ItemAddressClass hoveredAddress = new(__instance.Grid, hoveredLocation); DisableMerge = true; @@ -972,7 +953,7 @@ namespace UIFixes FindVerticalFirst = selectedItemContext.ItemRotation == ItemRotation.Vertical; operation = firstItem ? - InteractionsHandlerClass.Move(selectedItemContext.Item, new GridItemAddress(__instance.Grid, __instance.CalculateItemLocation(selectedItemContext)), traderAssortmentController.TraderController, false) : + InteractionsHandlerClass.Move(selectedItemContext.Item, new ItemAddressClass(__instance.Grid, __instance.CalculateItemLocation(selectedItemContext)), traderAssortmentController.TraderController, false) : InteractionsHandlerClass.QuickFindAppropriatePlace(selectedItemContext.Item, traderAssortmentController.TraderController, [__instance.Grid.ParentItem as LootItemClass], InteractionsHandlerClass.EMoveItemOrder.Apply, false); FindVerticalFirst = false; @@ -1036,7 +1017,7 @@ namespace UIFixes TraderAssortmentControllerClass traderAssortmentController = __instance.R().TraderAssortmentController; LocationInGrid hoveredLocation = __instance.CalculateItemLocation(itemContext); - GridItemAddress hoveredAddress = new(__instance.Grid, hoveredLocation); + ItemAddressClass hoveredAddress = new(__instance.Grid, hoveredLocation); itemContext.DragCancelled(); traderAssortmentController.PrepareToSell(itemContext.Item, hoveredLocation); @@ -1054,7 +1035,7 @@ namespace UIFixes FindVerticalFirst = false; - if (operation.Failed || operation.Value is not MoveOperation moveOperation || moveOperation.To is not GridItemAddress gridAddress) + if (operation.Failed || operation.Value is not MoveOperation moveOperation || moveOperation.To is not ItemAddressClass gridAddress) { break; } @@ -1137,34 +1118,68 @@ namespace UIFixes } // Reorder the grids to start with the same grid as FindOrigin, then loop around - public class FindLocationForItemPatch : ModulePatch + public class ReorderContainersPatch : ModulePatch { protected override MethodBase GetTargetMethod() { - return AccessTools.Method(typeof(GridFindExtensions), nameof(GridFindExtensions.FindLocationForItem)); + Type type = typeof(InteractionsHandlerClass).GetNestedTypes().Single(t => t.GetField("noSpaceError") != null); + return AccessTools.Method(type, "method_1"); } [PatchPrefix] - public static void Prefix(ref IEnumerable grids) + public static void Prefix(ref IEnumerable containersToPut) { if (!MultiSelect.Active || FindOrigin == null) { return; } - if (!grids.Any(g => g == FindOrigin.Grid)) + if (!containersToPut.Any(g => g == FindOrigin.Grid)) { return; } - var list = grids.ToList(); + AllowFindSameSpotPatch.DisableItemAddressEquals = true; + + var list = containersToPut.ToList(); while (list[0] != FindOrigin.Grid) { list.Add(list[0]); list.RemoveAt(0); } - grids = list; + containersToPut = list; + } + + [PatchPostfix] + public static void Postfix() + { + AllowFindSameSpotPatch.DisableItemAddressEquals = false; + } + } + + // This is an insane way of doing this, but inside of the above method, I want ItemAddress.Equals to always return false, to allow + // same place moves. + public class AllowFindSameSpotPatch : ModulePatch + { + public static bool DisableItemAddressEquals = false; + + protected override MethodBase GetTargetMethod() + { + return AccessTools.DeclaredMethod(typeof(ItemAddress), nameof(ItemAddress.Equals)); + } + + [PatchPrefix] + public static bool Prefix(ref bool __result) + { + if (!DisableItemAddressEquals) + { + return true; + } + + DisableItemAddressEquals = false; // Only do it one time (this is so hacky) + __result = false; + return false; } } @@ -1265,14 +1280,14 @@ namespace UIFixes private static void ShowPreview(GridView gridView, ItemContextClass itemContext, ItemOperation operation) { - GridItemAddress gridAddress = null; + ItemAddressClass gridAddress = null; if (operation.Value is MoveOperation moveOperation) { - gridAddress = moveOperation.To as GridItemAddress; + gridAddress = moveOperation.To as ItemAddressClass; } else if (operation.Value is NoOpMove noopMove) { - gridAddress = itemContext.ItemAddress as GridItemAddress; + gridAddress = itemContext.ItemAddress as ItemAddressClass; } else { @@ -1295,7 +1310,7 @@ namespace UIFixes ShowPreview(gridView, itemContext, gridAddress, backgroundColor); } - private static void ShowPreview(GridView gridView, ItemContextClass itemContext, GridItemAddress gridAddress, Color backgroundColor) + private static void ShowPreview(GridView gridView, ItemContextClass itemContext, ItemAddressClass gridAddress, Color backgroundColor) { Image preview = UnityEngine.Object.Instantiate(gridView.R().HighlightPanel, gridView.transform, false); preview.gameObject.SetActive(true); @@ -1338,8 +1353,8 @@ namespace UIFixes Previews.Clear(); } - private static GridItemAddress GetTargetGridAddress( - ItemContextClass itemContext, ItemContextClass selectedItemContext, GridItemAddress hoveredGridAddress) + private static ItemAddressClass GetTargetGridAddress( + ItemContextClass itemContext, ItemContextClass selectedItemContext, ItemAddressClass hoveredGridAddress) { if (Settings.MultiSelectStrat.Value == MultiSelectStrategy.FirstOpenSpace) { @@ -1348,8 +1363,8 @@ namespace UIFixes if (Settings.MultiSelectStrat.Value == MultiSelectStrategy.OriginalSpacing && itemContext != selectedItemContext && - itemContext.ItemAddress is GridItemAddress itemGridAddress && - selectedItemContext.ItemAddress is GridItemAddress selectedGridAddress && + itemContext.ItemAddress is ItemAddressClass itemGridAddress && + selectedItemContext.ItemAddress is ItemAddressClass selectedGridAddress && itemGridAddress.Container.ParentItem == selectedGridAddress.Container.ParentItem) { // Shared a parent with the dragged item - try to keep position diff --git a/Patches/OpenSortingTablePatch.cs b/Patches/OpenSortingTablePatch.cs index 6ad2f3c..65401b2 100644 --- a/Patches/OpenSortingTablePatch.cs +++ b/Patches/OpenSortingTablePatch.cs @@ -1,7 +1,7 @@ -using Aki.Reflection.Patching; -using Comfort.Common; +using Comfort.Common; using EFT.UI; using HarmonyLib; +using SPT.Reflection.Patching; using System.Linq; using System.Reflection; using UnityEngine; diff --git a/Patches/PutToolsBackPatch.cs b/Patches/PutToolsBackPatch.cs index 8476c9e..4b57145 100644 --- a/Patches/PutToolsBackPatch.cs +++ b/Patches/PutToolsBackPatch.cs @@ -1,7 +1,7 @@ -using Aki.Reflection.Patching; -using EFT; +using EFT; using EFT.InventoryLogic; using HarmonyLib; +using SPT.Reflection.Patching; using System; using System.Collections.Generic; using System.Linq; @@ -13,14 +13,14 @@ namespace UIFixes { protected override MethodBase GetTargetMethod() { - return AccessTools.Method(typeof(GClass1841), nameof(GClass1841.method_8)); + return AccessTools.Method(typeof(GClass1855), nameof(GClass1855.method_9)); } // The patched method can't handle new items that aren't in stash root. // Find items that are in subcontainers and handle them first - the patched method will ignore items that have a CurrentAddress // This is a subset of the original method - doesn't handle slots, equipment containers, etc. [PatchPrefix] - public static void Prefix(ref GClass1189[] newItems, Profile ___profile_0, ItemFactory ___gclass1486_0, GClass2764 ___gclass2764_0) + public static void Prefix(ref GClass1198[] newItems, Profile ___profile_0, ItemFactory ___itemFactory, GClass2780 ___gclass2780_0) { Inventory inventory = ___profile_0.Inventory; StashClass stash = inventory.Stash; @@ -40,10 +40,10 @@ namespace UIFixes List stashItems = stash.GetNotMergedItems().ToList(); - ItemFactory.GStruct134 tree = ___gclass1486_0.FlatItemsToTree(unhandledItems.ToArray(), true, null); + ItemFactory.GStruct135 tree = ___itemFactory.FlatItemsToTree(unhandledItems.ToArray(), true, null); foreach (Item item in tree.Items.Values.Where(i => i.CurrentAddress == null)) { - GClass1189 newItem = unhandledItems.First(i => i._id == item.Id); + GClass1198 newItem = unhandledItems.First(i => i._id == item.Id); if (newItem.parentId != null || newItem.slotId != null) { // Assuming here that unhandled items are trying to go into containers in the stash - find that container @@ -52,14 +52,14 @@ namespace UIFixes { if (containerCollection.GetContainer(newItem.slotId) is StashGridClass grid) { - LocationInGrid location = GClass1485.CreateItemLocation(newItem.location); - ItemAddress itemAddress = new GClass2769(grid, location); + LocationInGrid location = GClass1496.CreateItemLocation(newItem.location); + ItemAddress itemAddress = new ItemAddressClass(grid, location); - GStruct414 operation = InteractionsHandlerClass.Add(item, itemAddress, ___gclass2764_0, false); + GStruct414 operation = InteractionsHandlerClass.Add(item, itemAddress, ___gclass2780_0, false); if (operation.Succeeded) { - operation.Value.RaiseEvents(___gclass2764_0, CommandStatus.Begin); - operation.Value.RaiseEvents(___gclass2764_0, CommandStatus.Succeed); + operation.Value.RaiseEvents(___gclass2780_0, CommandStatus.Begin); + operation.Value.RaiseEvents(___gclass2780_0, CommandStatus.Succeed); } } } diff --git a/Patches/QuickAccessPanelPatches.cs b/Patches/QuickAccessPanelPatches.cs index c372a07..4a3ebae 100644 --- a/Patches/QuickAccessPanelPatches.cs +++ b/Patches/QuickAccessPanelPatches.cs @@ -1,11 +1,11 @@ -using Aki.Reflection.Patching; -using Bsg.GameSettings; +using Bsg.GameSettings; using Comfort.Common; using EFT.InputSystem; using EFT.InventoryLogic; using EFT.UI; using EFT.UI.Settings; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; namespace UIFixes diff --git a/Patches/RememberRepairerPatches.cs b/Patches/RememberRepairerPatches.cs index bc74241..8e83394 100644 --- a/Patches/RememberRepairerPatches.cs +++ b/Patches/RememberRepairerPatches.cs @@ -1,6 +1,6 @@ -using Aki.Reflection.Patching; -using EFT.UI; +using EFT.UI; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; using UnityEngine; diff --git a/Patches/RemoveDoorActionsPatch.cs b/Patches/RemoveDoorActionsPatch.cs index 262c541..24d508d 100644 --- a/Patches/RemoveDoorActionsPatch.cs +++ b/Patches/RemoveDoorActionsPatch.cs @@ -1,5 +1,5 @@ -using Aki.Reflection.Patching; -using HarmonyLib; +using HarmonyLib; +using SPT.Reflection.Patching; using System; using System.Linq; using System.Reflection; diff --git a/Patches/ScrollPatches.cs b/Patches/ScrollPatches.cs index 91684ee..2077fa0 100644 --- a/Patches/ScrollPatches.cs +++ b/Patches/ScrollPatches.cs @@ -1,10 +1,10 @@ -using Aki.Reflection.Patching; -using EFT.Hideout; +using EFT.Hideout; using EFT.UI; using EFT.UI.Chat; using EFT.UI.Ragfair; using EFT.UI.Utilities.LightScroller; using HarmonyLib; +using SPT.Reflection.Patching; using System; using System.Collections.Generic; using System.Reflection; @@ -345,7 +345,7 @@ namespace UIFixes } [PatchPostfix] - public static void Postfix(NotesTask __instance, GClass1249 quest) + public static void Postfix(NotesTask __instance, QuestClass quest) { void OnTaskSelected(bool open) { diff --git a/Patches/StackFirItemsPatches.cs b/Patches/StackFirItemsPatches.cs index 60af1ff..339ba1b 100644 --- a/Patches/StackFirItemsPatches.cs +++ b/Patches/StackFirItemsPatches.cs @@ -1,6 +1,6 @@ -using Aki.Reflection.Patching; -using EFT.InventoryLogic; +using EFT.InventoryLogic; using HarmonyLib; +using SPT.Reflection.Patching; using System; using System.Collections.Generic; using System.Linq; @@ -23,13 +23,13 @@ namespace UIFixes protected override MethodBase GetTargetMethod() { MethodInfo method = AccessTools.Method(typeof(InteractionsHandlerClass), nameof(InteractionsHandlerClass.smethod_0)); - MergeableItemType = method.GetParameters()[2].ParameterType.GetElementType(); // parameter is a ref type, get underlying type + MergeableItemType = method.GetParameters()[2].ParameterType.GetElementType(); // parameter is a ref type, get underlying type, GClass2751 return method; } // Reimplementing this entire method to ignore SpawnedInSession for certain types [PatchPrefix] - public static bool Prefix(IEnumerable gridsToPut, Item itemToMerge, ref object mergeableItem, int overrideCount, ref bool __result) + public static bool Prefix(IEnumerable containersToPut, Item itemToMerge, ref object mergeableItem, int overrideCount, ref bool __result) { if (!MergeableItemType.IsInstanceOfType(itemToMerge)) { @@ -56,8 +56,8 @@ namespace UIFixes ignoreSpawnedInSession = Settings.MergeFIROther.Value; } - mergeableItem = gridsToPut.SelectMany(x => x.Items) - .Where(x => MergeableItemType.IsInstanceOfType(x)) + mergeableItem = containersToPut.SelectMany(x => x.Items) + .Where(MergeableItemType.IsInstanceOfType) .Where(x => x != itemToMerge) .Where(x => x.TemplateId == itemToMerge.TemplateId) .Where(x => ignoreSpawnedInSession || x.SpawnedInSession == itemToMerge.SpawnedInSession) diff --git a/Patches/StackMoveGreedyPatches.cs b/Patches/StackMoveGreedyPatches.cs index 797b050..d2ca1d8 100644 --- a/Patches/StackMoveGreedyPatches.cs +++ b/Patches/StackMoveGreedyPatches.cs @@ -1,6 +1,6 @@ -using Aki.Reflection.Patching; -using EFT.UI.DragAndDrop; +using EFT.UI.DragAndDrop; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; using System.Threading; using System.Threading.Tasks; diff --git a/Patches/SwapPatches.cs b/Patches/SwapPatches.cs index 111cb21..566687e 100644 --- a/Patches/SwapPatches.cs +++ b/Patches/SwapPatches.cs @@ -1,11 +1,11 @@ -using Aki.Reflection.Patching; -using Aki.Reflection.Utils; -using Comfort.Common; +using Comfort.Common; using EFT; using EFT.InventoryLogic; using EFT.UI; using EFT.UI.DragAndDrop; using HarmonyLib; +using SPT.Reflection.Patching; +using SPT.Reflection.Utils; using System; using System.Collections.Generic; using System.Linq; @@ -49,7 +49,7 @@ namespace UIFixes new FixAddModFirearmOperationPatch().Enable(); } - private static bool ValidPrerequisites(ItemContextClass itemContext, ItemContextAbstractClass targetItemContext, object operation) + private static bool ValidPrerequisites(ItemContextClass itemContext, ItemContextAbstractClass targetItemContext, IInventoryEventResult operation) { if (!Settings.SwapItems.Value) { @@ -67,9 +67,7 @@ namespace UIFixes return false; } - var wrappedOperation = new R.GridViewCanAcceptOperation(operation); - - if (InHighlight || itemContext == null || targetItemContext == null || wrappedOperation.Succeeded) + if (InHighlight || itemContext == null || targetItemContext == null || operation.Succeeded) { return false; } @@ -90,7 +88,7 @@ namespace UIFixes return false; } - string error = wrappedOperation.Error.ToString(); + string error = operation.Error.ToString(); if (Settings.SwapImpossibleContainers.Value && !Plugin.InRaid() && error.StartsWith("No free room")) { // Check if it isn't allowed in that container, if so try to swap @@ -218,7 +216,7 @@ namespace UIFixes } [PatchPostfix] - public static void Postfix(GridView __instance, ItemContextClass itemContext, ItemContextAbstractClass targetItemContext, ref object operation, ref bool __result, Dictionary ___dictionary_0) + public static void Postfix(GridView __instance, ItemContextClass itemContext, ItemContextAbstractClass targetItemContext, ref IInventoryEventResult operation, ref bool __result, Dictionary ___dictionary_0) { if (!ValidPrerequisites(itemContext, targetItemContext, operation)) { @@ -313,7 +311,7 @@ namespace UIFixes { protected override MethodBase GetTargetMethod() { - return AccessTools.Method(R.SwapOperation.Type.GenericTypeArguments[0], "RaiseEvents"); // GClass2797 + return AccessTools.Method(R.SwapOperation.Type.GenericTypeArguments[0], "RaiseEvents"); // GClass2813 } [PatchPostfix] @@ -375,7 +373,7 @@ namespace UIFixes } [PatchPostfix] - public static void Postfix(ItemContextClass __instance, Slot slot, ItemContextAbstractClass targetItemContext, ref object operation, TraderControllerClass itemController, bool simulate, ref bool __result) + public static void Postfix(ItemContextClass __instance, Slot slot, ItemContextAbstractClass targetItemContext, ref IInventoryEventResult operation, TraderControllerClass itemController, bool simulate, ref bool __result) { // targetItemContext here is not the target item, it's the *parent* context, i.e. the owner of the slot // Do a few more checks @@ -458,7 +456,7 @@ namespace UIFixes { protected override MethodBase GetTargetMethod() { - Type type = PatchConstants.EftTypes.Single(t => t.GetMethod("CheckItemFilter", BindingFlags.Public | BindingFlags.Static) != null); // GClass2510 + Type type = PatchConstants.EftTypes.Single(t => t.GetMethod("CheckItemFilter", BindingFlags.Public | BindingFlags.Static) != null); // GClass2524 return AccessTools.Method(type, "CheckItemFilter"); } @@ -506,7 +504,7 @@ namespace UIFixes { protected override MethodBase GetTargetMethod() { - return AccessTools.Method(typeof(Player.FirearmController.Class1015), nameof(Player.FirearmController.Class1015.OnModChanged)); + return AccessTools.Method(typeof(Player.FirearmController.Class1039), nameof(Player.FirearmController.Class1039.OnModChanged)); } // The firearm state machine state Class1015 is the "adding mod" state @@ -514,11 +512,11 @@ namespace UIFixes // Patched to not be that stupid [PatchPrefix] public static bool Prefix( - Player.FirearmController.Class1015 __instance, + Player.FirearmController.Class1039 __instance, bool ___bool_0, FirearmsAnimator ___firearmsAnimator_0, Item ___item_0, - GClass1668 ___gclass1668_0, + WeaponManagerClass ___weaponManagerClass, Slot ___slot_0, Weapon ___weapon_0, Callback ___callback_0, @@ -532,12 +530,12 @@ namespace UIFixes ___bool_0 = true; ___firearmsAnimator_0.SetupMod(false); GameObject gameObject = Singleton.Instance.CreateItem(___item_0, true); - ___gclass1668_0.SetupMod(___slot_0, gameObject); + ___weaponManagerClass.SetupMod(___slot_0, gameObject); ___firearmsAnimator_0.Fold(___weapon_0.Folded); __instance.State = Player.EOperationState.Finished; // Begin change (moved from bottom) - ___firearmController_0.InitiateOperation().Start(null); + ___firearmController_0.InitiateOperation().Start(null); __instance.method_5(gameObject); // End change diff --git a/Patches/SyncScrollPositionPatches.cs b/Patches/SyncScrollPositionPatches.cs index 9d690e7..71b42b5 100644 --- a/Patches/SyncScrollPositionPatches.cs +++ b/Patches/SyncScrollPositionPatches.cs @@ -1,7 +1,7 @@ -using Aki.Reflection.Patching; -using EFT.UI; +using EFT.UI; using EFT.UI.Ragfair; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; using UnityEngine; using UnityEngine.UI; @@ -33,8 +33,9 @@ namespace UIFixes scrollRect.verticalNormalizedPosition = StashScrollPosition; + scrollRect.onValueChanged.RemoveListener(UpdateScrollPosition); scrollRect.onValueChanged.AddListener(UpdateScrollPosition); - element.R().UI.AddDisposable(() => scrollRect.onValueChanged.RemoveListener(UpdateScrollPosition)); + //element.R().UI.AddDisposable(() => scrollRect.onValueChanged.RemoveListener(UpdateScrollPosition)); } public class SyncStashScrollPatch : ModulePatch diff --git a/Patches/TradingAutoSwitchPatches.cs b/Patches/TradingAutoSwitchPatches.cs index ba6e537..4d53aaa 100644 --- a/Patches/TradingAutoSwitchPatches.cs +++ b/Patches/TradingAutoSwitchPatches.cs @@ -1,8 +1,8 @@ -using Aki.Reflection.Patching; -using Comfort.Common; +using Comfort.Common; using EFT.UI; using EFT.UI.DragAndDrop; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; using UnityEngine; using UnityEngine.EventSystems; diff --git a/Patches/TransferConfirmPatch.cs b/Patches/TransferConfirmPatch.cs index 9b103bb..960820c 100644 --- a/Patches/TransferConfirmPatch.cs +++ b/Patches/TransferConfirmPatch.cs @@ -1,6 +1,6 @@ -using Aki.Reflection.Patching; -using EFT.UI; +using EFT.UI; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; using System.Threading.Tasks; diff --git a/Patches/UnloadAmmoPatches.cs b/Patches/UnloadAmmoPatches.cs index 6cc2f2c..afd5ce9 100644 --- a/Patches/UnloadAmmoPatches.cs +++ b/Patches/UnloadAmmoPatches.cs @@ -1,4 +1,4 @@ -using Aki.Reflection.Patching; +using SPT.Reflection.Patching; using Comfort.Common; using EFT.HealthSystem; using EFT.InventoryLogic; @@ -25,7 +25,7 @@ namespace UIFixes { protected override MethodBase GetTargetMethod() { - return AccessTools.DeclaredProperty(typeof(GClass3032), nameof(GClass3032.AvailableInteractions)).GetMethod; + return AccessTools.DeclaredProperty(typeof(GClass3054), nameof(GClass3054.AvailableInteractions)).GetMethod; } [PatchPostfix] @@ -41,7 +41,7 @@ namespace UIFixes { protected override MethodBase GetTargetMethod() { - return AccessTools.DeclaredProperty(typeof(GClass3035), nameof(GClass3035.AvailableInteractions)).GetMethod; + return AccessTools.DeclaredProperty(typeof(GClass3057), nameof(GClass3057.AvailableInteractions)).GetMethod; } [PatchPostfix] @@ -88,11 +88,11 @@ namespace UIFixes { protected override MethodBase GetTargetMethod() { - return AccessTools.Constructor(typeof(ScavengerInventoryScreen.GClass3131), [typeof(GClass2764), typeof(GClass2764), typeof(IHealthController), typeof(StashClass), typeof(ISession)]); + return AccessTools.Constructor(typeof(ScavengerInventoryScreen.GClass3156), [typeof(GClass2780), typeof(GClass2780), typeof(IHealthController), typeof(StashClass), typeof(ISession)]); } [PatchPrefix] - public static void Prefix(GClass2764 scavController) + public static void Prefix(GClass2780 scavController) { scavController.Inventory.Stash = null; } diff --git a/Patches/WeaponPresetConfirmPatches.cs b/Patches/WeaponPresetConfirmPatches.cs index 94ee023..d5ce76a 100644 --- a/Patches/WeaponPresetConfirmPatches.cs +++ b/Patches/WeaponPresetConfirmPatches.cs @@ -1,6 +1,6 @@ -using Aki.Reflection.Patching; -using EFT.UI; +using EFT.UI; using HarmonyLib; +using SPT.Reflection.Patching; using System; using System.Linq; using System.Reflection; @@ -25,7 +25,7 @@ namespace UIFixes { protected override MethodBase GetTargetMethod() { - Type type = typeof(EditBuildScreen).GetNestedTypes().Single(x => x.GetMethod("CloseScreenInterruption") != null); // EditBuildScreen.GClass3126 + Type type = typeof(EditBuildScreen).GetNestedTypes().Single(x => x.GetMethod("CloseScreenInterruption") != null); // EditBuildScreen.GClass3151 return AccessTools.Method(type, "CloseScreenInterruption"); } diff --git a/Patches/WeaponZoomPatches.cs b/Patches/WeaponZoomPatches.cs index e82f2bf..e971b10 100644 --- a/Patches/WeaponZoomPatches.cs +++ b/Patches/WeaponZoomPatches.cs @@ -1,7 +1,7 @@ -using Aki.Reflection.Patching; -using EFT.UI; +using EFT.UI; using EFT.UI.WeaponModding; using HarmonyLib; +using SPT.Reflection.Patching; using System.Reflection; using UnityEngine.EventSystems; diff --git a/R.cs b/R.cs index 0e83cf2..b09d114 100644 --- a/R.cs +++ b/R.cs @@ -1,5 +1,4 @@ -using Aki.Reflection.Utils; -using Comfort.Common; +using Comfort.Common; using Diz.LanguageExtensions; using EFT.Hideout; using EFT.InputSystem; @@ -9,6 +8,7 @@ using EFT.UI.DragAndDrop; using EFT.UI.Ragfair; using EFT.UI.Utilities.LightScroller; using HarmonyLib; +using SPT.Reflection.Utils; using System; using System.Collections.Generic; using System.Linq; @@ -39,7 +39,7 @@ namespace UIFixes GridItemAddress.InitTypes(); SlotItemAddress.InitTypes(); GridView.InitTypes(); - GridViewCanAcceptOperation.InitTypes(); + //GridViewCanAcceptOperation.InitTypes(); SwapOperation.InitTypes(); InteractionButtonsContainer.InitTypes(); ContextMenuButton.InitTypes(); @@ -112,7 +112,7 @@ namespace UIFixes public static void InitTypes() { - Type = typeof(EFT.UI.MessageWindow).BaseType; + Type = typeof(EFT.UI.MessageWindow).BaseType; // DialogWindow AcceptMethod = AccessTools.Method(Type, "Accept"); } @@ -126,7 +126,7 @@ namespace UIFixes public static void InitTypes() { - Type = PatchConstants.EftTypes.Single(x => x.GetMethod("GetBoundItemNames") != null); // GClass960 + Type = PatchConstants.EftTypes.Single(x => x.GetMethod("GetBoundItemNames") != null); // GClass961 GetKeyNameMethod = AccessTools.Method(Type, "GetKeyName"); } @@ -154,7 +154,7 @@ namespace UIFixes public static void InitTypes() { - Type = typeof(EFT.Hideout.ProductionPanel).GetNestedTypes().Single(t => t.GetField("availableSearch") != null); // ProductionPanel.Class1631 + Type = typeof(EFT.Hideout.ProductionPanel).GetNestedTypes().Single(t => t.IsClass && t.GetField("availableSearch") != null); // ProductionPanel.Class1659 ProductionPanelField = AccessTools.Field(Type, "productionPanel_0"); } @@ -312,7 +312,7 @@ namespace UIFixes public static Color InvalidOperationColor { get { return (Color)InvalidOperationColorField.GetValue(null); } } } - public class GridViewCanAcceptOperation(object value) : Wrapper(value) + /* public class GridViewCanAcceptOperation(object value) : Wrapper(value) { public static Type Type { get; private set; } private static PropertyInfo SucceededProperty; @@ -327,20 +327,22 @@ namespace UIFixes public bool Succeeded { get { return (bool)SucceededProperty.GetValue(Value); } } public Error Error { get { return (Error)ErrorProperty.GetValue(Value); } } - } + }*/ public class SwapOperation(object value) : Wrapper(value) { public static Type Type { get; private set; } + private static Type CanAcceptType; private static MethodInfo ImplicitCastToGridViewCanAcceptOperationMethod; public static void InitTypes() { - Type = AccessTools.Method(typeof(InteractionsHandlerClass), nameof(InteractionsHandlerClass.Swap)).ReturnType; // GStruct414 - ImplicitCastToGridViewCanAcceptOperationMethod = Type.GetMethods().Single(m => m.Name == "op_Implicit" && m.ReturnType == GridViewCanAcceptOperation.Type); + Type = AccessTools.Method(typeof(InteractionsHandlerClass), nameof(InteractionsHandlerClass.Swap)).ReturnType; // GStruct414 + CanAcceptType = AccessTools.Method(typeof(EFT.UI.DragAndDrop.GridView), "CanAccept").GetParameters()[2].ParameterType.GetElementType(); // GStruct413, parameter is a ref type, get underlying type + ImplicitCastToGridViewCanAcceptOperationMethod = Type.GetMethods().Single(m => m.Name == "op_Implicit" && m.ReturnType == CanAcceptType); } - public object ToGridViewCanAcceptOperation() => ImplicitCastToGridViewCanAcceptOperationMethod.Invoke(null, [Value]); + public IInventoryEventResult ToGridViewCanAcceptOperation() => (IInventoryEventResult)ImplicitCastToGridViewCanAcceptOperationMethod.Invoke(null, [Value]); } public class InteractionButtonsContainer(object value) : UIElement(value) @@ -687,7 +689,7 @@ namespace UIFixes public static void InitTypes() { - Type = PatchConstants.EftTypes.Single(t => t.GetProperty("IsOwnedByPlayer") != null); // GClass3052 + Type = PatchConstants.EftTypes.Single(t => t.GetProperty("IsOwnedByPlayer") != null); // GClass3074 InsuranceCompanyField = AccessTools.GetDeclaredFields(Type).Single(f => f.FieldType == typeof(InsuranceCompanyClass)); } diff --git a/README.md b/README.md index 07aea51..7cc2a42 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,11 @@ Quality of life improvements and fixes for SPT Tarkov is full of annoyances but we can fix them! Sometimes. -✨ New in the latest version! - ## Added features New UI features enabled by this mod -- ✨ Multiselect - select multiple items at once with shift-click or dragging a selection box +- Multiselect - select multiple items at once with shift-click or dragging a selection box - Move items around as a group, drop them into containers, place them in grids - Ctrl-click and Alt-click to quick move or equip them all. Compatible with Quick Move to Containers! - Context menu to insure all, equip all, unequip all, unload ammo from all @@ -63,6 +61,7 @@ Existing SPT features made better #### Hideout - Remember window state when you leave hideout without closing (e.g. when searching for a recipe item on flea) +- Tools used in crafting will be returned to the container they were in #### Mail @@ -88,7 +87,7 @@ Fixing bugs that BSG won't or can't - Remove the unimplemented door actions like "Bang & clear" that are never going to happen - Fix the keybind for weapons always showing up as 1, 2, and 3. Now shows your actual keybind like every other slot -- ✨ Fix the quick item bar not respecting "Autohide" and "Never show" setting +- Fix the quick item bar not respecting "Autohide" and "Never show" setting #### Mail diff --git a/Settings.cs b/Settings.cs index 1d948ff..cb9ef57 100644 --- a/Settings.cs +++ b/Settings.cs @@ -126,7 +126,7 @@ namespace UIFixes "Show Transfer Items Confirmation Dialog", TransferConfirmationOption.Never, new ConfigDescription( - "When to show the confirmation dialog when you close the item transfer screen without taking all the items", + "When to show the confirmation dialog when you close the item transfer screen without tSPTng all the items", null, new ConfigurationManagerAttributes { }))); @@ -353,7 +353,7 @@ namespace UIFixes "Multiselect Item Placement", MultiSelectStrategy.OriginalSpacing, new ConfigDescription( - "Controls where multiselected items are placed, relative to the item being dragged. Note that original spacing only refers to items that were in the same grid.", + "Controls where multiselected items are placed, relative to the item being dragged", null, new ConfigurationManagerAttributes { }))); @@ -407,7 +407,7 @@ namespace UIFixes "Autostack Money with FiR Money", true, new ConfigDescription( - "Allows automatic stacking of Found In Raid money with other money, making container interaction easier", + "Allows automatic stacking of Found In Raid money with other money, mSPTng container interaction easier", null, new ConfigurationManagerAttributes { }))); @@ -416,7 +416,7 @@ namespace UIFixes "Autostack Ammo with FiR Ammo", false, new ConfigDescription( - "Allows automatic stacking of Found In Raid ammo with other money, making container interaction easier", + "Allows automatic stacking of Found In Raid ammo with other money, mSPTng container interaction easier", null, new ConfigurationManagerAttributes { }))); @@ -425,7 +425,7 @@ namespace UIFixes "Autostack Items with FiR Items", false, new ConfigDescription( - "Allows automatic stacking of Found In Raid items with other items, making container interaction easier", + "Allows automatic stacking of Found In Raid items with other items, mSPTng container interaction easier", null, new ConfigurationManagerAttributes { }))); diff --git a/TaskSerializer.cs b/TaskSerializer.cs index 0d9e24b..6ac4aa1 100644 --- a/TaskSerializer.cs +++ b/TaskSerializer.cs @@ -27,8 +27,11 @@ namespace UIFixes public void Cancel() { - totalTask.TrySetCanceled(); - Complete(); + if (!totalTask.Task.IsCompleted) + { + totalTask.TrySetCanceled(); + Complete(); + } } public void OnDisable() diff --git a/UIFixes.csproj b/UIFixes.csproj index 5a47841..b1093fe 100644 --- a/UIFixes.csproj +++ b/UIFixes.csproj @@ -4,7 +4,7 @@ net471 Tyfon.UIFixes SPT UI Fixes - 1.7.4 + 2.0.0 true latest Debug;Release;Dist @@ -15,17 +15,17 @@ - ..\..\..\..\SPT\3.8.3-debug - ..\..\..\..\SPT\3.8.3 - ..\..\..\..\SPT\3.8.3 + ..\..\..\..\SPT\3.9.0-debug + ..\..\..\..\SPT\3.9.0 + ..\..\..\..\SPT\3.9.0 - - $(PathToSPT)\EscapeFromTarkov_Data\Managed\Aki.Common.dll + + $(PathToSPT)\BepInEx\plugins\spt\spt-common.dll - - $(PathToSPT)\EscapeFromTarkov_Data\Managed\Aki.Reflection.dll + + $(PathToSPT)\BepInEx\plugins\spt\spt-reflection.dll $(PathToSPT)\EscapeFromTarkov_Data\Managed\AnimationSystem.Types.dll diff --git a/server/build.mjs b/server/build.mjs index ad1f7ff..e1525df 100644 --- a/server/build.mjs +++ b/server/build.mjs @@ -38,7 +38,7 @@ import ignore from "ignore"; import archiver from "archiver"; import winston from "winston"; -const sptPath = "/SPT/3.8.3-debug"; +const sptPath = "/SPT/3.9.0-debug"; // Get the command line arguments to determine whether to use verbose logging. const args = process.argv.slice(2); diff --git a/server/package.json b/server/package.json index cffe2dd..64ba71b 100644 --- a/server/package.json +++ b/server/package.json @@ -1,10 +1,10 @@ { "name": "uifixes", - "version": "1.7.4", + "version": "2.0.0", "main": "src/mod.js", "license": "MIT", "author": "Tyfon", - "akiVersion": "~3.8", + "sptVersion": "~3.9", "loadBefore": [], "loadAfter": [], "incompatibilities": [], diff --git a/server/src/mod.ts b/server/src/mod.ts index 3ca8be1..1020953 100644 --- a/server/src/mod.ts +++ b/server/src/mod.ts @@ -1,53 +1,29 @@ import type { DependencyContainer } from "tsyringe"; -import type { InventoryController } from "@spt-aki/controllers/InventoryController"; -import type { HideoutHelper } from "@spt-aki/helpers/HideoutHelper"; -import type { InRaidHelper } from "@spt-aki/helpers/InRaidHelper"; -import type { InventoryHelper } from "@spt-aki/helpers/InventoryHelper"; -import type { ItemHelper } from "@spt-aki/helpers/ItemHelper"; -import type { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; -import type { RagfairSortHelper } from "@spt-aki/helpers/RagfairSortHelper"; -import type { IHideoutSingleProductionStartRequestData } from "@spt-aki/models/eft/hideout/IHideoutSingleProductionStartRequestData"; -import type { IRagfairOffer } from "@spt-aki/models/eft/ragfair/IRagfairOffer"; -import { Money } from "@spt-aki/models/enums/Money"; -import type { IPreAkiLoadMod } from "@spt-aki/models/external/IPreAkiLoadMod"; -import type { ILogger } from "@spt-aki/models/spt/utils/ILogger"; -import type { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; -import type { StaticRouterModService } from "@spt-aki/services/mod/staticRouter/StaticRouterModService"; -import type { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import type { HideoutHelper } from "@spt/helpers/HideoutHelper"; +import type { InRaidHelper } from "@spt/helpers/InRaidHelper"; +import type { InventoryHelper } from "@spt/helpers/InventoryHelper"; +import type { ItemHelper } from "@spt/helpers/ItemHelper"; +import type { IHideoutSingleProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutSingleProductionStartRequestData"; +import type { IPreSptLoadMod } from "@spt/models/external/IPreSptLoadMod"; +import type { ILogger } from "@spt/models/spt/utils/ILogger"; +import type { DatabaseService } from "@spt/services/DatabaseService"; +import type { StaticRouterModService } from "@spt/services/mod/staticRouter/StaticRouterModService"; +import type { ICloner } from "@spt/utils/cloners/ICloner"; import config from "../config/config.json"; -class UIFixes implements IPreAkiLoadMod { - private databaseServer: DatabaseServer; +class UIFixes implements IPreSptLoadMod { + private databaseService: DatabaseService; private logger: ILogger; - public preAkiLoad(container: DependencyContainer): void { - this.databaseServer = container.resolve("DatabaseServer"); - this.logger = container.resolve("WinstonLogger"); + public preSptLoad(container: DependencyContainer): void { + this.databaseService = container.resolve("DatabaseService"); + this.logger = container.resolve("PrimaryLogger"); - const profileHelper = container.resolve("ProfileHelper"); const itemHelper = container.resolve("ItemHelper"); const staticRouterModService = container.resolve("StaticRouterModService"); - const jsonUtil = container.resolve("JsonUtil"); - - // Handle scav profile for post-raid scav transfer swaps (fixed in 3.9.0) - container.afterResolution( - "InventoryController", - (_, inventoryController: InventoryController) => { - const original = inventoryController.swapItem; - - inventoryController.swapItem = (pmcData, request, sessionID) => { - let playerData = pmcData; - if (request.fromOwner?.type === "Profile" && request.fromOwner.id !== playerData._id) { - playerData = profileHelper.getScavProfile(sessionID); - } - - return original.call(inventoryController, playerData, request, sessionID); - }; - }, - { frequency: "Always" } - ); + const cloner = container.resolve("RecursiveCloner"); // Keep quickbinds for items that aren't actually lost on death container.afterResolution( @@ -57,7 +33,7 @@ class UIFixes implements IPreAkiLoadMod { inRaidHelper.deleteInventory = (pmcData, sessionId) => { // Copy the existing quickbinds - const fastPanel = jsonUtil.clone(pmcData.Inventory.fastPanel); + const fastPanel = cloner.clone(pmcData.Inventory.fastPanel); // Nukes the inventory and the fastpanel original.call(inRaidHelper, pmcData, sessionId); @@ -73,23 +49,6 @@ class UIFixes implements IPreAkiLoadMod { { frequency: "Always" } ); - // Handle barter sort type (fixed in 3.9.0) - container.afterResolution( - "RagfairSortHelper", - (_, ragfairSortHelper: RagfairSortHelper) => { - const original = ragfairSortHelper.sortOffers; - - ragfairSortHelper.sortOffers = (offers, type, direction) => { - if (+type == 2) { - offers.sort(this.sortOffersByBarter); - } - - return original.call(ragfairSortHelper, offers, type, direction); - }; - }, - { frequency: "Always" } - ); - // Better tool return - starting production if (config.putToolsBack) { container.afterResolution( @@ -124,7 +83,7 @@ class UIFixes implements IPreAkiLoadMod { const original = inventoryHelper.addItemToStash; inventoryHelper.addItemToStash = (sessionId, request, pmcData, output) => { - const itemWithModsToAddClone = jsonUtil.clone(request.itemWithModsToAdd); + const itemWithModsToAddClone = cloner.clone(request.itemWithModsToAdd); // If a tool marked with uifixes is there, try to return it to its original container const tool = itemWithModsToAddClone[0]; @@ -141,13 +100,13 @@ class UIFixes implements IPreAkiLoadMod { containerId ); - const canPlaceResult = inventoryHelper.canPlaceItemInContainer( - jsonUtil.clone(containerFS2D), // will change the array so clone it - itemWithModsToAddClone - ); - - // In 3.8.3 canPlaceItemInContainer is wonky and returns undefined when the answer is yes - if (canPlaceResult === undefined) { + // will change the array so clone it + if ( + inventoryHelper.canPlaceItemInContainer( + cloner.clone(containerFS2D), + itemWithModsToAddClone + ) + ) { // At this point everything should succeed inventoryHelper.placeItemInContainer( containerFS2D, @@ -189,7 +148,7 @@ class UIFixes implements IPreAkiLoadMod { [ { url: "/uifixes/assortUnlocks", - action: (url, info, sessionId, output) => { + action: async (url, info, sessionId, output) => { return JSON.stringify(this.loadAssortmentUnlocks()); } } @@ -199,8 +158,8 @@ class UIFixes implements IPreAkiLoadMod { } private loadAssortmentUnlocks() { - const traders = this.databaseServer.getTables().traders; - const quests = this.databaseServer.getTables().templates.quests; + const traders = this.databaseService.getTraders(); + const quests = this.databaseService.getQuests(); const result: Record = {}; @@ -231,13 +190,6 @@ class UIFixes implements IPreAkiLoadMod { return result; } - - private sortOffersByBarter(a: IRagfairOffer, b: IRagfairOffer): number { - const moneyTpls = Object.values(Money); - const aIsOnlyMoney = a.requirements.length == 1 && moneyTpls.includes(a.requirements[0]._tpl) ? 1 : 0; - const bIsOnlyMoney = b.requirements.length == 1 && moneyTpls.includes(b.requirements[0]._tpl) ? 1 : 0; - return aIsOnlyMoney - bIsOnlyMoney; - } } module.exports = { mod: new UIFixes() }; diff --git a/server/tsconfig.json b/server/tsconfig.json index b9985cc..9ac1a11 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -12,11 +12,8 @@ "outDir": "tmp", "baseUrl": ".", "paths": { - "@spt-aki/*": ["./types/*"] + "@spt/*": ["./types/*"] } }, - "include": [ - "src/*", - "src/**/*" - ] -} \ No newline at end of file + "include": ["src/*", "src/**/*"] +}