diff --git a/Patches/ContainerStackPatch.cs b/Patches/ContainerStackPatch.cs new file mode 100644 index 0000000..20f827a --- /dev/null +++ b/Patches/ContainerStackPatch.cs @@ -0,0 +1,62 @@ +using Aki.Reflection.Patching; +using EFT.InventoryLogic; +using HarmonyLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace UIFixes +{ + internal class ContainerStackPatch : ModulePatch + { + private static Type MergeableItemType; + + protected override MethodBase GetTargetMethod() + { + MethodInfo method = AccessTools.Method(typeof(InteractionsHandlerClass), "smethod_0"); + MergeableItemType = method.GetParameters()[2].ParameterType.GetElementType(); // parameter is a ref type, get underlying type + return method; + } + + // Reimplementing this entire method to ignore SpawnedInSession for certain types + [PatchPrefix] + private static bool Prefix(IEnumerable gridsToPut, Item itemToMerge, ref object mergeableItem, int overrideCount, ref bool __result) + { + if (!MergeableItemType.IsInstanceOfType(itemToMerge)) + { + mergeableItem = null; + __result = false; + } + + if (overrideCount <= 0) + { + overrideCount = itemToMerge.StackObjectsCount; + } + + bool ignoreSpawnedInSession; + if (itemToMerge.Template is MoneyClass) + { + ignoreSpawnedInSession = Settings.MergeFIRMoney.Value; + } + else if (itemToMerge.Template is AmmoTemplate) + { + ignoreSpawnedInSession = Settings.MergeFIRAmmo.Value; + } + else + { + ignoreSpawnedInSession = Settings.MergeFIROther.Value; + } + + mergeableItem = gridsToPut.SelectMany(x => x.Items).Where(x => MergeableItemType.IsInstanceOfType(x)) + .Where(x => x != itemToMerge) + .Where(x => x.TemplateId == itemToMerge.TemplateId) + .Where(x => ignoreSpawnedInSession || x.SpawnedInSession == itemToMerge.SpawnedInSession) + .Where(x => x.StackObjectsCount < x.StackMaxSize) + .FirstOrDefault(x => overrideCount <= x.StackMaxSize - x.StackObjectsCount); + + __result = mergeableItem != null; + return false; + } + } +} diff --git a/Plugin.cs b/Plugin.cs index 9cb6234..3fd0c43 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -19,6 +19,7 @@ namespace UIFixes SwapPatch.Enable(); new TooltipPatch().Enable(); ItemPanelPatches.Enable(); + new ContainerStackPatch().Enable(); } } } diff --git a/Settings.cs b/Settings.cs index 906f13e..95b5909 100644 --- a/Settings.cs +++ b/Settings.cs @@ -4,6 +4,14 @@ namespace UIFixes { internal class Settings { + // Categories + private const string WeaponPresets = "Weapon Presets"; + private const string TransferItems = "Transfer Items"; + private const string Inventory = "Inventory"; + private const string InRaid = "In Raid"; + private const string Items = "Items"; + private const string ContainerStacking = "Containers autostack FiR and non-FiR"; + public static ConfigEntry WeaponPresetConfirmOnNavigate { get; set; } public static ConfigEntry WeaponPresetConfirmOnClose { get; set; } public static ConfigEntry TransferConfirmOnClose { get; set; } @@ -13,18 +21,24 @@ namespace UIFixes public static ConfigEntry RemoveDisabledActions { get; set; } public static ConfigEntry SwapItems { get; set; } public static ConfigEntry ShowModStats { get; set; } + public static ConfigEntry MergeFIRMoney { get; set; } + public static ConfigEntry MergeFIRAmmo { get; set; } + public static ConfigEntry MergeFIROther { get; set; } public static void Init(ConfigFile config) { - WeaponPresetConfirmOnNavigate = config.Bind("Weapon Presets", "Confirm on screen change", false, "Whether to confirm unsaved changes when you change screens without closing the preset"); - WeaponPresetConfirmOnClose = config.Bind("Weapon Presets", "Confirm on close", true, "Whether to still confirm unsaved changes when you actually close the preset"); - TransferConfirmOnClose = config.Bind("Transfer Items", "Confirm untransfered items", false, "Whether to pointlessly confirm that you're leaving the item transfer with literally no consequences"); - UseHomeEnd = config.Bind("Inventory", "Add support for Home and End", true, "Home and End will scroll to the top and bottom of lists"); - RebindPageUpDown = config.Bind("Inventory", "Use normal PageUp and PageDown (requires restart)", true, "Changes PageUp and PageDown to simply page up and down, not scroll all the way to top and bottom"); - MouseScrollMulti = config.Bind("Inventory", "Mousewheel scrolling multiplier", 1, "How many rows to scroll with the mousewheel"); - SwapItems = config.Bind("Inventory", "In-place item swapping", true); - RemoveDisabledActions = config.Bind("In Raid", "Hide unimplemented actions", false, "Hides actions you can't actually do, like \"Bang and Clear\", etc from locked doors and other interactable objects"); - ShowModStats = config.Bind("Items", "Show total mod stats", true, "Item mods will show stats that include mods attached to them (you can also control this from a mod's inspect window)"); + WeaponPresetConfirmOnNavigate = config.Bind(WeaponPresets, "Confirm on screen change", false, "Whether to confirm unsaved changes when you change screens without closing the preset"); + WeaponPresetConfirmOnClose = config.Bind(WeaponPresets, "Confirm on close", true, "Whether to still confirm unsaved changes when you actually close the preset"); + TransferConfirmOnClose = config.Bind(TransferItems, "Confirm untransfered items", false, "Whether to pointlessly confirm that you're leaving the item transfer with literally no consequences"); + UseHomeEnd = config.Bind(Inventory, "Add support for Home and End", true, "Home and End will scroll to the top and bottom of lists"); + RebindPageUpDown = config.Bind(Inventory, "Use normal PageUp and PageDown (requires restart)", true, "Changes PageUp and PageDown to simply page up and down, not scroll all the way to top and bottom"); + MouseScrollMulti = config.Bind(Inventory, "Mousewheel scrolling multiplier", 1, "How many rows to scroll with the mousewheel"); + SwapItems = config.Bind(Inventory, "In-place item swapping", true); + RemoveDisabledActions = config.Bind(InRaid, "Hide unimplemented actions", false, "Hides actions you can't actually do, like \"Bang and Clear\", etc from locked doors and other interactable objects"); + ShowModStats = config.Bind(Items, "Show total mod stats", true, "Item mods will show stats that include mods attached to them (you can also control this from a mod's inspect window)"); + MergeFIRMoney = config.Bind(ContainerStacking, "Money", true, "Allows automatic stacking of Found In Raid money with other money, making container interaction easier"); + MergeFIRAmmo = config.Bind(ContainerStacking, "Ammo", false, "Allows automatic stacking of Found In Raid ammo with other ammo, making container interaction easier"); + MergeFIROther = config.Bind(ContainerStacking, "Other", false, "Allows automatic stacking of all other Found In Raid items with other items, making container interaction easier"); } } } diff --git a/UIFixes.csproj b/UIFixes.csproj index 796063e..90faff9 100644 --- a/UIFixes.csproj +++ b/UIFixes.csproj @@ -9,33 +9,38 @@ latest + + ..\..\..\..\SPT\3.8.0-debug + ..\..\..\..\SPT\3.8.0 + + - ..\..\..\..\SPT\3.8.0\EscapeFromTarkov_Data\Managed\Aki.Reflection.dll + $(PathToSPT)\EscapeFromTarkov_Data\Managed\Aki.Reflection.dll - ..\..\..\..\SPT\3.8.0\EscapeFromTarkov_Data\Managed\Assembly-CSharp.dll + $(PathToSPT)\EscapeFromTarkov_Data\Managed\Assembly-CSharp.dll - ..\..\..\..\SPT\3.8.0-debug\EscapeFromTarkov_Data\Managed\ItemComponent.Types.dll + $(PathToSPT)\EscapeFromTarkov_Data\Managed\ItemComponent.Types.dll - ..\..\..\..\SPT\3.8.0\EscapeFromTarkov_Data\Managed\Sirenix.Serialization.dll + $(PathToSPT)\EscapeFromTarkov_Data\Managed\Sirenix.Serialization.dll - ..\..\..\..\SPT\3.8.0-debug\EscapeFromTarkov_Data\Managed\Unity.TextMeshPro.dll + $(PathToSPT)\EscapeFromTarkov_Data\Managed\Unity.TextMeshPro.dll - ..\..\..\..\SPT\3.8.0\EscapeFromTarkov_Data\Managed\UnityEngine.dll + $(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.dll - ..\..\..\..\SPT\3.8.0\EscapeFromTarkov_Data\Managed\UnityEngine.CoreModule.dll + $(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.CoreModule.dll - ..\..\..\..\SPT\3.8.0\EscapeFromTarkov_Data\Managed\UnityEngine.InputLegacyModule.dll + $(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.InputLegacyModule.dll - ..\..\..\..\SPT\3.8.0\EscapeFromTarkov_Data\Managed\UnityEngine.UI.dll + $(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.UI.dll @@ -47,6 +52,6 @@ - +