diff --git a/Patches/MultiSelectPatches.cs b/Patches/MultiSelectPatches.cs index eeaf7f1..011fee0 100644 --- a/Patches/MultiSelectPatches.cs +++ b/Patches/MultiSelectPatches.cs @@ -18,6 +18,7 @@ using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; using FleaRequirement = GClass1859; +using CurrencyUtil = GClass2531; namespace UIFixes; @@ -223,6 +224,10 @@ public static class MultiSelectPatches SellAllToFlea(); } + if (shiftDown && ctrlDown) { + SellAllToTrader(); + } + if (ctrlDown && !shiftDown && !altDown) { QuickMove(__instance, ___ItemUiContext, ___ItemController); @@ -339,6 +344,112 @@ public static class MultiSelectPatches Session.RagFair.AddOffer(true, [item.Id], [req], null); } } + + private static void SellAllToTrader() { + foreach (DragItemContext selectedItemContext in MultiSelect.SortedItemContexts()) { + try { + SellToTrader(selectedItemContext.Item); + } + catch (Exception e) { + Console.WriteLine("Oopsie!"); + Console.WriteLine(e); + } + } + } + + private static void SellToTrader(Item item) { + TraderOffer bestTraderOffer = GetBestTraderOffer(item); + TraderClass tc = Session.GetTrader(bestTraderOffer.TraderId); + + GClass2063.Class1765 @class = new GClass2063.Class1765(); + @class.source = new TaskCompletionSource(); + + var itemRef = new EFT.Trading.TradingItemReference { + Item = item, + Count = item.StackObjectsCount + }; + + Session.ConfirmSell(tc.Id, [itemRef], bestTraderOffer.Price, + @class.method_0); + Singleton.Instance.PlayUISound(EUISoundType.TradeOperationComplete); + } + + public sealed class TraderOffer { + public string TraderId; + public string TraderName; + public int Price; + public string Currency; + public double Course; + public int Count; + + public TraderOffer(string traderId, string traderName, int price, string currency, double course, + int count) { + TraderId = traderId; + TraderName = traderName; + Price = price; + Currency = currency; + Course = course; + Count = count; + } + } + + public static TraderOffer GetBestTraderOffer(Item item) { + if (!Session.Profile.Examined(item)) + return null; + + switch (item.Owner?.OwnerType) { + case EOwnerType.RagFair: + case EOwnerType.Trader: + if (item.StackObjectsCount > 1 || item.UnlimitedCount) { + item = item.CloneItem(); + item.StackObjectsCount = 1; + item.UnlimitedCount = false; + } + + break; + } + + TraderOffer highestOffer = null; + + if (item is Weapon weapon) { + foreach (TraderClass trader in Session.Traders) { + if (!trader.Info.Available || trader.Info.Disabled || !trader.Info.Unlocked) + continue; + + if (GetTraderOffer(weapon, trader) is TraderOffer offer) { + if (highestOffer == null || offer.Price > highestOffer.Price) + highestOffer = offer; + } + } + } + else { + foreach (TraderClass trader in Session.Traders) { + if (!trader.Info.Available || trader.Info.Disabled || !trader.Info.Unlocked) + continue; + + if (GetTraderOffer(item, trader) is TraderOffer offer) + if (highestOffer == null || offer.Price > highestOffer.Price) + highestOffer = offer; + } + } + + return highestOffer; + } + + private static TraderOffer GetTraderOffer(Item item, TraderClass trader) { + var result = trader.GetUserItemPrice(item); + if (result == null) + return null; + + return new TraderOffer( + trader.Id, + trader.LocalizedName, + result.Value.Amount, + CurrencyUtil.GetCurrencyCharById(result.Value.CurrencyId), + trader.GetSupplyData().CurrencyCourses[result.Value.CurrencyId], + item.StackObjectsCount + ); + } } public class ContextActionsPatch : ModulePatch @@ -1513,3 +1624,25 @@ public static class MultiSelectPatches return hoveredGridAddress; } } + +internal static class TraderClassExtensions { + private static ISession Session => ClientAppUtils.GetMainApp().GetClientBackEndSession(); + + private static readonly FieldInfo SupplyDataField = + typeof(TraderClass).GetField("supplyData_0", BindingFlags.NonPublic | BindingFlags.Instance); + + public static SupplyData GetSupplyData(this TraderClass trader) => + SupplyDataField.GetValue(trader) as SupplyData; + + public static void SetSupplyData(this TraderClass trader, SupplyData supplyData) => + SupplyDataField.SetValue(trader, supplyData); + + public static async void UpdateSupplyData(this TraderClass trader) { + Result result = await Session.GetSupplyData(trader.Id); + + if (result.Failed) + return; + + trader.SetSupplyData(result.Value); + } +} diff --git a/UIFixes.csproj b/UIFixes.csproj index e179f13..91bcde1 100644 --- a/UIFixes.csproj +++ b/UIFixes.csproj @@ -93,18 +93,4 @@ - - - -