refactor: Split item grid out of ItemBrowser
This commit is contained in:
1 parent
3195e7ba92
commit
6b3dcccc7c
2 files changed
+99
-85
No files matched your search
@@ -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<WeaponClass>().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<int, Item> _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)
|
||||
|
||||
@@ -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<WeaponClass>().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<int, Item> _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
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user