multigrid; gclass alias
This commit is contained in:
@@ -115,9 +115,6 @@ namespace UIFixes
|
|||||||
// Otherwise, ensure it's not overlapped by window UI
|
// Otherwise, ensure it's not overlapped by window UI
|
||||||
PointerEventData eventData = new(EventSystem.current);
|
PointerEventData eventData = new(EventSystem.current);
|
||||||
|
|
||||||
float widthMargin = 0.1f * (itemRect.xMax - itemRect.xMin);
|
|
||||||
float heightMargin = 0.1f * (itemRect.yMax - itemRect.yMin);
|
|
||||||
|
|
||||||
if (IsOnTop(itemRect, itemTransform, preloaderRaycaster)) // no preloaderUI on top of this?
|
if (IsOnTop(itemRect, itemTransform, preloaderRaycaster)) // no preloaderUI on top of this?
|
||||||
{
|
{
|
||||||
if (itemTransform.IsDescendantOf(Singleton<PreloaderUI>.Instance.transform))
|
if (itemTransform.IsDescendantOf(Singleton<PreloaderUI>.Instance.transform))
|
||||||
|
|||||||
146
MultiGrid.cs
Normal file
146
MultiGrid.cs
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
using EFT.InventoryLogic;
|
||||||
|
using EFT.UI.DragAndDrop;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
using GridItemAddress = GClass2769;
|
||||||
|
|
||||||
|
namespace UIFixes
|
||||||
|
{
|
||||||
|
public static class MultiGrid
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<Item, Dictionary<StashGridClass, Vector2Int>> GridOffsets = [];
|
||||||
|
private static readonly Dictionary<Item, Dictionary<int, Dictionary<int, StashGridClass>>> GridsByLocation = [];
|
||||||
|
|
||||||
|
public static LocationInGrid GetGridLocation(GridItemAddress realAddress)
|
||||||
|
{
|
||||||
|
if (!IsMultiGrid(realAddress))
|
||||||
|
{
|
||||||
|
return realAddress.LocationInGrid;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2Int gridOffset = GridOffsets[realAddress.Container.ParentItem][realAddress.Grid];
|
||||||
|
return new LocationInGrid(realAddress.LocationInGrid.x + gridOffset.x, realAddress.LocationInGrid.y + gridOffset.y, realAddress.LocationInGrid.r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GridItemAddress GetRealAddress(StashGridClass originGrid, LocationInGrid multigridLocation)
|
||||||
|
{
|
||||||
|
if (!IsMultiGrid(originGrid.ParentItem))
|
||||||
|
{
|
||||||
|
// Clamp to the actual grid
|
||||||
|
multigridLocation.x = Math.Max(0, Math.Min(originGrid.GridWidth.Value, multigridLocation.x));
|
||||||
|
multigridLocation.y = Math.Max(0, Math.Min(originGrid.GridHeight.Value, multigridLocation.y));
|
||||||
|
|
||||||
|
return new GridItemAddress(originGrid, multigridLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
var gridsByLocation = GridsByLocation[originGrid.ParentItem];
|
||||||
|
|
||||||
|
// Clamp to known "meta" grid
|
||||||
|
int x = Math.Max(0, Math.Min(gridsByLocation.Keys.Max(), multigridLocation.x));
|
||||||
|
int y = Math.Max(0, Math.Min(gridsByLocation[x].Keys.Max(), multigridLocation.y));
|
||||||
|
|
||||||
|
// Sanity check
|
||||||
|
if (!gridsByLocation.ContainsKey(x) || !gridsByLocation[x].ContainsKey(y))
|
||||||
|
{
|
||||||
|
// Perhaps some weird layout with gaps in the middle? Fall back to a known good
|
||||||
|
x = gridsByLocation.Keys.First();
|
||||||
|
y = gridsByLocation[x].Keys.First();
|
||||||
|
}
|
||||||
|
|
||||||
|
StashGridClass grid = gridsByLocation[x][y];
|
||||||
|
Vector2Int offsets = GridOffsets[originGrid.ParentItem][grid];
|
||||||
|
|
||||||
|
LocationInGrid location = new(x - offsets.x, y - offsets.y, multigridLocation.r);
|
||||||
|
return new GridItemAddress(grid, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Cache(GridView initialGridView)
|
||||||
|
{
|
||||||
|
if (initialGridView == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Item parent = initialGridView.Grid.ParentItem;
|
||||||
|
if (GridOffsets.ContainsKey(parent) || !IsMultiGrid(parent))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<StashGridClass, Vector2Int> gridOffsets = [];
|
||||||
|
Dictionary<int, Dictionary<int, StashGridClass>> gridsByLocation = [];
|
||||||
|
|
||||||
|
// Sometimes the parent's pivot is 0, 1; sometimes it's 0,0. Thanks BSG
|
||||||
|
RectTransform parentView = initialGridView.transform.parent.RectTransform();
|
||||||
|
Vector2 parentPosition = parentView.pivot.y == 1 ? parentView.position : new Vector2(parentView.position.x, parentView.position.y + parentView.sizeDelta.y);
|
||||||
|
|
||||||
|
GridView[] gridViews = parentView.GetComponentsInChildren<GridView>();
|
||||||
|
|
||||||
|
Vector2 gridSize = new(64f * parentView.lossyScale.x, 64f * parentView.lossyScale.y);
|
||||||
|
|
||||||
|
foreach (GridView gridView in gridViews)
|
||||||
|
{
|
||||||
|
// Get absolute offsets
|
||||||
|
float xOffset = gridView.transform.position.x - parentPosition.x;
|
||||||
|
float yOffset = -(gridView.transform.position.y - parentPosition.y); // invert y since grid coords are upper-left origin
|
||||||
|
|
||||||
|
int x = (int)Math.Round(xOffset / gridSize.x, MidpointRounding.AwayFromZero);
|
||||||
|
int y = (int)Math.Round(yOffset / gridSize.y, MidpointRounding.AwayFromZero);
|
||||||
|
|
||||||
|
gridOffsets.Add(gridView.Grid, new Vector2Int(x, y));
|
||||||
|
|
||||||
|
// Populate reverse lookup
|
||||||
|
for (int i = 0; i < gridView.Grid.GridWidth.Value; i++)
|
||||||
|
{
|
||||||
|
if (!gridsByLocation.ContainsKey(x + i))
|
||||||
|
{
|
||||||
|
gridsByLocation.Add(x + i, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
var rowGrids = gridsByLocation[x + i];
|
||||||
|
for (int j = 0; j < gridView.Grid.GridHeight.Value; j++)
|
||||||
|
{
|
||||||
|
rowGrids.Add(y + j, gridView.Grid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridOffsets.Add(parent, gridOffsets);
|
||||||
|
GridsByLocation.Add(parent, gridsByLocation);
|
||||||
|
|
||||||
|
// Best effort attempt at cleanup
|
||||||
|
IItemOwner owner = parent.Owner;
|
||||||
|
if (owner != null)
|
||||||
|
{
|
||||||
|
void onRemoveItem(GEventArgs3 eventArgs)
|
||||||
|
{
|
||||||
|
if (GridOffsets.ContainsKey(eventArgs.Item))
|
||||||
|
{
|
||||||
|
GridOffsets.Remove(eventArgs.Item);
|
||||||
|
GridsByLocation.Remove(eventArgs.Item);
|
||||||
|
owner.RemoveItemEvent -= onRemoveItem;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
owner.RemoveItemEvent += onRemoveItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsMultiGrid(GridItemAddress itemAddress)
|
||||||
|
{
|
||||||
|
return IsMultiGrid(itemAddress.Container.ParentItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsMultiGrid(Item item)
|
||||||
|
{
|
||||||
|
if (item is not LootItemClass lootItem)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lootItem.Grids.Length > 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,8 @@ using System.Linq;
|
|||||||
using TMPro;
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
using GridItemAddress = GClass2769;
|
||||||
|
|
||||||
namespace UIFixes
|
namespace UIFixes
|
||||||
{
|
{
|
||||||
public class MultiSelect
|
public class MultiSelect
|
||||||
@@ -79,12 +81,15 @@ namespace UIFixes
|
|||||||
ItemContextClass itemContext = new MultiSelectItemContext(itemView.ItemContext, itemView.ItemRotation);
|
ItemContextClass itemContext = new MultiSelectItemContext(itemView.ItemContext, itemView.ItemRotation);
|
||||||
|
|
||||||
// Subscribe to window closures to deselect
|
// Subscribe to window closures to deselect
|
||||||
GClass3085 windowContext = itemView.GetComponentInParent<GridWindow>()?.WindowContext ?? itemView.GetComponentInParent<InfoWindow>()?.WindowContext;
|
var windowContext = itemView.GetComponentInParent<GridWindow>()?.WindowContext ?? itemView.GetComponentInParent<InfoWindow>()?.WindowContext;
|
||||||
if (windowContext != null)
|
if (windowContext != null)
|
||||||
{
|
{
|
||||||
windowContext.OnClose += () => Deselect(itemContext);
|
windowContext.OnClose += () => Deselect(itemContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cache the gridview in case we need it
|
||||||
|
MultiGrid.Cache(itemView.Container as GridView);
|
||||||
|
|
||||||
dictionary.Add(itemContext, itemView);
|
dictionary.Add(itemContext, itemView);
|
||||||
ShowSelection(itemView);
|
ShowSelection(itemView);
|
||||||
}
|
}
|
||||||
@@ -193,14 +198,13 @@ namespace UIFixes
|
|||||||
// Can pass no itemContext, and it just sorts items by their grid order
|
// Can pass no itemContext, and it just sorts items by their grid order
|
||||||
public static IEnumerable<ItemContextClass> SortedItemContexts(ItemContextClass first = null, bool prepend = true)
|
public static IEnumerable<ItemContextClass> SortedItemContexts(ItemContextClass first = null, bool prepend = true)
|
||||||
{
|
{
|
||||||
static int gridOrder(LocationInGrid loc, StashGridClass grid) => grid.GridWidth.Value * loc.y + loc.x;
|
static int gridOrder(LocationInGrid loc) => 100 * loc.y + loc.x;
|
||||||
|
|
||||||
var result = ItemContexts
|
var result = ItemContexts
|
||||||
.Where(ic => first == null || ic.Item != first.Item)
|
.Where(ic => first == null || ic.Item != first.Item)
|
||||||
.OrderByDescending(ic => ic.ItemAddress is GClass2769)
|
.OrderByDescending(ic => ic.ItemAddress is GridItemAddress)
|
||||||
.ThenByDescending(ic => first != null && first.ItemAddress is GClass2769 originalDraggedAddress && ic.ItemAddress is GClass2769 selectedGridAddress && selectedGridAddress.Grid == originalDraggedAddress.Grid)
|
.ThenByDescending(ic => first != null && first.ItemAddress.Container.ParentItem == ic.ItemAddress.Container.ParentItem)
|
||||||
.ThenByDescending(ic => ic.ItemAddress is GClass2769 selectedGridAddress ? selectedGridAddress.Grid.Id : null)
|
.ThenBy(ic => ic.ItemAddress is GridItemAddress selectedGridAddress ? gridOrder(MultiGrid.GetGridLocation(selectedGridAddress)) : 0);
|
||||||
.ThenBy(ic => ic.ItemAddress is GClass2769 selectedGridAddress ? gridOrder(selectedGridAddress.LocationInGrid, selectedGridAddress.Grid) : 0);
|
|
||||||
|
|
||||||
return first != null && prepend ? result.Prepend(first) : result;
|
return first != null && prepend ? result.Prepend(first) : result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace UIFixes
|
|||||||
// Recreatign this function to add the comment section, so calling this with simulate = false doesn't break everything
|
// Recreatign this function to add the comment section, so calling this with simulate = false doesn't break everything
|
||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
[HarmonyPriority(Priority.Last)]
|
[HarmonyPriority(Priority.Last)]
|
||||||
public static bool Prefix(TraderControllerClass __instance, ItemContextAbstractClass itemContext, Item targetItem, bool partialTransferOnly, bool simulate, ref object __result)
|
public static bool Prefix(TraderControllerClass __instance, ItemContextAbstractClass itemContext, Item targetItem, bool partialTransferOnly, bool simulate, ref GStruct413 __result)
|
||||||
{
|
{
|
||||||
TraderControllerClass.Struct754 opStruct;
|
TraderControllerClass.Struct754 opStruct;
|
||||||
opStruct.targetItem = targetItem;
|
opStruct.targetItem = targetItem;
|
||||||
|
|||||||
@@ -17,6 +17,18 @@ using UnityEngine;
|
|||||||
using UnityEngine.EventSystems;
|
using UnityEngine.EventSystems;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
using ItemOperation = GStruct413;
|
||||||
|
using MoveOperation = GClass2786;
|
||||||
|
using GridItemAddress = GClass2769;
|
||||||
|
using GridFindExtensions = GClass2503;
|
||||||
|
using BaseItemInfoInteractions = GClass3021;
|
||||||
|
using GenericItemContext = GClass2817;
|
||||||
|
using Stackable = GClass2735;
|
||||||
|
using DestroyError = GClass3320;
|
||||||
|
using NoRoomError = GClass3292;
|
||||||
|
using GridModificationsUnavailableError = StashGridClass.GClass3291;
|
||||||
|
using MoveSameSpaceError = InteractionsHandlerClass.GClass3329;
|
||||||
|
|
||||||
namespace UIFixes
|
namespace UIFixes
|
||||||
{
|
{
|
||||||
public static class MultiSelectPatches
|
public static class MultiSelectPatches
|
||||||
@@ -28,7 +40,7 @@ namespace UIFixes
|
|||||||
private static readonly List<Image> Previews = [];
|
private static readonly List<Image> Previews = [];
|
||||||
|
|
||||||
// Point that various QuickFindPlace overrides should start at
|
// Point that various QuickFindPlace overrides should start at
|
||||||
private static GClass2769 FindOrigin = null;
|
private static GridItemAddress FindOrigin = null;
|
||||||
private static bool FindVerticalFirst = false;
|
private static bool FindVerticalFirst = false;
|
||||||
|
|
||||||
// Prevents QuickFind from attempting a merge
|
// Prevents QuickFind from attempting a merge
|
||||||
@@ -216,10 +228,10 @@ namespace UIFixes
|
|||||||
bool succeeded = true;
|
bool succeeded = true;
|
||||||
DisableMerge = true;
|
DisableMerge = true;
|
||||||
IgnoreItemParent = true;
|
IgnoreItemParent = true;
|
||||||
Stack<GStruct413> operations = new();
|
Stack<ItemOperation> operations = new();
|
||||||
foreach (ItemContextClass selectedItemContext in MultiSelect.SortedItemContexts())
|
foreach (ItemContextClass selectedItemContext in MultiSelect.SortedItemContexts())
|
||||||
{
|
{
|
||||||
GStruct413 operation = itemUiContext.QuickFindAppropriatePlace(selectedItemContext, itemController, false /*forceStash*/, false /*showWarnings*/, false /*simulate*/);
|
ItemOperation operation = itemUiContext.QuickFindAppropriatePlace(selectedItemContext, itemController, false /*forceStash*/, false /*showWarnings*/, false /*simulate*/);
|
||||||
if (operation.Succeeded && itemController.CanExecute(operation.Value))
|
if (operation.Succeeded && itemController.CanExecute(operation.Value))
|
||||||
{
|
{
|
||||||
operations.Push(operation);
|
operations.Push(operation);
|
||||||
@@ -232,7 +244,7 @@ namespace UIFixes
|
|||||||
|
|
||||||
if (operation.Value is IDestroyResult destroyResult && destroyResult.ItemsDestroyRequired)
|
if (operation.Value is IDestroyResult destroyResult && destroyResult.ItemsDestroyRequired)
|
||||||
{
|
{
|
||||||
NotificationManagerClass.DisplayWarningNotification(new GClass3320(gridItemView.Item, destroyResult.ItemsToDestroy).GetLocalizedDescription(), ENotificationDurationType.Default);
|
NotificationManagerClass.DisplayWarningNotification(new DestroyError(gridItemView.Item, destroyResult.ItemsToDestroy).GetLocalizedDescription(), ENotificationDurationType.Default);
|
||||||
succeeded = false;
|
succeeded = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -246,10 +258,10 @@ namespace UIFixes
|
|||||||
string itemSound = gridItemView.Item.ItemSound;
|
string itemSound = gridItemView.Item.ItemSound;
|
||||||
|
|
||||||
// We didn't simulate because we needed each result to depend on the last, but we have to undo before we actually do :S
|
// We didn't simulate because we needed each result to depend on the last, but we have to undo before we actually do :S
|
||||||
Stack<GStruct413> networkOps = new();
|
Stack<ItemOperation> networkOps = new();
|
||||||
while (operations.Any())
|
while (operations.Any())
|
||||||
{
|
{
|
||||||
GStruct413 operation = operations.Pop();
|
ItemOperation operation = operations.Pop();
|
||||||
operation.Value.RollBack();
|
operation.Value.RollBack();
|
||||||
networkOps.Push(operation);
|
networkOps.Push(operation);
|
||||||
}
|
}
|
||||||
@@ -277,7 +289,7 @@ namespace UIFixes
|
|||||||
{
|
{
|
||||||
protected override MethodBase GetTargetMethod()
|
protected override MethodBase GetTargetMethod()
|
||||||
{
|
{
|
||||||
return AccessTools.Method(typeof(GClass3021), nameof(GClass3021.ExecuteInteractionInternal));
|
return AccessTools.Method(typeof(BaseItemInfoInteractions), nameof(BaseItemInfoInteractions.ExecuteInteractionInternal));
|
||||||
}
|
}
|
||||||
|
|
||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
@@ -426,13 +438,15 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
|
|
||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
public static bool Prefix(GridView __instance, ItemContextClass itemContext, ItemContextAbstractClass targetItemContext, ref GStruct413 operation, ref bool __result, ItemUiContext ___itemUiContext_0)
|
public static bool Prefix(GridView __instance, ItemContextClass itemContext, ItemContextAbstractClass targetItemContext, ref ItemOperation operation, ref bool __result, ItemUiContext ___itemUiContext_0)
|
||||||
{
|
{
|
||||||
if (InPatch || !MultiSelect.Active)
|
if (InPatch || !MultiSelect.Active)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MultiGrid.Cache(__instance);
|
||||||
|
|
||||||
// Reimplementing this in order to control the simulate param. Need to *not* simulate, then rollback myself in order to test
|
// Reimplementing this in order to control the simulate param. Need to *not* simulate, then rollback myself in order to test
|
||||||
// multiple items going in
|
// multiple items going in
|
||||||
var wrappedInstance = __instance.R();
|
var wrappedInstance = __instance.R();
|
||||||
@@ -448,7 +462,7 @@ namespace UIFixes
|
|||||||
|
|
||||||
if (targetItemContext != null && !targetItemContext.ModificationAvailable)
|
if (targetItemContext != null && !targetItemContext.ModificationAvailable)
|
||||||
{
|
{
|
||||||
operation = new StashGridClass.GClass3291(__instance.Grid);
|
operation = new GridModificationsUnavailableError(__instance.Grid);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -465,7 +479,7 @@ namespace UIFixes
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GClass2769 hoveredAddress = new(__instance.Grid, hoveredLocation);
|
GridItemAddress hoveredAddress = new(__instance.Grid, hoveredLocation);
|
||||||
if (!item.CheckAction(hoveredAddress))
|
if (!item.CheckAction(hoveredAddress))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -476,9 +490,9 @@ namespace UIFixes
|
|||||||
bool isGridPlacement = targetItem == null;
|
bool isGridPlacement = targetItem == null;
|
||||||
|
|
||||||
// If everything selected is the same type and is a stackable type, allow partial success
|
// If everything selected is the same type and is a stackable type, allow partial success
|
||||||
bool allowPartialSuccess = targetItem != null && itemContext.Item is GClass2735 && MultiSelect.ItemContexts.All(ic => ic.Item.TemplateId == itemContext.Item.TemplateId);
|
bool allowPartialSuccess = targetItem != null && itemContext.Item is Stackable && MultiSelect.ItemContexts.All(ic => ic.Item.TemplateId == itemContext.Item.TemplateId);
|
||||||
|
|
||||||
Stack<GStruct413> operations = new();
|
Stack<ItemOperation> operations = new();
|
||||||
foreach (ItemContextClass selectedItemContext in MultiSelect.SortedItemContexts(itemContext))
|
foreach (ItemContextClass selectedItemContext in MultiSelect.SortedItemContexts(itemContext))
|
||||||
{
|
{
|
||||||
if (Settings.GreedyStackMove.Value && !isGridPlacement && selectedItemContext.Item.StackObjectsCount > 1)
|
if (Settings.GreedyStackMove.Value && !isGridPlacement && selectedItemContext.Item.StackObjectsCount > 1)
|
||||||
@@ -508,7 +522,7 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (operation.Error is GClass3292 noRoomError)
|
if (operation.Error is NoRoomError noRoomError)
|
||||||
{
|
{
|
||||||
// Wrap this error to display it
|
// Wrap this error to display it
|
||||||
operation = new(new DisplayableErrorWrapper(noRoomError));
|
operation = new(new DisplayableErrorWrapper(noRoomError));
|
||||||
@@ -555,19 +569,19 @@ namespace UIFixes
|
|||||||
ShowPreview(__instance, selectedItemContext, operation);
|
ShowPreview(__instance, selectedItemContext, operation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (operation.Error is InteractionsHandlerClass.GClass3329)
|
else if (operation.Error is MoveSameSpaceError)
|
||||||
{
|
{
|
||||||
// Moving item to the same place, cool, not a problem
|
// Moving item to the same place, cool, not a problem
|
||||||
__result = true;
|
__result = true;
|
||||||
operation = default;
|
operation = default;
|
||||||
if (isGridPlacement && selectedItemContext.Item.Parent is GClass2769 gridAddress)
|
if (isGridPlacement && selectedItemContext.Item.Parent is GridItemAddress gridAddress)
|
||||||
{
|
{
|
||||||
ShowPreview(__instance, selectedItemContext, gridAddress, R.GridView.ValidMoveColor);
|
ShowPreview(__instance, selectedItemContext, gridAddress, R.GridView.ValidMoveColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (operation.Error is GClass3292 noRoomError)
|
if (operation.Error is NoRoomError noRoomError)
|
||||||
{
|
{
|
||||||
// Wrap this error to display it
|
// Wrap this error to display it
|
||||||
operation = new(new DisplayableErrorWrapper(noRoomError));
|
operation = new(new DisplayableErrorWrapper(noRoomError));
|
||||||
@@ -651,12 +665,12 @@ namespace UIFixes
|
|||||||
DisableMerge = targetItemContext == null;
|
DisableMerge = targetItemContext == null;
|
||||||
|
|
||||||
LocationInGrid hoveredLocation = __instance.CalculateItemLocation(itemContext);
|
LocationInGrid hoveredLocation = __instance.CalculateItemLocation(itemContext);
|
||||||
GClass2769 hoveredAddress = new(__instance.Grid, hoveredLocation);
|
GridItemAddress hoveredAddress = new(__instance.Grid, hoveredLocation);
|
||||||
|
|
||||||
if (__instance.Grid.ParentItem is SortingTableClass)
|
if (__instance.Grid.ParentItem is SortingTableClass)
|
||||||
{
|
{
|
||||||
// Sorting table will need a targetItemContext. Dunno if this is the right type but all it needs is the .Item property
|
// Sorting table will need a targetItemContext. Dunno if this is the right type but all it needs is the .Item property
|
||||||
targetItemContext = new GClass2817(__instance.Grid.ParentItem, EItemViewType.Empty);
|
targetItemContext = new GenericItemContext(__instance.Grid.ParentItem, EItemViewType.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
var serializer = __instance.gameObject.AddComponent<ItemContextTaskSerializer>();
|
var serializer = __instance.gameObject.AddComponent<ItemContextTaskSerializer>();
|
||||||
@@ -686,7 +700,7 @@ namespace UIFixes
|
|||||||
{
|
{
|
||||||
var itemController = gridView.R().TraderController;
|
var itemController = gridView.R().TraderController;
|
||||||
|
|
||||||
GStruct413 operation = itemUiContext.QuickMoveToSortingTable(itemContext.Item, true);
|
ItemOperation operation = itemUiContext.QuickMoveToSortingTable(itemContext.Item, true);
|
||||||
if (operation.Failed || !itemController.CanExecute(operation.Value))
|
if (operation.Failed || !itemController.CanExecute(operation.Value))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -735,11 +749,11 @@ namespace UIFixes
|
|||||||
{
|
{
|
||||||
protected override MethodBase GetTargetMethod()
|
protected override MethodBase GetTargetMethod()
|
||||||
{
|
{
|
||||||
return AccessTools.Method(typeof(GClass2503), nameof(GClass2503.FindLocationForItem));
|
return AccessTools.Method(typeof(GridFindExtensions), nameof(GridFindExtensions.FindLocationForItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
public static bool Prefix(IEnumerable<StashGridClass> grids, Item item, ref GClass2769 __result)
|
public static bool Prefix(IEnumerable<StashGridClass> grids, Item item, ref GridItemAddress __result)
|
||||||
{
|
{
|
||||||
if (!MultiSelect.Active)
|
if (!MultiSelect.Active)
|
||||||
{
|
{
|
||||||
@@ -807,7 +821,7 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
|
|
||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
public static bool Prefix(SlotView __instance, ItemContextAbstractClass targetItemContext, ref GStruct413 operation, ref bool __result, InventoryControllerClass ___InventoryController)
|
public static bool Prefix(SlotView __instance, ItemContextAbstractClass targetItemContext, ref ItemOperation operation, ref bool __result, InventoryControllerClass ___InventoryController)
|
||||||
{
|
{
|
||||||
if (InPatch || !MultiSelect.Active)
|
if (InPatch || !MultiSelect.Active)
|
||||||
{
|
{
|
||||||
@@ -819,11 +833,11 @@ namespace UIFixes
|
|||||||
if (targetItemContext != null && !targetItemContext.ModificationAvailable ||
|
if (targetItemContext != null && !targetItemContext.ModificationAvailable ||
|
||||||
__instance.ParentItemContext != null && !__instance.ParentItemContext.ModificationAvailable)
|
__instance.ParentItemContext != null && !__instance.ParentItemContext.ModificationAvailable)
|
||||||
{
|
{
|
||||||
operation = new StashGridClass.GClass3291(__instance.Slot);
|
operation = new GridModificationsUnavailableError(__instance.Slot);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stack<GStruct413> operations = new();
|
Stack<ItemOperation> operations = new();
|
||||||
foreach (ItemContextClass itemContext in MultiSelect.SortedItemContexts())
|
foreach (ItemContextClass itemContext in MultiSelect.SortedItemContexts())
|
||||||
{
|
{
|
||||||
if (!Settings.GreedyStackMove.Value || itemContext.Item.StackObjectsCount <= 1)
|
if (!Settings.GreedyStackMove.Value || itemContext.Item.StackObjectsCount <= 1)
|
||||||
@@ -833,7 +847,7 @@ namespace UIFixes
|
|||||||
{
|
{
|
||||||
operations.Push(operation);
|
operations.Push(operation);
|
||||||
}
|
}
|
||||||
else if (operation.Error is InteractionsHandlerClass.GClass3329)
|
else if (operation.Error is MoveSameSpaceError)
|
||||||
{
|
{
|
||||||
// Moving item to the same place, cool, not a problem
|
// Moving item to the same place, cool, not a problem
|
||||||
__result = true;
|
__result = true;
|
||||||
@@ -929,7 +943,7 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
|
|
||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
public static bool Prefix(TradingTableGridView __instance, ItemContextClass itemContext, ref GStruct413 operation, ref bool __result)
|
public static bool Prefix(TradingTableGridView __instance, ItemContextClass itemContext, ref ItemOperation operation, ref bool __result)
|
||||||
{
|
{
|
||||||
if (!MultiSelect.Active)
|
if (!MultiSelect.Active)
|
||||||
{
|
{
|
||||||
@@ -946,11 +960,11 @@ namespace UIFixes
|
|||||||
bool firstItem = true;
|
bool firstItem = true;
|
||||||
|
|
||||||
LocationInGrid hoveredLocation = __instance.CalculateItemLocation(itemContext);
|
LocationInGrid hoveredLocation = __instance.CalculateItemLocation(itemContext);
|
||||||
GClass2769 hoveredAddress = new(__instance.Grid, hoveredLocation);
|
GridItemAddress hoveredAddress = new(__instance.Grid, hoveredLocation);
|
||||||
|
|
||||||
DisableMerge = true;
|
DisableMerge = true;
|
||||||
|
|
||||||
Stack<GStruct413> operations = new();
|
Stack<ItemOperation> operations = new();
|
||||||
foreach (ItemContextClass selectedItemContext in MultiSelect.SortedItemContexts(itemContext))
|
foreach (ItemContextClass selectedItemContext in MultiSelect.SortedItemContexts(itemContext))
|
||||||
{
|
{
|
||||||
if (traderAssortmentController.CanPrepareItemToSell(selectedItemContext.Item))
|
if (traderAssortmentController.CanPrepareItemToSell(selectedItemContext.Item))
|
||||||
@@ -959,7 +973,7 @@ namespace UIFixes
|
|||||||
FindVerticalFirst = selectedItemContext.ItemRotation == ItemRotation.Vertical;
|
FindVerticalFirst = selectedItemContext.ItemRotation == ItemRotation.Vertical;
|
||||||
|
|
||||||
operation = firstItem ?
|
operation = firstItem ?
|
||||||
InteractionsHandlerClass.Move(selectedItemContext.Item, new GClass2769(__instance.Grid, __instance.CalculateItemLocation(selectedItemContext)), traderAssortmentController.TraderController, false) :
|
InteractionsHandlerClass.Move(selectedItemContext.Item, new GridItemAddress(__instance.Grid, __instance.CalculateItemLocation(selectedItemContext)), traderAssortmentController.TraderController, false) :
|
||||||
InteractionsHandlerClass.QuickFindAppropriatePlace(selectedItemContext.Item, traderAssortmentController.TraderController, [__instance.Grid.ParentItem as LootItemClass], InteractionsHandlerClass.EMoveItemOrder.Apply, false);
|
InteractionsHandlerClass.QuickFindAppropriatePlace(selectedItemContext.Item, traderAssortmentController.TraderController, [__instance.Grid.ParentItem as LootItemClass], InteractionsHandlerClass.EMoveItemOrder.Apply, false);
|
||||||
|
|
||||||
FindVerticalFirst = false;
|
FindVerticalFirst = false;
|
||||||
@@ -1023,7 +1037,7 @@ namespace UIFixes
|
|||||||
TraderAssortmentControllerClass traderAssortmentController = __instance.R().TraderAssortmentController;
|
TraderAssortmentControllerClass traderAssortmentController = __instance.R().TraderAssortmentController;
|
||||||
|
|
||||||
LocationInGrid hoveredLocation = __instance.CalculateItemLocation(itemContext);
|
LocationInGrid hoveredLocation = __instance.CalculateItemLocation(itemContext);
|
||||||
GClass2769 hoveredAddress = new(__instance.Grid, hoveredLocation);
|
GridItemAddress hoveredAddress = new(__instance.Grid, hoveredLocation);
|
||||||
|
|
||||||
itemContext.DragCancelled();
|
itemContext.DragCancelled();
|
||||||
traderAssortmentController.PrepareToSell(itemContext.Item, hoveredLocation);
|
traderAssortmentController.PrepareToSell(itemContext.Item, hoveredLocation);
|
||||||
@@ -1037,11 +1051,11 @@ namespace UIFixes
|
|||||||
FindOrigin = GetTargetGridAddress(itemContext, selectedItemContext, hoveredAddress);
|
FindOrigin = GetTargetGridAddress(itemContext, selectedItemContext, hoveredAddress);
|
||||||
FindVerticalFirst = selectedItemContext.ItemRotation == ItemRotation.Vertical;
|
FindVerticalFirst = selectedItemContext.ItemRotation == ItemRotation.Vertical;
|
||||||
|
|
||||||
GStruct413 operation = InteractionsHandlerClass.QuickFindAppropriatePlace(selectedItemContext.Item, traderAssortmentController.TraderController, [__instance.Grid.ParentItem as LootItemClass], InteractionsHandlerClass.EMoveItemOrder.Apply, true);
|
ItemOperation operation = InteractionsHandlerClass.QuickFindAppropriatePlace(selectedItemContext.Item, traderAssortmentController.TraderController, [__instance.Grid.ParentItem as LootItemClass], InteractionsHandlerClass.EMoveItemOrder.Apply, true);
|
||||||
|
|
||||||
FindVerticalFirst = false;
|
FindVerticalFirst = false;
|
||||||
|
|
||||||
if (operation.Failed || operation.Value is not GClass2786 moveOperation || moveOperation.To is not GClass2769 gridAddress)
|
if (operation.Failed || operation.Value is not MoveOperation moveOperation || moveOperation.To is not GridItemAddress gridAddress)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1128,7 +1142,7 @@ namespace UIFixes
|
|||||||
{
|
{
|
||||||
protected override MethodBase GetTargetMethod()
|
protected override MethodBase GetTargetMethod()
|
||||||
{
|
{
|
||||||
return AccessTools.Method(typeof(GClass2503), nameof(GClass2503.FindLocationForItem));
|
return AccessTools.Method(typeof(GridFindExtensions), nameof(GridFindExtensions.FindLocationForItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
@@ -1250,9 +1264,9 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ShowPreview(GridView gridView, ItemContextClass itemContext, GStruct413 operation)
|
private static void ShowPreview(GridView gridView, ItemContextClass itemContext, ItemOperation operation)
|
||||||
{
|
{
|
||||||
if (operation.Value is not GClass2786 moveOperation || moveOperation.To is not GClass2769 gridAddress)
|
if (operation.Value is not MoveOperation moveOperation || moveOperation.To is not GridItemAddress gridAddress)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1273,7 +1287,7 @@ namespace UIFixes
|
|||||||
ShowPreview(gridView, itemContext, gridAddress, backgroundColor);
|
ShowPreview(gridView, itemContext, gridAddress, backgroundColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ShowPreview(GridView gridView, ItemContextClass itemContext, GClass2769 gridAddress, Color backgroundColor)
|
private static void ShowPreview(GridView gridView, ItemContextClass itemContext, GridItemAddress gridAddress, Color backgroundColor)
|
||||||
{
|
{
|
||||||
Image preview = UnityEngine.Object.Instantiate(gridView.R().HighlightPanel, gridView.transform, false);
|
Image preview = UnityEngine.Object.Instantiate(gridView.R().HighlightPanel, gridView.transform, false);
|
||||||
preview.gameObject.SetActive(true);
|
preview.gameObject.SetActive(true);
|
||||||
@@ -1287,7 +1301,7 @@ namespace UIFixes
|
|||||||
Quaternion quaternion = (gridAddress.LocationInGrid.r == ItemRotation.Horizontal) ? ItemViewFactory.HorizontalRotation : ItemViewFactory.VerticalRotation;
|
Quaternion quaternion = (gridAddress.LocationInGrid.r == ItemRotation.Horizontal) ? ItemViewFactory.HorizontalRotation : ItemViewFactory.VerticalRotation;
|
||||||
preview.transform.rotation = quaternion;
|
preview.transform.rotation = quaternion;
|
||||||
|
|
||||||
GStruct24 itemSize = itemContext.Item.CalculateRotatedSize(gridAddress.LocationInGrid.r);
|
var itemSize = itemContext.Item.CalculateRotatedSize(gridAddress.LocationInGrid.r);
|
||||||
LocationInGrid locationInGrid = gridAddress.LocationInGrid;
|
LocationInGrid locationInGrid = gridAddress.LocationInGrid;
|
||||||
|
|
||||||
RectTransform rectTransform = preview.rectTransform;
|
RectTransform rectTransform = preview.rectTransform;
|
||||||
@@ -1316,8 +1330,8 @@ namespace UIFixes
|
|||||||
Previews.Clear();
|
Previews.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GClass2769 GetTargetGridAddress(
|
private static GridItemAddress GetTargetGridAddress(
|
||||||
ItemContextClass itemContext, ItemContextClass selectedItemContext, GClass2769 hoveredGridAddress)
|
ItemContextClass itemContext, ItemContextClass selectedItemContext, GridItemAddress hoveredGridAddress)
|
||||||
{
|
{
|
||||||
if (Settings.MultiSelectStrat.Value == MultiSelectStrategy.FirstOpenSpace)
|
if (Settings.MultiSelectStrat.Value == MultiSelectStrategy.FirstOpenSpace)
|
||||||
{
|
{
|
||||||
@@ -1326,19 +1340,21 @@ namespace UIFixes
|
|||||||
|
|
||||||
if (Settings.MultiSelectStrat.Value == MultiSelectStrategy.OriginalSpacing &&
|
if (Settings.MultiSelectStrat.Value == MultiSelectStrategy.OriginalSpacing &&
|
||||||
itemContext != selectedItemContext &&
|
itemContext != selectedItemContext &&
|
||||||
itemContext.ItemAddress is GClass2769 itemGridAddress &&
|
itemContext.ItemAddress is GridItemAddress itemGridAddress &&
|
||||||
selectedItemContext.ItemAddress is GClass2769 selectedGridAddress &&
|
selectedItemContext.ItemAddress is GridItemAddress selectedGridAddress &&
|
||||||
itemGridAddress.Grid == selectedGridAddress.Grid)
|
itemGridAddress.Container.ParentItem == selectedGridAddress.Container.ParentItem)
|
||||||
{
|
{
|
||||||
// Shared a grid with the dragged item - try to keep position
|
// Shared a parent with the dragged item - try to keep position
|
||||||
int xDelta = selectedGridAddress.LocationInGrid.x - itemGridAddress.LocationInGrid.x;
|
LocationInGrid itemLocation = MultiGrid.GetGridLocation(itemGridAddress);
|
||||||
int yDelta = selectedGridAddress.LocationInGrid.y - itemGridAddress.LocationInGrid.y;
|
LocationInGrid selectedLocation = MultiGrid.GetGridLocation(selectedGridAddress);
|
||||||
|
LocationInGrid hoveredLocation = MultiGrid.GetGridLocation(hoveredGridAddress);
|
||||||
|
|
||||||
LocationInGrid newLocation = new(hoveredGridAddress.LocationInGrid.x + xDelta, hoveredGridAddress.LocationInGrid.y + yDelta, selectedGridAddress.LocationInGrid.r);
|
int xDelta = selectedLocation.x - itemLocation.x;
|
||||||
newLocation.x = Math.Max(0, Math.Min(hoveredGridAddress.Grid.GridWidth.Value, newLocation.x));
|
int yDelta = selectedLocation.y - itemLocation.y;
|
||||||
newLocation.y = Math.Max(0, Math.Min(hoveredGridAddress.Grid.GridHeight.Value, newLocation.y));
|
|
||||||
|
|
||||||
return new GClass2769(hoveredGridAddress.Grid, newLocation);
|
LocationInGrid newLocation = new(hoveredLocation.x + xDelta, hoveredLocation.y + yDelta, selectedLocation.r);
|
||||||
|
|
||||||
|
return MultiGrid.GetRealAddress(hoveredGridAddress.Grid, newLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
return hoveredGridAddress;
|
return hoveredGridAddress;
|
||||||
|
|||||||
Reference in New Issue
Block a user