unpack keybind; multi equip, unequip, unload ammo
This commit is contained in:
@@ -175,6 +175,22 @@ namespace UIFixes
|
||||
get { return SelectedItems.Count > 0; }
|
||||
}
|
||||
|
||||
// Sort the items to prioritize the items that share a grid with the dragged item, prepend the dragContext as the first one
|
||||
// Can pass no itemContext, and it just sorts items by their grid order
|
||||
public static IEnumerable<ItemContextClass> SortedItemContexts(ItemContextClass first = null, bool prepend = true)
|
||||
{
|
||||
static int gridOrder(LocationInGrid loc, StashGridClass grid) => grid.GridWidth.Value * loc.y + loc.x;
|
||||
|
||||
var result = ItemContexts
|
||||
.Where(ic => first == null || ic.Item != first.Item)
|
||||
.OrderByDescending(ic => ic.ItemAddress is GClass2769)
|
||||
.ThenByDescending(ic => first != null && first.ItemAddress is GClass2769 originalDraggedAddress && ic.ItemAddress is GClass2769 selectedGridAddress && selectedGridAddress.Grid == originalDraggedAddress.Grid)
|
||||
.ThenByDescending(ic => ic.ItemAddress is GClass2769 selectedGridAddress ? selectedGridAddress.Grid.Id : null)
|
||||
.ThenBy(ic => ic.ItemAddress is GClass2769 selectedGridAddress ? gridOrder(selectedGridAddress.LocationInGrid, selectedGridAddress.Grid) : 0);
|
||||
|
||||
return first != null && prepend ? result.Prepend(first) : result;
|
||||
}
|
||||
|
||||
public static void ShowDragCount(DraggedItemView draggedItemView)
|
||||
{
|
||||
if (draggedItemView != null && Count > 1)
|
||||
@@ -196,6 +212,68 @@ namespace UIFixes
|
||||
}
|
||||
}
|
||||
|
||||
public static int InteractionCount(EItemInfoButton interaction, ItemUiContext itemUiContext)
|
||||
{
|
||||
int count = 0;
|
||||
foreach (ItemContextClass selectedItemContext in SortedItemContexts())
|
||||
{
|
||||
ItemContextAbstractClass innerContext = selectedItemContext.GClass2813_0;
|
||||
if (innerContext == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var contextInteractions = itemUiContext.GetItemContextInteractions(innerContext, null);
|
||||
if (!contextInteractions.IsInteractionAvailable(interaction))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public static void EquipAll(ItemUiContext itemUiContext, bool allOrNothing)
|
||||
{
|
||||
if (!allOrNothing || InteractionCount(EItemInfoButton.Equip, itemUiContext) == Count)
|
||||
{
|
||||
foreach (ItemContextClass selectedItemContext in SortedItemContexts())
|
||||
{
|
||||
itemUiContext.QuickEquip(selectedItemContext.Item).HandleExceptions();
|
||||
}
|
||||
|
||||
itemUiContext.Tooltip?.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void UnequipAll(ItemUiContext itemUiContext, bool allOrNothing)
|
||||
{
|
||||
if (!allOrNothing || InteractionCount(EItemInfoButton.Unequip, itemUiContext) == Count)
|
||||
{
|
||||
foreach (ItemContextClass selectedItemContext in SortedItemContexts())
|
||||
{
|
||||
itemUiContext.Uninstall(selectedItemContext.GClass2813_0).HandleExceptions();
|
||||
}
|
||||
|
||||
itemUiContext.Tooltip?.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void UnloadAmmoAll(ItemUiContext itemUiContext, bool allOrNothing)
|
||||
{
|
||||
if (!allOrNothing || InteractionCount(EItemInfoButton.UnloadAmmo, itemUiContext) == Count)
|
||||
{
|
||||
foreach (ItemContextClass selectedItemContext in SortedItemContexts())
|
||||
{
|
||||
itemUiContext.UnloadAmmo(selectedItemContext.Item).HandleExceptions();
|
||||
}
|
||||
|
||||
itemUiContext.Tooltip?.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private static void ShowSelection(GridItemView itemView)
|
||||
{
|
||||
GameObject selectedMark = itemView.transform.Find("SelectedMark")?.gameObject;
|
||||
|
@@ -88,7 +88,12 @@ namespace UIFixes
|
||||
[PatchPostfix]
|
||||
public static void Postfix(string caption, TextMeshProUGUI ____text)
|
||||
{
|
||||
if (caption == EItemInfoButton.Insure.ToString() && MultiSelect.Count > 1)
|
||||
if (MultiSelect.Count < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (caption == EItemInfoButton.Insure.ToString())
|
||||
{
|
||||
InsuranceCompanyClass insurance = ItemUiContext.Instance.Session.InsuranceCompany;
|
||||
int count = MultiSelect.ItemContexts.Select(ic => ItemClass.FindOrCreate(ic.Item))
|
||||
@@ -99,6 +104,30 @@ namespace UIFixes
|
||||
{
|
||||
____text.text += " (x" + count + ")";
|
||||
}
|
||||
}
|
||||
else if (caption == EItemInfoButton.Equip.ToString())
|
||||
{
|
||||
int count = MultiSelect.InteractionCount(EItemInfoButton.Equip, ItemUiContext.Instance);
|
||||
if (count > 0)
|
||||
{
|
||||
____text.text += " (x" + count + ")";
|
||||
}
|
||||
}
|
||||
else if (caption == EItemInfoButton.Unequip.ToString())
|
||||
{
|
||||
int count = MultiSelect.InteractionCount(EItemInfoButton.Unequip, ItemUiContext.Instance);
|
||||
if (count > 0)
|
||||
{
|
||||
____text.text += " (x" + count + ")";
|
||||
}
|
||||
}
|
||||
else if (caption == EItemInfoButton.UnloadAmmo.ToString())
|
||||
{
|
||||
int count = MultiSelect.InteractionCount(EItemInfoButton.UnloadAmmo, ItemUiContext.Instance);
|
||||
if (count > 0)
|
||||
{
|
||||
____text.text += " (x" + count + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -78,6 +78,12 @@ namespace UIFixes
|
||||
return;
|
||||
}
|
||||
|
||||
if (Settings.UnpackKeyBind.Value.IsDown())
|
||||
{
|
||||
interactions.ExecuteInteraction(EItemInfoButton.Unpack);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Settings.FilterByKeyBind.Value.IsDown())
|
||||
{
|
||||
interactions.ExecuteInteraction(EItemInfoButton.FilterSearch);
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using Aki.Reflection.Patching;
|
||||
using Aki.Reflection.Utils;
|
||||
using Comfort.Common;
|
||||
using EFT.Communications;
|
||||
using EFT.InventoryLogic;
|
||||
@@ -38,31 +39,43 @@ namespace UIFixes
|
||||
|
||||
public static void Enable()
|
||||
{
|
||||
// Initialization
|
||||
new InitializeCommonUIPatch().Enable();
|
||||
new InitializeMenuUIPatch().Enable();
|
||||
|
||||
// Selection
|
||||
new SelectOnMouseDownPatch().Enable();
|
||||
new ItemViewClickPatch().Enable();
|
||||
new DeselectOnTradingItemViewClickPatch().Enable();
|
||||
new HandleItemViewInitPatch().Enable();
|
||||
new HandleItemViewKillPatch().Enable();
|
||||
new BeginDragPatch().Enable();
|
||||
new EndDragPatch().Enable();
|
||||
|
||||
// Workarounds
|
||||
new DisableSplitPatch().Enable();
|
||||
new DisableSplitTargetPatch().Enable();
|
||||
|
||||
// Actions
|
||||
new ItemViewClickPatch().Enable();
|
||||
new ContextActionsPatch().Enable();
|
||||
|
||||
// GridView
|
||||
new GridViewCanAcceptPatch().Enable();
|
||||
new GridViewAcceptItemPatch().Enable();
|
||||
new GridViewPickTargetPatch().Enable();
|
||||
new GridViewDisableHighlightPatch().Enable();
|
||||
new GridViewClearTooltipPatch().Enable();
|
||||
|
||||
// SlotView
|
||||
new SlotViewCanAcceptPatch().Enable();
|
||||
new SlotViewAcceptItemPatch().Enable();
|
||||
|
||||
// TradingTableGridView
|
||||
new TradingTableCanAcceptPatch().Enable();
|
||||
new TradingTableAcceptItemPatch().Enable();
|
||||
new TradingTableGetHighlightColorPatch().Enable();
|
||||
|
||||
// Various location finding
|
||||
new FindSpotKeepRotationPatch().Enable();
|
||||
new FindLocationForItemPatch().Enable();
|
||||
new FindPlaceToPutPatch().Enable();
|
||||
@@ -173,7 +186,7 @@ namespace UIFixes
|
||||
|
||||
if (altDown && !shiftDown && !ctrlDown)
|
||||
{
|
||||
QuickEquip(___ItemUiContext);
|
||||
MultiSelect.EquipAll(___ItemUiContext, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -188,45 +201,13 @@ namespace UIFixes
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void QuickEquip(ItemUiContext itemUiContext)
|
||||
{
|
||||
bool allowed = true;
|
||||
var selectedItemContexts = SortSelectedContexts(MultiSelect.ItemContexts);
|
||||
foreach (ItemContextClass selectedItemContext in selectedItemContexts)
|
||||
{
|
||||
ItemContextAbstractClass innerContext = selectedItemContext.GClass2813_0;
|
||||
if (innerContext == null)
|
||||
{
|
||||
allowed = false;
|
||||
break;
|
||||
}
|
||||
|
||||
var contextInteractions = itemUiContext.GetItemContextInteractions(innerContext, null);
|
||||
if (!contextInteractions.IsInteractionAvailable(EItemInfoButton.Equip))
|
||||
{
|
||||
allowed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (allowed)
|
||||
{
|
||||
foreach (ItemContextClass selectedItemContext in selectedItemContexts)
|
||||
{
|
||||
itemUiContext.QuickEquip(selectedItemContext.Item).HandleExceptions();
|
||||
}
|
||||
|
||||
itemUiContext.Tooltip?.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private static void QuickMove(GridItemView gridItemView, ItemUiContext itemUiContext, TraderControllerClass itemController)
|
||||
{
|
||||
bool succeeded = true;
|
||||
DisableMerge = true;
|
||||
IgnoreItemParent = true;
|
||||
Stack<GStruct413> operations = new();
|
||||
foreach (ItemContextClass selectedItemContext in SortSelectedContexts(MultiSelect.ItemContexts))
|
||||
foreach (ItemContextClass selectedItemContext in MultiSelect.SortedItemContexts())
|
||||
{
|
||||
GStruct413 operation = itemUiContext.QuickFindAppropriatePlace(selectedItemContext, itemController, false /*forceStash*/, false /*showWarnings*/, false /*simulate*/);
|
||||
if (operation.Succeeded && itemController.CanExecute(operation.Value))
|
||||
@@ -282,6 +263,38 @@ namespace UIFixes
|
||||
}
|
||||
}
|
||||
|
||||
public class ContextActionsPatch : ModulePatch
|
||||
{
|
||||
protected override MethodBase GetTargetMethod()
|
||||
{
|
||||
return AccessTools.Method(typeof(GClass3021), nameof(GClass3021.ExecuteInteractionInternal));
|
||||
}
|
||||
|
||||
[PatchPrefix]
|
||||
public static bool Prefix(GClass3021 __instance, EItemInfoButton interaction, ItemUiContext ___itemUiContext_1)
|
||||
{
|
||||
if (!MultiSelect.Active)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (interaction)
|
||||
{
|
||||
case EItemInfoButton.Equip:
|
||||
MultiSelect.EquipAll(___itemUiContext_1, false);
|
||||
return false;
|
||||
case EItemInfoButton.Unequip:
|
||||
MultiSelect.UnequipAll(___itemUiContext_1, false);
|
||||
return false;
|
||||
case EItemInfoButton.UnloadAmmo:
|
||||
MultiSelect.UnloadAmmoAll(___itemUiContext_1, false);
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TradingItemView overrides GridItemView.OnClick and doesn't call base
|
||||
public class DeselectOnTradingItemViewClickPatch : ModulePatch
|
||||
{
|
||||
@@ -446,7 +459,7 @@ namespace UIFixes
|
||||
bool showHighlights = targetItem == null;
|
||||
|
||||
Stack<GStruct413> operations = new();
|
||||
foreach (ItemContextClass selectedItemContext in SortSelectedContexts(MultiSelect.ItemContexts, itemContext))
|
||||
foreach (ItemContextClass selectedItemContext in MultiSelect.SortedItemContexts(itemContext))
|
||||
{
|
||||
FindOrigin = GetTargetGridAddress(itemContext, selectedItemContext, hoveredAddress);
|
||||
FindVerticalFirst = selectedItemContext.ItemRotation == ItemRotation.Vertical;
|
||||
@@ -566,7 +579,7 @@ namespace UIFixes
|
||||
}
|
||||
|
||||
var serializer = __instance.GetOrAddComponent<ItemContextTaskSerializer>();
|
||||
__result = serializer.Initialize(SortSelectedContexts(MultiSelect.ItemContexts, itemContext), ic =>
|
||||
__result = serializer.Initialize(MultiSelect.SortedItemContexts(itemContext), ic =>
|
||||
{
|
||||
FindOrigin = GetTargetGridAddress(itemContext, ic, hoveredAddress);
|
||||
FindVerticalFirst = ic.ItemRotation == ItemRotation.Vertical;
|
||||
@@ -677,23 +690,6 @@ namespace UIFixes
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the items to prioritize the items that share a grid with the dragged item, prepend the dragContext as the first one
|
||||
// Can pass no itemContext, and it just sorts items by their grid order
|
||||
private static IEnumerable<ItemContextClass> SortSelectedContexts(
|
||||
IEnumerable<ItemContextClass> selectedContexts, ItemContextClass itemContext = null, bool prepend = true)
|
||||
{
|
||||
static int gridOrder(LocationInGrid loc, StashGridClass grid) => grid.GridWidth.Value * loc.y + loc.x;
|
||||
|
||||
var result = selectedContexts
|
||||
.Where(ic => itemContext == null || ic.Item != itemContext.Item)
|
||||
.OrderByDescending(ic => ic.ItemAddress is GClass2769)
|
||||
.ThenByDescending(ic => itemContext != null && itemContext.ItemAddress is GClass2769 originalDraggedAddress && ic.ItemAddress is GClass2769 selectedGridAddress && selectedGridAddress.Grid == originalDraggedAddress.Grid)
|
||||
.ThenByDescending(ic => ic.ItemAddress is GClass2769 selectedGridAddress ? selectedGridAddress.Grid.Id : null)
|
||||
.ThenBy(ic => ic.ItemAddress is GClass2769 selectedGridAddress ? gridOrder(selectedGridAddress.LocationInGrid, selectedGridAddress.Grid) : 0);
|
||||
|
||||
return itemContext != null && prepend ? result.Prepend(itemContext) : result;
|
||||
}
|
||||
|
||||
public class GridViewDisableHighlightPatch : ModulePatch
|
||||
{
|
||||
protected override MethodBase GetTargetMethod()
|
||||
@@ -751,7 +747,7 @@ namespace UIFixes
|
||||
}
|
||||
|
||||
Stack<GStruct413> operations = new();
|
||||
foreach (ItemContextClass itemContext in SortSelectedContexts(MultiSelect.ItemContexts, null, false))
|
||||
foreach (ItemContextClass itemContext in MultiSelect.SortedItemContexts())
|
||||
{
|
||||
__result = itemContext.CanAccept(__instance.Slot, __instance.ParentItemContext, ___InventoryController, out operation, false /* simulate */);
|
||||
if (operation.Succeeded)
|
||||
@@ -798,7 +794,7 @@ namespace UIFixes
|
||||
InPatch = true;
|
||||
|
||||
var serializer = __instance.GetOrAddComponent<ItemContextTaskSerializer>();
|
||||
__result = serializer.Initialize(SortSelectedContexts(MultiSelect.ItemContexts, null, false), itemContext => __instance.AcceptItem(itemContext, targetItemContext));
|
||||
__result = serializer.Initialize(MultiSelect.SortedItemContexts(), itemContext => __instance.AcceptItem(itemContext, targetItemContext));
|
||||
|
||||
__result.ContinueWith(_ => { InPatch = false; });
|
||||
|
||||
@@ -834,7 +830,7 @@ namespace UIFixes
|
||||
GClass2769 hoveredAddress = new(__instance.Grid, hoveredLocation);
|
||||
|
||||
Stack<GStruct413> operations = new();
|
||||
foreach (ItemContextClass selectedItemContext in SortSelectedContexts(MultiSelect.ItemContexts, itemContext))
|
||||
foreach (ItemContextClass selectedItemContext in MultiSelect.SortedItemContexts(itemContext))
|
||||
{
|
||||
if (traderAssortmentController.CanPrepareItemToSell(selectedItemContext.Item))
|
||||
{
|
||||
@@ -912,7 +908,7 @@ namespace UIFixes
|
||||
itemContext.CloseDependentWindows();
|
||||
|
||||
// For the rest of the items, still need to use quickfind
|
||||
foreach (ItemContextClass selectedItemContext in SortSelectedContexts(MultiSelect.ItemContexts, itemContext, false))
|
||||
foreach (ItemContextClass selectedItemContext in MultiSelect.SortedItemContexts(itemContext, false))
|
||||
{
|
||||
FindOrigin = GetTargetGridAddress(itemContext, selectedItemContext, hoveredAddress);
|
||||
FindVerticalFirst = selectedItemContext.ItemRotation == ItemRotation.Vertical;
|
||||
|
10
Settings.cs
10
Settings.cs
@@ -58,6 +58,7 @@ namespace UIFixes
|
||||
public static ConfigEntry<KeyboardShortcut> UseKeyBind { get; set; }
|
||||
public static ConfigEntry<KeyboardShortcut> UseAllKeyBind { get; set; }
|
||||
public static ConfigEntry<KeyboardShortcut> UnloadKeyBind { get; set; }
|
||||
public static ConfigEntry<KeyboardShortcut> UnpackKeyBind { get; set; }
|
||||
public static ConfigEntry<KeyboardShortcut> FilterByKeyBind { get; set; }
|
||||
public static ConfigEntry<KeyboardShortcut> LinkedSearchKeyBind { get; set; }
|
||||
public static ConfigEntry<bool> UseRaidMouseScrollMulti { get; set; } // Advanced
|
||||
@@ -248,6 +249,15 @@ namespace UIFixes
|
||||
null,
|
||||
new ConfigurationManagerAttributes { })));
|
||||
|
||||
configEntries.Add(UnpackKeyBind = config.Bind(
|
||||
InputSection,
|
||||
"Unpack Shortcut",
|
||||
new KeyboardShortcut(KeyCode.None),
|
||||
new ConfigDescription(
|
||||
"Keybind to unpack a sealed weapons case, etc",
|
||||
null,
|
||||
new ConfigurationManagerAttributes { })));
|
||||
|
||||
configEntries.Add(FilterByKeyBind = config.Bind(
|
||||
InputSection,
|
||||
"Filter by Item Shortcut",
|
||||
|
Reference in New Issue
Block a user