internal static bool IsUsingForCrafting(ItemBag Bag)
 {
     return(BagsInUse != null && BagsInUse.Contains(Bag));
 }
Example #2
0
 public IEnumerator GetEnumerator()
 {
     return(ItemBag.GetEnumerator());
 }
Example #3
0
 public void Add(ResultItem resultItem)
 {
     ItemBag.Add(resultItem);
 }
 public ItemBagMenu(ItemBag Bag, IList <Item> InventorySource, int ActualCapacity, BagMenuOptions Options)
     : this(Bag, InventorySource, ActualCapacity, Options.InventoryColumns, Options.InventorySlotSize)
 {
 }
 private void Awake()
 {
     Instance = this;
     //currentItem = itemBoxs[0].item;
 }
        private static void Input_ButtonPressed(object sender, ButtonPressedEventArgs e)
        {
            try
            {
                Point CursorPos      = e.Cursor.LegacyScreenPixels().AsAndroidCompatibleCursorPoint();
                bool  IsGamepadInput = e.Button.TryGetController(out Buttons GamepadButtons);

                if (Game1.activeClickableMenu != null && Game1.activeClickableMenu is ItemBagMenu IBM)
                {
                    if (e.Button == SButton.MouseLeft || e.Button == SButton.MouseMiddle || e.Button == SButton.MouseRight)
                    {
                        try { IBM.OnMouseButtonPressed(e); }
                        catch (Exception ex) { Monitor.Log(string.Format("Unhandled error while handling Mouse button pressed: {0}\n\n{1}", ex.Message, ex.ToString()), LogLevel.Error); }
                    }
                    else if (e.Button == SButton.LeftShift || e.Button == SButton.RightShift || e.Button == SButton.LeftControl || e.Button == SButton.RightControl)
                    {
                        try { IBM.OnModifierKeyPressed(e); }
                        catch (Exception ex) { Monitor.Log(string.Format("Unhandled error while handling Modifier key pressed: {0}\n\n{1}", ex.Message, ex.ToString()), LogLevel.Error); }
                    }
                    else if (IsGamepadInput)
                    {
                        try
                        {
                            //  Handle navigation buttons
                            foreach (NavigationDirection Direction in Enum.GetValues(typeof(NavigationDirection)).Cast <NavigationDirection>())
                            {
                                if (GamepadControls.IsMatch(GamepadButtons, GamepadControls.NavigateSingleButtons[Direction]))
                                {
                                    NavigationButtonsPressedTime[Direction] = DateTime.Now;
                                }
                            }

                            IBM.OnGamepadButtonsPressed(GamepadButtons);
                        }
                        catch (Exception ex) { Monitor.Log(string.Format("Unhandled error while handling Gamepad button pressed: {0}\n\n{1}", ex.Message, ex.ToString()), LogLevel.Error); }
                    }
                }
                else if (Game1.activeClickableMenu != null && Game1.activeClickableMenu is GameMenu GM && GM.currentTab == GameMenu.inventoryTab)
                {
                    InventoryPage InvPage = GM.pages.First(x => x is InventoryPage) as InventoryPage;
                    InventoryMenu InvMenu = InvPage.inventory;

                    int  ClickedItemIndex     = InvMenu.getInventoryPositionOfClick(CursorPos.X, CursorPos.Y);
                    bool IsValidInventorySlot = ClickedItemIndex >= 0 && ClickedItemIndex < InvMenu.actualInventory.Count;
                    if (IsValidInventorySlot)
                    {
                        Item ClickedItem = InvMenu.actualInventory[ClickedItemIndex];

                        //  Double click an ItemBag to open it
                        if (e.Button == SButton.MouseLeft) //SButtonExtensions.IsUseToolButton(e.Button))
                        {
                            //  The first time the user clicks an item in their inventory, Game1.player.CursorSlotItem is set to what they clicked (so it's like drag/drop, they're now holding the item to move it)
                            //  So to detect a double click, we can't just check if they clicked the bag twice in a row, since on the second click the item would no longer be in their inventory.
                            //  Instead, we need to check if they clicked the bag and then we need to check Game1.player.CursorSlotItem on the next click
                            if (ClickedItem is ItemBag ClickedBag && Game1.player.CursorSlotItem == null)
                            {
                                LastClickedBagInventoryIndex = ClickedItemIndex;
                                LastClickedBag     = ClickedBag;
                                LastClickedBagTime = DateTime.Now;
                            }
                            else if (ClickedItem == null && Game1.player.CursorSlotItem is ItemBag DraggedBag && LastClickedBag == DraggedBag &&
                                     LastClickedBagInventoryIndex.HasValue && LastClickedBagInventoryIndex.Value == ClickedItemIndex &&
                                     LastClickedBagTime.HasValue && DateTime.Now.Subtract(LastClickedBagTime.Value).TotalMilliseconds <= DoubleClickThresholdMS)
                            {
                                LastClickedBag     = DraggedBag;
                                LastClickedBagTime = DateTime.Now;

                                //  Put the item that's being dragged back into their inventory
                                Game1.player.addItemToInventory(Game1.player.CursorSlotItem, ClickedItemIndex);
                                Game1.player.CursorSlotItem = null;

                                DraggedBag.OpenContents(Game1.player.Items, Game1.player.MaxItems);
                            }
                        }
                        //  Right-click an ItemBag to open it
                        else if ((e.Button == SButton.MouseRight || (IsGamepadInput && GamepadControls.IsMatch(GamepadButtons, GamepadControls.Current.OpenBagFromInventory))) &&
                                 ClickedItem is ItemBag ClickedBag && Game1.player.CursorSlotItem == null)
                        {
                            ClickedBag.OpenContents(Game1.player.Items, Game1.player.MaxItems);
                        }

                        //  Handle dropping an item into a bag from the Inventory menu
                        if (ClickedItem is ItemBag IB && Game1.player.CursorSlotItem != null && Game1.player.CursorSlotItem is Object Obj)
                        {
                            if (IB.IsValidBagItem(Obj) && (e.Button == SButton.MouseLeft || e.Button == SButton.MouseRight))
                            {
                                int Qty = ItemBag.GetQuantityToTransfer(e, Obj);
                                IB.MoveToBag(Obj, Qty, out int MovedQty, true, Game1.player.Items);

                                if (e.Button == SButton.MouseLeft)
                                // || (MovedQty > 0 && Obj.Stack == 0) // Handle moving the last quantity with a right-click
                                {
                                    //  Clicking the bag will have made it become the held CursorSlotItem, so queue up an action that will swap them back on next game tick
                                    QueueCursorSlotIndex     = ClickedItemIndex;
                                    QueuePlaceCursorSlotItem = true;
                                }
                            }
                        }
                    }
                }
                else if (Game1.activeClickableMenu == null &&
                         (e.Button == SButton.MouseLeft || e.Button == SButton.MouseRight || (IsGamepadInput && GamepadControls.IsMatch(GamepadButtons, GamepadControls.Current.OpenBagFromToolbar))))
                {
                    //  Check if they clicked a bag on the toolbar, open the bag if so
                    Toolbar toolbar = Game1.onScreenMenus.FirstOrDefault(x => x is Toolbar) as Toolbar;
                    if (toolbar != null)
                    {
                        try
                        {
                            List <ClickableComponent> toolbarButtons = typeof(Toolbar).GetField("buttons", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(toolbar) as List <ClickableComponent>;
                            if (toolbarButtons != null)
                            {
                                //  Find the slot on the toolbar that they clicked, if any
                                for (int i = 0; i < toolbarButtons.Count; i++)
                                {
                                    if (toolbarButtons[i].bounds.Contains(CursorPos) || (IsGamepadInput && toolbar.currentlySnappedComponent == toolbarButtons[i]))
                                    {
                                        int ActualIndex = i;
                                        if (Constants.TargetPlatform == GamePlatform.Android)
                                        {
                                            try
                                            {
                                                int StartIndex = Helper.Reflection.GetField <int>(toolbar, "_drawStartIndex").GetValue(); // This is completely untested
                                                ActualIndex = i + StartIndex;
                                            }
                                            catch (Exception) { }
                                        }

                                        //  Get the corresponding Item from the player's inventory
                                        Item item = Game1.player.Items[ActualIndex];
                                        if (item is ItemBag IB)
                                        {
                                            IB.OpenContents(Game1.player.Items, Game1.player.MaxItems);
                                        }
                                        break;
                                    }
                                }
                            }
                        }
                        catch (Exception) { }
                    }
                }
                else if (Game1.activeClickableMenu is ItemGrabMenu IGM && IGM.context is Chest ChestSource &&
                         (e.Button == SButton.MouseRight || e.Button == SButton.MouseMiddle || (IsGamepadInput && GamepadControls.IsMatch(GamepadButtons, GamepadControls.Current.OpenBagFromChest))))
                {
                    //  Check if they clicked a Bag in the inventory part of the chest interface
                    bool Handled = false;
                    for (int i = 0; i < IGM.inventory.inventory.Count; i++)
                    {
                        ClickableComponent Component = IGM.inventory.inventory[i];
                        if (Component != null && Component.bounds.Contains(CursorPos))
                        {
                            Item ClickedInvItem = i < 0 || i >= IGM.inventory.actualInventory.Count ? null : IGM.inventory.actualInventory[i];
                            if (ClickedInvItem is ItemBag IB)
                            {
                                IB.OpenContents(IGM.inventory.actualInventory, Game1.player.MaxItems);
                            }
                            Handled = true;
                            break;
                        }
                    }

                    bool IsMegaStorageCompatibleWithCurrentChest = IGM.ItemsToGrabMenu.capacity == DefaultChestCapacity ||
                                                                   MegaStorageInstalledVersion == null || MegaStorageInstalledVersion.IsNewerThan(new SemanticVersion(1, 4, 4));
                    if (!Handled && IsMegaStorageCompatibleWithCurrentChest)
                    {
                        //  Check if they clicked a Bag in the chest part of the chest interface
                        for (int i = 0; i < IGM.ItemsToGrabMenu.inventory.Count; i++)
                        {
                            ClickableComponent Component = IGM.ItemsToGrabMenu.inventory[i];
                            if (Component != null && Component.bounds.Contains(CursorPos))
                            {
                                Item ClickedChestItem = i < 0 || i >= IGM.ItemsToGrabMenu.actualInventory.Count ? null : IGM.ItemsToGrabMenu.actualInventory[i];
                                if (ClickedChestItem is ItemBag IB)
                                {
                                    IB.OpenContents(IGM.ItemsToGrabMenu.actualInventory, IGM.ItemsToGrabMenu.capacity);
                                }
                                Handled = true;
                                break;
                            }
                        }
                    }
                }
            }
        public void UpdateQuantities()
        {
            foreach (Object Item in ItemPlaceholders.Values)
            {
                Item.Stack = 0;
            }

            foreach (Object BagItem in Bag.Contents)
            {
                //  Find all placeholders requiring this item Id/Quality
                List <KeyValuePair <BundleItem, Object> > Placeholders = ItemPlaceholders.Where(x => ItemBag.AreItemsEquivalent(x.Value, BagItem, false, false))
                                                                         .OrderByDescending(x => x.Key.IsRequired).ToList();

                //  Distribute the Stack of this item to the placeholders, up to each placeholder's required quantity.
                //  EX: Suppose you have 10 Parsnips in the bag, and Task#1 requires 3 Parsnip, Task#2 Requires 12 Parsnip.
                //  Put 3/10 in Task#1, then 7/10 in Task#2. Thus Task#1 is now fulfilled, and Task#2 is at 7/12.
                int RemainingQuantity = BagItem.Stack;
                int CurrentIndex      = 0;
                while (RemainingQuantity > 0 && CurrentIndex < Placeholders.Count)
                {
                    int    RequiredQuantity = Placeholders[CurrentIndex].Key.Quantity;
                    Object Placeholder      = Placeholders[CurrentIndex].Value;

                    int Quantity = Math.Max(0, Math.Min(RemainingQuantity, RequiredQuantity));
                    Placeholder.Stack  = Quantity;
                    RemainingQuantity -= Quantity;

                    if (Quantity > 0 && BagItem.Category == Object.artisanGoodsCategory)
                    {
                        Placeholder.Price       = BagItem.Price;
                        Placeholder.Name        = BagItem.Name;
                        Placeholder.DisplayName = BagItem.DisplayName;
                    }

                    CurrentIndex++;
                }
            }
        }
Example #8
0
        internal static void OnGameLaunched()
        {
            IModHelper Helper = ItemBagsMod.ModInstance.Helper;

#if NEVER //DEBUG
            try
            {
                //  Retrieve the item Ids of various new items added by update 1.5

                List <string> NewItemNames = new List <string>()
                {
                    "Bug Steak", "Banana Pudding", "Ginger", "Ginger Ale", "Ginger Beer", "Mango Sticky Rice", "Piña Colada", "Poi", "Taro Root", "Tropical Curry", "Squid Ink Ravioli",
                    "Deluxe Fertilizer", "Deluxe Retaining Soil", "Hyper Speed-Gro",
                    "Bone Fragment", "Fossilized Skull", "Fossilized Spine", "Fossilized Tail", "Fossilized Leg", "Fossilized Ribs", "Snake Skull", "Snake Vertebrae",
                    "Cinder Shard", "Dragon Tooth", "Tiger Slime Egg", "Fairy Dust", "Golden Walnut", "Magma Cap", "Monster Musk", "Mummified Bat", "Mummified Frog", "Ostrich Egg", "Qi Gem", "Qi Seasoning",
                    "Radioactive Ore", "Radioactive Bar", "Taro Tuber", "Mushroom Tree Seed", "Magic Bait",
                    "Stingray", "Lionfish", "Blue Discus", "Glacierfish Jr.", "Legend II", "Ms. Angler", "Radioactive Carp", "Son of Crimsonfish",
                    "Cookout Kit", "Coffee Maker", "Mahogany Seed", "Heavy Tapper", "Mango Sapling", "Mango", "Banana Sapling", "Banana",
                    "Farm Computer", "Mini-Shipping Bin", "Warp Totem: Island", "Bone Mill", "Mini-Obelisk", "Ostrich Incubator", "Geode Crusher", "Pineapple Seeds", "Pineapple",
                    "Dark Sign", "Deconstructor", "Hopper", "Solar Panel", "Fiber Seeds"
                };

                //Game1.objectInformation.GroupBy(x => x.Value).Select(x => x.First()).OrderBy(x => x.Value).ToDictionary(x => x.Value, x => x.Key);
                Dictionary <string, int> AllItems = new Dictionary <string, int>();
                foreach (var item in Game1.objectInformation)
                {
                    AllItems[item.Value.Split('/').First()] = item.Key;
                }
                foreach (var item in Game1.bigCraftablesInformation)
                {
                    AllItems[item.Value.Split('/').First()] = item.Key;
                }

                AllItems = AllItems.OrderBy(x => x.Key).ToDictionary(x => x.Key, x => x.Value);

                List <string> NotFound = new List <string>();

                List <string> Result = new List <string>();

                Dictionary <string, int> NewItems = new Dictionary <string, int>();
                foreach (string Name in NewItemNames.OrderBy(x => x))
                {
                    if (!AllItems.TryGetValue(Name, out int Id))
                    {
                        NotFound.Add(Name);
                    }
                    else
                    {
                        NewItems.Add(Name, Id);

                        Object Instance     = new Object(Id, 1);
                        bool   HasQualities = CategoriesWithQualities.Contains(Instance.Category);
                        bool   IsStackable  = Instance.maximumStackSize() > 1;
                        string Category     = Instance.getCategoryName();
                        if (string.IsNullOrEmpty(Category))
                        {
                            Category = Instance.Category.ToString();
                        }
                        Result.Add(string.Format("{0} ({1}, {2}, {3}) (Quality={4})", Name, Id, Category, ItemBag.GetSingleItemPrice(Instance), HasQualities.ToString()));
                    }
                }

                string NewItemInfo = string.Join("\n", Result);
            }
            catch (Exception) { }
#endif

            //  Load modded items from JsonAssets the moment it finishes registering items
            if (Helper.ModRegistry.IsLoaded(ItemBagsMod.JAUniqueId))
            {
                IJsonAssetsAPI API = Helper.ModRegistry.GetApi <IJsonAssetsAPI>(ItemBagsMod.JAUniqueId);
                if (API != null)
                {
                    API.IdsFixed += (sender, e) => { OnJsonAssetsIdsFixed(API, ItemBagsMod.BagConfig); };
                }
            }
        }
Example #9
0
        private void Display_MenuChanged(object sender, MenuChangedEventArgs e)
        {
            //  Refresh completed Bundles in the community center
            if (e.OldMenu != null && e.OldMenu is JunimoNoteMenu)
            {
                CommunityCenterBundles.Instance = new CommunityCenterBundles();
            }

            if (e.NewMenu is ShopMenu SM)
            {
                //  Determine if the shop menu belongs to one of our managed shops
                bool    IsModifiableShop = false;
                BagShop BagShop          = BagShop.Pierre;
                if (SM.portraitPerson?.Name != null)
                {
                    //TODO test if the Stardew Valley Expanded shops like Isaac/Sophia/Alesia have non-null values for ShopMenu.portraitPerson.Name
                    if (Enum.TryParse(SM.portraitPerson.Name, out BagShop))
                    {
                        IsModifiableShop = true;
                    }
                }
                else if (SM.storeContext != null)
                {
                    if (SM.storeContext.Equals("Forest", StringComparison.CurrentCultureIgnoreCase))
                    {
                        if (SM.onPurchase?.GetMethodInfo().Name == "onTravelingMerchantShopPurchase") // nameof(Utility.onTravelingMerchantShopPurchase)
                        {
                            BagShop = BagShop.TravellingCart;
                        }
                        else
                        {
                            BagShop = BagShop.HatMouse;
                        }
                        IsModifiableShop = true;
                    }
                    else if (SM.storeContext.Equals("Town", StringComparison.CurrentCultureIgnoreCase) && SM.potraitPersonDialogue != null && SM.potraitPersonDialogue.Contains("Khadija"))
                    {
                        BagShop          = BagShop.Khadija;
                        IsModifiableShop = true;
                    }
                }

                //  Add Bag items to the shop's stock
                if (IsModifiableShop)
                {
                    Dictionary <ISalable, int[]> Stock = SM.itemPriceAndStock;

                    bool ShouldModifyStock = true;
                    if (BagShop == BagShop.Clint)
                    {
                        //  Assume user is viewing Clint tool upgrades if the stock doesn't contain Coal
                        if (!Stock.Any(x => x.Key is Object Obj && Obj.Name.Equals("Coal", StringComparison.CurrentCultureIgnoreCase)))
                        {
                            ShouldModifyStock = false;
                        }
                    }

                    if (ShouldModifyStock)
                    {
                        bool HasChangedStock = false;

                        List <ItemBag> OwnedBags = UserConfig.HideObsoleteBagsFromShops ? ItemBag.GetAllBags(true) : new List <ItemBag>();

                        //  Add Bounded Bags to stock
                        foreach (BagType Type in BagConfig.BagTypes)
                        {
                            foreach (BagSizeConfig SizeCfg in Type.SizeSettings)
                            {
                                bool IsSoldByShop = UserConfig.IsSizeVisibleInShops(SizeCfg.Size) && SizeCfg.Sellers.Contains(BagShop);
#if DEBUG
                                //IsSoldByShop = true;
#endif
                                if (IsSoldByShop)
                                {
                                    bool IsObsolete = false;
                                    if (UserConfig.HideObsoleteBagsFromShops)
                                    {
                                        IsObsolete = OwnedBags.Any(x => x is BoundedBag BB && BB.TypeInfo == Type && (int)BB.Size > (int)SizeCfg.Size);
                                    }

                                    if (!IsObsolete)
                                    {
                                        BoundedBag SellableInstance = new BoundedBag(Type, SizeCfg.Size, false);
                                        int        Price            = SellableInstance.GetPurchasePrice();
#if DEBUG
                                        //Price = 1 + (int)SizeCfg.Size;
#endif
                                        Stock.Add(SellableInstance, new int[] { Price, ShopMenu.infiniteStock });
                                        HasChangedStock = true;
                                    }
                                }
                            }
                        }

                        //  Add Bundle Bags to stock
                        foreach (BundleBagSizeConfig SizeCfg in UserConfig.BundleBagSettings)
                        {
                            ContainerSize Size = SizeCfg.Size;
                            if (BundleBag.ValidSizes.Contains(Size) && SizeCfg.Sellers.Contains(BagShop) && UserConfig.IsSizeVisibleInShops(Size))
                            {
                                bool IsObsolete = false;
                                if (UserConfig.HideObsoleteBagsFromShops)
                                {
                                    IsObsolete = OwnedBags.Any(x => x is BundleBag BB && (int)BB.Size > (int)Size);
                                }

                                if (!IsObsolete)
                                {
                                    BundleBag BundleBag = new BundleBag(Size, true);
                                    int       Price     = BundleBag.GetPurchasePrice();
                                    Stock.Add(BundleBag, new int[] { Price, ShopMenu.infiniteStock });
                                    HasChangedStock = true;
                                }
                            }
                        }

                        //  Add Rucksacks to stock
                        foreach (RucksackSizeConfig SizeCfg in UserConfig.RucksackSettings)
                        {
                            ContainerSize Size = SizeCfg.Size;
                            if (SizeCfg.Sellers.Contains(BagShop) && UserConfig.IsSizeVisibleInShops(Size))
                            {
                                bool IsObsolete = false;
                                if (UserConfig.HideObsoleteBagsFromShops)
                                {
                                    IsObsolete = OwnedBags.Any(x => x is Rucksack RS && (int)RS.Size > (int)Size);
                                }

                                if (!IsObsolete)
                                {
                                    Rucksack Rucksack = new Rucksack(Size, false, AutofillPriority.Low);
                                    int      Price    = Rucksack.GetPurchasePrice();
                                    Stock.Add(Rucksack, new int[] { Price, ShopMenu.infiniteStock });
                                    HasChangedStock = true;
                                }
                            }
                        }

                        //  Add Omni Bags to stock
                        foreach (OmniBagSizeConfig SizeCfg in UserConfig.OmniBagSettings)
                        {
                            ContainerSize Size = SizeCfg.Size;
                            if (SizeCfg.Sellers.Contains(BagShop) && UserConfig.IsSizeVisibleInShops(Size))
                            {
                                bool IsObsolete = false;
                                if (UserConfig.HideObsoleteBagsFromShops)
                                {
                                    IsObsolete = OwnedBags.Any(x => x is OmniBag OB && (int)OB.Size > (int)Size);
                                }

                                if (!IsObsolete)
                                {
                                    OmniBag OmniBag = new OmniBag(Size);
                                    int     Price   = OmniBag.GetPurchasePrice();
                                    Stock.Add(OmniBag, new int[] { Price, ShopMenu.infiniteStock });
                                    HasChangedStock = true;
                                }
                            }
                        }

                        if (HasChangedStock)
                        {
                            SM.setItemPriceAndStock(Stock);
                        }
                    }
                }
            }
        }
Example #10
0
        public void DrawToolTips(SpriteBatch b)
        {
            if (IsEmptyMenu)
            {
                return;
            }

            //  Draw tooltip over hovered item
            if (HoveredSlot.HasValue)
            {
                //  Get the hovered Item Id and ColumnType
                int?       ItemId = null;
                ColumnType?Column = null;
                foreach (var KVP in SlotBounds)
                {
                    foreach (var KVP2 in KVP.Value)
                    {
                        if (KVP2.Value == HoveredSlot.Value)
                        {
                            ItemId = KVP.Key;
                            Column = KVP2.Key;
                            break;
                        }
                    }

                    if (ItemId.HasValue && Column.HasValue)
                    {
                        break;
                    }
                }

                if (ItemId.HasValue && Column.HasValue)
                {
                    if (Column == ColumnType.RowValue)
                    {
                        List <Object> Items            = Placeholders[ItemId.Value].Values.ToList();
                        List <int>    Quantities       = Items.Select(x => x.Stack).ToList();
                        List <int>    SingleValues     = Items.Select(x => ItemBag.GetSingleItemPrice(x)).ToList();
                        List <int>    MultipliedValues = Items.Select(x => x.Stack * ItemBag.GetSingleItemPrice(x)).ToList();

                        //  Compute how many digits each column needs so that we can align each number properly by making each number take up the maximum size of other numbers in the same column
                        int   SingleValueColumnDigits     = SingleValues.Max(x => DrawHelpers.GetNumDigits(x));
                        int   QuantityColumnDigits        = Quantities.Max(x => DrawHelpers.GetNumDigits(x));
                        int   MultipliedValueColumnDigits = MultipliedValues.Max(x => DrawHelpers.GetNumDigits(x));
                        float DigitScale                 = 3.0f;
                        float SingleValueColumnWidth     = SingleValueColumnDigits * DigitScale * DrawHelpers.TinyDigitBaseWidth;
                        float QuantityColumnWidth        = QuantityColumnDigits * DigitScale * DrawHelpers.TinyDigitBaseWidth;
                        float MultipliedValueColumnWidth = MultipliedValueColumnDigits * DigitScale * DrawHelpers.TinyDigitBaseWidth;

                        //  Compute how big the tooltip needs to be
                        int   Margin     = 32;
                        int   LineHeight = 28;
                        int   HorizontalSeparatorHeight = 6;
                        int   SeparatorMargin           = 4;
                        float PlusCharacterWidth        = Game1.tinyFont.MeasureString("+").X;
                        float MultiplyCharacterWidth    = Game1.tinyFont.MeasureString("*").X;
                        float EqualsCharacterWidth      = Game1.tinyFont.MeasureString("=").X;
                        float SpaceWidth  = 7f;
                        int   TotalWidth  = (int)(Margin + PlusCharacterWidth + SpaceWidth + SingleValueColumnWidth + SpaceWidth + MultiplyCharacterWidth + SpaceWidth + QuantityColumnWidth + SpaceWidth + EqualsCharacterWidth + SpaceWidth + MultipliedValueColumnWidth + Margin);
                        int   TotalHeight = (int)(Margin + Items.Count * LineHeight + SeparatorMargin + HorizontalSeparatorHeight + SeparatorMargin + LineHeight + Margin);

                        //  Ensure tooltip is fully visible on screen
                        Rectangle ToolTipLocation = new Rectangle(HoveredSlot.Value.Right, HoveredSlot.Value.Top, TotalWidth, TotalHeight);
                        if (ToolTipLocation.Right > Game1.viewport.Size.Width)
                        {
                            ToolTipLocation = new Rectangle(HoveredSlot.Value.Left - TotalWidth, HoveredSlot.Value.Top, TotalWidth, TotalHeight);
                        }

                        //  Draw background
                        DrawHelpers.DrawBox(b, ToolTipLocation);

                        //  Draw each row of values
                        int ShadowOffset     = 2;
                        int CurrentYPosition = ToolTipLocation.Y + Margin;
                        for (int i = 0; i < Items.Count; i++)
                        {
                            float CurrentXPosition = ToolTipLocation.X + Margin;
                            if (i != 0)
                            {
                                DrawHelpers.DrawStringWithShadow(b, Game1.tinyFont, "+", CurrentXPosition, CurrentYPosition, Color.White, Color.Black, ShadowOffset, ShadowOffset);
                            }
                            CurrentXPosition += PlusCharacterWidth + SpaceWidth;
                            Utility.drawTinyDigits(SingleValues[i], b, new Vector2(CurrentXPosition + SingleValueColumnWidth - DrawHelpers.MeasureNumber(SingleValues[i], DigitScale), CurrentYPosition), DigitScale, 1.0f, Color.White);
                            CurrentXPosition += SingleValueColumnWidth + SpaceWidth;
                            DrawHelpers.DrawStringWithShadow(b, Game1.tinyFont, "*", CurrentXPosition, CurrentYPosition + LineHeight / 4, Color.White, Color.Black, ShadowOffset, ShadowOffset);
                            CurrentXPosition += MultiplyCharacterWidth + SpaceWidth;
                            Utility.drawTinyDigits(Quantities[i], b, new Vector2(CurrentXPosition + QuantityColumnWidth - DrawHelpers.MeasureNumber(Quantities[i], DigitScale), CurrentYPosition), DigitScale, 1.0f, Color.White);
                            CurrentXPosition += QuantityColumnWidth + SpaceWidth;
                            DrawHelpers.DrawStringWithShadow(b, Game1.tinyFont, "=", CurrentXPosition, CurrentYPosition - LineHeight / 6, Color.White, Color.Black, ShadowOffset, ShadowOffset);
                            CurrentXPosition += EqualsCharacterWidth + SpaceWidth;
                            Utility.drawTinyDigits(MultipliedValues[i], b, new Vector2(CurrentXPosition + MultipliedValueColumnWidth - DrawHelpers.MeasureNumber(MultipliedValues[i], DigitScale), CurrentYPosition), DigitScale, 1.0f, Color.White);

                            CurrentYPosition += LineHeight;
                        }

                        //  Draw separator
                        CurrentYPosition += SeparatorMargin;
                        DrawHelpers.DrawHorizontalSeparator(b, ToolTipLocation.X + Margin, CurrentYPosition, TotalWidth - Margin * 2, HorizontalSeparatorHeight);
                        CurrentYPosition += HorizontalSeparatorHeight + SeparatorMargin;

                        //  Draw total value
                        int       SummedValue         = MultipliedValues.Sum();
                        float     SummedValueWidth    = DrawHelpers.MeasureNumber(SummedValue, DigitScale) + GoldIconSourceRect.Width * 2f + 8;
                        Vector2   SummedValuePosition = new Vector2(ToolTipLocation.X + ((ToolTipLocation.Width - SummedValueWidth) / 2), CurrentYPosition + 6);
                        Rectangle IconDestination     = new Rectangle((int)SummedValuePosition.X, (int)(SummedValuePosition.Y + (DrawHelpers.TinyDigitBaseHeight * DigitScale - GoldIconSourceRect.Height * 2) / 2), GoldIconSourceRect.Width * 2, GoldIconSourceRect.Height * 2);
                        b.Draw(GoldIconTexture, IconDestination, GoldIconSourceRect, Color.White);
                        Utility.drawTinyDigits(SummedValue, b, new Vector2(SummedValuePosition.X + GoldIconSourceRect.Width * 2f + 8, SummedValuePosition.Y), DigitScale, 1.0f, GetValueColor(SummedValue));
                    }
                    else
                    {
                        Object    HoveredItem = Placeholders[ItemId.Value][ConvertColumnTypeToObjectQuality(Column.Value)];
                        Rectangle Location;
                        if (IsNavigatingWithGamepad)
                        {
                            Location = HoveredSlot.Value; //new Rectangle(HoveredSlot.Value.Right, HoveredSlot.Value.Bottom, 1, 1);
                        }
                        else
                        {
                            Location = new Rectangle(Game1.getMouseX() - 8, Game1.getMouseY() + 36, 8 + 36, 1);
                        }
                        DrawHelpers.DrawToolTipInfo(b, Location, HoveredItem, true, true, true, true, true, true, Bag.MaxStackSize);
                    }
                }
            }
        }
Example #11
0
 public bool IsValidBag(ItemBag IB)
 {
     return(IB != null && !(IB is OmniBag) && IB.Size <= this.Size);
 }
Example #12
0
        public void Draw(SpriteBatch b)
        {
            if (IsEmptyMenu)
            {
                return;
            }

            //b.Draw(TextureHelpers.GetSolidColorTexture(Game1.graphics.GraphicsDevice, Color.Orange), Bounds, Color.White);

            //  Draw column headers
            for (int i = 0; i < ColumnHeaderBounds.Count; i++)
            {
                Rectangle Destination = ColumnHeaderBounds[i];

                b.Draw(Game1.menuTexture, Destination, new Rectangle(64, 896, 64, 64), Color.White);

                Rectangle IconDestination = new Rectangle(Destination.X + Destination.Width / 4, Destination.Y + Destination.Height / 4, Destination.Width / 2, Destination.Height / 2);

                ColumnType Type = (ColumnType)(i % ColumnsPerGroup);

                if (Type == ColumnType.RowValue)
                {
                    //Could also use Game1.mouseCursors with SourceSprite = new Rectangle(280, 411, 16, 16);
                    b.Draw(GoldIconTexture, IconDestination, GoldIconSourceRect, Color.White);
                }
                else
                {
                    Rectangle SourceRect = ItemBag.QualityIconTexturePositions[ConvertColumnTypeToObjectQuality(Type)];
                    b.Draw(Game1.mouseCursors, IconDestination, SourceRect, Color.White);
                }
            }

            //  Draw cells
            foreach (var KVP in SlotBounds)
            {
                int ItemId = KVP.Key;

                foreach (var KVP2 in KVP.Value)
                {
                    ColumnType ColumnType  = KVP2.Key;
                    Rectangle  Destination = KVP2.Value;
                    b.Draw(Game1.menuTexture, Destination, new Rectangle(128, 128, 64, 64), Color.White);

                    //  Draw a thin yellow border if mouse is hovering this slot
                    bool IsHovered = Destination == HoveredSlot;
                    if (IsHovered)
                    {
                        Color     HighlightColor = Color.Yellow;
                        Texture2D Highlight      = TextureHelpers.GetSolidColorTexture(Game1.graphics.GraphicsDevice, HighlightColor);
                        b.Draw(Highlight, Destination, Color.White * 0.25f);

                        int BorderThickness = Destination.Width / 16;
                        DrawHelpers.DrawBorder(b, Destination, BorderThickness, HighlightColor);
                    }

                    if (ColumnType != ColumnType.RowValue)
                    {
                        ObjectQuality Quality     = ConvertColumnTypeToObjectQuality(ColumnType);
                        Object        CurrentItem = Placeholders[ItemId][Quality];

                        float IconScale = IsHovered ? 1.25f : 1.0f;
                        Color Overlay   = CurrentItem.Stack == 0 ? Color.White * 0.30f : Color.White;
                        DrawHelpers.DrawItem(b, Destination, CurrentItem, CurrentItem.Stack > 0, true, IconScale, 1.0f, Overlay, CurrentItem.Stack >= Bag.MaxStackSize ? Color.Red : Color.White);

                        OnItemSlotRendered?.Invoke(this, new ItemSlotRenderedEventArgs(b, Destination, CurrentItem, IsHovered));
                    }
                    else
                    {
                        //  Sum up the value of all different qualities of this item
                        int SummedValue = Placeholders[ItemId].Values.Sum(x => x.Stack * ItemBag.GetSingleItemPrice(x));
                        int NumDigits   = DrawHelpers.GetNumDigits(SummedValue);

                        //  Compute width/height of the number
                        float ValueScale;
                        int   ValueWidth, ValueHeight, CurrentIteration = 0;
                        do
                        {
                            ValueScale  = (2.7f - CurrentIteration * 0.1f) * Destination.Width / (float)BagInventoryMenu.DefaultInventoryIconSize;
                            ValueWidth  = (int)DrawHelpers.MeasureNumber(SummedValue, ValueScale);
                            ValueHeight = (int)(DrawHelpers.TinyDigitBaseHeight * ValueScale);
                            CurrentIteration++;
                        } while (ValueWidth > Destination.Width * 1.04); // * 1.04 to let the value extend very slightly outside the bounds of the slot

                        //  Draw the number in the center of the slot
                        Vector2 TopLeftPosition = new Vector2(Destination.X + (Destination.Width - ValueWidth) / 2 + 1, Destination.Y + (Destination.Height - ValueHeight) / 2);
                        Color   ValueColor      = GetValueColor(SummedValue);
                        Utility.drawTinyDigits(SummedValue, b, TopLeftPosition, ValueScale, 0f, ValueColor);
                    }
                }
            }
        }
 public void SetItem(ItemBag item, int slot)
 {
     if (slot < 0 || slot > Slots) return;
     _items[slot] = item;
     checkItems();
 }
        public void InitializePlaceholders()
        {
            List <Object> Temp = new List <Object>();

            IEnumerable <Object> SortedContents;

            switch (Rucksack.SortProperty)
            {
            case SortingProperty.Time:
                SortedContents = Rucksack.Contents;
                break;

            case SortingProperty.Name:
                SortedContents = Rucksack.Contents.OrderBy(x => x.DisplayName);
                break;

            case SortingProperty.Id:
                SortedContents = Rucksack.Contents.OrderBy(x => x.bigCraftable.Value).ThenBy(x => x.ParentSheetIndex);
                break;

            case SortingProperty.Category:
                //SortedContents = Rucksack.Contents.OrderBy(x => x.getCategorySortValue());
                SortedContents = Rucksack.Contents.OrderBy(x => x.getCategoryName());
                break;

            case SortingProperty.Quantity:
                SortedContents = Rucksack.Contents.OrderBy(x => x.Stack);
                break;

            case SortingProperty.SingleValue:
                SortedContents = Rucksack.Contents.OrderBy(x => ItemBag.GetSingleItemPrice(x));
                break;

            case SortingProperty.StackValue:
                SortedContents = Rucksack.Contents.OrderBy(x => ItemBag.GetSingleItemPrice(x) * x.Stack);
                break;

            case SortingProperty.Similarity:
                //Possible TODO: Maybe SortingProperty.Similarity shouldn't exist - maybe it should just be a "bool GroupBeforeSorting"
                //that only groups by ItemId (and maybe also sorts by Quality after). Then the grouping can be applied to any of the other sorting properties.
                //So it could just be a togglebutton to turn on/off like the Autofill Toggle

                SortedContents = Rucksack.Contents
                                 .OrderBy(Item => Item.getCategoryName()).GroupBy(Item => Item.getCategoryName()) // First sort and group by CategoryName
                                 .SelectMany(
                    CategoryGroup =>
                    CategoryGroup.GroupBy(Item => Item.ParentSheetIndex)             // Then Group by item Id
                    .SelectMany(IdGroup => IdGroup.OrderBy(y => y.Quality))          // Then sort by Quality
                    );
                break;

            default: throw new NotImplementedException(string.Format("Unexpected SortingProperty: {0}", Rucksack.SortProperty.ToString()));
            }
            if (Rucksack.SortOrder == SortingOrder.Descending)
            {
                SortedContents = SortedContents.Reverse();
            }

            //Possible TODO Add filtering?
            //For EX: if you only wanted to show Fish,
            //SortedContents = SortedContents.Where(x => x.Category == <WhateverTheIdIsForFishCategory>);

            TempVisualFeedback = new Dictionary <Object, DateTime>();
            foreach (Object Item in SortedContents)
            {
                bool WasRecentlyModified = Bag.RecentlyModified.TryGetValue(Item, out DateTime ModifiedTime);

                int NumSlots     = (Item.Stack - 1) / Rucksack.MaxStackSize + 1;
                int RemainingQty = Item.Stack;
                for (int i = 0; i < NumSlots; i++)
                {
                    Object Copy = ItemBag.CreateCopy(Item);
                    ItemBag.ForceSetQuantity(Copy, Math.Min(RemainingQty, Rucksack.MaxStackSize));
                    Temp.Add(Copy);
                    RemainingQty -= Copy.Stack;

                    if (WasRecentlyModified)
                    {
                        TempVisualFeedback.Add(Copy, ModifiedTime);
                    }
                }
            }

            this.PlaceholderItems = Temp.AsReadOnly();
        }
        /// <summary>Initializes extra data for the Crafting Page so it can search for and use materials within bags in your inventory.</summary>
        private static void OnCraftingPageActivated(IClickableMenu CraftingMenu)
        {
            //  Allow the CraftingPage to search for and use items inside of bags
            bool AllowUsingBundleBagItemsForCrafting = false;

            List <ItemBag> BagsInInventory = Game1.player.Items.Where(x => x != null && x is ItemBag).Cast <ItemBag>().ToList();
            List <ItemBag> SearchedBags    = BagsInInventory.ToList();

            //  Get the "_materialContainers" protected field that defines additional item containers to search for when using up materials during crafting
            IReflectedField <List <Chest> > ReflectionResult = Helper.Reflection.GetField <List <Chest> >(CraftingMenu, "_materialContainers", true);
            List <Chest> MaterialContainers = ReflectionResult.GetValue();

            if (MaterialContainers != null)
            {
                SearchedBags.AddRange(MaterialContainers.SelectMany(x => x.items).Where(x => x != null && x is ItemBag).Cast <ItemBag>());
            }

            if (SearchedBags.Any())
            {
                BagsInUse = new HashSet <ItemBag>(SearchedBags);

                if (MaterialContainers == null)
                {
                    MaterialContainers = new List <Chest>();
                    ReflectionResult.SetValue(MaterialContainers);
                }

                //  Create a temporary chest from the items of each bag, and add the chest to _materialContainers
                foreach (ItemBag IB in SearchedBags.Where(x => AllowUsingBundleBagItemsForCrafting || !(x is BundleBag)))
                {
                    //  Note that if the item inside the bag has Stack > 999, it must be split up into chunks with Stacks <= 999
                    //  Because the Game truncates the actual stack down to 999 anytime it modifies a stack value
                    if (IB is OmniBag OB)
                    {
                        foreach (ItemBag NestedBag in OB.NestedBags.Where(x => AllowUsingBundleBagItemsForCrafting || !(x is BundleBag)))
                        {
                            List <Item> TemporaryChestContents = new List <Item>();

                            foreach (Object Item in NestedBag.Contents)
                            {
                                if (Item.Stack > 999)
                                {
                                    if (SplitStacks == null)
                                    {
                                        SplitStacks = new Dictionary <Object, List <Object> >();
                                    }

                                    List <Object> Chunks = new List <Object>();

                                    int TotalStack     = Item.Stack;
                                    int DistributedAmt = 0;
                                    while (DistributedAmt < TotalStack)
                                    {
                                        int    CurrentStackAmt = Math.Min(999, TotalStack - DistributedAmt);
                                        Object Chunk           = ItemBag.CreateCopy(Item);
                                        ItemBag.ForceSetQuantity(Chunk, CurrentStackAmt);
                                        DistributedAmt += CurrentStackAmt;
                                        Chunks.Add(Chunk);
                                    }

                                    SplitStacks.Add(Item, Chunks);
                                    TemporaryChestContents.AddRange(Chunks);
                                }
                                else
                                {
                                    TemporaryChestContents.Add(Item);
                                }
                            }

                            Chest TempChest = new Chest(0, TemporaryChestContents, Vector2.Zero, false, 0);
                            MaterialContainers.Add(TempChest);
                        }
                    }
                    else
                    {
                        List <Item> TemporaryChestContents = new List <Item>();

                        foreach (Object Item in IB.Contents)
                        {
                            if (Item.Stack > 999)
                            {
                                if (SplitStacks == null)
                                {
                                    SplitStacks = new Dictionary <Object, List <Object> >();
                                }

                                List <Object> Chunks = new List <Object>();

                                int TotalStack     = Item.Stack;
                                int DistributedAmt = 0;
                                while (DistributedAmt < TotalStack)
                                {
                                    int    CurrentStackAmt = Math.Min(999, TotalStack - DistributedAmt);
                                    Object Chunk           = ItemBag.CreateCopy(Item);
                                    ItemBag.ForceSetQuantity(Chunk, CurrentStackAmt);
                                    DistributedAmt += CurrentStackAmt;
                                    Chunks.Add(Chunk);
                                }

                                SplitStacks.Add(Item, Chunks);
                                TemporaryChestContents.AddRange(Chunks);
                            }
                            else
                            {
                                TemporaryChestContents.Add(Item);
                            }
                        }

                        Chest TempChest = new Chest(0, TemporaryChestContents, Vector2.Zero, false, 0);
                        MaterialContainers.Add(TempChest);
                    }
                }
            }
        }
Example #16
0
        private static void OnJsonAssetsIdsFixed(IJsonAssetsAPI API, BagConfig Target, bool RevalidateInstances)
        {
            try
            {
                ItemBagsMod.ModdedItems.ImportModdedItems(API, ItemBagsMod.BagConfig);

                if (ItemBagsMod.TemporaryModdedBagTypes.Any())
                {
                    ItemBagsMod.ModInstance.Monitor.Log("Loading Modded Bags type info", LogLevel.Debug);

                    Dictionary <string, int> AllBigCraftableIds = new Dictionary <string, int>();
                    foreach (System.Collections.Generic.KeyValuePair <int, string> KVP in Game1.bigCraftablesInformation)
                    {
                        string ObjectName = KVP.Value.Split('/').First();
                        if (!AllBigCraftableIds.ContainsKey(ObjectName))
                        {
                            AllBigCraftableIds.Add(ObjectName, KVP.Key);
                        }
                    }

                    Dictionary <string, int> AllObjectIds = new Dictionary <string, int>();
                    foreach (System.Collections.Generic.KeyValuePair <int, string> KVP in Game1.objectInformation)
                    {
                        string ObjectName = KVP.Value.Split('/').First();
                        if (!AllObjectIds.ContainsKey(ObjectName))
                        {
                            AllObjectIds.Add(ObjectName, KVP.Key);
                        }
                    }

                    IDictionary <string, int> JABigCraftableIds = API.GetAllBigCraftableIds();
                    IDictionary <string, int> JAObjectIds       = API.GetAllObjectIds();

                    //  Now that JsonAssets has finished loading the modded items, go through each one, and convert the items into StoreableBagItems (which requires an Id instead of just a Name)
                    foreach (System.Collections.Generic.KeyValuePair <ModdedBag, BagType> KVP in ItemBagsMod.TemporaryModdedBagTypes)
                    {
                        foreach (BagSizeConfig SizeCfg in KVP.Value.SizeSettings)
                        {
                            HashSet <string>        FailedItemNames = new HashSet <string>();
                            List <StoreableBagItem> Items           = new List <StoreableBagItem>();

                            foreach (ModdedItem DesiredItem in KVP.Key.Items.Where(x => x.Size <= SizeCfg.Size))
                            {
                                StoreableBagItem Item = DesiredItem.ToStoreableBagItem(JABigCraftableIds, JAObjectIds, AllBigCraftableIds, AllObjectIds);
                                if (Item == null)
                                {
                                    FailedItemNames.Add(DesiredItem.Name);
                                }
                                else
                                {
                                    Items.Add(Item);
                                }
                            }

                            SizeCfg.Items = Items;

                            if (FailedItemNames.Any())
                            {
                                int    MaxNamesShown = 5;
                                string MissingItems  = string.Format("{0}{1}", string.Join(", ", FailedItemNames.Take(MaxNamesShown)),
                                                                     FailedItemNames.Count <= MaxNamesShown ? "" : string.Format(" + {0} more", (FailedItemNames.Count - MaxNamesShown)));
                                string WarningMsg = string.Format("Warning - {0} items could not be found for modded bag '{1} {2}'. Missing Items: {3}",
                                                                  FailedItemNames.Count, SizeCfg.Size.ToString(), KVP.Key.BagName, MissingItems);
                                ItemBagsMod.ModInstance.Monitor.Log(WarningMsg, LogLevel.Warn);
                            }
                        }
                    }

                    if (RevalidateInstances)
                    {
                        ItemBag.GetAllBags(true).ForEach(x => x.OnJsonAssetsItemIdsFixed(API, true));
                    }
                }
            }
            catch (Exception ex)
            {
                ItemBagsMod.ModInstance.Monitor.Log(string.Format("Failed to import modded bags. Error: {0}\n\n{1}", ex.Message, ex.ToString()), LogLevel.Error);
            }
        }
Example #17
0
 public PlayerModel()
 {
     this.ItemBag = new ItemBag();
     this.Wallet  = new Wallet(499);
 }
Example #18
0
 private void Awake()
 {
     instance  = this;
     inventory = new ItemBag(new Container(slots, bagObject), parent);
 }