/// <summary>Does the action.</summary> /// <param name="amount">Number of items.</param> /// <param name="clickLocation">Where the player clicked.</param> public override void PerformAction(int amount, Point clickLocation) { var pfx = $"[{nameof(BuyAction)}.{nameof(PerformAction)}]"; var chosen = this.ClickedItem; var chosen_max = chosen.maximumStackSize(); var nativeMenu = this.NativeShopMenu; var heldItem = Mod.Reflection.GetField <Item>(nativeMenu, "heldItem").GetValue(); Log.Trace( $"{pfx} chosen = {chosen}, nativeMenu = {nativeMenu}, ShopCurrencyType = {this.ShopCurrencyType} ({this.ShopCurrencyName})" ); // Using Linq here is slower by A LOT but ultimately MUCH more readable amount = Seq.Min(amount, GetMaxPurchasable(), chosen_max); // If we couldn't grab all that we wanted then only subtract the amount we were able to grab int numHeld = heldItem?.Stack ?? 0; if ((numHeld + amount) > chosen_max) { amount = chosen_max - numHeld; } if (amount <= 0) { Log.Trace($"{pfx} purchasable amount <= 0, purchase aborted"); return; } Log.Trace($"{pfx} Purchasing {amount} of {chosen.Name}"); // Try to purchase the item - method returns true if it should be removed from the shop since there's no more. var purchaseMethod = Mod.Reflection.GetMethod(nativeMenu, "tryToPurchaseItem"); int index = BuyAction.GetClickedItemIndex(nativeMenu, clickLocation); if (purchaseMethod.Invoke <bool>(chosen, heldItem, amount, clickLocation.X, clickLocation.Y, index)) { Log.TraceIfD($"{pfx} Item is limited, reducing stock"); // remove the purchased item from the stock etc. nativeMenu.itemPriceAndStock.Remove(chosen); nativeMenu.forSale.Remove(chosen); } }
/// <summary>Creates an instance of the action.</summary> /// <param name="shopMenu">Native shop menu.</param> /// <param name="mouse">Mouse position.</param> /// <returns>The instance or null if no valid item was selected.</returns> public static ShopAction Create(ShopMenu shopMenu, Point mouse) { var item = BuyAction.GetClickedShopItem(shopMenu, mouse); return(item != null ? new BuyAction(shopMenu, item) : null); }
/// <summary>Main event that derived handlers use to setup necessary hooks and other things needed to take over how the stack is split.</summary> /// <returns>If the input was handled or consumed.</returns> protected override EInputHandled OpenSplitMenu() { Log.TraceIfD($"[{nameof(ShopMenuHandler)}.{nameof(OpenSplitMenu)}] Entered"); this.CurrentShopAction = BuyAction.Create(this.NativeMenu, this.ClickItemLocation); return(TryOpenSplitMenu(this.CurrentShopAction)); }