multiselect debug, things seem good?
This commit is contained in:
@@ -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))
|
||||
|
@@ -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
50
MultiSelectDebug.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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()
|
||||
@@ -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;
|
||||
|
43
Settings.cs
43
Settings.cs
@@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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>
|
||||
|
Reference in New Issue
Block a user