public void DrawToolTips(SpriteBatch b) { // Draw tooltips on the hovered item inside the bag if (HoveredSlot.HasValue) { Object HoveredItem = GetHoveredItem(); if (HoveredItem != null) { 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); } } // Draw tooltips on the sidebar buttons if (IsRightSidebarVisible && HoveredContentsButton.HasValue) { string ButtonToolTip = ""; if (HoveredContentsButton.Value == ContentsSidebarButton.SortingProperty) { ButtonToolTip = ItemBagsMod.Translate(string.Format("RucksackSortProperty{0}ToolTip", Rucksack.SortProperty.ToString())); } else if (HoveredContentsButton.Value == ContentsSidebarButton.SortingOrder) { if (Rucksack.SortOrder == SortingOrder.Ascending) { ButtonToolTip = ItemBagsMod.Translate("RucksackSortOrderAscendingToolTip"); } else if (Rucksack.SortOrder == SortingOrder.Descending) { ButtonToolTip = ItemBagsMod.Translate("RucksackSortOrderDescendingToolTip"); } } if (!string.IsNullOrEmpty(ButtonToolTip)) { int Margin = 16; Vector2 ToolTipSize = Game1.smallFont.MeasureString(ButtonToolTip); DrawHelpers.DrawBox(b, HoveredContentsButtonBounds.Value.Left - (int)(ToolTipSize.X + Margin * 2), HoveredContentsButtonBounds.Value.Top, (int)(ToolTipSize.X + Margin * 2), (int)(ToolTipSize.Y + Margin * 2)); b.DrawString(Game1.smallFont, ButtonToolTip, new Vector2(HoveredContentsButtonBounds.Value.Left - Margin - ToolTipSize.X, HoveredContentsButtonBounds.Value.Top + Margin), Color.Black); } } }
public void Draw(SpriteBatch b) { Color HighlightColor = Color.Yellow; Texture2D Highlight = TextureHelpers.GetSolidColorTexture(Game1.graphics.GraphicsDevice, HighlightColor); DrawHelpers.DrawBox(b, Bounds); // Draw preview image b.Draw(Game1.menuTexture, PreviewDestination, new Rectangle(128, 128, 64, 64), Color.White); ItemBag CurrentBag = HoveredSprite.HasValue ? PreviewBag : Bag; DrawHelpers.DrawItem(b, PreviewDestination, CurrentBag, false, false, 1f, 1f, Color.White, Color.White); // Draw instructional text b.DrawString(InstructionFont, InstructionText, InstructionDestination, Color.Black, 0f, Vector2.Zero, InstructionScale, SpriteEffects.None, 1f); // Draw spritesheet with all icons to choose from DrawHelpers.DrawBorder(b, new Rectangle(TextureDestination.Left - 2, TextureDestination.Top - 2, TextureDestination.Width + 4, TextureDestination.Height + 4), 2, Color.Black); b.Draw(Texture, TextureDestination, new Rectangle(0, 0, TextureWidth, TextureHeight), Color.White); if (HoveredSprite.HasValue) { Rectangle Destination = HoveredSprite.Value.GetOffseted(new Point(TextureDestination.X, TextureDestination.Y)); b.Draw(Highlight, Destination, Color.White * 0.25f); int BorderThickness = Math.Max(2, HoveredSprite.Value.Width / SpriteSize); DrawHelpers.DrawBorder(b, Destination, BorderThickness, HighlightColor); } // Draw buttons b.Draw(Game1.menuTexture, DefaultButtonDestination, new Rectangle(128, 128, 64, 64), Color.White); b.DrawString(ButtonFont, DefaultButtonText, DefaultButtonTextDestination, Color.Black, 0f, Vector2.Zero, ButtonFontScale, SpriteEffects.None, 1f); b.Draw(Game1.menuTexture, CloseButtonDestination, new Rectangle(128, 128, 64, 64), Color.White); b.DrawString(ButtonFont, CloseButtonText, CloseButtonTextDestination, Color.Black, 0f, Vector2.Zero, ButtonFontScale, SpriteEffects.None, 1f); if (HoveredButton.HasValue) { Rectangle Destination = HoveredButton.Value; b.Draw(Highlight, Destination, Color.White * 0.25f); int BorderThickness = Math.Max(2, HoveredButton.Value.Width / 16); DrawHelpers.DrawBorder(b, Destination, BorderThickness, HighlightColor); } }
private void Display_RenderedWorld(object sender, RenderedWorldEventArgs e) { if (Game1.activeClickableMenu == null) { GameLocation CurrentLocation = Game1.player.currentLocation; bool IsHoveringPlacedObject = CurrentLocation.Objects.TryGetValue(HoveredTile, out SObject HoveredObject); if (IsHoveringPlacedObject) { if (UserConfig.DrawToolTip) { // Draw a tooltip that shows how many of the machine were combined, and its total combined processing power // Such as: "Quantity: 5\nPower: 465%" if (HoveredObject.TryGetCombinedQuantity(out int CombinedQuantity)) { float UIScaleFactor = Game1.options.zoomLevel / Game1.options.uiScale; SpriteFont DefaultFont = Game1.dialogueFont; int Padding = 25; int MarginBetweenColumns = 10; int MarginBetweenRows = 5; float LabelTextScale = 0.75f; float ValueTextScale = 1.0f; List <string> RowHeaders = new List <string>() { Helper.Translation.Get("ToolTipQuantityLabel"), Helper.Translation.Get("ToolTipPowerLabel") }; List <Vector2> RowHeaderSizes = RowHeaders.Select(x => DefaultFont.MeasureString(x) * LabelTextScale).ToList(); double ProcessingPower = UserConfig.ComputeProcessingPower(CombinedQuantity) * 100.0; string FormattedProcessingPower = string.Format("{0}%", ProcessingPower.ToString("#.#")); List <string> RowValues = new List <string>() { CombinedQuantity.ToString(), FormattedProcessingPower }; List <Vector2> RowValueSizes = RowValues.Select(x => DrawHelpers.MeasureStringWithSpecialNumbers(x, ValueTextScale, 0.0f)).ToList(); // Measure the tooltip List <int> RowHeights = new List <int>(); for (int i = 0; i < RowHeaders.Count; i++) { RowHeights.Add((int)Math.Max(RowHeaderSizes[i].Y, RowValueSizes[i].Y)); } List <int> ColumnWidths = new List <int> { (int)RowHeaderSizes.Max(x => x.X), (int)RowValueSizes.Max(x => x.X) }; int ToolTipTopWidth = Padding + ColumnWidths.Sum() + (ColumnWidths.Count - 1) * MarginBetweenColumns + Padding; int ToolTipHeight = Padding + RowHeights.Sum() + (RowHeights.Count - 1) * MarginBetweenRows + Padding; Point ToolTipTopleft = DrawHelpers.GetTopleftPosition(new Point(ToolTipTopWidth, ToolTipHeight), new Point((int)((MouseScreenPosition.X + UserConfig.ToolTipOffset.X) / UIScaleFactor), (int)((MouseScreenPosition.Y + UserConfig.ToolTipOffset.Y) / UIScaleFactor)), 100); // Draw tooltip background DrawHelpers.DrawBox(e.SpriteBatch, new Rectangle(ToolTipTopleft.X, ToolTipTopleft.Y, ToolTipTopWidth, ToolTipHeight)); // Draw each row's header and value int CurrentY = ToolTipTopleft.Y + Padding; for (int i = 0; i < RowHeights.Count; i++) { int CurrentRowHeight = RowHeights[i]; // Draw the row header Vector2 RowHeaderPosition = new Vector2( ToolTipTopleft.X + Padding + ColumnWidths[0] - RowHeaderSizes[i].X, CurrentY + (RowHeights[i] - RowHeaderSizes[i].Y) / 2.0f ); e.SpriteBatch.DrawString(DefaultFont, RowHeaders[i], RowHeaderPosition, Color.Black, 0.0f, Vector2.Zero, LabelTextScale, SpriteEffects.None, 1.0f); // Draw the row value Vector2 RowValuePosition = new Vector2( ToolTipTopleft.X + Padding + ColumnWidths[0] + MarginBetweenColumns, CurrentY + (RowHeights[i] - RowValueSizes[i].Y) / 2.0f ); DrawHelpers.DrawStringWithSpecialNumbers(e.SpriteBatch, RowValuePosition, RowValues[i], ValueTextScale, Color.White); CurrentY += CurrentRowHeight + MarginBetweenRows; } } } } } }
private void Display_RenderedWorld(object sender, StardewModdingAPI.Events.RenderedWorldEventArgs e) { if (Game1.activeClickableMenu == null && PlacedAugmentorsManager.Instance != null) { GameLocation CurrentLocation = Game1.player.currentLocation; bool IsHoveringPlacedObject = CurrentLocation.Objects.TryGetValue(HoveredTile, out Object HoveredObject); if (IsHoveringPlacedObject) { Dictionary <AugmentorType, int> AttachedAugmentors = PlacedAugmentorsManager.Instance.GetAugmentorQuantities(CurrentLocation.NameOrUniqueName, HoveredTile); bool HasAttachedAugmentors = AttachedAugmentors.Any(x => x.Value > 0); if (MachineInfo.TryGetMachineInfo(HoveredObject, out MachineInfo MI)) { SpriteFont DefaultFont = Game1.dialogueFont; // Draw a tooltip showing what effects the held item will have when attached to this machine if (Game1.player.CurrentItem is Augmentor HeldAugmentor && HeldAugmentor.IsAugmentable(HoveredObject)) { AttachedAugmentors.TryGetValue(HeldAugmentor.AugmentorType, out int CurrentAttachedQuantity); double CurrentEffect = CurrentAttachedQuantity <= 0 ? Augmentor.GetDefaultEffect(HeldAugmentor.AugmentorType) : Augmentor.ComputeEffect(HeldAugmentor.AugmentorType, CurrentAttachedQuantity, MI.RequiresInput); double NewEffectSingle = Augmentor.ComputeEffect(HeldAugmentor.AugmentorType, CurrentAttachedQuantity + 1, MI.RequiresInput); double NewEffectAll = Augmentor.ComputeEffect(HeldAugmentor.AugmentorType, CurrentAttachedQuantity + HeldAugmentor.Stack, MI.RequiresInput); // Example of desired tooltip: // ------------------------------------------- // | [Icon] Time to process: | // |-----------------------------------------| // | Current Effect: 95.5% | // | New Effect: 92.2% (1) / 81.1% (4) | // ------------------------------------------- int Padding = 28; int MarginAfterIcon = 10; float LabelTextScale = 0.75f; float ValueTextScale = 1.0f; // Compute sizes of each row so we know how big the tooltip is, and can horizontally center the header and other rows // Compute size of header int HeaderHorizontalPadding = 4; Augmentor.TryGetIconDetails(HeldAugmentor.AugmentorType, out Texture2D IconTexture, out Rectangle IconSourcePosition, out float IconScale, out SpriteEffects IconEffects); Vector2 IconSize = new Vector2(IconSourcePosition.Width * IconScale, IconSourcePosition.Height * IconScale); string HeaderText = string.Format("{0}:", HeldAugmentor.GetEffectDescription()); Vector2 HeaderTextSize = DefaultFont.MeasureString(HeaderText) * LabelTextScale; float HeaderRowWidth = IconSize.X + MarginAfterIcon + HeaderTextSize.X + HeaderHorizontalPadding * 2; float HeaderRowHeight = Math.Max(IconSize.Y, HeaderTextSize.Y); // Compute size of horizontal separator int HorizontalSeparatorHeight = 6; int HorizontalSeparatorMargin = 8; // Compute size of the labels before the effect values int MarginAfterLabel = 8; string CurrentEffectLabel = string.Format("{0}:", Translate("CurrentEffectLabel")); Vector2 CurrentEffectLabelSize = DefaultFont.MeasureString(CurrentEffectLabel) * LabelTextScale; string NewEffectLabel = string.Format("{0}:", Translate("NewEffectLabel")); Vector2 NewEffectLabelSize = DefaultFont.MeasureString(NewEffectLabel) * LabelTextScale; float EffectLabelWidth = Math.Max(CurrentEffectLabelSize.X, NewEffectLabelSize.X); Vector2 EffectLabelSize = new Vector2(EffectLabelWidth, CurrentEffectLabelSize.Y + NewEffectLabelSize.Y); // Compute size of the effect values string CurrentEffectValue = string.Format("{0}% ({1})", (CurrentEffect * 100.0).ToString("0.##"), CurrentAttachedQuantity); Vector2 CurrentEffectValueSize = DrawHelpers.MeasureStringWithSpecialNumbers(CurrentEffectValue, ValueTextScale, 0.0f); string NewEffectValue; if (HeldAugmentor.Stack > 1) { NewEffectValue = string.Format("{0}% ({1}) / {2}% ({3})", (NewEffectSingle * 100.0).ToString("0.##"), (CurrentAttachedQuantity + 1), (NewEffectAll * 100.0).ToString("0.##"), (CurrentAttachedQuantity + HeldAugmentor.Stack)); } else { NewEffectValue = string.Format("{0}% ({1})", (NewEffectSingle * 100.0).ToString("0.##"), (CurrentAttachedQuantity + 1)); } Vector2 NewEffectValueSize = DrawHelpers.MeasureStringWithSpecialNumbers(NewEffectValue, ValueTextScale, 0.0f); Vector2 EffectContentSize = new Vector2(EffectLabelWidth + MarginAfterLabel + Math.Max(CurrentEffectValueSize.X, NewEffectValueSize.X), Math.Max(CurrentEffectLabelSize.Y, CurrentEffectValueSize.Y) + Math.Max(NewEffectLabelSize.Y, NewEffectValueSize.Y)); // Compute total size of tooltip, draw the background Vector2 ToolTipSize = new Vector2(Padding * 2 + Math.Max(HeaderRowWidth, EffectContentSize.X), Padding + HeaderRowHeight + HorizontalSeparatorMargin + HorizontalSeparatorHeight + HorizontalSeparatorMargin + EffectContentSize.Y + Padding); Point ToolTipTopleft = DrawHelpers.GetTopleftPosition(new Point((int)ToolTipSize.X, (int)ToolTipSize.Y), MouseScreenPosition, 100); DrawHelpers.DrawBox(e.SpriteBatch, new Rectangle(ToolTipTopleft.X, ToolTipTopleft.Y, (int)ToolTipSize.X, (int)ToolTipSize.Y)); float CurrentY = ToolTipTopleft.Y + Padding; // Draw the header float HeaderStartX = ToolTipTopleft.X + (ToolTipSize.X - HeaderRowWidth) / 2.0f; Vector2 IconPosition = new Vector2(HeaderStartX, CurrentY + (HeaderRowHeight - IconSize.Y) / 2.0f); e.SpriteBatch.Draw(IconTexture, IconPosition, IconSourcePosition, Color.White, 0f, Vector2.Zero, IconScale, IconEffects, 1f); Vector2 HeaderTextPosition = new Vector2(HeaderStartX + IconSize.X + MarginAfterIcon, CurrentY + (HeaderRowHeight - HeaderTextSize.Y) / 2.0f); e.SpriteBatch.DrawString(DefaultFont, HeaderText, HeaderTextPosition, Color.Black, 0.0f, Vector2.Zero, LabelTextScale, SpriteEffects.None, 1.0f); CurrentY += HeaderRowHeight + HorizontalSeparatorMargin; // Draw the horizontal separator DrawHelpers.DrawHorizontalSeparator(e.SpriteBatch, ToolTipTopleft.X + Padding, (int)CurrentY, (int)(ToolTipSize.X - 2 * Padding), HorizontalSeparatorHeight); CurrentY += HorizontalSeparatorHeight + HorizontalSeparatorMargin; // Draw the current effect Vector2 CurrentEffectLabelPosition = new Vector2(ToolTipTopleft.X + Padding + (EffectLabelWidth - CurrentEffectLabelSize.X), CurrentY); Vector2 CurrentEffectValuePosition = new Vector2(ToolTipTopleft.X + Padding + EffectLabelWidth + MarginAfterLabel, CurrentY); e.SpriteBatch.DrawString(DefaultFont, CurrentEffectLabel, CurrentEffectLabelPosition, Color.Black, 0.0f, Vector2.Zero, LabelTextScale, SpriteEffects.None, 1.0f); DrawHelpers.DrawStringWithSpecialNumbers(e.SpriteBatch, CurrentEffectValuePosition, CurrentEffectValue, ValueTextScale, Color.White); CurrentY += Math.Max(CurrentEffectLabelSize.Y, CurrentEffectValueSize.Y); // Draw the new effect Vector2 NewEffectLabelPosition = new Vector2(ToolTipTopleft.X + Padding + (EffectLabelWidth - NewEffectLabelSize.X), CurrentY); Vector2 NewEffectValuePosition = new Vector2(ToolTipTopleft.X + Padding + EffectLabelWidth + MarginAfterLabel, CurrentY); e.SpriteBatch.DrawString(DefaultFont, NewEffectLabel, NewEffectLabelPosition, Color.Black, 0.0f, Vector2.Zero, LabelTextScale, SpriteEffects.None, 1.0f); DrawHelpers.DrawStringWithSpecialNumbers(e.SpriteBatch, NewEffectValuePosition, NewEffectValue, ValueTextScale, Color.White); } // Draw a tooltip showing what effects are currently applied to this machine else if (HasAttachedAugmentors) { int Padding = 28; int MarginAfterIcon = 10; // Compute the size of each icon Dictionary <AugmentorType, Vector2> IconSizes = new Dictionary <AugmentorType, Vector2>(); foreach (KeyValuePair <AugmentorType, int> KVP in AttachedAugmentors.Where(x => x.Value > 0)) { Augmentor.TryGetIconDetails(KVP.Key, out Texture2D IconTexture, out Rectangle IconSourcePosition, out float IconScale, out SpriteEffects IconEffects); Vector2 IconSize = new Vector2(IconSourcePosition.Width * IconScale, IconSourcePosition.Height * IconScale); IconSizes.Add(KVP.Key, IconSize); } float IconColumnWidth = IconSizes.Values.Max(x => x.Y); // Compute the size of each row (each row shows the effect of a type of augmentor that has been applied to this machine) Dictionary <AugmentorType, Vector2> RowSizes = new Dictionary <AugmentorType, Vector2>(); foreach (KeyValuePair <AugmentorType, int> KVP in AttachedAugmentors.Where(x => x.Value > 0)) { double CurrentEffect = Augmentor.ComputeEffect(KVP.Key, KVP.Value, MI.RequiresInput); string Text = string.Format("{0}% ({1})", (CurrentEffect * 100.0).ToString("0.#"), KVP.Value); Vector2 TextSize = DrawHelpers.MeasureStringWithSpecialNumbers(Text, 1.0f, 4.0f); float RowWidth = IconColumnWidth + MarginAfterIcon + TextSize.X; float RowHeight = Math.Max(IconSizes[KVP.Key].Y, TextSize.Y); RowSizes.Add(KVP.Key, new Vector2(RowWidth, RowHeight)); } // Compute total size of tooltip, draw the background Vector2 ToolTipSize = new Vector2(Padding * 2 + RowSizes.Values.Max(x => x.X), Padding * 2 + RowSizes.Values.Sum(x => x.Y)); Point ToolTipTopleft = DrawHelpers.GetTopleftPosition(new Point((int)ToolTipSize.X, (int)ToolTipSize.Y), MouseScreenPosition, 100); DrawHelpers.DrawBox(e.SpriteBatch, new Rectangle(ToolTipTopleft.X, ToolTipTopleft.Y, (int)ToolTipSize.X, (int)ToolTipSize.Y)); float CurrentY = ToolTipTopleft.Y + Padding; // Draw each row float RowStartX = ToolTipTopleft.X + Padding; foreach (KeyValuePair <AugmentorType, int> KVP in AttachedAugmentors.Where(x => x.Value > 0)) { float CurrentX = RowStartX; float RowHeight = RowSizes[KVP.Key].Y; // Draw the icon Augmentor.TryGetIconDetails(KVP.Key, out Texture2D IconTexture, out Rectangle IconSourcePosition, out float IconScale, out SpriteEffects IconEffects); Vector2 IconSize = IconSizes[KVP.Key]; Vector2 IconPosition = new Vector2(CurrentX + (IconColumnWidth - IconSize.X) / 2.0f, CurrentY + (RowHeight - IconSize.Y) / 2.0f); e.SpriteBatch.Draw(IconTexture, IconPosition, IconSourcePosition, Color.White, 0f, Vector2.Zero, IconScale, IconEffects, 1f); CurrentX += IconColumnWidth + MarginAfterIcon; // Draw the value double CurrentEffect = Augmentor.ComputeEffect(KVP.Key, KVP.Value, MI.RequiresInput); string Text = string.Format("{0}% ({1})", (CurrentEffect * 100.0).ToString("0.#"), KVP.Value); Vector2 TextSize = DrawHelpers.MeasureStringWithSpecialNumbers(Text, 1.0f, 0.0f); Vector2 TextPosition = new Vector2(CurrentX, CurrentY + (RowHeight - TextSize.Y) / 2.0f); DrawHelpers.DrawStringWithSpecialNumbers(e.SpriteBatch, TextPosition, Text, 1.0f, Color.White); CurrentY += RowHeight; } //Maybe also show MinutesUntilReady if it's not ReadyForHarvest? } } } }
public override void drawTooltip(SpriteBatch spriteBatch, ref int x, ref int y, SpriteFont font, float alpha, StringBuilder overrideText) { // If viewing this bag from a Shop, draw a custom tooltip that displays icons for each item the bag is capable of storing if (Game1.activeClickableMenu is ShopMenu) { int SlotSize = 32; // May want to try 48. 64 is probably too big especially for bags that can store a large # of different items int NumItems = SizeInfo.Items.Count; int Columns = Math.Min(12, NumItems); int Rows = NumItems == 0 ? 0 : (NumItems - 1) / Columns + 1; int TitleWidth = (int)(font.MeasureString(this.DisplayName).X * 1.5) + 24; // Not sure if this is the correct scale and margin that the game's default rendering of the title bar uses int TextWidth = (int)font.MeasureString(overrideText).X + 32; // Do not change this 32, it's the additional margin that the game uses around the description text int ItemsMargin = 24; int ItemsWidth = SlotSize * Columns + ItemsMargin * 2; int RequiredWidth = Math.Max(Math.Max(TextWidth, TitleWidth), ItemsWidth); int MarginAfterDescription = 24; int RequiredHeight = (int)font.MeasureString(overrideText).Y + MarginAfterDescription + Rows * SlotSize - 8 + (int)font.MeasureString("999").Y + 32; DrawHelpers.DrawBox(spriteBatch, new Rectangle(x, y, RequiredWidth, RequiredHeight)); // Draw the description text if (overrideText != null && !string.IsNullOrEmpty(overrideText.ToString()) && overrideText.ToString() != " ") { spriteBatch.DrawString(font, overrideText, new Vector2((float)(x + 16), (float)(y + 16 + 4)) + new Vector2(2f, 2f), Game1.textShadowColor * alpha); spriteBatch.DrawString(font, overrideText, new Vector2((float)(x + 16), (float)(y + 16 + 4)) + new Vector2(0f, 2f), Game1.textShadowColor * alpha); spriteBatch.DrawString(font, overrideText, new Vector2((float)(x + 16), (float)(y + 16 + 4)) + new Vector2(2f, 0f), Game1.textShadowColor * alpha); spriteBatch.DrawString(font, overrideText, new Vector2((float)(x + 16), (float)(y + 16 + 4)), (Game1.textColor * 0.9f) * alpha); y = y + (int)font.MeasureString(overrideText).Y; } // Draw icons for each item that this bag is capable of storing y += MarginAfterDescription; int RowStartX = x + (RequiredWidth - SlotSize * Columns) / 2; int CurrentX = RowStartX; int CurrentIndex = 0; foreach (StoreableBagItem ItemInfo in SizeInfo.Items) { if (CurrentIndex == Columns) { CurrentIndex = 0; CurrentX = RowStartX; y += SlotSize; } Object Item = ItemInfo.IsBigCraftable ? new Object(Vector2.Zero, ItemInfo.Id, false) : new Object(ItemInfo.Id, 0, false, -1, 0); Rectangle Destination = new Rectangle(CurrentX, y, SlotSize, SlotSize); spriteBatch.Draw(Game1.menuTexture, Destination, new Rectangle(128, 128, 64, 64), Color.White); DrawHelpers.DrawItem(spriteBatch, Destination, Item, false, false, 1f, 1f, Color.White, Color.White); CurrentX += SlotSize; CurrentIndex++; } // Finish filling in the current row with empty slots while (CurrentIndex < Columns) { Rectangle Destination = new Rectangle(CurrentX, y, SlotSize, SlotSize); spriteBatch.Draw(Game1.menuTexture, Destination, new Rectangle(64, 896, 64, 64), Color.White); CurrentX += SlotSize; CurrentIndex++; } y += SlotSize - 8; } else { base.drawTooltip(spriteBatch, ref x, ref y, font, alpha, overrideText); } }
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); } } } }
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); } } } }
private void Display_RenderedWorld(object sender, RenderedWorldEventArgs e) { if (Game1.activeClickableMenu == null) { GameLocation CurrentLocation = Game1.player.currentLocation; bool IsHoveringPlacedObject = CurrentLocation.Objects.TryGetValue(HoveredTile, out SObject HoveredObject); if (IsHoveringPlacedObject) { if (UserConfig.DrawToolTip) { // Draw a tooltip that shows how many of the machine were combined, and its total combined processing power // Such as: "Quantity: 5\nPower: 465%" if (HoveredObject.TryGetCombinedQuantity(out int CombinedQuantity)) { Cask Cask = HoveredObject as Cask; bool IsCask = Cask != null; CrabPot CrabPot = HoveredObject as CrabPot; bool IsCrabPot = CrabPot != null; bool IsScarecrow = HoveredObject.IsScarecrow(); bool HasHeldObject = HoveredObject.heldObject?.Value != null; float UIScaleFactor = Game1.options.zoomLevel / Game1.options.uiScale; SpriteFont DefaultFont = Game1.dialogueFont; int Padding = 25; int MarginBetweenColumns = 10; int MarginBetweenRows = 5; float LabelTextScale = 0.75f; float ValueTextScale = 1.0f; bool ShowDurationInfo = UserConfig.ToolTipShowDuration && UserConfig.ShouldModifyProcessingSpeed(HoveredObject); bool ShowQuantityInfo = UserConfig.ToolTipShowQuantity && UserConfig.ShouldModifyInputsAndOutputs(HoveredObject); // Compute row headers List <string> RowHeaders = new List <string>() { Helper.Translation.Get("ToolTipQuantityLabel"), Helper.Translation.Get("ToolTipPowerLabel") }; if (ShowDurationInfo) { if (IsCask) { //RowHeaders.Add(Helper.Translation.Get("ToolTipCaskAgingRateLabel")); if (HasHeldObject) { RowHeaders.Add(Helper.Translation.Get("ToolTipCaskDaysUntilIridiumLabel")); } } else if (IsCrabPot) { RowHeaders.Add(Helper.Translation.Get("ToolTipCrabPotProcessingIntervalLabel")); } else { if (HasHeldObject) { RowHeaders.Add(Helper.Translation.Get("ToolTipMinutesRemainingLabel")); } } } if (ShowQuantityInfo) { if (HasHeldObject && HoveredObject.HasModifiedOutput()) { RowHeaders.Add(Helper.Translation.Get("ToolTipProducedQuantityLabel")); } } if (IsScarecrow) { RowHeaders.Add(Helper.Translation.Get("ToolTipScarecrowRadiusLabel")); } List <Vector2> RowHeaderSizes = RowHeaders.Select(x => DefaultFont.MeasureString(x) * LabelTextScale).ToList(); double ProcessingPower = UserConfig.ComputeProcessingPower(CombinedQuantity) * 100.0; string FormattedProcessingPower = string.Format("{0}%", ProcessingPower.ToString("0.#")); // Compute row values List <string> RowValues = new List <string>() { CombinedQuantity.ToString(), FormattedProcessingPower }; if (ShowDurationInfo) { if (IsCask) { //RowValues.Add(Cask.agingRate.Value.ToString("0.##")); if (HasHeldObject) { RowValues.Add(Math.Ceiling(Cask.daysToMature.Value / Cask.agingRate.Value).ToString("0.##")); } } else if (IsCrabPot) { CrabPot.TryGetProcessingInterval(out double Power, out double IntervalHours, out int IntervalMinutes); RowValues.Add(IntervalMinutes.ToString()); } else { if (HasHeldObject) { RowValues.Add(HoveredObject.MinutesUntilReady.ToString("0.##")); } } } if (ShowQuantityInfo) { if (HasHeldObject && HoveredObject.HasModifiedOutput()) { RowValues.Add(HoveredObject.heldObject.Value.Stack.ToString()); } } if (IsScarecrow) { // Subtract 1 because the game internally counts the scarecrow's occupied tile as part of its radius, but users usually would be confused by that // So a typical user expects radius=8 for a regular scarecrow, even though the game does its calculations with radius=9 int OriginalRadius = HoveredObject.GetScarecrowBaseRadius() - 1; int AlteredRadius = HoveredObject.GetScarecrowRadius() - 1; //RowValues.Add(string.Format("{0}-->{1}", OriginalRadius, AlteredRadius)); RowValues.Add(AlteredRadius.ToString()); } List <Vector2> RowValueSizes = RowValues.Select(x => DrawHelpers.MeasureStringWithSpecialNumbers(x, ValueTextScale, 0.0f)).ToList(); // Measure the tooltip List <int> RowHeights = new List <int>(); for (int i = 0; i < RowHeaders.Count; i++) { RowHeights.Add((int)Math.Max(RowHeaderSizes[i].Y, RowValueSizes[i].Y)); } List <int> ColumnWidths = new List <int> { (int)RowHeaderSizes.Max(x => x.X), (int)RowValueSizes.Max(x => x.X) }; int ToolTipTopWidth = Padding + ColumnWidths.Sum() + (ColumnWidths.Count - 1) * MarginBetweenColumns + Padding; int ToolTipHeight = Padding + RowHeights.Sum() + (RowHeights.Count - 1) * MarginBetweenRows + Padding; Point ToolTipTopleft = DrawHelpers.GetTopleftPosition(new Point(ToolTipTopWidth, ToolTipHeight), new Point((int)((MouseScreenPosition.X + UserConfig.ToolTipOffset.X) / UIScaleFactor), (int)((MouseScreenPosition.Y + UserConfig.ToolTipOffset.Y) / UIScaleFactor)), 100); // Draw tooltip background DrawHelpers.DrawBox(e.SpriteBatch, new Rectangle(ToolTipTopleft.X, ToolTipTopleft.Y, ToolTipTopWidth, ToolTipHeight)); // Draw each row's header and value int CurrentY = ToolTipTopleft.Y + Padding; for (int i = 0; i < RowHeights.Count; i++) { int CurrentRowHeight = RowHeights[i]; // Draw the row header Vector2 RowHeaderPosition = new Vector2( ToolTipTopleft.X + Padding + ColumnWidths[0] - RowHeaderSizes[i].X, CurrentY + (RowHeights[i] - RowHeaderSizes[i].Y) / 2.0f ); e.SpriteBatch.DrawString(DefaultFont, RowHeaders[i], RowHeaderPosition, Color.Black, 0.0f, Vector2.Zero, LabelTextScale, SpriteEffects.None, 1.0f); // Draw the row value Vector2 RowValuePosition = new Vector2( ToolTipTopleft.X + Padding + ColumnWidths[0] + MarginBetweenColumns, CurrentY + (RowHeights[i] - RowValueSizes[i].Y) / 2.0f ); DrawHelpers.DrawStringWithSpecialNumbers(e.SpriteBatch, RowValuePosition, RowValues[i], ValueTextScale, Color.White); CurrentY += CurrentRowHeight + MarginBetweenRows; } } } } } }