Esempio n. 1
0
        public static void updateItemListAfterShop(object sender, StardewModdingAPI.Events.MenuChangedEventArgs e)
        {
            if (e.OldMenu is ShopMenu sm && lastInventoryId != null && itemLists.ContainsKey(lastInventoryId))
            {
                Dictionary <ISalable, int[]> itemPriceAndStock = sm.itemPriceAndStock;
                foreach (Item item in itemLists[lastInventoryId])
                {
                    Item i    = item.getOne();
                    int  sold = 0;
                    if (itemPriceAndStock.ContainsKey(i))
                    {
                        sold       = item.Stack - itemPriceAndStock[i][1];
                        item.Stack = itemPriceAndStock[i][1];
                    }
                    else
                    {
                        sold       = item.Stack;
                        item.Stack = 0;
                    }

                    if (sm.portraitPerson is NPC npc && npc.Name == "PlayerShop")
                    {
                        long umid = long.Parse(sm.portraitPerson.endOfRouteMessage.Value);
                        if (Game1.getFarmer(umid) is Farmer f)
                        {
                            ShopMenu.chargePlayer(f, sm.getCurrency(), -(i.salePrice() * sold));
                        }
                    }
                }

                itemLists[lastInventoryId].RemoveAll(it => it.Stack <= 0);
                lastInventoryId = null;
            }
        }
