multiselect debug, things seem good?

This commit is contained in:
Tyfon
2024-06-15 17:10:58 -07:00
parent 3c76f3c588
commit b562a8665d
6 changed files with 173 additions and 84 deletions

View File

@@ -17,6 +17,7 @@ namespace UIFixes
private Vector3 selectOrigin;
private Vector3 selectEnd;
private GraphicRaycaster localRaycaster;
private GraphicRaycaster preloaderRaycaster;
private bool drawing;
@@ -27,6 +28,12 @@ namespace UIFixes
selectTexture.SetPixel(0, 0, new Color(1f, 1f, 1f, 0.6f));
selectTexture.Apply();
localRaycaster = GetComponentInParent<GraphicRaycaster>();
if (localRaycaster == null)
{
throw new InvalidOperationException("DrawMultiSelect couldn't find GraphicRayCaster in parents");
}
preloaderRaycaster = Singleton<PreloaderUI>.Instance.transform.GetChild(0).GetComponent<GraphicRaycaster>();
if (preloaderRaycaster == null)
{
@@ -41,13 +48,16 @@ namespace UIFixes
return;
}
// checking ItemUiContext is a quick and easy way to know the mouse is over an item
if (Input.GetKeyDown(KeyCode.Mouse0) && ItemUiContext.Instance.R().ItemContext == null)
{
PointerEventData eventData = new(EventSystem.current);
eventData.position = Input.mousePosition;
PointerEventData eventData = new(EventSystem.current)
{
position = Input.mousePosition
};
List<RaycastResult> results = new();
var preloaderRaycaster = Singleton<PreloaderUI>.Instance.transform.GetChild(0).GetComponent<GraphicRaycaster>();
List<RaycastResult> results = [];
localRaycaster.Raycast(eventData, results);
preloaderRaycaster.Raycast(eventData, results);
foreach (GameObject gameObject in results.Select(r => r.gameObject))
@@ -86,7 +96,7 @@ namespace UIFixes
float width = itemRect.xMax - itemRect.xMin;
float height = itemRect.yMax - itemRect.yMin;
List<RaycastResult> raycastResults = new();
List<RaycastResult> raycastResults = [];
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))

View File

