gridview containers can accept
This commit is contained in:
@@ -1,34 +1,68 @@
|
|||||||
using EFT.UI;
|
using Comfort.Common;
|
||||||
|
using EFT.UI;
|
||||||
using EFT.UI.DragAndDrop;
|
using EFT.UI.DragAndDrop;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
namespace UIFixes
|
namespace UIFixes
|
||||||
{
|
{
|
||||||
public class DrawMultiSelect : MonoBehaviour
|
public class DrawMultiSelect : MonoBehaviour
|
||||||
{
|
{
|
||||||
Texture2D selectTexture;
|
private Texture2D selectTexture;
|
||||||
|
|
||||||
Vector3 selectOrigin;
|
private Vector3 selectOrigin;
|
||||||
Vector3 selectEnd;
|
private Vector3 selectEnd;
|
||||||
|
|
||||||
bool drawing;
|
private GraphicRaycaster preloaderRaycaster;
|
||||||
|
|
||||||
|
private bool drawing;
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
selectTexture = new Texture2D(1, 1);
|
selectTexture = new Texture2D(1, 1);
|
||||||
selectTexture.SetPixel(0, 0, new Color(1f, 1f, 1f, 0.8f));
|
selectTexture.SetPixel(0, 0, new Color(1f, 1f, 1f, 0.6f));
|
||||||
selectTexture.Apply();
|
selectTexture.Apply();
|
||||||
|
|
||||||
|
preloaderRaycaster = Singleton<PreloaderUI>.Instance.transform.GetChild(0).GetComponent<GraphicRaycaster>();
|
||||||
|
if (preloaderRaycaster == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("DrawMultiSelect couldn't find the PreloaderUI GraphicRayCaster");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
|
if (!Settings.EnableMultiSelect.Value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Input.GetKeyDown(KeyCode.Mouse0) && ItemUiContext.Instance.R().ItemContext == null)
|
if (Input.GetKeyDown(KeyCode.Mouse0) && ItemUiContext.Instance.R().ItemContext == null)
|
||||||
{
|
{
|
||||||
|
PointerEventData eventData = new(EventSystem.current);
|
||||||
|
eventData.position = Input.mousePosition;
|
||||||
|
|
||||||
|
List<RaycastResult> results = new();
|
||||||
|
var preloaderRaycaster = Singleton<PreloaderUI>.Instance.transform.GetChild(0).GetComponent<GraphicRaycaster>();
|
||||||
|
preloaderRaycaster.Raycast(eventData, results);
|
||||||
|
|
||||||
|
foreach (GameObject gameObject in results.Select(r => r.gameObject))
|
||||||
|
{
|
||||||
|
var dragInterfaces = gameObject.GetComponents<MonoBehaviour>()
|
||||||
|
.Where(c => c is IDragHandler || c is IBeginDragHandler)
|
||||||
|
.Where(c => c is not ScrollRectNoDrag) // this disables scrolling, it doesn't add it
|
||||||
|
.Where(c => c.name != "Inner"); // there's a random DragTrigger sitting in ItemInfoWindows
|
||||||
|
|
||||||
|
if (dragInterfaces.Any())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
selectOrigin = Input.mousePosition;
|
selectOrigin = Input.mousePosition;
|
||||||
drawing = true;
|
drawing = true;
|
||||||
}
|
}
|
||||||
@@ -37,20 +71,62 @@ namespace UIFixes
|
|||||||
{
|
{
|
||||||
selectEnd = Input.mousePosition;
|
selectEnd = Input.mousePosition;
|
||||||
|
|
||||||
Rect selectRect = new(selectOrigin.x, selectOrigin.y, selectEnd.x - selectOrigin.x, selectEnd.y - selectOrigin.y);
|
Rect selectRect = new(selectOrigin, selectEnd - selectOrigin);
|
||||||
foreach (GridItemView gridItemView in GetComponentsInChildren<GridItemView>())
|
foreach (GridItemView gridItemView in GetComponentsInChildren<GridItemView>().Concat(Singleton<PreloaderUI>.Instance.GetComponentsInChildren<GridItemView>()))
|
||||||
{
|
{
|
||||||
RectTransform itemTransform = gridItemView.GetComponent<RectTransform>();
|
RectTransform itemTransform = gridItemView.GetComponent<RectTransform>();
|
||||||
Rect screenRect = new((Vector2)itemTransform.position + itemTransform.rect.position, itemTransform.rect.size);
|
Rect itemRect = new((Vector2)itemTransform.position + itemTransform.rect.position * itemTransform.lossyScale, itemTransform.rect.size * itemTransform.lossyScale);
|
||||||
|
|
||||||
if (selectRect.Overlaps(screenRect, true))
|
if (selectRect.Overlaps(itemRect, true))
|
||||||
{
|
{
|
||||||
|
// Otherwise, ensure it's not overlapped by window UI
|
||||||
|
PointerEventData eventData = new(EventSystem.current);
|
||||||
|
|
||||||
|
// Non-absolute width/height
|
||||||
|
float width = itemRect.xMax - itemRect.xMin;
|
||||||
|
float height = itemRect.yMax - itemRect.yMin;
|
||||||
|
|
||||||
|
List<RaycastResult> raycastResults = new();
|
||||||
|
eventData.position = new Vector2(itemRect.xMin + 0.1f * width, itemRect.yMin + 0.1f * height);
|
||||||
|
preloaderRaycaster.Raycast(eventData, raycastResults);
|
||||||
|
if (raycastResults.Any() && !raycastResults[0].gameObject.transform.IsDescendantOf(itemTransform))
|
||||||
|
{
|
||||||
|
MultiSelect.Deselect(gridItemView);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
raycastResults.Clear();
|
||||||
|
eventData.position = new Vector2(itemRect.xMin + 0.1f * width, itemRect.yMax - 0.1f * height);
|
||||||
|
preloaderRaycaster.Raycast(eventData, raycastResults);
|
||||||
|
if (raycastResults.Any() && !raycastResults[0].gameObject.transform.IsDescendantOf(itemTransform))
|
||||||
|
{
|
||||||
|
MultiSelect.Deselect(gridItemView);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
raycastResults.Clear();
|
||||||
|
eventData.position = new Vector2(itemRect.xMax - 0.1f * width, itemRect.yMax - 0.1f * height);
|
||||||
|
preloaderRaycaster.Raycast(eventData, raycastResults);
|
||||||
|
if (raycastResults.Any() && !raycastResults[0].gameObject.transform.IsDescendantOf(itemTransform))
|
||||||
|
{
|
||||||
|
MultiSelect.Deselect(gridItemView);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
raycastResults.Clear();
|
||||||
|
eventData.position = new Vector2(itemRect.xMax - 0.1f * width, itemRect.yMin + 0.1f * height);
|
||||||
|
preloaderRaycaster.Raycast(eventData, raycastResults);
|
||||||
|
if (raycastResults.Any() && !raycastResults[0].gameObject.transform.IsDescendantOf(itemTransform))
|
||||||
|
{
|
||||||
|
MultiSelect.Deselect(gridItemView);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
MultiSelect.Select(gridItemView);
|
MultiSelect.Select(gridItemView);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
MultiSelect.Deselect(gridItemView);
|
||||||
MultiSelect.Deselect(gridItemView);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,6 +158,27 @@ namespace UIFixes
|
|||||||
GUI.DrawTexture(lineArea, selectTexture);
|
GUI.DrawTexture(lineArea, selectTexture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TransformExtensions
|
||||||
|
{
|
||||||
|
public static bool IsDescendantOf(this Transform transform, Transform target)
|
||||||
|
{
|
||||||
|
if (transform == target)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (transform.parent != null)
|
||||||
|
{
|
||||||
|
transform = transform.parent;
|
||||||
|
if (transform == target)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
using EFT.InventoryLogic;
|
using EFT.UI.DragAndDrop;
|
||||||
using EFT.UI.DragAndDrop;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using TMPro;
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@@ -22,8 +18,13 @@ namespace UIFixes
|
|||||||
{
|
{
|
||||||
// Grab the selection objects from ragfair as templates
|
// Grab the selection objects from ragfair as templates
|
||||||
RagfairNewOfferItemView ragfairNewOfferItemView = ItemViewFactory.CreateFromPool<RagfairNewOfferItemView>("ragfair_layout");
|
RagfairNewOfferItemView ragfairNewOfferItemView = ItemViewFactory.CreateFromPool<RagfairNewOfferItemView>("ragfair_layout");
|
||||||
|
|
||||||
SelectedMarkTemplate = UnityEngine.Object.Instantiate(ragfairNewOfferItemView.R().SelectedMark, null, false);
|
SelectedMarkTemplate = UnityEngine.Object.Instantiate(ragfairNewOfferItemView.R().SelectedMark, null, false);
|
||||||
|
UnityEngine.Object.DontDestroyOnLoad(SelectedMarkTemplate);
|
||||||
|
|
||||||
SelectedBackgroundTemplate = UnityEngine.Object.Instantiate(ragfairNewOfferItemView.R().SelectedBackground, null, false);
|
SelectedBackgroundTemplate = UnityEngine.Object.Instantiate(ragfairNewOfferItemView.R().SelectedBackground, null, false);
|
||||||
|
UnityEngine.Object.DontDestroyOnLoad(SelectedBackgroundTemplate);
|
||||||
|
|
||||||
ragfairNewOfferItemView.ReturnToPool();
|
ragfairNewOfferItemView.ReturnToPool();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +92,7 @@ namespace UIFixes
|
|||||||
|
|
||||||
public static bool Active
|
public static bool Active
|
||||||
{
|
{
|
||||||
get { return SelectedItemViews.Any(); }
|
get { return SelectedItemViews.Count > 1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsSelected(GridItemView itemView)
|
public static bool IsSelected(GridItemView itemView)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using Aki.Reflection.Patching;
|
using Aki.Reflection.Patching;
|
||||||
using Comfort.Common;
|
using EFT.InventoryLogic;
|
||||||
using EFT.UI;
|
using EFT.UI;
|
||||||
using EFT.UI.DragAndDrop;
|
using EFT.UI.DragAndDrop;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
@@ -8,7 +8,6 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using TMPro;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.EventSystems;
|
using UnityEngine.EventSystems;
|
||||||
|
|
||||||
@@ -29,6 +28,7 @@ namespace UIFixes
|
|||||||
new EndDragPatch().Enable();
|
new EndDragPatch().Enable();
|
||||||
|
|
||||||
new GridViewCanAcceptPatch().Enable();
|
new GridViewCanAcceptPatch().Enable();
|
||||||
|
new GridViewAcceptItemPatch().Enable();
|
||||||
new SlotViewCanAcceptPatch().Enable();
|
new SlotViewCanAcceptPatch().Enable();
|
||||||
new SlotViewAcceptItemPatch().Enable();
|
new SlotViewAcceptItemPatch().Enable();
|
||||||
}
|
}
|
||||||
@@ -43,11 +43,16 @@ namespace UIFixes
|
|||||||
[PatchPostfix]
|
[PatchPostfix]
|
||||||
public static void Postfix(CommonUI __instance)
|
public static void Postfix(CommonUI __instance)
|
||||||
{
|
{
|
||||||
|
if (!Settings.EnableMultiSelect.Value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MultiSelect.Initialize();
|
MultiSelect.Initialize();
|
||||||
|
|
||||||
__instance.InventoryScreen.GetOrAddComponent<DrawMultiSelect>();
|
__instance.InventoryScreen.GetOrAddComponent<DrawMultiSelect>();
|
||||||
//__instance.TransferItemsInRaidScreen.GetOrAddComponent<DrawMultiSelect>();
|
__instance.TransferItemsInRaidScreen.GetOrAddComponent<DrawMultiSelect>();
|
||||||
//__instance.TransferItemsScreen.GetOrAddComponent<DrawMultiSelect>();
|
__instance.TransferItemsScreen.GetOrAddComponent<DrawMultiSelect>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,13 +66,18 @@ namespace UIFixes
|
|||||||
[PatchPostfix]
|
[PatchPostfix]
|
||||||
public static void Postfix(GridItemView __instance, PointerEventData.InputButton button)
|
public static void Postfix(GridItemView __instance, PointerEventData.InputButton button)
|
||||||
{
|
{
|
||||||
if (button == PointerEventData.InputButton.Left && (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)))
|
if (!Settings.EnableMultiSelect.Value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__instance.Item != null && button == PointerEventData.InputButton.Left && (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)))
|
||||||
{
|
{
|
||||||
MultiSelect.Toggle(__instance);
|
MultiSelect.Toggle(__instance);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (button == PointerEventData.InputButton.Left)// && !MultiSelect.IsSelected(__instance))
|
if (button == PointerEventData.InputButton.Left)
|
||||||
{
|
{
|
||||||
MultiSelect.Clear();
|
MultiSelect.Clear();
|
||||||
}
|
}
|
||||||
@@ -84,6 +94,11 @@ namespace UIFixes
|
|||||||
[PatchPostfix]
|
[PatchPostfix]
|
||||||
public static void Postfix(ItemView __instance, PointerEventData eventData)
|
public static void Postfix(ItemView __instance, PointerEventData eventData)
|
||||||
{
|
{
|
||||||
|
if (!Settings.EnableMultiSelect.Value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (eventData.button == PointerEventData.InputButton.Left && (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)))
|
if (eventData.button == PointerEventData.InputButton.Left && (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)))
|
||||||
{
|
{
|
||||||
// This will be shift-click, let it cook
|
// This will be shift-click, let it cook
|
||||||
@@ -107,6 +122,11 @@ namespace UIFixes
|
|||||||
[PatchPostfix]
|
[PatchPostfix]
|
||||||
public static void Postfix(ItemView __instance)
|
public static void Postfix(ItemView __instance)
|
||||||
{
|
{
|
||||||
|
if (!Settings.EnableMultiSelect.Value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (__instance is GridItemView gridItemView)
|
if (__instance is GridItemView gridItemView)
|
||||||
{
|
{
|
||||||
MultiSelect.Deselect(gridItemView);
|
MultiSelect.Deselect(gridItemView);
|
||||||
@@ -124,12 +144,22 @@ namespace UIFixes
|
|||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
public static void Prefix()
|
public static void Prefix()
|
||||||
{
|
{
|
||||||
|
if (!Settings.EnableMultiSelect.Value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MultiSelect.BeginDrag();
|
MultiSelect.BeginDrag();
|
||||||
}
|
}
|
||||||
|
|
||||||
[PatchPostfix]
|
[PatchPostfix]
|
||||||
public static void Postfix(ItemView __instance)
|
public static void Postfix(ItemView __instance)
|
||||||
{
|
{
|
||||||
|
if (!Settings.EnableMultiSelect.Value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MultiSelect.ShowDragCount(__instance.DraggedItemView);
|
MultiSelect.ShowDragCount(__instance.DraggedItemView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,6 +174,11 @@ namespace UIFixes
|
|||||||
[PatchPostfix]
|
[PatchPostfix]
|
||||||
public static void Postfix()
|
public static void Postfix()
|
||||||
{
|
{
|
||||||
|
if (!Settings.EnableMultiSelect.Value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MultiSelect.EndDrag();
|
MultiSelect.EndDrag();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,27 +193,84 @@ namespace UIFixes
|
|||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
public static bool Prefix(GridView __instance, ItemContextAbstractClass targetItemContext, ref GStruct413 operation, ref bool __result)
|
public static bool Prefix(GridView __instance, ItemContextAbstractClass targetItemContext, ref GStruct413 operation, ref bool __result)
|
||||||
{
|
{
|
||||||
if (InPatch || !MultiSelect.Active)
|
if (!Settings.EnableMultiSelect.Value || InPatch || !MultiSelect.Active)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reimplementing this in order to control the simulate param. Need to *not* simulate, then rollback myself in order to test
|
||||||
|
// multiple items going in
|
||||||
|
var wrappedInstance = __instance.R();
|
||||||
operation = default;
|
operation = default;
|
||||||
__result = false;
|
__result = false;
|
||||||
return false;
|
|
||||||
|
|
||||||
/* InPatch = true;
|
if (__instance.Grid == null || wrappedInstance.NonInteractable)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetItemContext != null && !targetItemContext.ModificationAvailable)
|
||||||
|
{
|
||||||
|
operation = new StashGridClass.GClass3291(__instance.Grid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Item targetItem = __instance.method_8(targetItemContext);
|
||||||
|
|
||||||
|
// baby steps: bail if no targetItem for now
|
||||||
|
if (targetItem == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stack<GStruct413> operations = new();
|
||||||
foreach (ItemContextClass itemContext in MultiSelect.ItemContexts)
|
foreach (ItemContextClass itemContext in MultiSelect.ItemContexts)
|
||||||
{
|
{
|
||||||
__result = __instance.CanAccept(itemContext, targetItemContext, out operation);
|
operation = wrappedInstance.TraderController.ExecutePossibleAction(itemContext, targetItem, false /* splitting */, false /* simulate */);
|
||||||
if (!__result)
|
if (__result = operation.Succeeded)
|
||||||
|
{
|
||||||
|
operations.Push(operation);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InPatch = false;
|
// We didn't simulate so now we undo
|
||||||
return false;*/
|
while (operations.Any())
|
||||||
|
{
|
||||||
|
operations.Pop().Value?.RollBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
// result and operation are set to the last one that completed - so success if they all passed, or the first failure
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GridViewAcceptItemPatch : ModulePatch
|
||||||
|
{
|
||||||
|
protected override MethodBase GetTargetMethod()
|
||||||
|
{
|
||||||
|
return AccessTools.Method(typeof(GridView), nameof(GridView.AcceptItem));
|
||||||
|
}
|
||||||
|
|
||||||
|
[PatchPrefix]
|
||||||
|
public static bool Prefix(GridView __instance, ItemContextAbstractClass targetItemContext, ref Task __result)
|
||||||
|
{
|
||||||
|
if (!Settings.EnableMultiSelect.Value || InPatch || !MultiSelect.Active)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
InPatch = true;
|
||||||
|
|
||||||
|
var serializer = __instance.GetOrAddComponent<TaskSerializer>();
|
||||||
|
__result = serializer.Initialize(MultiSelect.ItemContexts, itemContext => __instance.AcceptItem(itemContext, targetItemContext));
|
||||||
|
|
||||||
|
__result.ContinueWith(_ => { InPatch = false; });
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,27 +282,43 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
|
|
||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
public static bool Prefix(SlotView __instance, ItemContextAbstractClass targetItemContext, ref GStruct413 operation, ref bool __result)
|
public static bool Prefix(SlotView __instance, ItemContextAbstractClass targetItemContext, ref GStruct413 operation, ref bool __result, InventoryControllerClass ___InventoryController)
|
||||||
{
|
{
|
||||||
if (InPatch || !MultiSelect.Active)
|
if (!Settings.EnableMultiSelect.Value || InPatch || !MultiSelect.Active)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
operation = default;
|
// Reimplementing this in order to control the simulate param. Need to *not* simulate, then rollback myself in order to test
|
||||||
__result = false;
|
// multiple items going in
|
||||||
|
if (targetItemContext != null && !targetItemContext.ModificationAvailable ||
|
||||||
|
__instance.ParentItemContext != null && !__instance.ParentItemContext.ModificationAvailable)
|
||||||
|
{
|
||||||
|
operation = new StashGridClass.GClass3291(__instance.Slot);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
InPatch = true;
|
Stack<GStruct413> operations = new();
|
||||||
foreach (ItemContextClass itemContext in MultiSelect.ItemContexts)
|
foreach (ItemContextClass itemContext in MultiSelect.ItemContexts)
|
||||||
{
|
{
|
||||||
__result = __instance.CanAccept(itemContext, targetItemContext, out operation);
|
__result = itemContext.CanAccept(__instance.Slot, __instance.ParentItemContext, ___InventoryController, out operation, false /* simulate */);
|
||||||
if (!__result)
|
if (operation.Succeeded)
|
||||||
|
{
|
||||||
|
operations.Push(operation);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InPatch = false;
|
// We didn't simulate so now we undo
|
||||||
|
while(operations.Any())
|
||||||
|
{
|
||||||
|
operations.Pop().Value?.RollBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
// result and operation are set to the last one that completed - so success if they all passed, or the first failure
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -225,22 +333,18 @@ namespace UIFixes
|
|||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
public static bool Prefix(SlotView __instance, ItemContextAbstractClass targetItemContext, ref Task __result)
|
public static bool Prefix(SlotView __instance, ItemContextAbstractClass targetItemContext, ref Task __result)
|
||||||
{
|
{
|
||||||
if (InPatch || !MultiSelect.Active)
|
if (!Settings.EnableMultiSelect.Value || InPatch || !MultiSelect.Active)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
InPatch = true;
|
InPatch = true;
|
||||||
/* __result = Task.CompletedTask;
|
|
||||||
foreach (ItemContextClass itemContext in MultiSelect.ItemContexts.ToList())
|
|
||||||
{
|
|
||||||
__result = __result.ContinueWith(_ => __instance.AcceptItem(itemContext, targetItemContext));
|
|
||||||
}*/
|
|
||||||
|
|
||||||
var serializer = __instance.GetOrAddComponent<TaskSerializer>();
|
var serializer = __instance.GetOrAddComponent<TaskSerializer>();
|
||||||
__result = serializer.Initialize(MultiSelect.ItemContexts, itemContext => __instance.AcceptItem(itemContext, targetItemContext));
|
__result = serializer.Initialize(MultiSelect.ItemContexts, itemContext => __instance.AcceptItem(itemContext, targetItemContext));
|
||||||
|
|
||||||
__result.ContinueWith(_ => { InPatch = false; });
|
__result.ContinueWith(_ => { InPatch = false; });
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,6 +358,7 @@ namespace UIFixes
|
|||||||
|
|
||||||
public Task Initialize(IEnumerable<ItemContextClass> itemContexts, Func<ItemContextClass, Task> func)
|
public Task Initialize(IEnumerable<ItemContextClass> itemContexts, Func<ItemContextClass, Task> func)
|
||||||
{
|
{
|
||||||
|
// Create new contexts because the underlying ones will be disposed when drag ends
|
||||||
this.itemContexts = new(itemContexts);
|
this.itemContexts = new(itemContexts);
|
||||||
this.func = func;
|
this.func = func;
|
||||||
|
|
||||||
@@ -283,31 +388,5 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public class GridViewAcceptItemPatch : ModulePatch
|
|
||||||
{
|
|
||||||
protected override MethodBase GetTargetMethod()
|
|
||||||
{
|
|
||||||
return AccessTools.Method(typeof(GridView), nameof(GridView.AcceptItem));
|
|
||||||
}
|
|
||||||
|
|
||||||
[PatchPrefix]
|
|
||||||
public static async bool Prefix(GridView __instance, ItemContextAbstractClass targetItemContext, ref Task __result)
|
|
||||||
{
|
|
||||||
if (InPatch || !MultiSelectContext.Instance.Any())
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
InPatch = true;
|
|
||||||
foreach (ItemContextClass itemContext in MultiSelectContext.Instance.SelectedDragContexts)
|
|
||||||
{
|
|
||||||
await __instance.AcceptItem(itemContext, targetItemContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
InPatch = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ namespace UIFixes
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!___bool_8 && ctrlPressed && tradingItemView.TraderAssortmentControler.QuickFindTradingAppropriatePlace(__instance.Item, null))
|
if (!___bool_8 && ctrlPressed && tradingItemView.TraderAssortmentController.QuickFindTradingAppropriatePlace(__instance.Item, null))
|
||||||
{
|
{
|
||||||
__instance.ItemContext.CloseDependentWindows();
|
__instance.ItemContext.CloseDependentWindows();
|
||||||
__instance.HideTooltip();
|
__instance.HideTooltip();
|
||||||
@@ -91,7 +91,7 @@ namespace UIFixes
|
|||||||
|
|
||||||
if (___bool_8)
|
if (___bool_8)
|
||||||
{
|
{
|
||||||
tradingItemView.TraderAssortmentControler.SelectItem(__instance.Item);
|
tradingItemView.TraderAssortmentController.SelectItem(__instance.Item);
|
||||||
|
|
||||||
BuyTab.OnPointerClick(null);
|
BuyTab.OnPointerClick(null);
|
||||||
|
|
||||||
|
|||||||
4
R.cs
4
R.cs
@@ -295,7 +295,7 @@ namespace UIFixes
|
|||||||
public static void InitTypes()
|
public static void InitTypes()
|
||||||
{
|
{
|
||||||
Type = typeof(EFT.UI.DragAndDrop.GridView);
|
Type = typeof(EFT.UI.DragAndDrop.GridView);
|
||||||
TraderControllerField = AccessTools.GetDeclaredFields(Type).Single(f => f.FieldType == typeof(TraderControllerClass));
|
TraderControllerField = AccessTools.GetDeclaredFields(Type).Single(f => f.FieldType == typeof(TraderControllerClass)); // field gclass2758_0
|
||||||
NonInteractableField = AccessTools.Field(Type, "_nonInteractable");
|
NonInteractableField = AccessTools.Field(Type, "_nonInteractable");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -562,7 +562,7 @@ namespace UIFixes
|
|||||||
TraderAssortmentControllerField = AccessTools.GetDeclaredFields(Type).Single(t => t.FieldType == typeof(TraderAssortmentControllerClass));
|
TraderAssortmentControllerField = AccessTools.GetDeclaredFields(Type).Single(t => t.FieldType == typeof(TraderAssortmentControllerClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
public TraderAssortmentControllerClass TraderAssortmentControler { get { return (TraderAssortmentControllerClass)TraderAssortmentControllerField.GetValue(Value); } }
|
public TraderAssortmentControllerClass TraderAssortmentController { get { return (TraderAssortmentControllerClass)TraderAssortmentControllerField.GetValue(Value); } }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GridWindow(object value) : UIInputNode(value)
|
public class GridWindow(object value) : UIInputNode(value)
|
||||||
|
|||||||
10
Settings.cs
10
Settings.cs
@@ -54,6 +54,7 @@ namespace UIFixes
|
|||||||
public static ConfigEntry<int> MouseScrollMultiInRaid { get; set; } // Advanced
|
public static ConfigEntry<int> MouseScrollMultiInRaid { get; set; } // Advanced
|
||||||
|
|
||||||
// Inventory
|
// Inventory
|
||||||
|
public static ConfigEntry<bool> EnableMultiSelect { get; set; }
|
||||||
public static ConfigEntry<bool> SwapItems { get; set; }
|
public static ConfigEntry<bool> SwapItems { get; set; }
|
||||||
public static ConfigEntry<bool> SwapImpossibleContainers { get; set; }
|
public static ConfigEntry<bool> SwapImpossibleContainers { get; set; }
|
||||||
public static ConfigEntry<bool> SynchronizeStashScrolling { get; set; }
|
public static ConfigEntry<bool> SynchronizeStashScrolling { get; set; }
|
||||||
@@ -272,6 +273,15 @@ namespace UIFixes
|
|||||||
new ConfigurationManagerAttributes { IsAdvanced = true })));
|
new ConfigurationManagerAttributes { IsAdvanced = true })));
|
||||||
|
|
||||||
// Inventory
|
// Inventory
|
||||||
|
configEntries.Add(EnableMultiSelect = config.Bind(
|
||||||
|
InventorySection,
|
||||||
|
"Enable Multiselect",
|
||||||
|
true,
|
||||||
|
new ConfigDescription(
|
||||||
|
"Enable multiselect via Shift-click and drag-to-select",
|
||||||
|
null,
|
||||||
|
new ConfigurationManagerAttributes { })));
|
||||||
|
|
||||||
configEntries.Add(SwapItems = config.Bind(
|
configEntries.Add(SwapItems = config.Bind(
|
||||||
InventorySection,
|
InventorySection,
|
||||||
"Enable In-Place Item Swapping",
|
"Enable In-Place Item Swapping",
|
||||||
|
|||||||
@@ -66,6 +66,9 @@
|
|||||||
<Reference Include="UnityEngine.UI">
|
<Reference Include="UnityEngine.UI">
|
||||||
<HintPath>$(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.UI.dll</HintPath>
|
<HintPath>$(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.UI.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.UIModule">
|
||||||
|
<HintPath>$(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.UIModule.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<PackageReference Include="BepInEx.Analyzers" Version="1.*" PrivateAssets="all" />
|
<PackageReference Include="BepInEx.Analyzers" Version="1.*" PrivateAssets="all" />
|
||||||
<PackageReference Include="BepInEx.Core" Version="5.*" />
|
<PackageReference Include="BepInEx.Core" Version="5.*" />
|
||||||
<PackageReference Include="BepInEx.PluginInfoProps" Version="1.*" />
|
<PackageReference Include="BepInEx.PluginInfoProps" Version="1.*" />
|
||||||
|
|||||||
Reference in New Issue
Block a user