From 6b3dcccc7c6d6a80262f02fde389c6a4413e4ca6 Mon Sep 17 00:00:00 2001 From: LeonardoVAC Date: Fri, 16 Oct 2026 00:38:45 -0300 Subject: [PATCH] refactor: Split item grid out of ItemBrowser --- src/TerraSharp/UI/ItemBrowser.cs | 87 +--------------------------- src/TerraSharp/UI/ItemGrid.cs | 97 ++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 85 deletions(-) create mode 100644 src/TerraSharp/UI/ItemGrid.cs diff --git a/src/TerraSharp/UI/ItemBrowser.cs b/src/TerraSharp/UI/ItemBrowser.cs index dc9bf17..ee1a5bd 100644 --- a/src/TerraSharp/UI/ItemBrowser.cs +++ b/src/TerraSharp/UI/ItemBrowser.cs @@ -1,89 +1,14 @@ -using System; -using System.Collections.Generic; -using System.Linq; using Microsoft.Xna.Framework; using Terraria; -using Terraria.GameContent.Creative; -using Terraria.ID; -using Terraria.Localization; -using Terraria.UI; -#if TMODLOADER -using Terraria.ModLoader; -#endif namespace TerraSharp.UI; -public sealed class ItemBrowser() : GridBrowser("items", "Item Browser", new Vector2(660, 120), 532, 520, "Search items by name or ID", "items", new IdIndex(() => ItemCount, Lang.GetItemNameValue), Categories()) +public sealed class ItemBrowser() : ItemGrid("items", "Item Browser", new Vector2(660, 120), 534, 520, []) { const int InventorySlots = 50; -#if TMODLOADER - static int ItemCount => ItemLoader.ItemCount; -#else - static int ItemCount => ItemID.Count; -#endif - - enum WeaponClass { Melee, Ranged, Magic, Summon, Other } - - static readonly IItemEntryFilter Weapon = new ItemFilters.Weapon(); - - // Journey duplication filters paired with Infinite_Icons frame indices. - static readonly (IItemEntryFilter Filter, int Icon)[] Filters = [(new ItemFilters.Tools(), 6), (new ItemFilters.Armor(), 2), (new ItemFilters.Vanity(), 8), (new ItemFilters.Accessories(), 1), (new ItemFilters.MiscAccessories(), 9), (new ItemFilters.Consumables(), 3), (new ItemFilters.BuildingBlock(), 4), (new ItemFilters.Furniture(), 7), (new ItemFilters.Materials(), 10)]; - - static BrowserCategory[] Categories() => - [ - new("All", _ => true), - new(Language.GetTextValue(Weapon.GetDisplayNameKey()), type => Fits(Weapon, type), 0, [.. Enum.GetValues(typeof(WeaponClass)).Cast().Select(weaponClass => new BrowserCategory(weaponClass.ToString(), type => ContentSample(type) is { } item && ClassOf(item) == weaponClass)), new("Ammo", type => ContentSample(type) is { ammo: > 0 })]), - .. Filters.Select(entry => new BrowserCategory(Language.GetTextValue(entry.Filter.GetDisplayNameKey()), type => Fits(entry.Filter, type), entry.Icon)), - new(Language.GetTextValue("CreativePowers.TabMisc"), type => !Fits(Weapon, type) && !Filters.Any(entry => Fits(entry.Filter, type)), 5), - ]; - - static Item? ContentSample(int type) => ContentSamples.ItemsByType.TryGetValue(type, out Item? item) ? item : null; - - // Whips must be classified as summon weapons before checking melee. - static WeaponClass? ClassOf(Item item) - { - if (!Weapon.FitsFilter(item) || item.pick > 0 || item.axe > 0 || item.hammer > 0 || item.ammo > 0) - return null; -#if TMODLOADER - if (item.CountsAsClass(DamageClass.Summon)) - return WeaponClass.Summon; - if (item.CountsAsClass(DamageClass.Magic)) - return WeaponClass.Magic; - if (item.CountsAsClass(DamageClass.Ranged)) - return WeaponClass.Ranged; - if (item.CountsAsClass(DamageClass.Melee)) - return WeaponClass.Melee; -#else - if (item.summon) - return WeaponClass.Summon; - if (item.magic) - return WeaponClass.Magic; - if (item.ranged) - return WeaponClass.Ranged; - if (item.melee) - return WeaponClass.Melee; -#endif - return WeaponClass.Other; - } - - static bool Fits(IItemEntryFilter filter, int type) => ContentSample(type) is { } item && filter.FitsFilter(item); - - readonly Dictionary _samples = []; - public override void OnOpen() => Main.playerInventory = true; - Item Sample(int type) - { - if (!_samples.TryGetValue(type, out Item? item)) - { - item = new Item(); - item.SetDefaults(type); - _samples[type] = item; - } - return item; - } - protected override void DrawContent(Rectangle body) { DrawSearchGrid(body, body.Y, body.Bottom - 30); @@ -92,18 +17,10 @@ public sealed class ItemBrowser() : GridBrowser("items", "Item Browser", new Vec protected override void DrawSlot(int type, Rectangle bounds, bool hot) { - Widgets.Slot(bounds, hot); - Render.Item(Widgets.SpriteBatch, type, new Rectangle(bounds.X + 6, bounds.Y + 6, bounds.Width - 12, bounds.Height - 12)); + DrawItem(type, bounds, hot); if (!hot) return; -#if TMODLOADER - Item sample = Sample(type); - ItemSlot.MouseHover(ref sample, ItemSlot.Context.CreativeInfinite); -#else - ItemSlot.MouseHover(Sample(type), ItemSlot.Context.CreativeInfinite); -#endif - if (Widgets.Click) Give(type, Widgets.Shift); else if (Widgets.RightClick) diff --git a/src/TerraSharp/UI/ItemGrid.cs b/src/TerraSharp/UI/ItemGrid.cs new file mode 100644 index 0000000..4009dad --- /dev/null +++ b/src/TerraSharp/UI/ItemGrid.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Xna.Framework; +using Terraria; +using Terraria.GameContent.Creative; +using Terraria.ID; +using Terraria.Localization; +using Terraria.UI; +#if TMODLOADER +using Terraria.ModLoader; +#endif + +namespace TerraSharp.UI; + +public abstract class ItemGrid(string id, string title, Vector2 position, int width, int height, BrowserCategory[] extra) : GridBrowser(id, title, position, width, height, "Search items by name or ID", "items", new IdIndex(() => ItemCount, Lang.GetItemNameValue), [.. Categories(), .. extra]) +{ +#if TMODLOADER + static int ItemCount => ItemLoader.ItemCount; +#else + static int ItemCount => ItemID.Count; +#endif + + enum WeaponClass { Melee, Ranged, Magic, Summon, Other } + + static readonly IItemEntryFilter Weapon = new ItemFilters.Weapon(); + + // Journey duplication filters paired with Infinite_Icons frame indices. + static readonly (IItemEntryFilter Filter, int Icon)[] Filters = [(new ItemFilters.Tools(), 6), (new ItemFilters.Armor(), 2), (new ItemFilters.Vanity(), 8), (new ItemFilters.Accessories(), 1), (new ItemFilters.MiscAccessories(), 9), (new ItemFilters.Consumables(), 3), (new ItemFilters.BuildingBlock(), 4), (new ItemFilters.Furniture(), 7), (new ItemFilters.Materials(), 10)]; + + static BrowserCategory[] Categories() => + [ + new("All", _ => true), + new(Language.GetTextValue(Weapon.GetDisplayNameKey()), type => Fits(Weapon, type), 0, [.. Enum.GetValues(typeof(WeaponClass)).Cast().Select(weaponClass => new BrowserCategory(weaponClass.ToString(), type => ContentSample(type) is { } item && ClassOf(item) == weaponClass)), new("Ammo", type => ContentSample(type) is { ammo: > 0 })]), + .. Filters.Select(entry => new BrowserCategory(Language.GetTextValue(entry.Filter.GetDisplayNameKey()), type => Fits(entry.Filter, type), entry.Icon)), + new(Language.GetTextValue("CreativePowers.TabMisc"), type => !Fits(Weapon, type) && !Filters.Any(entry => Fits(entry.Filter, type)), 5), + ]; + + static Item? ContentSample(int type) => ContentSamples.ItemsByType.TryGetValue(type, out Item? item) ? item : null; + + // Whips must be classified as summon weapons before checking melee. + static WeaponClass? ClassOf(Item item) + { + if (!Weapon.FitsFilter(item) || item.pick > 0 || item.axe > 0 || item.hammer > 0 || item.ammo > 0) + return null; +#if TMODLOADER + if (item.CountsAsClass(DamageClass.Summon)) + return WeaponClass.Summon; + if (item.CountsAsClass(DamageClass.Magic)) + return WeaponClass.Magic; + if (item.CountsAsClass(DamageClass.Ranged)) + return WeaponClass.Ranged; + if (item.CountsAsClass(DamageClass.Melee)) + return WeaponClass.Melee; +#else + if (item.summon) + return WeaponClass.Summon; + if (item.magic) + return WeaponClass.Magic; + if (item.ranged) + return WeaponClass.Ranged; + if (item.melee) + return WeaponClass.Melee; +#endif + return WeaponClass.Other; + } + + static bool Fits(IItemEntryFilter filter, int type) => ContentSample(type) is { } item && filter.FitsFilter(item); + + readonly Dictionary _samples = []; + + Item Sample(int type) + { + if (!_samples.TryGetValue(type, out Item? item)) + { + item = new Item(); + item.SetDefaults(type); + _samples[type] = item; + } + return item; + } + + protected void DrawItem(int type, Rectangle bounds, bool hot, bool selected = false) + { + Widgets.Slot(bounds, hot, selected); + Render.Item(Widgets.SpriteBatch, type, new Rectangle(bounds.X + 6, bounds.Y + 6, bounds.Width - 12, bounds.Height - 12)); + if (!hot) + return; + +#if TMODLOADER + Item sample = Sample(type); + ItemSlot.MouseHover(ref sample, ItemSlot.Context.CreativeInfinite); +#else + ItemSlot.MouseHover(Sample(type), ItemSlot.Context.CreativeInfinite); +#endif + } +}