diff --git a/Multiselect/MultiSelect.cs b/Multiselect/MultiSelect.cs index ffd0725..b5680f7 100644 --- a/Multiselect/MultiSelect.cs +++ b/Multiselect/MultiSelect.cs @@ -3,6 +3,7 @@ using EFT.UI; using EFT.UI.DragAndDrop; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using TMPro; using UnityEngine; @@ -18,7 +19,7 @@ namespace UIFixes private static readonly Dictionary SelectedItems = []; private static readonly Dictionary SecondaryItems = []; - private static ItemContextTaskSerializer UnloadSerializer = null; + private static ItemContextTaskSerializer LoadUnloadSerializer = null; public static bool Enabled { @@ -288,9 +289,29 @@ namespace UIFixes } } + public static Task LoadAmmoAll(ItemUiContext itemUiContext, string ammoTemplateId, bool allOrNothing) + { + StopLoading(); + 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 = taskSerializer; + itemUiContext.Tooltip?.Close(); + + return result; + } + + return Task.CompletedTask; + } + public static void UnloadAmmoAll(ItemUiContext itemUiContext, bool allOrNothing) { - StopUnloading(); + StopLoading(); 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 @@ -299,20 +320,20 @@ namespace UIFixes SortedItemContexts().Where(ic => InteractionAvailable(ic, EItemInfoButton.UnloadAmmo, itemUiContext)), itemContext => itemUiContext.UnloadAmmo(itemContext.Item)); - UnloadSerializer = taskSerializer; + LoadUnloadSerializer = taskSerializer; itemUiContext.Tooltip?.Close(); } } - public static void StopUnloading() + public static void StopLoading() { - if (UnloadSerializer == null) + if (LoadUnloadSerializer == null) { return; } - UnloadSerializer.Cancel(); - UnloadSerializer = null; + LoadUnloadSerializer.Cancel(); + LoadUnloadSerializer = null; } public static void UnpackAll(ItemUiContext itemUiContext, bool allOrNothing) diff --git a/Patches/ContextMenuPatches.cs b/Patches/ContextMenuPatches.cs index 39f2ca0..a47d38f 100644 --- a/Patches/ContextMenuPatches.cs +++ b/Patches/ContextMenuPatches.cs @@ -121,6 +121,14 @@ namespace UIFixes ____text.text += " (x" + count + ")"; } } + else if (caption == EItemInfoButton.LoadAmmo.ToString()) + { + int count = MultiSelect.InteractionCount(EItemInfoButton.LoadAmmo, ItemUiContext.Instance); + if (count > 0) + { + ____text.text += " (x" + count + ")"; + } + } else if (caption == EItemInfoButton.UnloadAmmo.ToString()) { int count = MultiSelect.InteractionCount(EItemInfoButton.UnloadAmmo, ItemUiContext.Instance); @@ -136,7 +144,6 @@ namespace UIFixes { ____text.text += " (x" + count + ")"; } - } } } diff --git a/Patches/LoadAmmoInRaidPatches.cs b/Patches/LoadAmmoInRaidPatches.cs index cb39240..c6942ad 100644 --- a/Patches/LoadAmmoInRaidPatches.cs +++ b/Patches/LoadAmmoInRaidPatches.cs @@ -69,11 +69,13 @@ namespace UIFixes if (bullets != null) { int count = GridView.smethod_0(magazine, bullets); - inventoryController.LoadMagazine(bullets, magazine, count, false).HandleExceptions(); + __result = inventoryController.LoadMagazine(bullets, magazine, count, false); + } + else + { + __result = Task.CompletedTask; } - // The calling code in this instance doesn't do anything with the task, but it does await it, so if this doesn't return a Task it nullrefs - __result = Task.CompletedTask; return false; } } diff --git a/Patches/LoadMultipleMagazinesPatches.cs b/Patches/LoadMultipleMagazinesPatches.cs new file mode 100644 index 0000000..c30dc83 --- /dev/null +++ b/Patches/LoadMultipleMagazinesPatches.cs @@ -0,0 +1,89 @@ +using Aki.Reflection.Patching; +using EFT.InventoryLogic; +using EFT.UI; +using HarmonyLib; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +namespace UIFixes +{ + public static class LoadMultipleMagazinesPatches + { + private static ItemFilter[] CombinedFilters; + + public static void Enable() + { + new FindCompatibleAmmoPatch().Enable(); + new CheckCompatibilityPatch().Enable(); + new LoadAmmoPatch().Enable(); + } + + public class FindCompatibleAmmoPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(ItemUiContext), nameof(ItemUiContext.FindCompatibleAmmo)); + } + + [PatchPrefix] + public static void Prefix(MagazineClass magazine) + { + if (MultiSelect.Active) + { + CombinedFilters = MultiSelect.SortedItemContexts() + .Select(itemContext => itemContext.Item) + .OfType() + .SelectMany(mag => mag.Cartridges.Filters) + .ToArray(); + } + } + + [PatchPostfix] + public static void Postfix() + { + CombinedFilters = null; + } + } + + public class CheckCompatibilityPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(MagazineClass), nameof(MagazineClass.CheckCompatibility)); + } + + [PatchPrefix] + public static bool Prefix(BulletClass ammo, ref bool __result) + { + if (CombinedFilters == null) + { + return true; + } + + __result = CombinedFilters.CheckItemFilter(ammo); + return false; + } + } + + public class LoadAmmoPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(GClass3043), nameof(GClass3043.method_6)); + } + + [PatchPrefix] + public static bool Prefix(string ammoTemplateId, ref Task __result, ItemUiContext ___itemUiContext_0) + { + if (!MultiSelect.Active) + { + return true; + } + + __result = MultiSelect.LoadAmmoAll(___itemUiContext_0, ammoTemplateId, false); + return false; + } + } + } +} diff --git a/Patches/MultiSelectPatches.cs b/Patches/MultiSelectPatches.cs index b4b9bf6..0d58637 100644 --- a/Patches/MultiSelectPatches.cs +++ b/Patches/MultiSelectPatches.cs @@ -333,7 +333,7 @@ namespace UIFixes [PatchPostfix] public static void Postfix() { - MultiSelect.StopUnloading(); + MultiSelect.StopLoading(); } } diff --git a/Plugin.cs b/Plugin.cs index e9f553c..8d362be 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -54,6 +54,7 @@ namespace UIFixes StackMoveGreedyPatches.Enable(); UnloadAmmoPatches.Enable(); new FixTraderControllerSimulateFalsePatch().Enable(); + LoadMultipleMagazinesPatches.Enable(); } public static bool InRaid()