From bde9049a009d042de75e0ee4783826bdfb3d17bc Mon Sep 17 00:00:00 2001 From: Sebastian Mahr Date: Thu, 11 Jul 2024 14:19:04 +0200 Subject: [PATCH] show multiple lines of comunity bundle --- .../Infrastructure/Helpers/BundleHelper.cs | 23 ++++---- .../UIElements/ShowItemHoverInformation.cs | 58 ++++++++++++++----- 2 files changed, 57 insertions(+), 24 deletions(-) diff --git a/UIInfoSuite2/Infrastructure/Helpers/BundleHelper.cs b/UIInfoSuite2/Infrastructure/Helpers/BundleHelper.cs index 52922123..5ebf353e 100644 --- a/UIInfoSuite2/Infrastructure/Helpers/BundleHelper.cs +++ b/UIInfoSuite2/Infrastructure/Helpers/BundleHelper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Microsoft.Xna.Framework; using StardewModdingAPI; using StardewValley; @@ -11,7 +12,7 @@ namespace UIInfoSuite2.Infrastructure.Helpers; using BundleIngredientsCache = Dictionary>>; -public record BundleRequiredItem(string Name, int BannerWidth, int Id, string QualifiedId, int Quality); +public record BundleRequiredItem(string Name, int BannerWidth, int Id, string QualifiedId, int Quality, int Count); public record BundleKeyData(string Name, int Color); @@ -48,7 +49,7 @@ private static int GetBundleBannerWidthForName(string bundleName) return 68 + (int)Game1.dialogueFont.MeasureString(bundleName).X; } - public static BundleRequiredItem? GetBundleItemIfNotDonated(Item item) + public static List? GetBundleItemIfNotDonated(Item item) { if (item is not SObject donatedItem || donatedItem.bigCraftable.Value) { @@ -72,7 +73,7 @@ private static int GetBundleBannerWidthForName(string bundleName) } - BundleRequiredItem? output; + List? output; List>? bundleRequiredItemsList; if (bundlesIngredientsInfo.TryGetValue(donatedItem.QualifiedItemId, out bundleRequiredItemsList)) @@ -94,11 +95,13 @@ private static int GetBundleBannerWidthForName(string bundleName) return output ?? null; } - private static BundleRequiredItem? GetBundleItemIfNotDonatedFromList(List>? lists, ISalable obj) + private static List? GetBundleItemIfNotDonatedFromList(List>? lists, ISalable obj) { + + List output = new(); if (lists == null) { - return null; + return output; } foreach (List list in lists) @@ -107,23 +110,23 @@ private static int GetBundleBannerWidthForName(string bundleName) { continue; } - BundleKeyData? bundleKeyData = GetBundleKeyDataFromIndex(list[0]); if (bundleKeyData == null) { continue; } - return new BundleRequiredItem( + output.Add(new BundleRequiredItem( bundleKeyData.Name, GetBundleBannerWidthForName(bundleKeyData.Name), list[0], obj.QualifiedItemId, - obj.Quality - ); + obj.Quality, + list[1] + )); } - return null; + return output; } public static void PopulateBundleNameMappings(bool force = false) diff --git a/UIInfoSuite2/UIElements/ShowItemHoverInformation.cs b/UIInfoSuite2/UIElements/ShowItemHoverInformation.cs index 6bfb8af2..15900060 100644 --- a/UIInfoSuite2/UIElements/ShowItemHoverInformation.cs +++ b/UIInfoSuite2/UIElements/ShowItemHoverInformation.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI; @@ -15,6 +17,8 @@ namespace UIInfoSuite2.UIElements; +public record RequiredBundleItem(string Text, Color? Color); + internal class ShowItemHoverInformation : IDisposable { private readonly ClickableTextureComponent _bundleIcon = new( @@ -26,6 +30,10 @@ internal class ShowItemHoverInformation : IDisposable private readonly IModHelper _helper; + private readonly Dictionary _colorCache = new(); + + private readonly int bundleInfoHeight = 36; + private readonly PerScreen _hoverItem = new(); private readonly ClickableTextureComponent _museumIcon; @@ -154,17 +162,24 @@ private void DrawAdvancedTooltip(SpriteBatch spriteBatch) hoveredObject.Type != "Fish" && hoveredObject.Category != Object.skillBooksCategory; - string? requiredBundleName = null; - Color? bundleColor = null; + List? requiredBundleItems = new(); if (hoveredObject != null) { - BundleRequiredItem? bundleDisplayData = BundleHelper.GetBundleItemIfNotDonated(hoveredObject); + + List? bundleDisplayData = BundleHelper.GetBundleItemIfNotDonated(hoveredObject); + if (bundleDisplayData != null) { - requiredBundleName = bundleDisplayData.Name; - - // TODO cache these colors so we're not doing it every time - bundleColor = BundleHelper.GetRealColorFromIndex(bundleDisplayData.Id)?.Desaturate(0.35f); + bundleDisplayData.ForEach(item => + { + _colorCache.TryGetValue(item.Id, out Color? bundleColor); + if (bundleColor == null) + { + bundleColor = BundleHelper.GetRealColorFromIndex(item.Id)?.Desaturate(0.35f); + _colorCache[item.Id] = bundleColor; + } + requiredBundleItems.Add(new RequiredBundleItem(item.Name + " : " + item.Count, bundleColor)); + }); } } @@ -172,10 +187,12 @@ private void DrawAdvancedTooltip(SpriteBatch spriteBatch) int windowWidth, windowHeight; var bundleHeaderWidth = 0; - if (!string.IsNullOrEmpty(requiredBundleName)) + if (requiredBundleItems.Count > 0) { // bundleHeaderWidth = ((bundleIcon.Width * 3 = 45) - 7 = 38) + 3 + bundleTextSize.X + 3 + ((shippingBin.Width * 1.2 = 36) - 12 = 24) - bundleHeaderWidth = 68 + (int)Game1.dialogueFont.MeasureString(requiredBundleName).X; + int maxWidth = requiredBundleItems.Max(item => (int)Game1.dialogueFont.MeasureString(item.Text).X); + + bundleHeaderWidth = 68 + maxWidth; } var itemTextWidth = (int)Game1.smallFont.MeasureString(itemPrice.ToString()).X; @@ -203,9 +220,9 @@ private void DrawAdvancedTooltip(SpriteBatch spriteBatch) windowHeight += 40; } - if (!string.IsNullOrEmpty(requiredBundleName)) + if (requiredBundleItems.Count > 0) { - windowHeight += 4; + windowHeight += 4 + bundleInfoHeight * (requiredBundleItems.Count - 1); drawPositionOffset.Y += 4; } @@ -234,7 +251,16 @@ private void DrawAdvancedTooltip(SpriteBatch spriteBatch) } var windowPos = new Vector2(windowX, windowY); + + if(requiredBundleItems.Count > 1) + { + windowPos.Y += bundleInfoHeight * (requiredBundleItems.Count - 1); + } Vector2 drawPosition = windowPos + new Vector2(16, 20) + drawPositionOffset; + if(requiredBundleItems.Count > 1) + { + windowPos.Y -= bundleInfoHeight * (requiredBundleItems.Count - 1); + } // Icons are drawn in 32x40 cells. The small font has a cap height of 18 and an offset of (2, 6) var rowHeight = 40; @@ -244,7 +270,7 @@ private void DrawAdvancedTooltip(SpriteBatch spriteBatch) if (itemPrice > 0 || stackPrice > 0 || cropPrice > 0 || - !string.IsNullOrEmpty(requiredBundleName) || + requiredBundleItems.Count > 0 || notDonatedYet || notShippedYet) { @@ -342,11 +368,15 @@ private void DrawAdvancedTooltip(SpriteBatch spriteBatch) ); } - if (!string.IsNullOrEmpty(requiredBundleName)) + if (requiredBundleItems.Count > 0) { // Draws a 30x42 bundle icon offset by (-7, -13) from the top-left corner of the window // and the 36px high banner with the bundle name - DrawBundleBanner(spriteBatch, requiredBundleName, windowPos + new Vector2(-7, -13), windowWidth, bundleColor); + for (int i = 0; i < requiredBundleItems.Count; i++) + { + var item = requiredBundleItems[i]; + DrawBundleBanner(spriteBatch, item.Text, windowPos + new Vector2(-7, -13) + new Vector2(0, bundleInfoHeight * i), windowWidth, item.Color); + } } if (notShippedYet)