Auto-stack money, ammo, other in containers

This commit is contained in:
Tyfon
2024-04-29 15:12:48 -07:00
parent 7baaecc6e1
commit 42508308bc
4 changed files with 101 additions and 19 deletions

View File

@@ -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<StashGridClass> 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;
}
}
}

View File

@@ -19,6 +19,7 @@ namespace UIFixes
SwapPatch.Enable();
new TooltipPatch().Enable();
ItemPanelPatches.Enable();
new ContainerStackPatch().Enable();
}
}
}

View File

@@ -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<bool> WeaponPresetConfirmOnNavigate { get; set; }
public static ConfigEntry<bool> WeaponPresetConfirmOnClose { get; set; }
public static ConfigEntry<bool> TransferConfirmOnClose { get; set; }
@@ -13,18 +21,24 @@ namespace UIFixes
public static ConfigEntry<bool> RemoveDisabledActions { get; set; }
public static ConfigEntry<bool> SwapItems { get; set; }
public static ConfigEntry<bool> ShowModStats { get; set; }
public static ConfigEntry<bool> MergeFIRMoney { get; set; }
public static ConfigEntry<bool> MergeFIRAmmo { get; set; }
public static ConfigEntry<bool> MergeFIROther { get; set; }
public static void Init(ConfigFile config)
{
WeaponPresetConfirmOnNavigate = config.Bind<bool>("Weapon Presets", "Confirm on screen change", false, "Whether to confirm unsaved changes when you change screens without closing the preset");
WeaponPresetConfirmOnClose = config.Bind<bool>("Weapon Presets", "Confirm on close", true, "Whether to still confirm unsaved changes when you actually close the preset");
TransferConfirmOnClose = config.Bind<bool>("Transfer Items", "Confirm untransfered items", false, "Whether to pointlessly confirm that you're leaving the item transfer with literally no consequences");
UseHomeEnd = config.Bind<bool>("Inventory", "Add support for Home and End", true, "Home and End will scroll to the top and bottom of lists");
RebindPageUpDown = config.Bind<bool>("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<int>("Inventory", "Mousewheel scrolling multiplier", 1, "How many rows to scroll with the mousewheel");
SwapItems = config.Bind<bool>("Inventory", "In-place item swapping", true);
RemoveDisabledActions = config.Bind<bool>("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<bool>("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<bool>(WeaponPresets, "Confirm on screen change", false, "Whether to confirm unsaved changes when you change screens without closing the preset");
WeaponPresetConfirmOnClose = config.Bind<bool>(WeaponPresets, "Confirm on close", true, "Whether to still confirm unsaved changes when you actually close the preset");
TransferConfirmOnClose = config.Bind<bool>(TransferItems, "Confirm untransfered items", false, "Whether to pointlessly confirm that you're leaving the item transfer with literally no consequences");
UseHomeEnd = config.Bind<bool>(Inventory, "Add support for Home and End", true, "Home and End will scroll to the top and bottom of lists");
RebindPageUpDown = config.Bind<bool>(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<int>(Inventory, "Mousewheel scrolling multiplier", 1, "How many rows to scroll with the mousewheel");
SwapItems = config.Bind<bool>(Inventory, "In-place item swapping", true);
RemoveDisabledActions = config.Bind<bool>(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<bool>(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<bool>(ContainerStacking, "Money", true, "Allows automatic stacking of Found In Raid money with other money, making container interaction easier");
MergeFIRAmmo = config.Bind<bool>(ContainerStacking, "Ammo", false, "Allows automatic stacking of Found In Raid ammo with other ammo, making container interaction easier");
MergeFIROther = config.Bind<bool>(ContainerStacking, "Other", false, "Allows automatic stacking of all other Found In Raid items with other items, making container interaction easier");
}
}
}

View File

@@ -9,33 +9,38 @@
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup>
<PathToSPT Condition="'$(Configuration)'=='Debug'">..\..\..\..\SPT\3.8.0-debug</PathToSPT>
<PathToSPT Condition="'$(Configuration)'=='Release'">..\..\..\..\SPT\3.8.0</PathToSPT>
</PropertyGroup>
<ItemGroup>
<Reference Include="Aki.Reflection">
<HintPath>..\..\..\..\SPT\3.8.0\EscapeFromTarkov_Data\Managed\Aki.Reflection.dll</HintPath>
<HintPath>$(PathToSPT)\EscapeFromTarkov_Data\Managed\Aki.Reflection.dll</HintPath>
</Reference>
<Reference Include="Assembly-CSharp">
<HintPath>..\..\..\..\SPT\3.8.0\EscapeFromTarkov_Data\Managed\Assembly-CSharp.dll</HintPath>
<HintPath>$(PathToSPT)\EscapeFromTarkov_Data\Managed\Assembly-CSharp.dll</HintPath>
</Reference>
<Reference Include="ItemComponent.Types">
<HintPath>..\..\..\..\SPT\3.8.0-debug\EscapeFromTarkov_Data\Managed\ItemComponent.Types.dll</HintPath>
<HintPath>$(PathToSPT)\EscapeFromTarkov_Data\Managed\ItemComponent.Types.dll</HintPath>
</Reference>
<Reference Include="Sirenix.Serialization">
<HintPath>..\..\..\..\SPT\3.8.0\EscapeFromTarkov_Data\Managed\Sirenix.Serialization.dll</HintPath>
<HintPath>$(PathToSPT)\EscapeFromTarkov_Data\Managed\Sirenix.Serialization.dll</HintPath>
</Reference>
<Reference Include="Unity.TextMeshPro">
<HintPath>..\..\..\..\SPT\3.8.0-debug\EscapeFromTarkov_Data\Managed\Unity.TextMeshPro.dll</HintPath>
<HintPath>$(PathToSPT)\EscapeFromTarkov_Data\Managed\Unity.TextMeshPro.dll</HintPath>
</Reference>
<Reference Include="UnityEngine">
<HintPath>..\..\..\..\SPT\3.8.0\EscapeFromTarkov_Data\Managed\UnityEngine.dll</HintPath>
<HintPath>$(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>..\..\..\..\SPT\3.8.0\EscapeFromTarkov_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
<HintPath>$(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.InputLegacyModule">
<HintPath>..\..\..\..\SPT\3.8.0\EscapeFromTarkov_Data\Managed\UnityEngine.InputLegacyModule.dll</HintPath>
<HintPath>$(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.InputLegacyModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.UI">
<HintPath>..\..\..\..\SPT\3.8.0\EscapeFromTarkov_Data\Managed\UnityEngine.UI.dll</HintPath>
<HintPath>$(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.UI.dll</HintPath>
</Reference>
<PackageReference Include="BepInEx.Analyzers" Version="1.*" PrivateAssets="all" />
<PackageReference Include="BepInEx.Core" Version="5.*" />
@@ -47,6 +52,6 @@
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="if $(ConfigurationName) == Debug (&#xD;&#xA; copy &quot;$(TargetPath)&quot; &quot;$(ProjectDir)\..\..\..\..\SPT\3.8.0-debug\BepInEx\plugins\$(TargetName).dll&quot;&#xD;&#xA; copy &quot;$(ProjectDir)$(OutDir)$(TargetName).pdb&quot; &quot;$(ProjectDir)\..\..\..\..\SPT\3.8.0-debug\BepInEx\plugins\$(TargetName).pdb&quot;&#xD;&#xA;) else (&#xD;&#xA; copy &quot;$(TargetPath)&quot; &quot;$(ProjectDir)\..\..\..\..\SPT\3.8.0\BepInEx\plugins\$(TargetName).dll&quot;&#xD;&#xA;)" />
<Exec Command="if $(ConfigurationName) == Debug (&#xD;&#xA; copy &quot;$(TargetPath)&quot; &quot;$(ProjectDir)\$(PathToSPT)\BepInEx\plugins\$(TargetName).dll&quot;&#xD;&#xA; copy &quot;$(ProjectDir)$(OutDir)$(TargetName).pdb&quot; &quot;$(ProjectDir)\$(PathToSPT)\BepInEx\plugins\$(TargetName).pdb&quot;&#xD;&#xA;) else (&#xD;&#xA; copy &quot;$(TargetPath)&quot; &quot;$(ProjectDir)\$(PathToSPT)\BepInEx\plugins\$(TargetName).dll&quot;&#xD;&#xA;)" />
</Target>
</Project>