internal static bool IsUsingForCrafting(ItemBag Bag) { return(BagsInUse != null && BagsInUse.Contains(Bag)); }
public IEnumerator GetEnumerator() { return(ItemBag.GetEnumerator()); }
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++; } } }
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); }; } } }
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); } } } } }
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); } } } }
public bool IsValidBag(ItemBag IB) { return(IB != null && !(IB is OmniBag) && IB.Size <= this.Size); }
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); } } } }
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); } }
public PlayerModel() { this.ItemBag = new ItemBag(); this.Wallet = new Wallet(499); }
private void Awake() { instance = this; inventory = new ItemBag(new Container(slots, bagObject), parent); }