fixes, renames, cleanup
This commit is contained in:
@@ -47,7 +47,7 @@ namespace UIFixes
|
|||||||
|
|
||||||
public static void Clear()
|
public static void Clear()
|
||||||
{
|
{
|
||||||
// ToList() because we'll be modifying the collection
|
// ToList() because modifying the collection
|
||||||
foreach (GridItemView itemView in SelectedItemViews.Keys.ToList())
|
foreach (GridItemView itemView in SelectedItemViews.Keys.ToList())
|
||||||
{
|
{
|
||||||
Deselect(itemView);
|
Deselect(itemView);
|
||||||
|
@@ -91,31 +91,36 @@ namespace UIFixes
|
|||||||
|
|
||||||
public class CreateSubInteractionsInventoryPatch : ModulePatch
|
public class CreateSubInteractionsInventoryPatch : ModulePatch
|
||||||
{
|
{
|
||||||
|
private static bool LoadingInsuranceActions = false;
|
||||||
|
|
||||||
protected override MethodBase GetTargetMethod()
|
protected override MethodBase GetTargetMethod()
|
||||||
{
|
{
|
||||||
return AccessTools.Method(InventoryRootInteractionsType, "CreateSubInteractions");
|
return AccessTools.Method(InventoryRootInteractionsType, "CreateSubInteractions");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int GetPlayerRubles(ItemUiContext itemUiContext)
|
|
||||||
{
|
|
||||||
StashClass stash = itemUiContext.R().InventoryController.Inventory.Stash;
|
|
||||||
if (stash == null)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return R.Money.GetMoneySums(stash.Grid.ContainedItems.Keys)[ECurrencyType.RUB];
|
|
||||||
}
|
|
||||||
|
|
||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
public static bool Prefix(EItemInfoButton parentInteraction, ISubInteractions subInteractionsWrapper, Item ___item_0, ItemUiContext ___itemUiContext_1)
|
public static bool Prefix(EItemInfoButton parentInteraction, ISubInteractions subInteractionsWrapper, Item ___item_0, ItemUiContext ___itemUiContext_1)
|
||||||
{
|
{
|
||||||
|
// Clear this, since something else should be active (even a different mouseover of the insurance button)
|
||||||
|
LoadingInsuranceActions = false;
|
||||||
|
|
||||||
if (parentInteraction == EItemInfoButton.Insure)
|
if (parentInteraction == EItemInfoButton.Insure)
|
||||||
{
|
{
|
||||||
int playerRubles = GetPlayerRubles(___itemUiContext_1);
|
int playerRubles = GetPlayerRubles(___itemUiContext_1);
|
||||||
|
|
||||||
CurrentInsuranceInteractions = new(___item_0, ___itemUiContext_1, playerRubles);
|
CurrentInsuranceInteractions = new(___item_0, ___itemUiContext_1, playerRubles);
|
||||||
CurrentInsuranceInteractions.LoadAsync(() => subInteractionsWrapper.SetSubInteractions(CurrentInsuranceInteractions));
|
|
||||||
|
// Because this is async, need to protect against a different subInteractions activating before loading is done
|
||||||
|
// This isn't thread-safe at all but now the race condition is a microsecond instead of hundreds of milliseconds.
|
||||||
|
LoadingInsuranceActions = true;
|
||||||
|
CurrentInsuranceInteractions.LoadAsync(() =>
|
||||||
|
{
|
||||||
|
if (LoadingInsuranceActions)
|
||||||
|
{
|
||||||
|
subInteractionsWrapper.SetSubInteractions(CurrentInsuranceInteractions);
|
||||||
|
LoadingInsuranceActions = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -150,6 +155,8 @@ namespace UIFixes
|
|||||||
|
|
||||||
public class CreateSubInteractionsTradingPatch : ModulePatch
|
public class CreateSubInteractionsTradingPatch : ModulePatch
|
||||||
{
|
{
|
||||||
|
private static bool LoadingInsuranceActions = false;
|
||||||
|
|
||||||
protected override MethodBase GetTargetMethod()
|
protected override MethodBase GetTargetMethod()
|
||||||
{
|
{
|
||||||
return AccessTools.Method(TradingRootInteractionsType, "CreateSubInteractions");
|
return AccessTools.Method(TradingRootInteractionsType, "CreateSubInteractions");
|
||||||
@@ -158,22 +165,40 @@ namespace UIFixes
|
|||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
public static bool Prefix(object __instance, EItemInfoButton parentInteraction, ISubInteractions subInteractionsWrapper, ItemUiContext ___itemUiContext_0)
|
public static bool Prefix(object __instance, EItemInfoButton parentInteraction, ISubInteractions subInteractionsWrapper, ItemUiContext ___itemUiContext_0)
|
||||||
{
|
{
|
||||||
Dictionary<ECurrencyType, int> playerCurrencies = R.Money.GetMoneySums(___itemUiContext_0.R().InventoryController.Inventory.Stash.Grid.ContainedItems.Keys);
|
// Clear this, since something else should be active (even a different mouseover of the insurance button)
|
||||||
int playerRubles = playerCurrencies[ECurrencyType.RUB];
|
LoadingInsuranceActions = false;
|
||||||
|
|
||||||
// CreateSubInteractions is only on the base class here, which doesn't have an Item. But __instance is actually a GClass3032
|
|
||||||
Item item = (Item)TradingRootInteractionsItemField.GetValue(__instance);
|
|
||||||
|
|
||||||
if (parentInteraction == EItemInfoButton.Insure)
|
if (parentInteraction == EItemInfoButton.Insure)
|
||||||
{
|
{
|
||||||
|
int playerRubles = GetPlayerRubles(___itemUiContext_0);
|
||||||
|
|
||||||
|
// CreateSubInteractions is only on the base class here, which doesn't have an Item. But __instance is actually a GClass3032
|
||||||
|
Item item = (Item)TradingRootInteractionsItemField.GetValue(__instance);
|
||||||
|
|
||||||
CurrentInsuranceInteractions = new(item, ___itemUiContext_0, playerRubles);
|
CurrentInsuranceInteractions = new(item, ___itemUiContext_0, playerRubles);
|
||||||
CurrentInsuranceInteractions.LoadAsync(() => subInteractionsWrapper.SetSubInteractions(CurrentInsuranceInteractions));
|
|
||||||
|
// Because this is async, need to protect against a different subInteractions activating before loading is done
|
||||||
|
// This isn't thread-safe at all but now the race condition is a microsecond instead of hundreds of milliseconds.
|
||||||
|
LoadingInsuranceActions = true;
|
||||||
|
CurrentInsuranceInteractions.LoadAsync(() =>
|
||||||
|
{
|
||||||
|
if (LoadingInsuranceActions)
|
||||||
|
{
|
||||||
|
subInteractionsWrapper.SetSubInteractions(CurrentInsuranceInteractions);
|
||||||
|
LoadingInsuranceActions = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parentInteraction == EItemInfoButton.Repair)
|
if (parentInteraction == EItemInfoButton.Repair)
|
||||||
{
|
{
|
||||||
|
int playerRubles = GetPlayerRubles(___itemUiContext_0);
|
||||||
|
|
||||||
|
// CreateSubInteractions is only on the base class here, which doesn't have an Item. But __instance is actually a GClass3032
|
||||||
|
Item item = (Item)TradingRootInteractionsItemField.GetValue(__instance);
|
||||||
|
|
||||||
CurrentRepairInteractions = new(item, ___itemUiContext_0, playerRubles);
|
CurrentRepairInteractions = new(item, ___itemUiContext_0, playerRubles);
|
||||||
subInteractionsWrapper.SetSubInteractions(CurrentRepairInteractions);
|
subInteractionsWrapper.SetSubInteractions(CurrentRepairInteractions);
|
||||||
|
|
||||||
@@ -276,5 +301,16 @@ namespace UIFixes
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int GetPlayerRubles(ItemUiContext itemUiContext)
|
||||||
|
{
|
||||||
|
StashClass stash = itemUiContext.R().InventoryController.Inventory.Stash;
|
||||||
|
if (stash == null)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return R.Money.GetMoneySums(stash.Grid.ContainedItems.Keys)[ECurrencyType.RUB];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -113,7 +113,7 @@ namespace UIFixes
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore scroll position now that the we're loaded
|
// Restore scroll position now that offers are loaded
|
||||||
if (History.Any())
|
if (History.Any())
|
||||||
{
|
{
|
||||||
offerViewList.R().Scroller.SetScrollPosition(History.Peek().scrollPosition);
|
offerViewList.R().Scroller.SetScrollPosition(History.Peek().scrollPosition);
|
||||||
@@ -239,7 +239,7 @@ namespace UIFixes
|
|||||||
newRule.SortType = filterRule.SortType;
|
newRule.SortType = filterRule.SortType;
|
||||||
newRule.SortDirection = filterRule.SortDirection;
|
newRule.SortDirection = filterRule.SortDirection;
|
||||||
|
|
||||||
// We can't set handbookId yet - it limits the result set and that in turn limits what categories even display
|
// Can't set handbookId yet - it limits the result set and that in turn limits what categories even display
|
||||||
DelayedHandbookId = filterRule.HandbookId;
|
DelayedHandbookId = filterRule.HandbookId;
|
||||||
|
|
||||||
ragfair.SetFilterRule(newRule, true, true);
|
ragfair.SetFilterRule(newRule, true, true);
|
||||||
@@ -339,7 +339,7 @@ namespace UIFixes
|
|||||||
return AccessTools.Method(typeof(OfferViewList), nameof(OfferViewList.method_10));
|
return AccessTools.Method(typeof(OfferViewList), nameof(OfferViewList.method_10));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The firs thing this method does is set scrollposition to 0, so we need to grab it first
|
// The first thing this method does is set scrollposition to 0, so grab it first
|
||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
public static void Prefix(LightScroller ____scroller)
|
public static void Prefix(LightScroller ____scroller)
|
||||||
{
|
{
|
||||||
|
@@ -72,7 +72,7 @@ namespace UIFixes
|
|||||||
inventoryController.LoadMagazine(bullets, magazine, count, false).HandleExceptions();
|
inventoryController.LoadMagazine(bullets, magazine, count, false).HandleExceptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The calling code in this instance doesn't do anything with the task, but it does await it, so if we don't return a Task it nullrefs
|
// The calling code in this instance doesn't do anything with the task, but it does await it, so if this doesn't return a Task it nullrefs
|
||||||
__result = Task.CompletedTask;
|
__result = Task.CompletedTask;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -240,7 +240,7 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
|
|
||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
public static bool Prefix(GridView __instance, ItemContextClass itemContext, ItemContextAbstractClass targetItemContext, ref GStruct413 operation, ref bool __result)
|
public static bool Prefix(GridView __instance, ItemContextClass itemContext, ItemContextAbstractClass targetItemContext, ref GStruct413 operation, ref bool __result, ItemUiContext ___itemUiContext_0)
|
||||||
{
|
{
|
||||||
if (!Settings.EnableMultiSelect.Value || InPatch || !MultiSelect.Active)
|
if (!Settings.EnableMultiSelect.Value || InPatch || !MultiSelect.Active)
|
||||||
{
|
{
|
||||||
@@ -311,6 +311,12 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Wrap this error to display it
|
||||||
|
if (operation.Error is GClass3292 noRoomError)
|
||||||
|
{
|
||||||
|
operation = new(new DisplayableErrorWrapper(noRoomError));
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,7 +332,7 @@ namespace UIFixes
|
|||||||
HidePreviews();
|
HidePreviews();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We didn't simulate so now we undo
|
// Didn't simulate so now undo
|
||||||
while (operations.Any())
|
while (operations.Any())
|
||||||
{
|
{
|
||||||
operations.Pop().Value?.RollBack();
|
operations.Pop().Value?.RollBack();
|
||||||
@@ -335,6 +341,21 @@ namespace UIFixes
|
|||||||
// result and operation are set to the last one that completed - so success if they all passed, or the first failure
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GridView.HighlightItemViewPosition has a blacklist of errors it won't show, but it shows other types.
|
||||||
|
// Wrapping an error can get past that
|
||||||
|
private class DisplayableErrorWrapper(InventoryError error) : InventoryError
|
||||||
|
{
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return error.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string GetLocalizedDescription()
|
||||||
|
{
|
||||||
|
return error.GetLocalizedDescription();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GridViewAcceptItemPatch : ModulePatch
|
public class GridViewAcceptItemPatch : ModulePatch
|
||||||
@@ -470,7 +491,7 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
|
|
||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
public static bool Prefix(SlotView __instance, ItemContextAbstractClass targetItemContext, ref GStruct413 operation, ref bool __result, InventoryControllerClass ___InventoryController)
|
public static bool Prefix(SlotView __instance, ItemContextAbstractClass targetItemContext, ref GStruct413 operation, ref bool __result, InventoryControllerClass ___InventoryController, ItemUiContext ___ItemUiContext)
|
||||||
{
|
{
|
||||||
if (!Settings.EnableMultiSelect.Value || InPatch || !MultiSelect.Active)
|
if (!Settings.EnableMultiSelect.Value || InPatch || !MultiSelect.Active)
|
||||||
{
|
{
|
||||||
@@ -500,7 +521,7 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We didn't simulate so now we undo
|
// Didn't simulate so now undo
|
||||||
while (operations.Any())
|
while (operations.Any())
|
||||||
{
|
{
|
||||||
operations.Pop().Value?.RollBack();
|
operations.Pop().Value?.RollBack();
|
||||||
@@ -599,7 +620,7 @@ namespace UIFixes
|
|||||||
HidePreviews();
|
HidePreviews();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We didn't simulate so now we undo
|
// Didn't simulate so now undo
|
||||||
while (operations.Any())
|
while (operations.Any())
|
||||||
{
|
{
|
||||||
operations.Pop().Value?.RollBack();
|
operations.Pop().Value?.RollBack();
|
||||||
@@ -631,7 +652,7 @@ namespace UIFixes
|
|||||||
traderAssortmentController.PrepareToSell(itemContext.Item, locationInGrid);
|
traderAssortmentController.PrepareToSell(itemContext.Item, locationInGrid);
|
||||||
itemContext.CloseDependentWindows();
|
itemContext.CloseDependentWindows();
|
||||||
|
|
||||||
// For the rest of the items we still need to use quickfind
|
// For the rest of the items, still need to use quickfind
|
||||||
foreach (ItemContextClass selectedItemContext in MultiSelect.ItemContexts.Where(ic => ic.Item != itemContext.Item))
|
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);
|
GStruct413 operation = InteractionsHandlerClass.QuickFindAppropriatePlace(selectedItemContext.Item, traderAssortmentController.TraderController, [__instance.Grid.ParentItem as LootItemClass], InteractionsHandlerClass.EMoveItemOrder.Apply, true);
|
||||||
|
@@ -15,10 +15,10 @@ namespace UIFixes
|
|||||||
{
|
{
|
||||||
public static class SwapPatches
|
public static class SwapPatches
|
||||||
{
|
{
|
||||||
// Source container for the drag - we have to grab this early to check it
|
// Source container for the drag - grab this early to check it
|
||||||
private static IContainer SourceContainer;
|
private static IContainer SourceContainer;
|
||||||
|
|
||||||
// Whether we're being called from the "check every slot" loop
|
// Whether it's being called from the "check every slot" loop
|
||||||
private static bool InHighlight = false;
|
private static bool InHighlight = false;
|
||||||
|
|
||||||
// The most recent CheckItemFilter result - needed to differentiate "No room" from incompatible
|
// The most recent CheckItemFilter result - needed to differentiate "No room" from incompatible
|
||||||
@@ -237,7 +237,7 @@ namespace UIFixes
|
|||||||
// This is the location you're dragging it, including rotation
|
// This is the location you're dragging it, including rotation
|
||||||
LocationInGrid itemToLocation = __instance.CalculateItemLocation(itemContext);
|
LocationInGrid itemToLocation = __instance.CalculateItemLocation(itemContext);
|
||||||
|
|
||||||
// Target is a grid because we're in the GridView patch, i.e. you're dragging it over a grid
|
// Target is a grid because this is the GridView patch, i.e. you're dragging it over a grid
|
||||||
var targetGridItemAddress = new R.GridItemAddress(targetItemAddress);
|
var targetGridItemAddress = new R.GridItemAddress(targetItemAddress);
|
||||||
ItemAddress itemToAddress = R.GridItemAddress.Create(targetGridItemAddress.Grid, itemToLocation);
|
ItemAddress itemToAddress = R.GridItemAddress.Create(targetGridItemAddress.Grid, itemToLocation);
|
||||||
|
|
||||||
@@ -276,7 +276,7 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're coming from a grid, try rotating the target object
|
// If coming from a grid, try rotating the target object
|
||||||
if (R.GridItemAddress.Type.IsInstanceOfType(itemAddress))
|
if (R.GridItemAddress.Type.IsInstanceOfType(itemAddress))
|
||||||
{
|
{
|
||||||
var targetToLocation = new R.GridItemAddress(targetToAddress).LocationInGrid;
|
var targetToLocation = new R.GridItemAddress(targetToAddress).LocationInGrid;
|
||||||
@@ -286,7 +286,7 @@ namespace UIFixes
|
|||||||
var result = InteractionsHandlerClass.Swap(item, itemToAddress, targetItem, targetToAddress, traderControllerClass, true);
|
var result = InteractionsHandlerClass.Swap(item, itemToAddress, targetItem, targetToAddress, traderControllerClass, true);
|
||||||
if (result.Succeeded)
|
if (result.Succeeded)
|
||||||
{
|
{
|
||||||
// Only save this operation result if it succeeded, otherwise we return the non-rotated result from above
|
// Only save this operation result if it succeeded, otherwise return the non-rotated result from above
|
||||||
operation = new R.SwapOperation(result).ToGridViewCanAcceptOperation();
|
operation = new R.SwapOperation(result).ToGridViewCanAcceptOperation();
|
||||||
__result = true;
|
__result = true;
|
||||||
return;
|
return;
|
||||||
@@ -443,7 +443,7 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CanApply, when dealing with containers, eventually calls down into FindPlaceForItem, which calls CheckItemFilter. For reasons,
|
// CanApply, when dealing with containers, eventually calls down into FindPlaceForItem, which calls CheckItemFilter. For reasons,
|
||||||
// if an item fails the filters, it returns the error "no space", instead of "no action". Try to detect this, so we can swap.
|
// if an item fails the filters, it returns the error "no space", instead of "no action". Try to detect this in order to swap.
|
||||||
public class DetectFilterForSwapPatch : ModulePatch
|
public class DetectFilterForSwapPatch : ModulePatch
|
||||||
{
|
{
|
||||||
protected override MethodBase GetTargetMethod()
|
protected override MethodBase GetTargetMethod()
|
||||||
@@ -461,7 +461,7 @@ namespace UIFixes
|
|||||||
}
|
}
|
||||||
|
|
||||||
// When dragging an item around, by default it updates an ItemSpecificationPanel when you drag an item on top of a slot
|
// When dragging an item around, by default it updates an ItemSpecificationPanel when you drag an item on top of a slot
|
||||||
// It doesn't do anything when you drag an item from a slot onto some other item elsewhere. But with swap, we should update the item panel then too.
|
// It doesn't do anything when you drag an item from a slot onto some other item elsewhere. But with swap, update the item panel then too.
|
||||||
public class InspectWindowUpdateStatsOnSwapPatch : ModulePatch
|
public class InspectWindowUpdateStatsOnSwapPatch : ModulePatch
|
||||||
{
|
{
|
||||||
protected override MethodBase GetTargetMethod()
|
protected override MethodBase GetTargetMethod()
|
||||||
|
Reference in New Issue
Block a user