Use EquipItem in item management and add filters to changed item types.

This commit is contained in:
Ottermandias 2023-06-09 16:10:02 +02:00
parent 5fcb07487e
commit d9c5c053cf
19 changed files with 641 additions and 375 deletions

View file

@ -9,15 +9,15 @@ using Penumbra.GameData.Structs;
namespace Penumbra.GameData.Data;
internal sealed class EquipmentIdentificationList : KeyList<Item>
internal sealed class EquipmentIdentificationList : KeyList<EquipItem>
{
private const string Tag = "EquipmentIdentification";
private const string Tag = "EquipmentIdentification";
public EquipmentIdentificationList(DalamudPluginInterface pi, ClientLanguage language, DataManager gameData)
: base(pi, Tag, language, ObjectIdentification.IdentificationVersion, CreateEquipmentList(gameData, language))
{ }
public IEnumerable<Item> Between(SetId modelId, EquipSlot slot = EquipSlot.Unknown, byte variant = 0)
public IEnumerable<EquipItem> Between(SetId modelId, EquipSlot slot = EquipSlot.Unknown, byte variant = 0)
{
if (slot == EquipSlot.Unknown)
return Between(ToKey(modelId, 0, 0), ToKey(modelId, (EquipSlot)0xFF, 0xFF));
@ -33,15 +33,10 @@ internal sealed class EquipmentIdentificationList : KeyList<Item>
public static ulong ToKey(SetId modelId, EquipSlot slot, byte variant)
=> ((ulong)modelId << 32) | ((ulong)slot << 16) | variant;
public static ulong ToKey(Item i)
{
var model = (SetId)((Lumina.Data.Parsing.Quad)i.ModelMain).A;
var slot = ((EquipSlot)i.EquipSlotCategory.Row).ToSlot();
var variant = (byte)((Lumina.Data.Parsing.Quad)i.ModelMain).B;
return ToKey(model, slot, variant);
}
public static ulong ToKey(EquipItem i)
=> ToKey(i.ModelId, i.Slot, i.Variant);
protected override IEnumerable<ulong> ToKeys(Item i)
protected override IEnumerable<ulong> ToKeys(EquipItem i)
{
yield return ToKey(i);
}
@ -49,12 +44,12 @@ internal sealed class EquipmentIdentificationList : KeyList<Item>
protected override bool ValidKey(ulong key)
=> key != 0;
protected override int ValueKeySelector(Item data)
=> (int)data.RowId;
protected override int ValueKeySelector(EquipItem data)
=> (int)data.Id;
private static IEnumerable<Item> CreateEquipmentList(DataManager gameData, ClientLanguage language)
private static IEnumerable<EquipItem> CreateEquipmentList(DataManager gameData, ClientLanguage language)
{
var items = gameData.GetExcelSheet<Item>(language)!;
return items.Where(i => ((EquipSlot)i.EquipSlotCategory.Row).IsEquipmentPiece());
return items.Where(i => ((EquipSlot)i.EquipSlotCategory.Row).IsEquipmentPiece()).Select(EquipItem.FromArmor);
}
}

View file

@ -5,32 +5,41 @@ using System.Linq;
using Dalamud;
using Dalamud.Data;
using Dalamud.Plugin;
using Dalamud.Utility;
using Lumina.Excel.GeneratedSheets;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
namespace Penumbra.GameData.Data;
public sealed class ItemData : DataSharer, IReadOnlyDictionary<FullEquipType, IReadOnlyList<Item>>
public sealed class ItemData : DataSharer, IReadOnlyDictionary<FullEquipType, IReadOnlyList<EquipItem>>
{
private readonly IReadOnlyList<IReadOnlyList<Item>> _items;
private readonly IReadOnlyList<IReadOnlyList<EquipItem>> _items;
private static IReadOnlyList<IReadOnlyList<Item>> CreateItems(DataManager dataManager, ClientLanguage language)
private static IReadOnlyList<IReadOnlyList<EquipItem>> CreateItems(DataManager dataManager, ClientLanguage language)
{
var tmp = Enum.GetValues<FullEquipType>().Select(t => new List<Item>(1024)).ToArray();
var tmp = Enum.GetValues<FullEquipType>().Select(_ => new List<EquipItem>(1024)).ToArray();
var itemSheet = dataManager.GetExcelSheet<Item>(language)!;
foreach (var item in itemSheet)
foreach (var item in itemSheet.Where(i => i.Name.RawData.Length > 1))
{
var type = item.ToEquipType();
if (type != FullEquipType.Unknown && item.Name.RawData.Length > 1)
tmp[(int)type].Add(item);
if (type.IsWeapon())
{
if (item.ModelMain != 0)
tmp[(int)type].Add(EquipItem.FromMainhand(item));
if (item.ModelSub != 0)
tmp[(int)type].Add(EquipItem.FromOffhand(item));
}
else if (type != FullEquipType.Unknown)
{
tmp[(int)type].Add(EquipItem.FromArmor(item));
}
}
var ret = new IReadOnlyList<Item>[tmp.Length];
ret[0] = Array.Empty<Item>();
var ret = new IReadOnlyList<EquipItem>[tmp.Length];
ret[0] = Array.Empty<EquipItem>();
for (var i = 1; i < tmp.Length; ++i)
ret[i] = tmp[i].OrderBy(item => item.Name.ToDalamudString().TextValue).ToArray();
ret[i] = tmp[i].OrderBy(item => item.Name).ToArray();
return ret;
}
@ -44,10 +53,10 @@ public sealed class ItemData : DataSharer, IReadOnlyDictionary<FullEquipType, IR
protected override void DisposeInternal()
=> DisposeTag("ItemList");
public IEnumerator<KeyValuePair<FullEquipType, IReadOnlyList<Item>>> GetEnumerator()
public IEnumerator<KeyValuePair<FullEquipType, IReadOnlyList<EquipItem>>> GetEnumerator()
{
for (var i = 1; i < _items.Count; ++i)
yield return new KeyValuePair<FullEquipType, IReadOnlyList<Item>>((FullEquipType)i, _items[i]);
yield return new KeyValuePair<FullEquipType, IReadOnlyList<EquipItem>>((FullEquipType)i, _items[i]);
}
IEnumerator IEnumerable.GetEnumerator()
@ -59,7 +68,7 @@ public sealed class ItemData : DataSharer, IReadOnlyDictionary<FullEquipType, IR
public bool ContainsKey(FullEquipType key)
=> (int)key < _items.Count && key != FullEquipType.Unknown;
public bool TryGetValue(FullEquipType key, out IReadOnlyList<Item> value)
public bool TryGetValue(FullEquipType key, out IReadOnlyList<EquipItem> value)
{
if (ContainsKey(key))
{
@ -71,12 +80,12 @@ public sealed class ItemData : DataSharer, IReadOnlyDictionary<FullEquipType, IR
return false;
}
public IReadOnlyList<Item> this[FullEquipType key]
public IReadOnlyList<EquipItem> this[FullEquipType key]
=> TryGetValue(key, out var ret) ? ret : throw new IndexOutOfRangeException();
public IEnumerable<FullEquipType> Keys
=> Enum.GetValues<FullEquipType>().Skip(1);
public IEnumerable<IReadOnlyList<Item>> Values
public IEnumerable<IReadOnlyList<EquipItem>> Values
=> _items.Skip(1);
}

View file

@ -65,7 +65,7 @@ internal sealed class ObjectIdentification : DataSharer, IObjectIdentifier
return ret;
}
public IEnumerable<Item> Identify(SetId setId, WeaponType weaponType, ushort variant, EquipSlot slot)
public IEnumerable<EquipItem> Identify(SetId setId, WeaponType weaponType, ushort variant, EquipSlot slot)
=> slot switch
{
EquipSlot.MainHand => _weapons.Between(setId, weaponType, (byte)variant),

View file

@ -9,7 +9,7 @@ using Penumbra.GameData.Structs;
namespace Penumbra.GameData.Data;
internal sealed class WeaponIdentificationList : KeyList<Item>
internal sealed class WeaponIdentificationList : KeyList<EquipItem>
{
private const string Tag = "WeaponIdentification";
private const int Version = 1;
@ -18,10 +18,10 @@ internal sealed class WeaponIdentificationList : KeyList<Item>
: base(pi, Tag, language, Version, CreateWeaponList(gameData, language))
{ }
public IEnumerable<Item> Between(SetId modelId)
public IEnumerable<EquipItem> Between(SetId modelId)
=> Between(ToKey(modelId, 0, 0), ToKey(modelId, 0xFFFF, 0xFF));
public IEnumerable<Item> Between(SetId modelId, WeaponType type, byte variant = 0)
public IEnumerable<EquipItem> Between(SetId modelId, WeaponType type, byte variant = 0)
{
if (type == 0)
return Between(ToKey(modelId, 0, 0), ToKey(modelId, 0xFFFF, 0xFF));
@ -37,38 +37,31 @@ internal sealed class WeaponIdentificationList : KeyList<Item>
public static ulong ToKey(SetId modelId, WeaponType type, byte variant)
=> ((ulong)modelId << 32) | ((ulong)type << 16) | variant;
public static ulong ToKey(Item i, bool offhand)
{
var quad = offhand ? (Lumina.Data.Parsing.Quad)i.ModelSub : (Lumina.Data.Parsing.Quad)i.ModelMain;
return ToKey(quad.A, quad.B, (byte)quad.C);
}
public static ulong ToKey(EquipItem i)
=> ToKey(i.ModelId, i.WeaponType, i.Variant);
protected override IEnumerable<ulong> ToKeys(Item i)
protected override IEnumerable<ulong> ToKeys(EquipItem data)
{
var key1 = 0ul;
if (i.ModelMain != 0)
{
key1 = ToKey(i, false);
yield return key1;
}
if (i.ModelSub != 0)
{
var key2 = ToKey(i, true);
if (key1 != key2)
yield return key2;
}
yield return ToKey(data);
}
protected override bool ValidKey(ulong key)
=> key != 0;
protected override int ValueKeySelector(Item data)
=> (int)data.RowId;
protected override int ValueKeySelector(EquipItem data)
=> (int)data.Id;
private static IEnumerable<Item> CreateWeaponList(DataManager gameData, ClientLanguage language)
private static IEnumerable<EquipItem> CreateWeaponList(DataManager gameData, ClientLanguage language)
=> gameData.GetExcelSheet<Item>(language)!.SelectMany(ToEquipItems);
private static IEnumerable<EquipItem> ToEquipItems(Item item)
{
var items = gameData.GetExcelSheet<Item>(language)!;
return items.Where(i => (EquipSlot)i.EquipSlotCategory.Row is EquipSlot.MainHand or EquipSlot.OffHand or EquipSlot.BothHand);
if ((EquipSlot)item.EquipSlotCategory.Row is not (EquipSlot.MainHand or EquipSlot.OffHand or EquipSlot.BothHand))
yield break;
if (item.ModelMain != 0)
yield return EquipItem.FromMainhand(item);
if (item.ModelSub != 0)
yield return EquipItem.FromOffhand(item);
}
}