From 2300b25e638b35a69c08baf29c6bca6dcf3cdafc Mon Sep 17 00:00:00 2001 From: Tyfon <29051038+tyfon7@users.noreply.github.com> Date: Sun, 7 Jul 2024 14:55:52 -0700 Subject: [PATCH] fix bsg returning wrong error for 'slot not empty' --- Patches/SwapPatches.cs | 45 ++++++++++++++++++++++++++++++------------ R.cs | 44 +---------------------------------------- 2 files changed, 33 insertions(+), 56 deletions(-) diff --git a/Patches/SwapPatches.cs b/Patches/SwapPatches.cs index 566687e..275cc3d 100644 --- a/Patches/SwapPatches.cs +++ b/Patches/SwapPatches.cs @@ -1,4 +1,5 @@ using Comfort.Common; +using Diz.LanguageExtensions; using EFT; using EFT.InventoryLogic; using EFT.UI; @@ -43,6 +44,7 @@ namespace UIFixes new DetectSlotHighlightPrecheckPatch().Enable(); new SlotCanAcceptSwapPatch().Enable(); new DetectFilterForSwapPatch().Enable(); + new FixNoGridErrorPatch().Enable(); new SwapOperationRaiseEventsPatch().Enable(); new RememberSwapGridHoverPatch().Enable(); new InspectWindowUpdateStatsOnSwapPatch().Enable(); @@ -89,7 +91,10 @@ namespace UIFixes } string error = operation.Error.ToString(); - if (Settings.SwapImpossibleContainers.Value && !Plugin.InRaid() && error.StartsWith("No free room")) + + // Since 3.9 containers and items with slots return the same "no free room" error. If the item doesn't have grids it's not a container. + bool isContainer = targetItemContext.Item is LootItemClass compoundItem && compoundItem.Grids.Length > 0; + if (Settings.SwapImpossibleContainers.Value && isContainer && !Plugin.InRaid() && error.StartsWith("No free room")) { // Check if it isn't allowed in that container, if so try to swap if (LastCheckItemFilterId == itemContext.Item.Id && !LastCheckItemFilterResult) @@ -179,11 +184,8 @@ namespace UIFixes return false; } - if (R.GridItemAddress.Type.IsInstanceOfType(itemAddressA) && R.GridItemAddress.Type.IsInstanceOfType(itemAddressB)) + if (itemAddressA is ItemAddressClass gridItemAddressA && itemAddressB is ItemAddressClass gridItemAddressB) { - var gridItemAddressA = new R.GridItemAddress(itemAddressA); - var gridItemAddressB = new R.GridItemAddress(itemAddressB); - LocationInGrid locationA = gridItemAddressA.LocationInGrid; LocationInGrid locationB = gridItemAddressB.LocationInGrid; StashGridClass grid = gridItemAddressA.Grid; @@ -246,18 +248,16 @@ namespace UIFixes LocationInGrid itemToLocation = __instance.CalculateItemLocation(itemContext); // Target is a grid because this is the GridView patch, i.e. you're dragging it over a grid - var targetGridItemAddress = new R.GridItemAddress(targetItemAddress); - ItemAddress itemToAddress = R.GridItemAddress.Create(targetGridItemAddress.Grid, itemToLocation); + var targetGridItemAddress = targetItemAddress as ItemAddressClass; + ItemAddress itemToAddress = new ItemAddressClass(targetGridItemAddress.Grid, itemToLocation); ItemAddress targetToAddress; - if (R.GridItemAddress.Type.IsInstanceOfType(itemAddress)) + if (itemAddress is ItemAddressClass gridItemAddress) { - var gridItemAddress = new R.GridItemAddress(itemAddress); - LocationInGrid targetToLocation = gridItemAddress.LocationInGrid.Clone(); targetToLocation.r = targetGridItemAddress.LocationInGrid.r; - targetToAddress = R.GridItemAddress.Create(gridItemAddress.Grid, targetToLocation); + targetToAddress = new ItemAddressClass(gridItemAddress.Grid, targetToLocation); } else if (R.SlotItemAddress.Type.IsInstanceOfType(itemAddress)) { @@ -285,9 +285,9 @@ namespace UIFixes } // If coming from a grid, try rotating the target object - if (R.GridItemAddress.Type.IsInstanceOfType(itemAddress)) + if (itemAddress is ItemAddressClass gridItemAddress2) { - var targetToLocation = new R.GridItemAddress(targetToAddress).LocationInGrid; + var targetToLocation = gridItemAddress2.LocationInGrid; targetToLocation.r = targetToLocation.r == ItemRotation.Horizontal ? ItemRotation.Vertical : ItemRotation.Horizontal; if (!ItemsOverlap(item, itemToAddress, targetItem, targetToAddress)) { @@ -468,6 +468,25 @@ namespace UIFixes } } + public class FixNoGridErrorPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + Type type = typeof(InteractionsHandlerClass).GetNestedTypes().Single(t => t.GetField("noSpaceError") != null); + return AccessTools.Method(type, "method_1"); + } + + [PatchPostfix] + public static void Postfix(IEnumerable containersToPut, ref GStruct414 __result, Error ___noSpaceError, Error ___noActionsError) + { + // Since 3.9 EFT handles slots in addition to containers here, they get the wrong error + if (!containersToPut.Any(c => c is StashGridClass) && __result.Error == ___noSpaceError) + { + __result = new(___noActionsError); + } + } + } + // When dragging an item around, by default it updates an ItemSpecificationPanel when you drag an item on top of a slot // It doesn't do anything when you drag an item from a slot onto some other item elsewhere. But with swap, update the item panel then too. public class InspectWindowUpdateStatsOnSwapPatch : ModulePatch diff --git a/R.cs b/R.cs index b09d114..2def81d 100644 --- a/R.cs +++ b/R.cs @@ -1,5 +1,4 @@ using Comfort.Common; -using Diz.LanguageExtensions; using EFT.Hideout; using EFT.InputSystem; using EFT.InventoryLogic; @@ -36,10 +35,8 @@ namespace UIFixes AreaScreenSubstrate.InitTypes(); ItemSpecificationPanel.InitTypes(); CompactCharacteristicPanel.InitTypes(); - GridItemAddress.InitTypes(); SlotItemAddress.InitTypes(); GridView.InitTypes(); - //GridViewCanAcceptOperation.InitTypes(); SwapOperation.InitTypes(); InteractionButtonsContainer.InitTypes(); ContextMenuButton.InitTypes(); @@ -246,28 +243,6 @@ namespace UIFixes public ItemAttributeClass CompareItemAttribute { get { return (ItemAttributeClass)CompareItemAttributeField.GetValue(Value); } } } - public class GridItemAddress(object value) : Wrapper(value) - { - public static Type Type { get; private set; } - private static FieldInfo LocationInGridField; - private static PropertyInfo GridProperty; - - public static void InitTypes() - { - Type = PatchConstants.EftTypes.Single(t => typeof(ItemAddress).IsAssignableFrom(t) && t.GetProperty("Grid") != null); // GClass2769 - LocationInGridField = AccessTools.Field(Type, "LocationInGrid"); - GridProperty = AccessTools.Property(Type, "Grid"); - } - - public static ItemAddress Create(StashGridClass grid, LocationInGrid location) - { - return (ItemAddress)Activator.CreateInstance(Type, [grid, location]); - } - - public LocationInGrid LocationInGrid { get { return (LocationInGrid)LocationInGridField.GetValue(Value); } } - public StashGridClass Grid { get { return (StashGridClass)GridProperty.GetValue(Value); } } - } - public class SlotItemAddress(object value) : Wrapper(value) { public static Type Type { get; private set; } @@ -275,7 +250,7 @@ namespace UIFixes public static void InitTypes() { - Type = PatchConstants.EftTypes.Single(t => typeof(ItemAddress).IsAssignableFrom(t) && t.GetField("Slot") != null); // GClass2767 + Type = PatchConstants.EftTypes.Single(t => typeof(ItemAddress).IsAssignableFrom(t) && t.GetField("Slot") != null); // GClass2783 SlotField = AccessTools.Field(Type, "Slot"); } @@ -312,23 +287,6 @@ namespace UIFixes public static Color InvalidOperationColor { get { return (Color)InvalidOperationColorField.GetValue(null); } } } - /* public class GridViewCanAcceptOperation(object value) : Wrapper(value) - { - public static Type Type { get; private set; } - private static PropertyInfo SucceededProperty; - private static PropertyInfo ErrorProperty; - - public static void InitTypes() - { - Type = AccessTools.Method(typeof(EFT.UI.DragAndDrop.GridView), "CanAccept").GetParameters()[2].ParameterType.GetElementType(); // GStruct413, parameter is a ref type, get underlying type - SucceededProperty = AccessTools.Property(Type, "Succeeded"); - ErrorProperty = AccessTools.Property(Type, "Error"); - } - - 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; }