Esempio n. 2
0
        internal static void GiftToNpc(string npcName)
        {
            NPC    npc      = Game1.getCharacterFromName(npcName);
            Farmer who      = Game1.player;
            string giftName = who.ActiveObject.DisplayName;

            npc.receiveGift(who.ActiveObject, who, true, 1, DataLoader.ModConfig.ShowDialogOnItemDelivery);
            ShopMenu.chargePlayer(who, 0, DataLoader.ModConfig.GiftServiceFee);
            who.reduceActiveItemByOne();
            who.completeQuest(25);
            if (!DataLoader.ModConfig.ShowDialogOnItemDelivery)
            {
                Game1.drawObjectDialogue(DataLoader.I18N.Get("Shipment.Gift.GiftSent", new { Gift = giftName, Npc = npc.displayName }));
            }
            if (DataLoader.ModConfig.EnableJealousyFromMailedGifts)
            {
                if (npc.datable.Value &&
                    who.spouse != null &&
                    !who.spouse.Contains(npc.Name) &&
                    !who.spouse.Contains("Krobus") &&
                    Utility.isMale(who.spouse) == Utility.isMale(npc.Name) &&
                    Game1.random.NextDouble() < 0.3 - (double)((float)who.LuckLevel / 100f) - who.DailyLuck &&
                    !npc.isBirthday(Game1.currentSeason, Game1.dayOfMonth) &&
                    who.friendshipData[npc.Name].IsDating())
                {
                    NPC spouse = Game1.getCharacterFromName(who.spouse);
                    who.changeFriendship(-30, spouse);
                    spouse.CurrentDialogue.Clear();
                    spouse.CurrentDialogue.Push(new Dialogue(Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.3985", npc.displayName), spouse));
                }
            }
        }
Esempio n. 3
0
        private void BuyTempTool(Farmer who)
        {
            // NOTE: there's no thread safe method for money transactions, so I suppose the game doesn't care about it as well?

            // TODO: handle upgradeLevel so rented tool is not always the cheapest

            Item toolToBuy = this.GetRentedToolByTool(GetToolBeingUpgraded(who));

            if (toolToBuy == null)
            {
                return;
            }

            int toolCost = this.GetToolCost(toolToBuy);

            if (who.money >= toolCost && who.freeSpotsInInventory() > 0)
            {
                ShopMenu.chargePlayer(who, 0, toolCost);
                who.addItemToInventory(toolToBuy);
                this.shouldCreateSucceededToRentTools = true;
            }
            else
            {
                this.shouldCreateFailedToRentTools = true;
            }
        }
Esempio n. 4
0
        /// <summary>Does the action.</summary>
        /// <param name="amount">Number of items.</param>
        /// <param name="clickLocation">Where the player clicked (i.e., when selecting item to split).</param>
        public override void PerformAction(int amount, Point clickLocation)
        {
            amount      = Math.Min(amount, this.ClickedItem.Stack);
            this.Amount = amount; // Remove if we don't need to carry this around

            // Sell item
            int price = CalculateSalePrice(this.ClickedItem, amount);

            ShopMenu.chargePlayer(Game1.player, this.ShopCurrencyType, price);
            Log.Trace($"[{nameof(SellAction)}.{nameof(PerformAction)}] Charged player {price} for {amount} of {this.ClickedItem.Name}");

            // Update the stack amount/remove the item
            var actualInventory = this.InvMenu.actualInventory;
            var index           = actualInventory.IndexOf(this.ClickedItem);

            if (index >= 0 && index < actualInventory.Count)
            {
                int amountRemaining = this.ClickedItem.Stack - amount;
                if (amountRemaining > 0)
                {
                    actualInventory[index].Stack = amountRemaining;
                }
                else
                {
                    actualInventory[index] = null;
                }
            }

            Game1.playSound("purchaseClick");
            if (amount < 1)
            {
                return;
            }
            Animate(amount, clickLocation);
        }
Esempio n. 5
0
        public static bool mailbox()
        {
            try
            {
                if (Game1.player.mailbox.Count == 0 && Game1.player.CurrentTool is Tool tool)
                {
                    if (Game1.player.toolBeingUpgraded.Value == null)
                    {
                        if (tool is Axe || tool is Pickaxe || tool is Hoe || tool is WateringCan)
                        {
                            Dictionary <ISalable, int[]> blacksmithUpgradeStock = Utility.getBlacksmithUpgradeStock(Game1.player);
                            int[] cost = blacksmithUpgradeStock
                                         .Where(s => s.Key.GetType() == tool.GetType())
                                         .Select(s => s.Value)
                                         .FirstOrDefault();
                            if (cost != null)
                            {
                                int       price    = cost[0];
                                int       barIndex = cost[2];
                                const int barCount = 5;
                                if (Game1.player.Money >= price)
                                {
                                    if (Game1.player.hasItemInInventory(barIndex, barCount))
                                    {
                                        ShopMenu.chargePlayer(Game1.player, 0, price);
                                        Game1.player.removeItemsFromInventory(barIndex, barCount);

                                        Game1.drawObjectDialogue(DataLoader.I18N.Get("Shipment.Clint.UpgradeLetter.ToolSent", new { Tool = tool.DisplayName }));

                                        tool.UpgradeLevel++;
                                        Game1.player.removeItemFromInventory(tool);
                                        Game1.player.toolBeingUpgraded.Value      = tool;
                                        Game1.player.daysLeftForToolUpgrade.Value = 2;
                                        Game1.playSound("parry");
                                    }
                                    else
                                    {
                                        Game1.drawObjectDialogue(DataLoader.I18N.Get("Shipment.Clint.UpgradeLetter.NoBars", new { Tool = tool.DisplayName }));
                                    }
                                }
                                else
                                {
                                    Game1.drawObjectDialogue(DataLoader.I18N.Get("Shipment.Clint.UpgradeLetter.NoMoney", new { Tool = tool.DisplayName }));
                                }
                                return(false);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                MailServicesModEntry.ModMonitor.Log("Error trying to send the tool to upgrade.", LogLevel.Error);
                MailServicesModEntry.ModMonitor.Log($"The error message above:{e.Message}", LogLevel.Trace);
            }
            return(true);
        }
Esempio n. 6
0
        /// <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)
        {
            amount      = Math.Min(amount, this.ClickedItem.Stack);
            this.Amount = amount; // Remove if we don't need to carry this around

            // Sell item
            int price = CalculateSalePrice(this.ClickedItem, amount);

            ShopMenu.chargePlayer(Game1.player, this.ShopCurrencyType, price);
            this.Monitor.Log($"Charged player {price} for {amount} of {this.ClickedItem.Name}", LogLevel.Trace);

            // Update the stack amount/remove the item
            var actualInventory = this.Inventory.actualInventory;
            var index           = actualInventory.IndexOf(this.ClickedItem);

            if (index >= 0 && index < actualInventory.Count)
            {
                int amountRemaining = this.ClickedItem.Stack - amount;
                if (amountRemaining > 0)
                {
                    actualInventory[index].Stack = amountRemaining;
                }
                else
                {
                    actualInventory[index] = null;
                }
            }

            Game1.playSound("purchaseClick");

            // The animation seems to only play when we sell 1
            if (amount == 1)
            {
                // Play the sell animation
                var animationsField = this.Reflection.GetField <List <TemporaryAnimatedSprite> >(this.NativeShopMenu, "animations");
                var animations      = animationsField.GetValue();

                // Messy because it's a direct copy-paste from the source code
                Vector2 value = this.Inventory.snapToClickableComponent(clickLocation.X, clickLocation.Y);
                animations.Add(new TemporaryAnimatedSprite(Game1.debrisSpriteSheet.Name, new Rectangle(Game1.random.Next(2) * Game1.tileSize, 256, Game1.tileSize, Game1.tileSize), 9999f, 1, 999, value + new Vector2(32f, 32f), false, false)
                {
                    alphaFade    = 0.025f,
                    motion       = Utility.getVelocityTowardPoint(new Point((int)value.X + 32, (int)value.Y + 32), Game1.dayTimeMoneyBox.position + new Vector2(96f, 196f), 12f),
                    acceleration = Utility.getVelocityTowardPoint(new Point((int)value.X + 32, (int)value.Y + 32), Game1.dayTimeMoneyBox.position + new Vector2(96f, 196f), 0.5f)
                });

                animationsField.SetValue(animations);
            }
        }
        /// <summary>
        /// To call when the items were recovered.
        /// Charge the player and clear the lost items list if needed.
        /// </summary>
        public static void ItemsRecovered()
        {
            Dictionary <ISalable, int[]> adventureRecoveryStock = Utility.getAdventureRecoveryStock();
            RecoveryConfig recoveryConfig = DataLoader.GetRecoveryConfig(Game1.player);

            _itemsToRecover.Value.ForEach(item =>
            {
                if (!recoveryConfig.RecoverForFree)
                {
                    ShopMenu.chargePlayer(Game1.player, 0, adventureRecoveryStock[item][0]);
                }
                Game1.player.itemsLostLastDeath.Remove(item);
            });
            if (!recoveryConfig.DisableClearLostItemsOnRandomRecovery && !recoveryConfig.RecoverAllItems)
            {
                Game1.player.itemsLostLastDeath.Clear();
            }
            _itemsToRecover.Value = null;
        }
Esempio n. 8
0
        /// <summary>Attach an onSell callback to a ShopMenu, while keeping the default sell behavior.</summary>
        /// <param name="shop">The ShopMenu.</param>
        /// <param name="onSell">The callback to be attached. A return value of true exits the menu.</param>
        public static void AttachQuietSellCallback(ShopMenu shop, Func <ISalable, bool> onSell)
        {
            Func <ISalable, bool> origOnSell = shop.onSell;

            shop.onSell = delegate(ISalable salable)
            {
                bool exit = onSell(salable);

                if (origOnSell != null)
                {
                    return(origOnSell(salable) || exit);
                }
                else if (salable is Item item)
                {
                    ISalable?buybackItem    = null;
                    float    sellPercentage = (float?)SellPercentageField.GetValue(shop) ?? 1f;
                    int      sellPrice;

                    if (item is SObject obj)
                    {
                        sellPrice = (int)(obj.sellToStorePrice() * sellPercentage);
                    }
                    else
                    {
                        sellPrice = (int)(item.salePrice() * sellPercentage / 2);
                    }

                    ShopMenu.chargePlayer(Game1.player, shop.currency, -sellPrice * item.Stack);

                    if (shop.CanBuyback())
                    {
                        buybackItem = shop.AddBuybackItem(item, sellPrice, item.Stack);
                    }

                    if (item is SObject && ((SObject)item).Edibility != -300)
                    {
                        if (buybackItem != null && shop.buyBackItemsToResellTomorrow.ContainsKey(buybackItem))
                        {
                            shop.buyBackItemsToResellTomorrow[buybackItem].Stack += item.Stack;
                        }
                        else if (Game1.currentLocation is ShopLocation location)
                        {
                            Item clone = item.getOne();
                            clone.Stack = item.Stack;

                            if (buybackItem != null)
                            {
                                shop.buyBackItemsToResellTomorrow[buybackItem] = clone;
                            }

                            location.itemsToStartSellingTomorrow.Add(clone);
                        }
                    }

                    if (AnimationsField.GetValue(shop) is List <TemporaryAnimatedSprite> animations)
                    {
                        Vector2 animationPosition     = shop.inventory.snapToClickableComponent(Game1.getMouseX(), Game1.getMouseY()) + new Vector2(32f, 32f);
                        Vector2 animationMotionTarget = new Vector2(shop.xPositionOnScreen - 36, shop.yPositionOnScreen + shop.height - shop.inventory.height - 16);
                        int     coins = item.Stack / 8 + 2;

                        for (int i = 0; i < coins; i++)
                        {
                            animations.Add(new TemporaryAnimatedSprite("TileSheets\\debris", new Rectangle(Game1.random.Next(2) * 16, 64, 16, 16), 9999f, 1, 999, animationPosition, false, false)
                            {
                                scale     = 2f,
                                alphaFade = 0.025f,
                                delayBeforeAnimationStart = i * 25,
                                motion       = new Vector2(Game1.random.Next(-3, 4), -4f),
                                acceleration = new Vector2(0, 0.5f)
                            });

                            animations.Add(new TemporaryAnimatedSprite("TileSheets\\debris", new Rectangle(Game1.random.Next(2) * 16, 64, 16, 16), 9999f, 1, 999, animationPosition, false, false)
                            {
                                scale     = 4f,
                                alphaFade = 0.025f,
                                delayBeforeAnimationStart = i * 25,
                                motion       = Utility.getVelocityTowardPoint(animationPosition, animationMotionTarget, 8f),
                                acceleration = Utility.getVelocityTowardPoint(animationPosition, animationMotionTarget, 0.5f)
                            });
                        }

                        if (shop.inventory.getItemAt(Game1.getMouseX(), Game1.getMouseY()) == null)
                        {
                            animations.Add(new TemporaryAnimatedSprite(5, animationPosition, Color.White)
                            {
                                motion = new Vector2(0, -0.5f)
                            });
                        }
                    }

                    Game1.playSound("sell");
                    Game1.playSound("purchase");
                }

                return(exit);
            };
        }
        /// Callback answer for dialogue choice on upgrade menu.
        private void CallAnswer(Farmer who, string answer)
        {
            bool buySuccess = false;

            if (answer.Equals("Leave"))
            {
                return;
            }
            else if (answer.Equals("Storage"))
            {
                int[] prices = { 2000, 5000, 10000, 20000, 30000, 50000 };
                if (ShopMenu.getPlayerCurrencyAmount(Game1.player, 0) >= prices[this.upgradeStorage])
                {
                    ShopMenu.chargePlayer(Game1.player, 0, prices[this.upgradeStorage]);
                    this.upgradeStorage++;
                    Game1.drawObjectDialogue("Thank you very much! Your upgrade will be installed by tomorrow.");
                    return;
                }
            }
            else if (answer.Equals("ID"))
            {
                Game1.drawObjectDialogue("We cannot provide you with this service at the moment.");
                return;
            }
            else if (answer.Equals("Lim"))
            {
                if (ShopMenu.getPlayerCurrencyAmount(Game1.player, 0) >= 10000)
                {
                    ShopMenu.chargePlayer(Game1.player, 0, 10000);
                    this.upgradeModules += upgradeLim;
                    buySuccess           = true;
                }
            }
            else if (answer.Equals("Warp"))
            {
                if (ShopMenu.getPlayerCurrencyAmount(Game1.player, 0) >= 20000)
                {
                    ShopMenu.chargePlayer(Game1.player, 0, 20000);
                    this.upgradeModules += upgradeWarp;
                    buySuccess           = true;
                }
            }
            else if (answer.Equals("Portal"))
            {
                if (ShopMenu.getPlayerCurrencyAmount(Game1.player, 0) >= 50000)
                {
                    ShopMenu.chargePlayer(Game1.player, 0, 50000);
                    this.upgradeModules += upgradePortal;
                    buySuccess           = true;
                }
            }
            else if (answer.Equals("Dimension"))
            {
                if (ShopMenu.getPlayerCurrencyAmount(Game1.player, 0) >= 150000)
                {
                    ShopMenu.chargePlayer(Game1.player, 0, 150000);
                    this.upgradeModules += upgradeDimension;
                    buySuccess           = true;
                }
            }

            if (buySuccess)
            {
                Game1.drawObjectDialogue("Thank you very much! Your upgrade module should be active now.");
            }
            else
            {
                Game1.drawObjectDialogue("It seem like you dont have enough money...");
            }
        }
Esempio n. 10
0
        private void doGridLayoutRightClick(ButtonPressedEventArgs e)
        {
            var       forSale           = Helper.Reflection.GetField <List <ISalable> >(shop, "forSale").GetValue();
            var       itemPriceAndStock = Helper.Reflection.GetField <Dictionary <ISalable, int[]> >(shop, "itemPriceAndStock").GetValue();
            var       currency          = Helper.Reflection.GetField <int>(shop, "currency").GetValue();
            var       animations        = Helper.Reflection.GetField <List <TemporaryAnimatedSprite> >(shop, "animations").GetValue();
            var       poof             = Helper.Reflection.GetField <TemporaryAnimatedSprite>(shop, "poof").GetValue();
            var       heldItem         = Helper.Reflection.GetField <ISalable>(shop, "heldItem").GetValue();
            var       currentItemIndex = Helper.Reflection.GetField <int>(shop, "currentItemIndex").GetValue();
            var       sellPercentage   = Helper.Reflection.GetField <float>(shop, "sellPercentage").GetValue();
            const int UNIT_WIDTH       = 160;
            const int UNIT_HEIGHT      = 144;
            int       unitsWide        = (shop.width - 32) / UNIT_WIDTH;

            int x = (int)e.Cursor.ScreenPixels.X;
            int y = (int)e.Cursor.ScreenPixels.Y;

            if (shop.upperRightCloseButton.containsPoint(x, y))
            {
                shop.exitThisMenu(true);
                return;
            }

            // Copying a lot from right click code
            Vector2 clickableComponent = shop.inventory.snapToClickableComponent(x, y);

            if (heldItem == null)
            {
                Item obj = shop.inventory.rightClick(x, y, null, false);
                if (obj != null)
                {
                    if (shop.onSell != null)
                    {
                        shop.onSell(obj);
                    }
                    else
                    {
                        ShopMenu.chargePlayer(Game1.player, currency, -((obj is StardewValley.Object ? (int)((double)(obj as StardewValley.Object).sellToStorePrice() * (double)sellPercentage) : (int)((double)(obj.salePrice() / 2) * (double)sellPercentage)) * obj.Stack));
                        Item obj2 = (Item)null;
                        if (Game1.mouseClickPolling > 300)
                        {
                            Game1.playSound("purchaseRepeat");
                        }
                        else
                        {
                            Game1.playSound("purchaseClick");
                        }
                        animations.Add(new TemporaryAnimatedSprite("TileSheets\\debris", new Rectangle(Game1.random.Next(2) * 64, 256, 64, 64), 9999f, 1, 999, clickableComponent + new Vector2(32f, 32f), false, false)
                        {
                            alphaFade    = 0.025f,
                            motion       = Utility.getVelocityTowardPoint(new Point((int)clickableComponent.X + 32, (int)clickableComponent.Y + 32), Game1.dayTimeMoneyBox.position + new Vector2(96f, 196f), 12f),
                            acceleration = Utility.getVelocityTowardPoint(new Point((int)clickableComponent.X + 32, (int)clickableComponent.Y + 32), Game1.dayTimeMoneyBox.position + new Vector2(96f, 196f), 0.5f)
                        });
                        if (obj is StardewValley.Object && (obj as StardewValley.Object).Edibility != -300)
                        {
                            (Game1.getLocationFromName("SeedShop") as StardewValley.Locations.SeedShop).itemsToStartSellingTomorrow.Add(obj.getOne());
                        }
                        if (shop.inventory.getItemAt(x, y) == null)
                        {
                            Game1.playSound("sell");
                            animations.Add(new TemporaryAnimatedSprite(5, clickableComponent + new Vector2(32f, 32f), Color.White, 8, false, 100f, 0, -1, -1f, -1, 0)
                            {
                                motion = new Vector2(0.0f, -0.5f)
                            });
                        }
                    }
                }
            }
            else
            {
                heldItem = shop.inventory.leftClick(x, y, (Item)heldItem, true);
                Helper.Reflection.GetField <ISalable>(shop, "heldItem").SetValue(heldItem);
            }
            for (int i = currentItemIndex * unitsWide; i < forSale.Count && i < currentItemIndex * unitsWide + unitsWide * 3; ++i)
            {
                int       ix   = i % unitsWide;
                int       iy   = i / unitsWide;
                Rectangle rect = new Rectangle(shop.xPositionOnScreen + 16 + ix * UNIT_WIDTH, shop.yPositionOnScreen + 16 + iy * UNIT_HEIGHT - currentItemIndex * UNIT_HEIGHT, UNIT_WIDTH, UNIT_HEIGHT);
                if (rect.Contains(x, y) && forSale[i] != null)
                {
                    int index2 = i;
                    if (forSale[index2] == null)
                    {
                        break;
                    }
                    int numberToBuy       = Game1.oldKBState.IsKeyDown(Keys.LeftShift) ? Math.Min(Math.Min(5, ShopMenu.getPlayerCurrencyAmount(Game1.player, currency) / itemPriceAndStock[forSale[index2]][0]), itemPriceAndStock[forSale[index2]][1]) : 1;
                    var tryToPurchaseItem = Helper.Reflection.GetMethod(shop, "tryToPurchaseItem");
                    if (numberToBuy > 0 && tryToPurchaseItem.Invoke <bool>(forSale[index2], heldItem, numberToBuy, x, y, index2))
                    {
                        itemPriceAndStock.Remove(forSale[index2]);
                        forSale.RemoveAt(index2);
                    }
                    if (heldItem == null || !Game1.options.SnappyMenus || (Game1.activeClickableMenu == null || !(Game1.activeClickableMenu is ShopMenu)) || !Game1.player.addItemToInventoryBool((Item)heldItem, false))
                    {
                        break;
                    }
                    heldItem = (Item)null;
                    Helper.Reflection.GetField <ISalable>(shop, "heldItem").SetValue(heldItem);
                    DelayedAction.playSoundAfterDelay("coin", 100, (GameLocation)null);
                    break;
                }
            }
        }
Esempio n. 11
0
        private void doGridLayoutLeftClick(ButtonPressedEventArgs e)
        {
            var       forSale           = Helper.Reflection.GetField <List <ISalable> >(shop, "forSale").GetValue();
            var       itemPriceAndStock = Helper.Reflection.GetField <Dictionary <ISalable, int[]> >(shop, "itemPriceAndStock").GetValue();
            var       currency          = Helper.Reflection.GetField <int>(shop, "currency").GetValue();
            var       animations        = Helper.Reflection.GetField <List <TemporaryAnimatedSprite> >(shop, "animations").GetValue();
            var       poof             = Helper.Reflection.GetField <TemporaryAnimatedSprite>(shop, "poof").GetValue();
            var       heldItem         = Helper.Reflection.GetField <ISalable>(shop, "heldItem").GetValue();
            var       currentItemIndex = Helper.Reflection.GetField <int>(shop, "currentItemIndex").GetValue();
            var       sellPercentage   = Helper.Reflection.GetField <float>(shop, "sellPercentage").GetValue();
            var       scrollBar        = Helper.Reflection.GetField <ClickableTextureComponent>(shop, "scrollBar").GetValue();
            var       scrollBarRunner  = Helper.Reflection.GetField <Rectangle>(shop, "scrollBarRunner").GetValue();
            var       downArrow        = Helper.Reflection.GetField <ClickableTextureComponent>(shop, "downArrow").GetValue();
            var       upArrow          = Helper.Reflection.GetField <ClickableTextureComponent>(shop, "upArrow").GetValue();
            const int UNIT_WIDTH       = 160;
            const int UNIT_HEIGHT      = 144;
            int       unitsWide        = (shop.width - 32) / UNIT_WIDTH;

            int x = (int)e.Cursor.ScreenPixels.X;
            int y = (int)e.Cursor.ScreenPixels.Y;

            if (shop.upperRightCloseButton.containsPoint(x, y))
            {
                shop.exitThisMenu(true);
                return;
            }

            // Copying a lot from left click code
            if (downArrow.containsPoint(x, y) && currentItemIndex < Math.Max(0, forSale.Count - 18))
            {
                downArrow.scale = downArrow.baseScale;
                Helper.Reflection.GetField <int>(shop, "currentItemIndex").SetValue(currentItemIndex += 1);
                if (forSale.Count > 0)
                {
                    scrollBar.bounds.Y = scrollBarRunner.Height / Math.Max(1, (forSale.Count / 6) - 1 + 1) * currentItemIndex + upArrow.bounds.Bottom + 4;
                    if (currentItemIndex == forSale.Count / 6 - 1)
                    {
                        scrollBar.bounds.Y = downArrow.bounds.Y - scrollBar.bounds.Height - 4;
                    }
                }
                Game1.playSound("shwip");
            }
            else if (upArrow.containsPoint(x, y) && currentItemIndex > 0)
            {
                upArrow.scale = upArrow.baseScale;
                Helper.Reflection.GetField <int>(shop, "currentItemIndex").SetValue(currentItemIndex -= 1);
                if (forSale.Count > 0)
                {
                    scrollBar.bounds.Y = scrollBarRunner.Height / Math.Max(1, (forSale.Count / 6) - 1 + 1) * currentItemIndex + upArrow.bounds.Bottom + 4;
                    if (currentItemIndex == forSale.Count / 6 - 1)
                    {
                        scrollBar.bounds.Y = downArrow.bounds.Y - scrollBar.bounds.Height - 4;
                    }
                }
                Game1.playSound("shwip");
            }
            else if (scrollBarRunner.Contains(x, y))
            {
                int y1 = scrollBar.bounds.Y;
                scrollBar.bounds.Y = Math.Min(shop.yPositionOnScreen + shop.height - 64 - 12 - scrollBar.bounds.Height, Math.Max(y, shop.yPositionOnScreen + upArrow.bounds.Height + 20));
                currentItemIndex   = Math.Min(forSale.Count / 6 - 1, Math.Max(0, (int)((double)forSale.Count / 6 * (double)((float)(y - scrollBarRunner.Y) / (float)scrollBarRunner.Height))));
                Helper.Reflection.GetField <int>(shop, "currentItemIndex").SetValue(currentItemIndex);
                if (forSale.Count > 0)
                {
                    scrollBar.bounds.Y = scrollBarRunner.Height / Math.Max(1, (forSale.Count / 6) - 1 + 1) * currentItemIndex + upArrow.bounds.Bottom + 4;
                    if (currentItemIndex == forSale.Count / 6 - 1)
                    {
                        scrollBar.bounds.Y = downArrow.bounds.Y - scrollBar.bounds.Height - 4;
                    }
                }
                int y2 = scrollBar.bounds.Y;
                if (y1 == y2)
                {
                    return;
                }
                Game1.playSound("shiny4");
            }
            Vector2 clickableComponent = shop.inventory.snapToClickableComponent(x, y);

            if (heldItem == null)
            {
                Item obj = shop.inventory.leftClick(x, y, null, false);
                if (obj != null)
                {
                    if (shop.onSell != null)
                    {
                        shop.onSell(obj);
                    }
                    else
                    {
                        ShopMenu.chargePlayer(Game1.player, currency, -((obj is StardewValley.Object ? (int)((double)(obj as StardewValley.Object).sellToStorePrice() * (double)sellPercentage) : (int)((double)(obj.salePrice() / 2) * (double)sellPercentage)) * obj.Stack));
                        int num = obj.Stack / 8 + 2;
                        for (int index = 0; index < num; ++index)
                        {
                            animations.Add(new TemporaryAnimatedSprite("TileSheets\\debris", new Rectangle(Game1.random.Next(2) * 16, 64, 16, 16), 9999f, 1, 999, clickableComponent + new Vector2(32f, 32f), false, false)
                            {
                                alphaFade    = 0.025f,
                                motion       = new Vector2((float)Game1.random.Next(-3, 4), -4f),
                                acceleration = new Vector2(0.0f, 0.5f),
                                delayBeforeAnimationStart = index * 25,
                                scale = 2f
                            });
                            animations.Add(new TemporaryAnimatedSprite("TileSheets\\debris", new Rectangle(Game1.random.Next(2) * 16, 64, 16, 16), 9999f, 1, 999, clickableComponent + new Vector2(32f, 32f), false, false)
                            {
                                scale     = 4f,
                                alphaFade = 0.025f,
                                delayBeforeAnimationStart = index * 50,
                                motion       = Utility.getVelocityTowardPoint(new Point((int)clickableComponent.X + 32, (int)clickableComponent.Y + 32), new Vector2((float)(shop.xPositionOnScreen - 36), (float)(shop.yPositionOnScreen + shop.height - shop.inventory.height - 16)), 8f),
                                acceleration = Utility.getVelocityTowardPoint(new Point((int)clickableComponent.X + 32, (int)clickableComponent.Y + 32), new Vector2((float)(shop.xPositionOnScreen - 36), (float)(shop.yPositionOnScreen + shop.height - shop.inventory.height - 16)), 0.5f)
                            });
                        }
                        if (obj is StardewValley.Object && (obj as StardewValley.Object).Edibility != -300)
                        {
                            Item one = obj.getOne();
                            one.Stack = obj.Stack;
                            (Game1.getLocationFromName("SeedShop") as StardewValley.Locations.SeedShop).itemsToStartSellingTomorrow.Add(one);
                        }
                        Game1.playSound("sell");
                        Game1.playSound("purchase");
                    }
                }
            }
            else
            {
                heldItem = shop.inventory.leftClick(x, y, (Item)heldItem, true);
                Helper.Reflection.GetField <ISalable>(shop, "heldItem").SetValue(heldItem);
            }
            for (int i = currentItemIndex * unitsWide; i < forSale.Count && i < currentItemIndex * unitsWide + unitsWide * 3; ++i)
            {
                int       ix   = i % unitsWide;
                int       iy   = i / unitsWide;
                Rectangle rect = new Rectangle(shop.xPositionOnScreen + 16 + ix * UNIT_WIDTH, shop.yPositionOnScreen + 16 + iy * UNIT_HEIGHT - currentItemIndex * UNIT_HEIGHT, UNIT_WIDTH, UNIT_HEIGHT);
                if (rect.Contains(x, y) && forSale[i] != null)
                {
                    int numberToBuy = Math.Min(Game1.oldKBState.IsKeyDown(Keys.LeftShift) ? Math.Min(Math.Min(5, ShopMenu.getPlayerCurrencyAmount(Game1.player, currency) / Math.Max(1, itemPriceAndStock[forSale[i]][0])), Math.Max(1, itemPriceAndStock[forSale[i]][1])) : 1, forSale[i].maximumStackSize());
                    if (numberToBuy == -1)
                    {
                        numberToBuy = 1;
                    }
                    var tryToPurchaseItem = Helper.Reflection.GetMethod(shop, "tryToPurchaseItem");
                    if (numberToBuy > 0 && tryToPurchaseItem.Invoke <bool>(forSale[i], heldItem, numberToBuy, x, y, i))
                    {
                        itemPriceAndStock.Remove(forSale[i]);
                        forSale.RemoveAt(i);
                    }
                    else if (numberToBuy <= 0)
                    {
                        Game1.dayTimeMoneyBox.moneyShakeTimer = 1000;
                        Game1.playSound("cancel");
                    }
                    if (heldItem != null && Game1.options.SnappyMenus && (Game1.activeClickableMenu != null && Game1.activeClickableMenu is ShopMenu) && Game1.player.addItemToInventoryBool((Item)heldItem, false))
                    {
                        heldItem = (Item)null;
                        Helper.Reflection.GetField <ISalable>(shop, "heldItem").SetValue(heldItem);
                        DelayedAction.playSoundAfterDelay("coin", 100, (GameLocation)null);
                    }
                }
            }
        }
Esempio n. 12
0
        public static bool mailbox()
        {
            try
            {
                if (!DataLoader.ModConfig.DisableQuestService && Game1.player.mailbox.Count == 0 && Game1.player.ActiveObject != null)
                {
                    foreach (Quest quest in Game1.player.questLog)
                    {
                        if (quest is ItemDeliveryQuest itemDeliveryQuest && !itemDeliveryQuest.completed.Value)
                        {
                            var item = Game1.player.ActiveObject;
                            if ((item.ParentSheetIndex == itemDeliveryQuest.item.Value || item.Category == itemDeliveryQuest.item.Value))
                            {
                                NPC npc = Game1.getCharacterFromName(itemDeliveryQuest.target.Value);
                                if (item.Stack >= itemDeliveryQuest.number.Value)
                                {
                                    if (Game1.player.Money >= DataLoader.ModConfig.QuestServiceFee)
                                    {
                                        ShopMenu.chargePlayer(Game1.player, 0, DataLoader.ModConfig.QuestServiceFee);
                                        Game1.player.ActiveObject.Stack -= (int)itemDeliveryQuest.number.Value - 1;
                                        if (DataLoader.ModConfig.ShowDialogOnItemDelivery)
                                        {
                                            itemDeliveryQuest.reloadDescription();
                                            npc.CurrentDialogue.Push(new Dialogue(itemDeliveryQuest.targetMessage, npc));
                                            Game1.drawDialogue(npc);
                                        }
                                        Game1.player.reduceActiveItemByOne();
                                        if ((bool)itemDeliveryQuest.dailyQuest.Value)
                                        {
                                            Game1.player.changeFriendship(150, npc);
                                            if (itemDeliveryQuest.deliveryItem.Value == null)
                                            {
                                                itemDeliveryQuest.deliveryItem.Value = new SObject(Vector2.Zero, itemDeliveryQuest.item.Value, 1);
                                            }
                                            itemDeliveryQuest.moneyReward.Value = itemDeliveryQuest.deliveryItem.Value.Price * 3;
                                        }
                                        else
                                        {
                                            Game1.player.changeFriendship(255, npc);
                                        }
                                        itemDeliveryQuest.questComplete();
                                    }
                                    else
                                    {
                                        Game1.drawObjectDialogue(DataLoader.I18N.Get("Shipment.Quest.ItemDelivery.NoMoney"));
                                    }
                                }
                                else
                                {
                                    if (DataLoader.ModConfig.ShowDialogOnItemDelivery)
                                    {
                                        npc.CurrentDialogue.Push(new Dialogue(Game1.content.LoadString("Strings\\StringsFromCSFiles:ItemDeliveryQuest.cs.13615", itemDeliveryQuest.number.Value), npc));
                                        Game1.drawDialogue(npc);
                                    }
                                    else
                                    {
                                        Game1.drawObjectDialogue(DataLoader.I18N.Get("Shipment.Quest.ItemDelivery.NotEnoughItems", new { Npc = npc.displayName, Number = itemDeliveryQuest.number.Value }));
                                    }
                                }
                                return(false);
                            }
                        }
                        else if (quest is LostItemQuest lostItemQuest && !lostItemQuest.completed.Value)
                        {
                            if (lostItemQuest.itemFound.Value && Game1.player.hasItemInInventory(lostItemQuest.itemIndex.Value, 1))
                            {
                                lostItemQuest.questComplete();
                                NPC npc = Game1.getCharacterFromName(lostItemQuest.npcName.Value);

                                if (DataLoader.ModConfig.ShowDialogOnItemDelivery)
                                {
                                    Dictionary <int, string> questData = Game1.temporaryContent.Load <Dictionary <int, string> >("Data\\Quests");
                                    string thankYou = (questData[lostItemQuest.id.Value].Length > 9) ? questData[lostItemQuest.id.Value].Split('/')[9] : Game1.content.LoadString("Data\\ExtraDialogue:LostItemQuest_DefaultThankYou");
                                    npc.setNewDialogue(thankYou);
                                    Game1.drawDialogue(npc);
                                }
                                Game1.player.changeFriendship(250, npc);
                                Game1.player.removeFirstOfThisItemFromInventory(lostItemQuest.itemIndex.Value);
                                return(false);
                            }
                        }
                    }
                }