Stack-first sort, by replacing method_2

This commit is contained in:
Tyfon
2024-07-13 20:00:12 -07:00
parent ed9858de00
commit 1cc6c6855a

View File

@@ -1,8 +1,14 @@
using System.Reflection;
using Comfort.Common;
using Diz.LanguageExtensions;
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;
using System.Threading.Tasks;
using UnityEngine;
namespace UIFixes;
@@ -13,6 +19,7 @@ public static class SortPatches
{
new SortPatch().Enable();
new ShiftClickPatch().Enable();
new StackFirstPatch().Enable();
}
public class SortPatch : ModulePatch
@@ -54,4 +61,83 @@ public static class SortPatches
return false;
}
}
public class StackFirstPatch : ModulePatch
{
protected override MethodBase GetTargetMethod()
{
return AccessTools.Method(typeof(GridSortPanel), nameof(GridSortPanel.method_1));
}
// Normally this method just calls method_2 and eats the exceptions
// This sidesteps method_2 and calls my Sort, to do stacking
[PatchPrefix]
public static bool Prefix(GridSortPanel __instance, LootItemClass ___lootItemClass, InventoryControllerClass ___inventoryControllerClass)
{
Sort(__instance, ___lootItemClass, ___inventoryControllerClass).HandleExceptions();
return false;
}
private static async Task Sort(GridSortPanel instance, LootItemClass lootItem, InventoryControllerClass inventoryController)
{
instance.method_3(true);
Error error = await StackAll(lootItem, inventoryController);
if (error == null)
{
GStruct414<GClass2824> sortOperation = InteractionsHandlerClass.Sort(lootItem, inventoryController, false);
if (sortOperation.Succeeded)
{
IResult result = await inventoryController.TryRunNetworkTransaction(sortOperation);
sortOperation.Value.RaiseEvents(inventoryController, result.Succeed ? CommandStatus.Succeed : CommandStatus.Failed);
}
else
{
error = sortOperation.Error;
}
}
if (error is InventoryError inventoryError)
{
NotificationManagerClass.DisplayWarningNotification(inventoryError.GetLocalizedDescription());
}
instance.method_3(false);
}
private static async Task<Error> StackAll(LootItemClass lootItem, InventoryControllerClass inventoryController)
{
Error error = null;
List<GStruct414<GInterface343>> transferOrMergeOperations = [];
var mergeableItems = lootItem.Grids.SelectMany(g => g.Items)
.OfType<Stackable>()
.Where(i => i.StackObjectsCount < i.StackMaxSize)
.ToArray();
foreach (Item item in mergeableItems)
{
// Check the item hasn't been merged to full or away yet
if (item.StackObjectsCount == 0 || item.StackObjectsCount == item.StackMaxSize)
{
continue;
}
if (InteractionsHandlerClass.smethod_0(lootItem.Grids, item, out GClass2751 targetItem, 1))
{
var operation = InteractionsHandlerClass.TransferOrMerge(item, targetItem, inventoryController, true);
if (operation.Succeeded)
{
await inventoryController.TryRunNetworkTransaction(operation);
}
else
{
error = operation.Error;
}
}
}
return error;
}
}
}