internal Object GetHoveredItem() { if (IsJojaMember) { return(null); } else { if (HoveredBundleItem != null) { if (ItemPlaceholders.TryGetValue(HoveredBundleItem, out Object IncompleteItem)) { return(IncompleteItem); } else { return(HoveredBundleItem.ToObject()); } } else { return(null); } } }
public BundleBagMenu(ItemBagMenu IBM, BundleBag Bag, int Columns, int SlotSize, bool ShowLockedSlots, int Padding) { this.IBM = IBM; this.BundleBag = Bag; this.IsJojaMember = CommunityCenterBundles.Instance.IsJojaMember; Bag.OnContentsChanged += Bag_ContentsChanged; this.Padding = Padding; this.ColumnCount = Columns; this.OriginalSlotSize = SlotSize; this.SlotSize = SlotSize; this.ShowLockedSlots = ShowLockedSlots; this.ItemPlaceholders = new Dictionary <BundleItem, Object>(); CommunityCenterBundles.Instance.IterateAllBundleItems(x => { if (!BundleBag.InvalidRooms[BundleBag.Size].Contains(x.Task.Room.Name)) { if (!x.IsCompleted) { ItemPlaceholders.Add(x, x.ToObject()); } } }); UpdateQuantities(); SetTopLeft(Point.Zero, false); InitializeLayout(1); }
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++; } } }
public void DrawToolTips(SpriteBatch b) { if (!IsJojaMember) { if (HoveredBundleItem != null) { Object HoveredItem = GetHoveredItem(); if (HoveredItem != null) { Rectangle Location; if (IsNavigatingWithGamepad) { Location = ItemSlotPositions[HoveredBundleItem].GetOffseted(TopLeftScreenPosition); } else { Location = new Rectangle(Game1.getMouseX() - 8, Game1.getMouseY() + 36, 8 + 36, 1); } DrawHelpers.DrawToolTipInfo(b, Location, HoveredItem, true, true, true, true, true, true, HoveredBundleItem.Quantity, !HoveredBundleItem.IsCompleted, Color.White); } } if (HoveredBundleTask != null) { Rectangle ToolTipAnchorPoint = TaskHeaderPositions[HoveredBundleTask].GetOffseted(TopLeftScreenPosition); int Padding = 20; int TaskImageSize = 96; int RewardIconSize = 48; int RewardWidth = RewardIconSize + 12 + RewardIconSize; // Compute header SpriteFont HeaderFont = Game1.dialogueFont; float HeaderScale = 1f; string HeaderText = !string.IsNullOrEmpty(HoveredBundleTask.TranslatedName) ? HoveredBundleTask.TranslatedName : HoveredBundleTask.Name + " Bundle"; Vector2 HeaderSize = HeaderFont.MeasureString(HeaderText) * HeaderScale; // Compute description int ReadyToComplete = 0; foreach (BundleItem BI in HoveredBundleTask.Items) { if (!BI.IsCompleted && ItemPlaceholders.TryGetValue(BI, out Object Placeholder) && Placeholder.Stack >= BI.Quantity) { ReadyToComplete++; } } SpriteFont BodyFont = Game1.smallFont; float BodyScale = 1.0f; string BodyText = HoveredBundleTask.IsCompleted ? ItemBagsMod.Translate("BundleTaskCompletedToolTip") : ItemBagsMod.Translate("BundleTaskIncompleteToolTip", new Dictionary <string, string>() { { "CompletedCount", HoveredBundleTask.Items.Count(x => x.IsCompleted).ToString() }, { "TotalCount", HoveredBundleTask.Items.Count.ToString() }, { "ReadyToCompleteCount", ReadyToComplete.ToString() }, { "RequiredCount", HoveredBundleTask.RequiredItemCount.ToString() } }); Vector2 BodySize = BodyFont.MeasureString(BodyText) * BodyScale; int ToolTipWidth = (int)new List <float>() { TaskImageSize, HeaderSize.X, BodySize.X, RewardWidth }.Max() + Padding * 2; int ToolTipHeight = Padding + TaskImageSize + 16 + (int)HeaderSize.Y + 12 + (int)BodySize.Y + 12 + RewardIconSize + Padding; // Ensure tooltip is fully visible on screen Rectangle Position = new Rectangle(ToolTipAnchorPoint.Right, ToolTipAnchorPoint.Top, ToolTipWidth, ToolTipHeight); if (Position.Right > Game1.viewport.Size.Width) { Position = new Rectangle(ToolTipAnchorPoint.Left - ToolTipWidth, Position.Top, Position.Width, Position.Height); } if (Position.Bottom > Game1.viewport.Size.Height) { Position = new Rectangle(Position.X, ToolTipAnchorPoint.Bottom - ToolTipHeight, Position.Width, Position.Height); } DrawHelpers.DrawBox(b, Position); int CurrentY = Position.Y + Padding; // Draw image associated with this task Rectangle TaskImagePosition = new Rectangle(Position.X + (Position.Width - TaskImageSize) / 2, CurrentY, TaskImageSize, TaskImageSize); DrawHelpers.DrawBorder(b, new Rectangle(TaskImagePosition.Left - 4, TaskImagePosition.Top - 4, TaskImagePosition.Width + 8, TaskImagePosition.Height + 8), 4, Color.Black); b.Draw(HoveredBundleTask.ActualLargeIconTexture, TaskImagePosition, HoveredBundleTask.ActualLargeIconPosition, Color.White); CurrentY += TaskImageSize + 16; // Draw header text (Task's name) Vector2 HeaderPosition = new Vector2(Position.X + (Position.Width - HeaderSize.X) / 2, CurrentY); b.DrawString(HeaderFont, HeaderText, HeaderPosition, Color.Black, 0f, Vector2.Zero, HeaderScale, SpriteEffects.None, 1f); CurrentY += (int)(HeaderSize.Y + 12); // Draw description text Vector2 BodyPosition = new Vector2(Position.X + (Position.Width - BodySize.X) / 2, CurrentY); b.DrawString(BodyFont, BodyText, BodyPosition, Color.SlateGray, 0f, Vector2.Zero, BodyScale, SpriteEffects.None, 1f); CurrentY += (int)(BodySize.Y + 12); // Draw reward item Rectangle RewardPosition = new Rectangle(Position.X + (Position.Width - RewardWidth) / 2, CurrentY, RewardWidth, RewardIconSize); b.Draw(TextureHelpers.JunimoNoteTexture, new Rectangle(RewardPosition.X, RewardPosition.Y, RewardIconSize, RewardIconSize), new Rectangle(548, 264, 18, 18), Color.White); if (HoveredBundleTask.Reward != null) { DrawHelpers.DrawItem(b, new Rectangle(RewardPosition.Right - RewardIconSize, RewardPosition.Y, RewardIconSize, RewardIconSize), HoveredBundleTask.Reward.ToItem(), true, true, 1f, 1f, Color.White, Color.White); } } } }
public void Draw(SpriteBatch b) { if (IsJojaMember) { Rectangle BackgroundDestination = new Rectangle(Padding, Padding, RelativeBounds.Width - Padding * 2, RelativeBounds.Height - Padding * 2).GetOffseted(TopLeftScreenPosition); b.Draw(TextureHelpers.JojaCDForm, BackgroundDestination, new Rectangle(0, 0, TextureHelpers.JojaCDForm.Width, TextureHelpers.JojaCDForm.Height - 16), Color.White); string Text = "You Traitor!"; SpriteFont Font = Game1.smallFont; Vector2 TextSize = Font.MeasureString(Text) * 2; int JojaSuxDestinationSize = 128; int BoxPadding = 32; int BoxWidth = Math.Max((int)TextSize.X, JojaSuxDestinationSize) + BoxPadding * 2; int BoxHeight = (int)TextSize.Y + BoxPadding * 2 + JojaSuxDestinationSize - JojaSuxDestinationSize / 8; Rectangle BoxDestination = new Rectangle((RelativeBounds.Width - BoxWidth) / 2, (RelativeBounds.Height - BoxHeight) / 2, BoxWidth, BoxHeight).GetOffseted(TopLeftScreenPosition); DrawHelpers.DrawBox(b, BoxDestination); Vector2 TextDestination = new Vector2(BoxDestination.X + (BoxDestination.Width - TextSize.X) / 2, BoxDestination.Y + BoxPadding); b.DrawString(Font, Text, TextDestination, Color.Black, 0f, Vector2.Zero, 2f, SpriteEffects.None, 1f); Rectangle JojaSuxSourcePosition = new Rectangle(258, 640, 32, 32); Rectangle JojaSuxDestination = new Rectangle(BoxDestination.X + (BoxDestination.Width - JojaSuxDestinationSize) / 2, BoxDestination.Bottom - BoxPadding - JojaSuxDestinationSize, JojaSuxDestinationSize, JojaSuxDestinationSize); b.Draw(Game1.mouseCursors, JojaSuxDestination, JojaSuxSourcePosition, Color.White); } else { // Draw room names foreach (KeyValuePair <BundleRoom, Rectangle> RoomHeader in RoomHeaderPositions) { bool IsCompleted = RoomHeader.Key.IsCompleted; Rectangle Position = RoomHeader.Value.GetOffseted(TopLeftScreenPosition); DrawHelpers.DrawBox(b, Position); string Text = RoomHeader.Key.DisplayName; Vector2 Size = RoomHeaderFont.MeasureString(Text) * RoomHeaderScale; b.DrawString(RoomHeaderFont, Text, new Vector2(Position.X + (Position.Width - Size.X) / 2, Position.Y + (Position.Height - Size.Y) / 2), IsCompleted ? Color.Green : Color.Black, 0f, Vector2.Zero, RoomHeaderScale, SpriteEffects.None, 1f); if (IsCompleted) { Rectangle CheckMarkDestination = new Rectangle(Position.Right - SlotSize / 6 - CheckMark.Width * CheckMarkScale, Position.Bottom - SlotSize / 6 - CheckMark.Height * CheckMarkScale, CheckMark.Width * CheckMarkScale, CheckMark.Height * CheckMarkScale); b.Draw(TextureHelpers.PlayerStatusList, CheckMarkDestination, CheckMark, Color.White); } } // Draw the backgrounds of each slot foreach (Rectangle LockedSlot in LockedSlotPositions) { b.Draw(Game1.menuTexture, LockedSlot.GetOffseted(TopLeftScreenPosition), new Rectangle(64, 896, 64, 64), Color.White); } foreach (KeyValuePair <BundleItem, Rectangle> ItemSlot in ItemSlotPositions) { Rectangle TexturePosition; if (ItemSlot.Key.IsCompleted) { TexturePosition = SlotDarkBackground; } else { Object Item = ItemPlaceholders[ItemSlot.Key]; if (Item.Stack == 0) { TexturePosition = SlotLightBackground; } else if (Item.Stack == ItemSlot.Key.Quantity) { TexturePosition = SlotDarkBackground; } else { TexturePosition = SlotMediumBackground; } } b.Draw(TextureHelpers.JunimoNoteTexture, ItemSlot.Value.GetOffseted(TopLeftScreenPosition), TexturePosition, Color.White); } foreach (KeyValuePair <BundleTask, Rectangle> TaskHeader in TaskHeaderPositions) { Rectangle TexturePosition = SlotMediumBackground; if (TaskHeader.Key.IsCompleted) { TexturePosition = SlotDarkBackground; } b.Draw(TextureHelpers.JunimoNoteTexture, TaskHeader.Value.GetOffseted(TopLeftScreenPosition), TexturePosition, Color.White); } // Draw the Task headers foreach (KeyValuePair <BundleTask, Rectangle> TaskHeader in TaskHeaderPositions) { bool IsCompleted = TaskHeader.Key.IsCompleted; // Draw a thin yellow border if mouse is hovering this slot bool IsHovered = TaskHeader.Key == HoveredBundleTask; if (IsHovered) { Rectangle Destination = TaskHeader.Value.GetOffseted(TopLeftScreenPosition); 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); } Rectangle Slot = TaskHeader.Value; Rectangle ScaledSlot = new Rectangle(Slot.X + Slot.Width / 6, Slot.Y + Slot.Height / 6, Slot.Width - Slot.Width / 3, Slot.Height - Slot.Height / 3); Rectangle SourceIconPosition = IsCompleted ? TaskHeader.Key.SpriteSmallIconOpenedPosition : TaskHeader.Key.SpriteSmallIconClosedPosition; b.Draw(TextureHelpers.JunimoNoteTexture, ScaledSlot.GetOffseted(TopLeftScreenPosition), SourceIconPosition, Color.White); if (IsCompleted) { Rectangle CheckMarkDestination = new Rectangle(Slot.Right - 1 - CheckMark.Width * CheckMarkScale, Slot.Bottom - 1 - CheckMark.Height * CheckMarkScale, CheckMark.Width * CheckMarkScale, CheckMark.Height * CheckMarkScale).GetOffseted(TopLeftScreenPosition); b.Draw(TextureHelpers.PlayerStatusList, CheckMarkDestination, CheckMark, Color.White); } } // Draw the items of each slot foreach (KeyValuePair <BundleItem, Rectangle> ItemSlot in ItemSlotPositions) { Rectangle Destination = ItemSlot.Value.GetOffseted(TopLeftScreenPosition); Object CurrentItem; if (!ItemPlaceholders.TryGetValue(ItemSlot.Key, out CurrentItem)) { CurrentItem = ItemSlot.Key.ToObject(); } bool IsCompleted = ItemSlot.Key.IsCompleted; // Draw a thin yellow border if mouse is hovering this slot bool IsHovered = ItemSlot.Key == HoveredBundleItem; 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); } float IconScale = IsHovered ? 1.25f : 1.0f; Color Overlay = CurrentItem.Stack == 0 || IsCompleted ? Color.White * 0.30f : Color.White; bool DrawQuantity = CurrentItem.Stack > 0 && !IsCompleted && ItemSlot.Key.Quantity > 1; DrawHelpers.DrawItem(b, Destination, CurrentItem, DrawQuantity, true, IconScale, 1.0f, Overlay, CurrentItem.Stack >= ItemSlot.Key.Quantity ? Color.Green : Color.White); if (IsCompleted) { Rectangle CheckMarkDestination = new Rectangle(Destination.Right - 1 - CheckMark.Width * CheckMarkScale, Destination.Bottom - 1 - CheckMark.Height * CheckMarkScale, CheckMark.Width * CheckMarkScale, CheckMark.Height * CheckMarkScale); b.Draw(TextureHelpers.PlayerStatusList, CheckMarkDestination, CheckMark, Color.White); } } } }