public void Draw(SpriteBatch b) { //b.Draw(TextureHelpers.GetSolidColorTexture(Game1.graphics.GraphicsDevice, Color.Red), ContentsBounds, Color.White); if (HorizontalSeparatorPosition.HasValue) { DrawHelpers.DrawHorizontalSeparator(b, HorizontalSeparatorPosition.Value); } GroupedOptions.Draw(b); UngroupedOptions.Draw(b); }
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 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); } } } }