@@ -1,4 +1,5 @@
using EFT.UI.DragAndDrop;
using System;
using System.Collections.Generic;
using System.Linq;
using TMPro;
@@ -11,8 +12,8 @@ namespace UIFixes
private static GameObject SelectedMarkTemplate;
private static GameObject SelectedBackgroundTemplate;
private static readonly HashSet<GridItemView> SelectedItemViews = [];
private static readonly List<ItemContextClass> SelectedItemContexts = [];
private static readonly Dictionary<GridItemView, ItemContextClass> SelectedItemViews = [];
private static readonly List<ItemContextClass> SortedItemContexts = [];
public static void Initialize()
{
@@ -35,7 +36,7 @@ namespace UIFixes
return;
}
if (SelectedItemViews.Contains(itemView))
if (SelectedItemViews.ContainsKey(itemView))
{
Deselect(itemView);
}
@@ -48,7 +49,7 @@ namespace UIFixes
public static void Clear()
{
// ToList() because we'll be modifying the collection
foreach (GridItemView itemView in SelectedItemViews.ToList())
foreach (GridItemView itemView in SelectedItemViews.Keys.ToList())
{
Deselect(itemView);
}
@@ -56,28 +57,39 @@ namespace UIFixes
public static void Select(GridItemView itemView)
{
if (itemView.IsInteractable && SelectedItemViews.Add(itemView))
if (itemView.IsInteractable && !SelectedItemViews.ContainsKey(itemView))
{
ItemContextClass itemContext = new ItemContextClass(itemView.ItemContext, itemView.ItemRotation);
itemContext.GClass2813_0.OnDisposed += RugPull;
itemContext.OnDisposed += RugPull;
SelectedItemViews.Add(itemView, itemContext);
SortedItemContexts.Add(itemContext);
ShowSelection(itemView);
}
}
public static void Deselect(GridItemView itemView)
{
if (SelectedItemViews.Remove(itemView))
if (SelectedItemViews.TryGetValue(itemView, out ItemContextClass itemContext))
{
itemContext.GClass2813_0.OnDisposed -= RugPull;
itemContext.OnDisposed -= RugPull;
itemContext.Dispose();
SortedItemContexts.Remove(itemContext);
SelectedItemViews.Remove(itemView);
HideSelection(itemView);
}
}
public static IEnumerable<ItemView> ItemViews
public static bool IsSelected(GridItemView itemView)
{
get { return SelectedItemViews; }
return SelectedItemViews.ContainsKey(itemView);
}
public static IEnumerable<ItemContextClass> ItemContexts
{
get { return SelectedItemContexts; }
get { return SortedItemContexts; }
}
public static int Count
@@ -85,39 +97,11 @@ namespace UIFixes
get { return SelectedItemViews.Count; }
}
public static bool Contains(GridItemView itemView)
{
return SelectedItemViews.Contains(itemView);
}
public static bool Active
{
get { return SelectedItemViews.Count > 1; }
}
public static bool IsSelected(GridItemView itemView)
{
return SelectedItemViews.Contains(itemView);
}
public static void BeginDrag()
{
foreach (ItemView itemView in SelectedItemViews)
{
SelectedItemContexts.Add(new ItemContextClass(itemView.ItemContext, itemView.ItemRotation));
}
}
public static void EndDrag()
{
foreach(ItemContextClass itemContext in SelectedItemContexts)
{
itemContext.Dispose();
}
SelectedItemContexts.Clear();
}
public static void ShowDragCount(DraggedItemView draggedItemView)
{
if (Count > 1)
@@ -139,6 +123,11 @@ namespace UIFixes
}
}
private static void RugPull()
{
throw new InvalidOperationException("ItemContext disposed before MultiSelect was done with it!");
}
private static void ShowSelection(GridItemView itemView)
{
GameObject selectedMark = itemView.transform.Find("SelectedMark")?.gameObject;

50
MultiSelectDebug.cs Normal file
View File

@@ -0,0 +1,50 @@
using System.Text;
using UnityEngine;
namespace UIFixes
{
public class MultiSelectDebug : MonoBehaviour
{
private GUIStyle guiStyle;
private Rect guiRect = new(20, 20, 0, 0);
GUIContent guiContent;
public void OnGUI()
{
if (!Settings.EnableMultiSelect.Value || !Settings.ShowMultiSelectDebug.Value)
{
return;
}
guiStyle ??= new GUIStyle(GUI.skin.box)
{
alignment = TextAnchor.MiddleLeft,
fontSize = 14,
margin = new RectOffset(3, 3, 3, 3),
richText = true
};
guiContent ??= new GUIContent();
StringBuilder builder = new();
builder.Append("<b>MultiSelect</b>\n");
builder.AppendFormat("Active: <color={0}>{1}</color>\n", MultiSelect.Active ? "green" : "red", MultiSelect.Active);
builder.AppendFormat("Count: <color=yellow>{0}</color>\n", MultiSelect.Count);
builder.Append("Items:\n");
foreach (ItemContextClass itemContext in MultiSelect.ItemContexts)
{
builder.Append(itemContext.Item.ToString());
builder.AppendLine();
}
guiContent.text = builder.ToString();
guiRect.size = guiStyle.CalcSize(guiContent);
GUI.Box(guiRect, guiContent, guiStyle);
}
}
}

View File

@@ -1,4 +1,5 @@
using Aki.Reflection.Patching;
using Comfort.Common;
using EFT.InventoryLogic;
using EFT.UI;
using EFT.UI.DragAndDrop;
@@ -23,14 +24,15 @@ namespace UIFixes
new InitializePatch().Enable();
new SelectPatch().Enable();
new DeselectOnOtherMouseDown().Enable();
new DeselectOnMovePatch().Enable();
new DeselectOnItemViewKillPatch().Enable();
new BeginDragPatch().Enable();
new EndDragPatch().Enable();
new GridViewCanAcceptPatch().Enable();
new GridViewAcceptItemPatch().Enable();
new SlotViewCanAcceptPatch().Enable();
new SlotViewAcceptItemPatch().Enable();
new InspectWindowHack().Enable();
}
public class InitializePatch : ModulePatch
@@ -50,9 +52,14 @@ namespace UIFixes
MultiSelect.Initialize();
__instance.InventoryScreen.GetOrAddComponent<DrawMultiSelect>();
__instance.InventoryScreen.transform.Find("Items Panel").gameObject.GetOrAddComponent<DrawMultiSelect>();
__instance.TransferItemsInRaidScreen.GetOrAddComponent<DrawMultiSelect>();
__instance.TransferItemsScreen.GetOrAddComponent<DrawMultiSelect>();
if (Settings.ShowMultiSelectDebug.Value)
{
Singleton<PreloaderUI>.Instance.GetOrAddComponent<MultiSelectDebug>();
}
}
}
@@ -112,15 +119,15 @@ namespace UIFixes
}
}
public class DeselectOnMovePatch : ModulePatch
public class DeselectOnItemViewKillPatch : ModulePatch
{
protected override MethodBase GetTargetMethod()
{
return AccessTools.Method(typeof(ItemView), nameof(ItemView.Kill));
}
[PatchPostfix]
public static void Postfix(ItemView __instance)
[PatchPrefix]
public static void Prefix(ItemView __instance)
{
if (!Settings.EnableMultiSelect.Value)
{
@@ -141,17 +148,6 @@ namespace UIFixes
return AccessTools.Method(typeof(ItemView), nameof(ItemView.OnBeginDrag));
}
[PatchPrefix]
public static void Prefix()
{
if (!Settings.EnableMultiSelect.Value)
{
return;
}
MultiSelect.BeginDrag();
}
[PatchPostfix]
public static void Postfix(ItemView __instance)
{
@@ -164,25 +160,6 @@ namespace UIFixes
}
}
public class EndDragPatch : ModulePatch
{
protected override MethodBase GetTargetMethod()
{
return AccessTools.Method(typeof(ItemView), nameof(ItemView.OnEndDrag));
}
[PatchPostfix]
public static void Postfix()
{
if (!Settings.EnableMultiSelect.Value)
{
return;
}
MultiSelect.EndDrag();
}
}
public class GridViewCanAcceptPatch : ModulePatch
{
protected override MethodBase GetTargetMethod()
@@ -291,7 +268,7 @@ namespace UIFixes
// Reimplementing this in order to control the simulate param. Need to *not* simulate, then rollback myself in order to test
// multiple items going in
if (targetItemContext != null && !targetItemContext.ModificationAvailable ||
if (targetItemContext != null && !targetItemContext.ModificationAvailable ||
__instance.ParentItemContext != null && !__instance.ParentItemContext.ModificationAvailable)
{
operation = new StashGridClass.GClass3291(__instance.Slot);
@@ -313,7 +290,7 @@ namespace UIFixes
}
// We didn't simulate so now we undo
while(operations.Any())
while (operations.Any())
{
operations.Pop().Value?.RollBack();
}
@@ -349,6 +326,29 @@ namespace UIFixes
}
}
// The inspect window likes to recreate itself entirely when a slot is removed, which destroys all of the gridviews and
// borks the multiselect. This patch just stops it from responding until the last one (since by then the selection is down to 1, which
// is considered inactive multiselect)
public class InspectWindowHack : ModulePatch
{
protected override MethodBase GetTargetMethod()
{
return AccessTools.Method(typeof(ItemSpecificationPanel), nameof(ItemSpecificationPanel.OnRemoveFromSlotEvent));
}
[PatchPrefix]
public static bool Prefix()
{
if (!Settings.EnableMultiSelect.Value || !MultiSelect.Active)
{
return true;
}
// Just skip it when multiselect is active
return false;
}
}
public class TaskSerializer : MonoBehaviour
{
private Func<ItemContextClass, Task> func;
@@ -375,7 +375,7 @@ namespace UIFixes
{
return;
}
if (itemContexts.Any())
{
currentTask = func(itemContexts.Dequeue());

View File

@@ -55,6 +55,7 @@ namespace UIFixes
// Inventory
public static ConfigEntry<bool> EnableMultiSelect { get; set; }
public static ConfigEntry<bool> ShowMultiSelectDebug { get; set; } // Advanced
public static ConfigEntry<bool> SwapItems { get; set; }
public static ConfigEntry<bool> SwapImpossibleContainers { get; set; }
public static ConfigEntry<bool> SynchronizeStashScrolling { get; set; }
@@ -278,10 +279,19 @@ namespace UIFixes
"Enable Multiselect",
true,
new ConfigDescription(
"Enable multiselect via Shift-click and drag-to-select",
"Enable multiselect via Shift-click and drag-to-select. This cannot be used together with Auto-open Sorting Table",
null,
new ConfigurationManagerAttributes { })));
configEntries.Add(ShowMultiSelectDebug = config.Bind(
InventorySection,
"Show Multiselect Debug",
false,
new ConfigDescription(
"Enable multi-select debugging display",
null,
new ConfigurationManagerAttributes { IsAdvanced = true })));
configEntries.Add(SwapItems = config.Bind(
InventorySection,
"Enable In-Place Item Swapping",
@@ -339,9 +349,9 @@ namespace UIFixes
configEntries.Add(AutoOpenSortingTable = config.Bind(
InventorySection,
"Auto-open Sorting Table",
true,
false,
new ConfigDescription(
"Automatically open the sorting table if it's closed when you shift-click an item",
"Automatically open the sorting table if it's closed when you shift-click an item. This and Enable Multiselect cannot be used together.",
null,
new ConfigurationManagerAttributes { })));
@@ -502,7 +512,10 @@ namespace UIFixes
new ConfigurationManagerAttributes { IsAdvanced = true })));
RecalcOrder(configEntries);
ToggleExclusives();
}
private static void RecalcOrder(List<ConfigEntryBase> configEntries)
{
// Set the Order field for all settings, to avoid unnecessary changes when adding new settings
@@ -517,5 +530,29 @@ namespace UIFixes
settingOrder--;
}
}
private static void ToggleExclusives()
{
if (Settings.EnableMultiSelect.Value)
{
Settings.AutoOpenSortingTable.Value = false;
}
Settings.EnableMultiSelect.SettingChanged += (_, _) =>
{
if (Settings.EnableMultiSelect.Value)
{
Settings.AutoOpenSortingTable.Value = false;
}
};
Settings.AutoOpenSortingTable.SettingChanged += (_, _) =>
{
if (Settings.AutoOpenSortingTable.Value)
{
Settings.EnableMultiSelect.Value = false;
}
};
}
}
}

View File

@@ -63,6 +63,9 @@
<Reference Include="UnityEngine.InputLegacyModule">
<HintPath>$(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.InputLegacyModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.TextRenderingModule">
<HintPath>..\..\..\..\SPT\3.8.3-debug\EscapeFromTarkov_Data\Managed\UnityEngine.TextRenderingModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.UI">
<HintPath>$(PathToSPT)\EscapeFromTarkov_Data\Managed\UnityEngine.UI.dll</HintPath>
</Reference>