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 Microsoft.Xna.Framework;
|
||||||
using Terraria;
|
using Terraria;
|
||||||
using Terraria.GameContent.Creative;
|
|
||||||
using Terraria.ID;
|
|
||||||
using Terraria.Localization;
|
|
||||||
using Terraria.UI;
|
|
||||||
#if TMODLOADER
|
|
||||||
using Terraria.ModLoader;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace TerraSharp.UI;
|
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;
|
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;
|
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)
|
protected override void DrawContent(Rectangle body)
|
||||||
{
|
{
|
||||||
DrawSearchGrid(body, body.Y, body.Bottom - 30);
|
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)
|
protected override void DrawSlot(int type, Rectangle bounds, bool hot)
|
||||||
{
|
{
|
||||||
Widgets.Slot(bounds, hot);
|
DrawItem(type, bounds, hot);
|
||||||
Render.Item(Widgets.SpriteBatch, type, new Rectangle(bounds.X + 6, bounds.Y + 6, bounds.Width - 12, bounds.Height - 12));
|
|
||||||
if (!hot)
|
if (!hot)
|
||||||
return;
|
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)
|
if (Widgets.Click)
|
||||||
Give(type, Widgets.Shift);
|
Give(type, Widgets.Shift);
|
||||||
else if (Widgets.RightClick)
|
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