trading view, lots of fixes
This commit is contained in:
@@ -21,6 +21,7 @@ namespace UIFixes
|
|||||||
private GraphicRaycaster preloaderRaycaster;
|
private GraphicRaycaster preloaderRaycaster;
|
||||||
|
|
||||||
private bool drawing;
|
private bool drawing;
|
||||||
|
private bool secondary;
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
@@ -75,6 +76,7 @@ namespace UIFixes
|
|||||||
|
|
||||||
selectOrigin = Input.mousePosition;
|
selectOrigin = Input.mousePosition;
|
||||||
drawing = true;
|
drawing = true;
|
||||||
|
secondary = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drawing)
|
if (drawing)
|
||||||
@@ -101,7 +103,7 @@ namespace UIFixes
|
|||||||
preloaderRaycaster.Raycast(eventData, raycastResults);
|
preloaderRaycaster.Raycast(eventData, raycastResults);
|
||||||
if (raycastResults.Any() && !raycastResults[0].gameObject.transform.IsDescendantOf(itemTransform))
|
if (raycastResults.Any() && !raycastResults[0].gameObject.transform.IsDescendantOf(itemTransform))
|
||||||
{
|
{
|
||||||
MultiSelect.Deselect(gridItemView);
|
MultiSelect.Deselect(gridItemView, secondary);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +112,7 @@ namespace UIFixes
|
|||||||
preloaderRaycaster.Raycast(eventData, raycastResults);
|
preloaderRaycaster.Raycast(eventData, raycastResults);
|
||||||
if (raycastResults.Any() && !raycastResults[0].gameObject.transform.IsDescendantOf(itemTransform))
|
if (raycastResults.Any() && !raycastResults[0].gameObject.transform.IsDescendantOf(itemTransform))
|
||||||
{
|
{
|
||||||
MultiSelect.Deselect(gridItemView);
|
MultiSelect.Deselect(gridItemView, secondary);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +121,7 @@ namespace UIFixes
|
|||||||
preloaderRaycaster.Raycast(eventData, raycastResults);
|
preloaderRaycaster.Raycast(eventData, raycastResults);
|
||||||
if (raycastResults.Any() && !raycastResults[0].gameObject.transform.IsDescendantOf(itemTransform))
|
if (raycastResults.Any() && !raycastResults[0].gameObject.transform.IsDescendantOf(itemTransform))
|
||||||
{
|
{
|
||||||
MultiSelect.Deselect(gridItemView);
|
MultiSelect.Deselect(gridItemView, secondary);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,21 +130,26 @@ namespace UIFixes
|
|||||||
preloaderRaycaster.Raycast(eventData, raycastResults);
|
preloaderRaycaster.Raycast(eventData, raycastResults);
|
||||||
if (raycastResults.Any() && !raycastResults[0].gameObject.transform.IsDescendantOf(itemTransform))
|
if (raycastResults.Any() && !raycastResults[0].gameObject.transform.IsDescendantOf(itemTransform))
|
||||||
{
|
{
|
||||||
MultiSelect.Deselect(gridItemView);
|
MultiSelect.Deselect(gridItemView, secondary);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiSelect.Select(gridItemView);
|
MultiSelect.Select(gridItemView, secondary);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiSelect.Deselect(gridItemView);
|
MultiSelect.Deselect(gridItemView, secondary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drawing && !Input.GetKey(KeyCode.Mouse0))
|
if (drawing && !Input.GetKey(KeyCode.Mouse0))
|
||||||
{
|
{
|
||||||
drawing = false;
|
drawing = false;
|
||||||
|
if (secondary)
|
||||||
|
{
|
||||||
|
MultiSelect.CombineSecondary();
|
||||||
|
secondary = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,6 +15,9 @@ namespace UIFixes
|
|||||||
private static readonly Dictionary<GridItemView, ItemContextClass> SelectedItemViews = [];
|
private static readonly Dictionary<GridItemView, ItemContextClass> SelectedItemViews = [];
|
||||||
private static readonly List<ItemContextClass> SortedItemContexts = [];
|
private static readonly List<ItemContextClass> SortedItemContexts = [];
|
||||||
|
|
||||||
|
private static readonly Dictionary<GridItemView, ItemContextClass> SecondaryItemViews = [];
|
||||||
|
private static readonly List<ItemContextClass> SecondaryItemContexts = [];
|
||||||
|
|
||||||
public static void Initialize()
|
public static void Initialize()
|
||||||
{
|
{
|
||||||
// Grab the selection objects from ragfair as templates
|
// Grab the selection objects from ragfair as templates
|
||||||
@@ -29,15 +32,16 @@ namespace UIFixes
|
|||||||
ragfairNewOfferItemView.ReturnToPool();
|
ragfairNewOfferItemView.ReturnToPool();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Toggle(GridItemView itemView)
|
public static void Toggle(GridItemView itemView, bool secondary = false)
|
||||||
{
|
{
|
||||||
if (SelectedItemViews.ContainsKey(itemView))
|
var dictionary = secondary ? SecondaryItemViews : SelectedItemViews;
|
||||||
|
if (dictionary.ContainsKey(itemView))
|
||||||
{
|
{
|
||||||
Deselect(itemView);
|
Deselect(itemView, secondary);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Select(itemView);
|
Select(itemView, secondary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,29 +54,38 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Select(GridItemView itemView)
|
public static void Select(GridItemView itemView, bool secondary = false)
|
||||||
{
|
{
|
||||||
if (itemView.IsSelectable() && !SelectedItemViews.ContainsKey(itemView))
|
var dictionary = secondary ? SecondaryItemViews : SelectedItemViews;
|
||||||
|
var list = secondary ? SecondaryItemContexts : SortedItemContexts;
|
||||||
|
|
||||||
|
if (itemView.IsSelectable() && !SelectedItemViews.ContainsKey(itemView) && !SecondaryItemViews.ContainsKey(itemView))
|
||||||
{
|
{
|
||||||
ItemContextClass itemContext = new(itemView.ItemContext, itemView.ItemRotation);
|
ItemContextClass itemContext = new(itemView.ItemContext, itemView.ItemRotation);
|
||||||
itemContext.GClass2813_0.OnDisposed += RugPull;
|
itemContext.GClass2813_0.OnDisposed += RugPull;
|
||||||
itemContext.OnDisposed += RugPull;
|
itemContext.OnDisposed += RugPull;
|
||||||
|
|
||||||
SelectedItemViews.Add(itemView, itemContext);
|
// Remove event handlers that no one cares about and cause stack overflows
|
||||||
SortedItemContexts.Add(itemContext);
|
itemContext.method_1();
|
||||||
|
|
||||||
|
dictionary.Add(itemView, itemContext);
|
||||||
|
list.Add(itemContext);
|
||||||
ShowSelection(itemView);
|
ShowSelection(itemView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Deselect(GridItemView itemView)
|
public static void Deselect(GridItemView itemView, bool secondary = false)
|
||||||
{
|
{
|
||||||
if (SelectedItemViews.TryGetValue(itemView, out ItemContextClass itemContext))
|
var dictionary = secondary ? SecondaryItemViews : SelectedItemViews;
|
||||||
|
var list = secondary ? SecondaryItemContexts : SortedItemContexts;
|
||||||
|
|
||||||
|
if (dictionary.TryGetValue(itemView, out ItemContextClass itemContext))
|
||||||
{
|
{
|
||||||
itemContext.GClass2813_0.OnDisposed -= RugPull;
|
itemContext.GClass2813_0.OnDisposed -= RugPull;
|
||||||
itemContext.OnDisposed -= RugPull;
|
itemContext.OnDisposed -= RugPull;
|
||||||
itemContext.Dispose();
|
itemContext.Dispose();
|
||||||
SortedItemContexts.Remove(itemContext);
|
list.Remove(itemContext);
|
||||||
SelectedItemViews.Remove(itemView);
|
dictionary.Remove(itemView);
|
||||||
HideSelection(itemView);
|
HideSelection(itemView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,16 +95,42 @@ namespace UIFixes
|
|||||||
return SelectedItemViews.ContainsKey(itemView);
|
return SelectedItemViews.ContainsKey(itemView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void CombineSecondary()
|
||||||
|
{
|
||||||
|
foreach (var entry in SecondaryItemViews)
|
||||||
|
{
|
||||||
|
SelectedItemViews.Add(entry.Key, entry.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (ItemContextClass itemContext in SecondaryItemContexts)
|
||||||
|
{
|
||||||
|
SortedItemContexts.Add(itemContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondaryItemViews.Clear();
|
||||||
|
SecondaryItemContexts.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
public static IEnumerable<ItemContextClass> ItemContexts
|
public static IEnumerable<ItemContextClass> ItemContexts
|
||||||
{
|
{
|
||||||
get { return SortedItemContexts; }
|
get { return SortedItemContexts; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<ItemContextClass> SecondaryContexts
|
||||||
|
{
|
||||||
|
get { return SecondaryItemContexts; }
|
||||||
|
}
|
||||||
|
|
||||||
public static int Count
|
public static int Count
|
||||||
{
|
{
|
||||||
get { return SelectedItemViews.Count; }
|
get { return SelectedItemViews.Count; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int SecondaryCount
|
||||||
|
{
|
||||||
|
get { return SecondaryItemViews.Count; }
|
||||||
|
}
|
||||||
|
|
||||||
public static bool Active
|
public static bool Active
|
||||||
{
|
{
|
||||||
get { return SelectedItemViews.Count > 1; }
|
get { return SelectedItemViews.Count > 1; }
|
||||||
@@ -159,7 +198,22 @@ namespace UIFixes
|
|||||||
{
|
{
|
||||||
public static bool IsSelectable(this ItemView itemView)
|
public static bool IsSelectable(this ItemView itemView)
|
||||||
{
|
{
|
||||||
return itemView.IsInteractable && itemView.IsSearched && itemView.RemoveError.Value == null;
|
// Common non-interactable stuff
|
||||||
|
if (!itemView.IsInteractable || !itemView.IsSearched || itemView.RemoveError.Value != null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// You can't multi-select trader's items or items being sold
|
||||||
|
if (itemView is TradingItemView tradingItemView)
|
||||||
|
{
|
||||||
|
if (itemView is not TradingPlayerItemView || tradingItemView.R().IsBeingSold)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
using System.Text;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace UIFixes
|
namespace UIFixes
|
||||||
@@ -31,8 +32,7 @@ namespace UIFixes
|
|||||||
|
|
||||||
builder.Append("<b>MultiSelect</b>\n");
|
builder.Append("<b>MultiSelect</b>\n");
|
||||||
builder.AppendFormat("Active: <color={0}>{1}</color>\n", MultiSelect.Active ? "green" : "red", MultiSelect.Active);
|
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.AppendFormat("Items: <color=yellow>{0}</color>\n", MultiSelect.Count);
|
||||||
builder.Append("Items:\n");
|
|
||||||
|
|
||||||
foreach (ItemContextClass itemContext in MultiSelect.ItemContexts)
|
foreach (ItemContextClass itemContext in MultiSelect.ItemContexts)
|
||||||
{
|
{
|
||||||
@@ -40,6 +40,16 @@ namespace UIFixes
|
|||||||
builder.AppendLine();
|
builder.AppendLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MultiSelect.SecondaryContexts.Any())
|
||||||
|
{
|
||||||
|
builder.AppendFormat("Secondary Items: <color=yellow>{0}</color>\n", MultiSelect.SecondaryCount);
|
||||||
|
foreach (ItemContextClass itemContext in MultiSelect.SecondaryContexts)
|
||||||
|
{
|
||||||
|
builder.Append(itemContext.Item.ToString());
|
||||||
|
builder.AppendLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
guiContent.text = builder.ToString();
|
guiContent.text = builder.ToString();
|
||||||
|
|
||||||
guiRect.size = guiStyle.CalcSize(guiContent);
|
guiRect.size = guiStyle.CalcSize(guiContent);
|
||||||
|
@@ -21,31 +21,36 @@ namespace UIFixes
|
|||||||
private static bool InPatch = false;
|
private static bool InPatch = false;
|
||||||
|
|
||||||
// If the can accept method should render highlights
|
// If the can accept method should render highlights
|
||||||
private static bool ShowHighlights = false;
|
|
||||||
private static readonly List<Image> HighlightPanels = [];
|
private static readonly List<Image> HighlightPanels = [];
|
||||||
|
|
||||||
public static void Enable()
|
public static void Enable()
|
||||||
{
|
{
|
||||||
new InitializePatch().Enable();
|
new InitializeCommonUIPatch().Enable();
|
||||||
new SelectPatch().Enable();
|
new InitializeMenuUIPatch().Enable();
|
||||||
new DeselectOnOtherMouseDown().Enable();
|
new SelectOnMouseDownPatch().Enable();
|
||||||
|
new DeselectOnGridItemViewClickPatch().Enable();
|
||||||
|
new DeselectOnTradingItemViewClickPatch().Enable();
|
||||||
new DeselectOnItemViewKillPatch().Enable();
|
new DeselectOnItemViewKillPatch().Enable();
|
||||||
new BeginDragPatch().Enable();
|
new BeginDragPatch().Enable();
|
||||||
new EndDragPatch().Enable();
|
new EndDragPatch().Enable();
|
||||||
new InspectWindowHack().Enable();
|
new InspectWindowHack().Enable();
|
||||||
|
new DisableSplitPatch().Enable();
|
||||||
|
new DisableSplitTargetPatch().Enable();
|
||||||
|
|
||||||
new GridViewCanAcceptPatch().Enable();
|
new GridViewCanAcceptPatch().Enable();
|
||||||
new GridViewAcceptItemPatch().Enable();
|
new GridViewAcceptItemPatch().Enable();
|
||||||
new GridViewPickTargetPatch().Enable();
|
new GridViewPickTargetPatch().Enable();
|
||||||
new GridViewHighlightPatch().Enable();
|
|
||||||
new GridViewDisableHighlightPatch().Enable();
|
new GridViewDisableHighlightPatch().Enable();
|
||||||
|
|
||||||
new SlotViewCanAcceptPatch().Enable();
|
new SlotViewCanAcceptPatch().Enable();
|
||||||
new SlotViewAcceptItemPatch().Enable();
|
new SlotViewAcceptItemPatch().Enable();
|
||||||
|
|
||||||
|
new TradingTableCanAcceptPatch().Enable();
|
||||||
|
new TradingTableAcceptItemPatch().Enable();
|
||||||
|
new TradingTableGetHighlightColorPatch().Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class InitializePatch : ModulePatch
|
public class InitializeCommonUIPatch : ModulePatch
|
||||||
{
|
{
|
||||||
protected override MethodBase GetTargetMethod()
|
protected override MethodBase GetTargetMethod()
|
||||||
{
|
{
|
||||||
@@ -73,35 +78,26 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SelectPatch : ModulePatch
|
public class InitializeMenuUIPatch : ModulePatch
|
||||||
{
|
{
|
||||||
protected override MethodBase GetTargetMethod()
|
protected override MethodBase GetTargetMethod()
|
||||||
{
|
{
|
||||||
return AccessTools.Method(typeof(GridItemView), nameof(GridItemView.OnClick));
|
return AccessTools.Method(typeof(MenuUI), nameof(MenuUI.Awake));
|
||||||
}
|
}
|
||||||
|
|
||||||
[PatchPostfix]
|
[PatchPostfix]
|
||||||
public static void Postfix(GridItemView __instance, PointerEventData.InputButton button)
|
public static void Postfix(MenuUI __instance)
|
||||||
{
|
{
|
||||||
if (!Settings.EnableMultiSelect.Value)
|
if (!Settings.EnableMultiSelect.Value)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__instance.Item != null && button == PointerEventData.InputButton.Left && (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)))
|
__instance.TraderScreensGroup.transform.Find("Deal Screen").gameObject.GetOrAddComponent<DrawMultiSelect>();
|
||||||
{
|
|
||||||
MultiSelect.Toggle(__instance);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (button == PointerEventData.InputButton.Left)
|
|
||||||
{
|
|
||||||
MultiSelect.Clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DeselectOnOtherMouseDown : ModulePatch
|
public class SelectOnMouseDownPatch : ModulePatch
|
||||||
{
|
{
|
||||||
protected override MethodBase GetTargetMethod()
|
protected override MethodBase GetTargetMethod()
|
||||||
{
|
{
|
||||||
@@ -116,13 +112,60 @@ namespace UIFixes
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eventData.button == PointerEventData.InputButton.Left && (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)))
|
if (__instance is GridItemView gridItemView && eventData.button == PointerEventData.InputButton.Left && (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)))
|
||||||
{
|
{
|
||||||
// This will be shift-click, let it cook
|
MultiSelect.Toggle(gridItemView);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__instance is not GridItemView gridItemView || !MultiSelect.IsSelected(gridItemView))
|
if (__instance is not GridItemView gridItemView2 || !MultiSelect.IsSelected(gridItemView2))
|
||||||
|
{
|
||||||
|
MultiSelect.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DeselectOnGridItemViewClickPatch : ModulePatch
|
||||||
|
{
|
||||||
|
protected override MethodBase GetTargetMethod()
|
||||||
|
{
|
||||||
|
return AccessTools.Method(typeof(GridItemView), nameof(GridItemView.OnClick));
|
||||||
|
}
|
||||||
|
|
||||||
|
[PatchPostfix]
|
||||||
|
public static void Postfix(GridItemView __instance, PointerEventData.InputButton button)
|
||||||
|
{
|
||||||
|
if (!Settings.EnableMultiSelect.Value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mousedown handles most things, just need to handle the non-shift click of a selected item
|
||||||
|
if (button == PointerEventData.InputButton.Left && !Input.GetKey(KeyCode.LeftShift) && !Input.GetKey(KeyCode.RightShift))
|
||||||
|
{
|
||||||
|
MultiSelect.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TradingItemView overrides GridItemView.OnClick and doesn't call base
|
||||||
|
public class DeselectOnTradingItemViewClickPatch : ModulePatch
|
||||||
|
{
|
||||||
|
protected override MethodBase GetTargetMethod()
|
||||||
|
{
|
||||||
|
return AccessTools.Method(typeof(TradingItemView), nameof(TradingItemView.OnClick));
|
||||||
|
}
|
||||||
|
|
||||||
|
[PatchPostfix]
|
||||||
|
public static void Postfix(TradingItemView __instance, PointerEventData.InputButton button)
|
||||||
|
{
|
||||||
|
if (!Settings.EnableMultiSelect.Value || __instance is not TradingPlayerItemView)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mousedown handles most things, just need to handle the non-shift click of a selected item
|
||||||
|
if (button == PointerEventData.InputButton.Left && !Input.GetKey(KeyCode.LeftShift) && !Input.GetKey(KeyCode.RightShift))
|
||||||
{
|
{
|
||||||
MultiSelect.Clear();
|
MultiSelect.Clear();
|
||||||
}
|
}
|
||||||
@@ -263,7 +306,7 @@ namespace UIFixes
|
|||||||
operations.Push(operation);
|
operations.Push(operation);
|
||||||
if (targetItem != null && showHighlights) // targetItem was originally null so this is the rest of the items
|
if (targetItem != null && showHighlights) // targetItem was originally null so this is the rest of the items
|
||||||
{
|
{
|
||||||
ShowHighlight(__instance, operation);
|
ShowHighlight(__instance, selectedItemContext, operation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -315,7 +358,8 @@ namespace UIFixes
|
|||||||
// Setting the fallback after initializing means it only applies after the first item is already moved
|
// Setting the fallback after initializing means it only applies after the first item is already moved
|
||||||
GridViewPickTargetPatch.FallbackResult = __instance.Grid.ParentItem;
|
GridViewPickTargetPatch.FallbackResult = __instance.Grid.ParentItem;
|
||||||
|
|
||||||
__result.ContinueWith(_ => {
|
__result.ContinueWith(_ =>
|
||||||
|
{
|
||||||
InPatch = false;
|
InPatch = false;
|
||||||
GridViewPickTargetPatch.FallbackResult = null;
|
GridViewPickTargetPatch.FallbackResult = null;
|
||||||
});
|
});
|
||||||
@@ -340,38 +384,7 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GridViewHighlightPatch : ModulePatch
|
private static void ShowHighlight(GridView gridView, ItemContextClass itemContext, GStruct413 operation)
|
||||||
{
|
|
||||||
protected override MethodBase GetTargetMethod()
|
|
||||||
{
|
|
||||||
return AccessTools.Method(typeof(GridView), nameof(GridView.HighlightItemViewPosition));
|
|
||||||
}
|
|
||||||
|
|
||||||
[PatchPrefix]
|
|
||||||
public static void Prefix(ItemContextAbstractClass targetItemContext)
|
|
||||||
{
|
|
||||||
if (!Settings.EnableMultiSelect.Value || !MultiSelect.Active || targetItemContext != null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ShowHighlights = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
[PatchPostfix]
|
|
||||||
public static void Postfix(GridView __instance, ItemContextClass itemContext, ItemContextAbstractClass targetItemContext, Image ____highlightPanel)
|
|
||||||
{
|
|
||||||
if (!Settings.EnableMultiSelect.Value || !MultiSelect.Active || targetItemContext != null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ShowHighlights = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ShowHighlight(GridView gridView, GStruct413 operation)
|
|
||||||
{
|
{
|
||||||
if (operation.Value is not GClass2786 moveOperation || moveOperation.To is not GClass2769 gridAddress)
|
if (operation.Value is not GClass2786 moveOperation || moveOperation.To is not GClass2769 gridAddress)
|
||||||
{
|
{
|
||||||
@@ -383,7 +396,7 @@ namespace UIFixes
|
|||||||
GridView otherGridView = gridView.transform.parent.GetComponentsInChildren<GridView>().FirstOrDefault(gv => gv.Grid == gridAddress.Grid);
|
GridView otherGridView = gridView.transform.parent.GetComponentsInChildren<GridView>().FirstOrDefault(gv => gv.Grid == gridAddress.Grid);
|
||||||
if (otherGridView != null)
|
if (otherGridView != null)
|
||||||
{
|
{
|
||||||
ShowHighlight(otherGridView, operation);
|
ShowHighlight(otherGridView, itemContext, operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -393,7 +406,7 @@ namespace UIFixes
|
|||||||
Image highLightPanel = UnityEngine.Object.Instantiate(gridView.R().HighlightPanel, gridView.transform, false);
|
Image highLightPanel = UnityEngine.Object.Instantiate(gridView.R().HighlightPanel, gridView.transform, false);
|
||||||
highLightPanel.gameObject.SetActive(true);
|
highLightPanel.gameObject.SetActive(true);
|
||||||
HighlightPanels.Add(highLightPanel);
|
HighlightPanels.Add(highLightPanel);
|
||||||
highLightPanel.color = gridView.GetHighlightColor(null, operation, null); // 1st and 3rd args aren't even used
|
highLightPanel.color = gridView.GetHighlightColor(itemContext, operation, null);
|
||||||
|
|
||||||
RectTransform rectTransform = highLightPanel.rectTransform;
|
RectTransform rectTransform = highLightPanel.rectTransform;
|
||||||
rectTransform.localScale = Vector3.one;
|
rectTransform.localScale = Vector3.one;
|
||||||
@@ -420,8 +433,7 @@ namespace UIFixes
|
|||||||
{
|
{
|
||||||
foreach (Image highLightPanel in HighlightPanels)
|
foreach (Image highLightPanel in HighlightPanels)
|
||||||
{
|
{
|
||||||
highLightPanel.gameObject.SetActive(false);
|
UnityEngine.Object.Destroy(highLightPanel.gameObject);
|
||||||
UnityEngine.Object.Destroy(highLightPanel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HighlightPanels.Clear();
|
HighlightPanels.Clear();
|
||||||
@@ -516,6 +528,144 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class TradingTableCanAcceptPatch : ModulePatch
|
||||||
|
{
|
||||||
|
protected override MethodBase GetTargetMethod()
|
||||||
|
{
|
||||||
|
return AccessTools.Method(typeof(TradingTableGridView), nameof(TradingTableGridView.CanAccept));
|
||||||
|
}
|
||||||
|
|
||||||
|
[PatchPrefix]
|
||||||
|
public static bool Prefix(TradingTableGridView __instance, ItemContextClass itemContext, ItemContextAbstractClass targetItemContext, ref GStruct413 operation, ref bool __result)
|
||||||
|
{
|
||||||
|
if (!Settings.EnableMultiSelect.Value || !MultiSelect.Active)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
operation = default;
|
||||||
|
__result = false;
|
||||||
|
|
||||||
|
TraderAssortmentControllerClass traderAssortmentController = __instance.R().TraderAssortmentController;
|
||||||
|
|
||||||
|
HideHighlights();
|
||||||
|
|
||||||
|
bool firstItem = true;
|
||||||
|
|
||||||
|
Stack<GStruct413> operations = new();
|
||||||
|
IEnumerable<ItemContextClass> itemContexts = MultiSelect.ItemContexts.Where(ic => ic.Item != itemContext.Item).Prepend(itemContext);
|
||||||
|
foreach (ItemContextClass selectedItemContext in itemContexts)
|
||||||
|
{
|
||||||
|
if (traderAssortmentController.CanPrepareItemToSell(selectedItemContext.Item))
|
||||||
|
{
|
||||||
|
operation = firstItem ?
|
||||||
|
InteractionsHandlerClass.Move(selectedItemContext.Item, new GClass2769(__instance.Grid, __instance.CalculateItemLocation(selectedItemContext)), traderAssortmentController.TraderController, false) :
|
||||||
|
InteractionsHandlerClass.QuickFindAppropriatePlace(selectedItemContext.Item, traderAssortmentController.TraderController, [__instance.Grid.ParentItem as LootItemClass], InteractionsHandlerClass.EMoveItemOrder.Apply, false);
|
||||||
|
|
||||||
|
if (__result = operation.Succeeded)
|
||||||
|
{
|
||||||
|
operations.Push(operation);
|
||||||
|
if (!firstItem) // targetItem was originally null so this is the rest of the items
|
||||||
|
{
|
||||||
|
ShowHighlight(__instance, selectedItemContext, operation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
operation = default;
|
||||||
|
__result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
firstItem = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We didn't simulate so now we undo
|
||||||
|
while (operations.Any())
|
||||||
|
{
|
||||||
|
operations.Pop().Value?.RollBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TradingTableAcceptItemPatch : ModulePatch
|
||||||
|
{
|
||||||
|
protected override MethodBase GetTargetMethod()
|
||||||
|
{
|
||||||
|
return AccessTools.Method(typeof(TradingTableGridView), nameof(TradingTableGridView.AcceptItem));
|
||||||
|
}
|
||||||
|
|
||||||
|
[PatchPrefix]
|
||||||
|
public static bool Prefix(TradingTableGridView __instance, ItemContextClass itemContext, ItemContextAbstractClass targetItemContext, ref Task __result)
|
||||||
|
{
|
||||||
|
if (!Settings.EnableMultiSelect.Value || !MultiSelect.Active)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TraderAssortmentControllerClass traderAssortmentController = __instance.R().TraderAssortmentController;
|
||||||
|
|
||||||
|
LocationInGrid locationInGrid = __instance.CalculateItemLocation(itemContext);
|
||||||
|
itemContext.DragCancelled();
|
||||||
|
traderAssortmentController.PrepareToSell(itemContext.Item, locationInGrid);
|
||||||
|
itemContext.CloseDependentWindows();
|
||||||
|
|
||||||
|
// For the rest of the items we still need to use quickfind
|
||||||
|
foreach (ItemContextClass selectedItemContext in MultiSelect.ItemContexts.Where(ic => ic.Item != itemContext.Item))
|
||||||
|
{
|
||||||
|
GStruct413 operation = InteractionsHandlerClass.QuickFindAppropriatePlace(selectedItemContext.Item, traderAssortmentController.TraderController, [__instance.Grid.ParentItem as LootItemClass], InteractionsHandlerClass.EMoveItemOrder.Apply, true);
|
||||||
|
if (operation.Failed || operation.Value is not GClass2786 moveOperation || moveOperation.To is not GClass2769 gridAddress)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
traderAssortmentController.PrepareToSell(selectedItemContext.Item, gridAddress.LocationInGrid);
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiSelect.Clear(); // explicitly clear since the items are no longer selectable
|
||||||
|
__result = Task.CompletedTask;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reimplement this method because BSG ignores the operation that is passed in and re-does the entire logic,
|
||||||
|
// like the dumb assholes they are
|
||||||
|
public class TradingTableGetHighlightColorPatch : ModulePatch
|
||||||
|
{
|
||||||
|
protected override MethodBase GetTargetMethod()
|
||||||
|
{
|
||||||
|
return AccessTools.Method(typeof(TradingTableGridView), nameof(TradingTableGridView.GetHighlightColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
[PatchPrefix]
|
||||||
|
public static bool Prefix(TradingTableGridView __instance, ItemContextClass itemContext, ItemContextAbstractClass targetItemContext, ref Color __result)
|
||||||
|
{
|
||||||
|
if (!Settings.EnableMultiSelect.Value || !MultiSelect.Active || targetItemContext != null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TraderAssortmentControllerClass traderAssortmentController = __instance.R().TraderAssortmentController;
|
||||||
|
if (MultiSelect.ItemContexts.All(ic => traderAssortmentController.CanPrepareItemToSell(ic.Item)))
|
||||||
|
{
|
||||||
|
__result = R.GridView.ValidMoveColor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
__result = R.GridView.InvalidOperationColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The inspect window likes to recreate itself entirely when a slot is removed, which destroys all of the gridviews and
|
// 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
|
// 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)
|
// is considered inactive multiselect)
|
||||||
@@ -539,6 +689,40 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class DisableSplitPatch : ModulePatch
|
||||||
|
{
|
||||||
|
protected override MethodBase GetTargetMethod()
|
||||||
|
{
|
||||||
|
return AccessTools.Method(typeof(TraderControllerClass), nameof(TraderControllerClass.ExecutePossibleAction), [typeof(ItemContextAbstractClass), typeof(Item), typeof(bool), typeof(bool)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[PatchPrefix]
|
||||||
|
public static void Prefix(ref bool partialTransferOnly)
|
||||||
|
{
|
||||||
|
if (MultiSelect.Active)
|
||||||
|
{
|
||||||
|
partialTransferOnly = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DisableSplitTargetPatch : ModulePatch
|
||||||
|
{
|
||||||
|
protected override MethodBase GetTargetMethod()
|
||||||
|
{
|
||||||
|
return AccessTools.Method(typeof(TraderControllerClass), nameof(TraderControllerClass.ExecutePossibleAction), [typeof(ItemContextAbstractClass), typeof(ItemContextAbstractClass), typeof(ItemAddress), typeof(bool), typeof(bool)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[PatchPrefix]
|
||||||
|
public static void Prefix(ref bool partialTransferOnly)
|
||||||
|
{
|
||||||
|
if (MultiSelect.Active)
|
||||||
|
{
|
||||||
|
partialTransferOnly = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class TaskSerializer : MonoBehaviour
|
public class TaskSerializer : MonoBehaviour
|
||||||
{
|
{
|
||||||
private Func<ItemContextClass, Task> func;
|
private Func<ItemContextClass, Task> func;
|
||||||
|
26
R.cs
26
R.cs
@@ -59,6 +59,7 @@ namespace UIFixes
|
|||||||
RepairStrategy.InitTypes();
|
RepairStrategy.InitTypes();
|
||||||
ContextMenuHelper.InitTypes();
|
ContextMenuHelper.InitTypes();
|
||||||
RagfairNewOfferItemView.InitTypes();
|
RagfairNewOfferItemView.InitTypes();
|
||||||
|
TradingTableGridView.InitTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class Wrapper(object value)
|
public abstract class Wrapper(object value)
|
||||||
@@ -292,18 +293,23 @@ namespace UIFixes
|
|||||||
private static FieldInfo TraderControllerField;
|
private static FieldInfo TraderControllerField;
|
||||||
private static FieldInfo NonInteractableField;
|
private static FieldInfo NonInteractableField;
|
||||||
private static FieldInfo HighlightPanelField;
|
private static FieldInfo HighlightPanelField;
|
||||||
|
private static FieldInfo ValidMoveColorField;
|
||||||
|
private static FieldInfo InvalidOperationColorField;
|
||||||
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)); // field gclass2758_0
|
TraderControllerField = AccessTools.GetDeclaredFields(Type).Single(f => f.FieldType == typeof(TraderControllerClass)); // field gclass2758_0
|
||||||
NonInteractableField = AccessTools.Field(Type, "_nonInteractable");
|
NonInteractableField = AccessTools.Field(Type, "_nonInteractable");
|
||||||
HighlightPanelField = AccessTools.Field(Type, "_highlightPanel");
|
HighlightPanelField = AccessTools.Field(Type, "_highlightPanel");
|
||||||
|
ValidMoveColorField = AccessTools.Field(Type, "ValidMoveColor");
|
||||||
|
InvalidOperationColorField = AccessTools.Field(Type, "InvalidOperationColor");
|
||||||
}
|
}
|
||||||
|
|
||||||
public TraderControllerClass TraderController { get { return (TraderControllerClass)TraderControllerField.GetValue(Value); } }
|
public TraderControllerClass TraderController { get { return (TraderControllerClass)TraderControllerField.GetValue(Value); } }
|
||||||
public bool NonInteractable { get { return (bool)NonInteractableField.GetValue(Value); } }
|
public bool NonInteractable { get { return (bool)NonInteractableField.GetValue(Value); } }
|
||||||
public Image HighlightPanel { get { return (Image)HighlightPanelField.GetValue(Value); } }
|
public Image HighlightPanel { get { return (Image)HighlightPanelField.GetValue(Value); } }
|
||||||
|
public static Color ValidMoveColor { get { return (Color)ValidMoveColorField.GetValue(null); } }
|
||||||
|
public static Color InvalidOperationColor { get { return (Color)InvalidOperationColorField.GetValue(null); } }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GridViewCanAcceptOperation(object value) : Wrapper(value)
|
public class GridViewCanAcceptOperation(object value) : Wrapper(value)
|
||||||
@@ -558,14 +564,17 @@ namespace UIFixes
|
|||||||
{
|
{
|
||||||
public static Type Type { get; private set; }
|
public static Type Type { get; private set; }
|
||||||
private static FieldInfo TraderAssortmentControllerField;
|
private static FieldInfo TraderAssortmentControllerField;
|
||||||
|
private static FieldInfo IsBeingSoldField;
|
||||||
|
|
||||||
public static void InitTypes()
|
public static void InitTypes()
|
||||||
{
|
{
|
||||||
Type = typeof(EFT.UI.DragAndDrop.TradingItemView);
|
Type = typeof(EFT.UI.DragAndDrop.TradingItemView);
|
||||||
TraderAssortmentControllerField = AccessTools.GetDeclaredFields(Type).Single(t => t.FieldType == typeof(TraderAssortmentControllerClass));
|
TraderAssortmentControllerField = AccessTools.GetDeclaredFields(Type).Single(t => t.FieldType == typeof(TraderAssortmentControllerClass));
|
||||||
|
IsBeingSoldField = AccessTools.GetDeclaredFields(Type).First(f => f.FieldType == typeof(BindableState<bool>));
|
||||||
}
|
}
|
||||||
|
|
||||||
public TraderAssortmentControllerClass TraderAssortmentController { get { return (TraderAssortmentControllerClass)TraderAssortmentControllerField.GetValue(Value); } }
|
public TraderAssortmentControllerClass TraderAssortmentController { get { return (TraderAssortmentControllerClass)TraderAssortmentControllerField.GetValue(Value); } }
|
||||||
|
public bool IsBeingSold { get { return ((BindableState<bool>)IsBeingSoldField.GetValue(Value)).Value; } }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GridWindow(object value) : UIInputNode(value)
|
public class GridWindow(object value) : UIInputNode(value)
|
||||||
@@ -695,6 +704,20 @@ namespace UIFixes
|
|||||||
public GameObject SelectedMark { get { return (GameObject)SelectedMarkField.GetValue(Value); } }
|
public GameObject SelectedMark { get { return (GameObject)SelectedMarkField.GetValue(Value); } }
|
||||||
public GameObject SelectedBackground { get { return (GameObject)SelectedBackgroundField.GetValue(Value); } }
|
public GameObject SelectedBackground { get { return (GameObject)SelectedBackgroundField.GetValue(Value); } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class TradingTableGridView(object value) : GridView(value)
|
||||||
|
{
|
||||||
|
public new static Type Type { get; private set; }
|
||||||
|
private static FieldInfo TraderAssortmentControllerField;
|
||||||
|
|
||||||
|
public new static void InitTypes()
|
||||||
|
{
|
||||||
|
Type = typeof(EFT.UI.DragAndDrop.TradingTableGridView);
|
||||||
|
TraderAssortmentControllerField = AccessTools.GetDeclaredFields(Type).Single(f => f.FieldType == typeof(TraderAssortmentControllerClass));
|
||||||
|
}
|
||||||
|
|
||||||
|
public TraderAssortmentControllerClass TraderAssortmentController { get { return (TraderAssortmentControllerClass)TraderAssortmentControllerField.GetValue(Value); } }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RExtentensions
|
public static class RExtentensions
|
||||||
@@ -722,5 +745,6 @@ namespace UIFixes
|
|||||||
public static R.RepairerParametersPanel R(this RepairerParametersPanel value) => new(value);
|
public static R.RepairerParametersPanel R(this RepairerParametersPanel value) => new(value);
|
||||||
public static R.MessageWindow R(this MessageWindow value) => new(value);
|
public static R.MessageWindow R(this MessageWindow value) => new(value);
|
||||||
public static R.RagfairNewOfferItemView R(this RagfairNewOfferItemView value) => new(value);
|
public static R.RagfairNewOfferItemView R(this RagfairNewOfferItemView value) => new(value);
|
||||||
|
public static R.TradingTableGridView R(this TradingTableGridView value) => new(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user