mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
Make equipitems sharable again.
This commit is contained in:
parent
323b4d6f21
commit
8436455936
9 changed files with 146 additions and 52 deletions
|
|
@ -6,10 +6,11 @@ using Dalamud.Plugin;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
using PseudoEquipItem = System.ValueTuple<string, uint, ushort, ushort, ushort, byte, byte>;
|
||||||
|
|
||||||
namespace Penumbra.GameData.Data;
|
namespace Penumbra.GameData.Data;
|
||||||
|
|
||||||
internal sealed class EquipmentIdentificationList : KeyList<EquipItem>
|
internal sealed class EquipmentIdentificationList : KeyList<PseudoEquipItem>
|
||||||
{
|
{
|
||||||
private const string Tag = "EquipmentIdentification";
|
private const string Tag = "EquipmentIdentification";
|
||||||
|
|
||||||
|
|
@ -20,11 +21,11 @@ internal sealed class EquipmentIdentificationList : KeyList<EquipItem>
|
||||||
public IEnumerable<EquipItem> 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)
|
if (slot == EquipSlot.Unknown)
|
||||||
return Between(ToKey(modelId, 0, 0), ToKey(modelId, (EquipSlot)0xFF, 0xFF));
|
return Between(ToKey(modelId, 0, 0), ToKey(modelId, (EquipSlot)0xFF, 0xFF)).Select(e => (EquipItem)e);
|
||||||
if (variant == 0)
|
if (variant == 0)
|
||||||
return Between(ToKey(modelId, slot, 0), ToKey(modelId, slot, 0xFF));
|
return Between(ToKey(modelId, slot, 0), ToKey(modelId, slot, 0xFF)).Select(e => (EquipItem)e);
|
||||||
|
|
||||||
return Between(ToKey(modelId, slot, variant), ToKey(modelId, slot, variant));
|
return Between(ToKey(modelId, slot, variant), ToKey(modelId, slot, variant)).Select(e => (EquipItem)e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose(DalamudPluginInterface pi, ClientLanguage language)
|
public void Dispose(DalamudPluginInterface pi, ClientLanguage language)
|
||||||
|
|
@ -34,9 +35,9 @@ internal sealed class EquipmentIdentificationList : KeyList<EquipItem>
|
||||||
=> ((ulong)modelId << 32) | ((ulong)slot << 16) | variant;
|
=> ((ulong)modelId << 32) | ((ulong)slot << 16) | variant;
|
||||||
|
|
||||||
public static ulong ToKey(EquipItem i)
|
public static ulong ToKey(EquipItem i)
|
||||||
=> ToKey(i.ModelId, i.Slot, i.Variant);
|
=> ToKey(i.ModelId, i.Type.ToSlot(), i.Variant);
|
||||||
|
|
||||||
protected override IEnumerable<ulong> ToKeys(EquipItem i)
|
protected override IEnumerable<ulong> ToKeys(PseudoEquipItem i)
|
||||||
{
|
{
|
||||||
yield return ToKey(i);
|
yield return ToKey(i);
|
||||||
}
|
}
|
||||||
|
|
@ -44,12 +45,12 @@ internal sealed class EquipmentIdentificationList : KeyList<EquipItem>
|
||||||
protected override bool ValidKey(ulong key)
|
protected override bool ValidKey(ulong key)
|
||||||
=> key != 0;
|
=> key != 0;
|
||||||
|
|
||||||
protected override int ValueKeySelector(EquipItem data)
|
protected override int ValueKeySelector(PseudoEquipItem data)
|
||||||
=> (int)data.Id;
|
=> (int)data.Item2;
|
||||||
|
|
||||||
private static IEnumerable<EquipItem> CreateEquipmentList(DataManager gameData, ClientLanguage language)
|
private static IEnumerable<PseudoEquipItem> CreateEquipmentList(DataManager gameData, ClientLanguage language)
|
||||||
{
|
{
|
||||||
var items = gameData.GetExcelSheet<Item>(language)!;
|
var items = gameData.GetExcelSheet<Item>(language)!;
|
||||||
return items.Where(i => ((EquipSlot)i.EquipSlotCategory.Row).IsEquipmentPiece()).Select(EquipItem.FromArmor);
|
return items.Where(i => ((EquipSlot)i.EquipSlotCategory.Row).IsEquipmentPiece()).Select(i => (PseudoEquipItem)EquipItem.FromArmor(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
|
|
@ -18,7 +17,6 @@ public static partial class GamePaths
|
||||||
: GenderRace.Unknown;
|
: GenderRace.Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static partial class Monster
|
public static partial class Monster
|
||||||
{
|
{
|
||||||
public static partial class Imc
|
public static partial class Imc
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,17 @@ using Dalamud.Plugin;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
using PseudoEquipItem = System.ValueTuple<string, uint, ushort, ushort, ushort, byte, byte>;
|
||||||
|
|
||||||
namespace Penumbra.GameData.Data;
|
namespace Penumbra.GameData.Data;
|
||||||
|
|
||||||
public sealed class ItemData : DataSharer, IReadOnlyDictionary<FullEquipType, IReadOnlyList<EquipItem>>
|
public sealed class ItemData : DataSharer, IReadOnlyDictionary<FullEquipType, IReadOnlyList<EquipItem>>
|
||||||
{
|
{
|
||||||
private readonly IReadOnlyList<IReadOnlyList<EquipItem>> _items;
|
private readonly IReadOnlyDictionary<uint, PseudoEquipItem> _mainItems;
|
||||||
|
private readonly IReadOnlyDictionary<uint, PseudoEquipItem> _offItems;
|
||||||
|
private readonly IReadOnlyList<IReadOnlyList<PseudoEquipItem>> _byType;
|
||||||
|
|
||||||
private static IReadOnlyList<IReadOnlyList<EquipItem>> CreateItems(DataManager dataManager, ClientLanguage language)
|
private static IReadOnlyList<IReadOnlyList<PseudoEquipItem>> CreateItems(DataManager dataManager, ClientLanguage language)
|
||||||
{
|
{
|
||||||
var tmp = Enum.GetValues<FullEquipType>().Select(_ => new List<EquipItem>(1024)).ToArray();
|
var tmp = Enum.GetValues<FullEquipType>().Select(_ => new List<EquipItem>(1024)).ToArray();
|
||||||
|
|
||||||
|
|
@ -28,7 +31,7 @@ public sealed class ItemData : DataSharer, IReadOnlyDictionary<FullEquipType, IR
|
||||||
if (item.ModelMain != 0)
|
if (item.ModelMain != 0)
|
||||||
tmp[(int)type].Add(EquipItem.FromMainhand(item));
|
tmp[(int)type].Add(EquipItem.FromMainhand(item));
|
||||||
if (item.ModelSub != 0)
|
if (item.ModelSub != 0)
|
||||||
tmp[(int)type].Add(EquipItem.FromOffhand(item));
|
tmp[(int)type.Offhand()].Add(EquipItem.FromOffhand(item));
|
||||||
}
|
}
|
||||||
else if (type != FullEquipType.Unknown)
|
else if (type != FullEquipType.Unknown)
|
||||||
{
|
{
|
||||||
|
|
@ -36,56 +39,141 @@ public sealed class ItemData : DataSharer, IReadOnlyDictionary<FullEquipType, IR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var ret = new IReadOnlyList<EquipItem>[tmp.Length];
|
var ret = new IReadOnlyList<PseudoEquipItem>[tmp.Length];
|
||||||
ret[0] = Array.Empty<EquipItem>();
|
ret[0] = Array.Empty<PseudoEquipItem>();
|
||||||
for (var i = 1; i < tmp.Length; ++i)
|
for (var i = 1; i < tmp.Length; ++i)
|
||||||
ret[i] = tmp[i].OrderBy(item => item.Name).ToArray();
|
ret[i] = tmp[i].OrderBy(item => item.Name).Select(s => (PseudoEquipItem)s).ToArray();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IReadOnlyDictionary<uint, PseudoEquipItem> CreateMainItems(IReadOnlyList<IReadOnlyList<PseudoEquipItem>> items)
|
||||||
|
{
|
||||||
|
var dict = new Dictionary<uint, PseudoEquipItem>(1024 * 4);
|
||||||
|
foreach (var type in Enum.GetValues<FullEquipType>().Where(v => !FullEquipTypeExtensions.OffhandTypes.Contains(v)))
|
||||||
|
{
|
||||||
|
var list = items[(int)type];
|
||||||
|
foreach (var item in list)
|
||||||
|
dict.TryAdd(item.Item2, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
dict.TrimExcess();
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IReadOnlyDictionary<uint, PseudoEquipItem> CreateOffItems(IReadOnlyList<IReadOnlyList<PseudoEquipItem>> items)
|
||||||
|
{
|
||||||
|
var dict = new Dictionary<uint, PseudoEquipItem>(128);
|
||||||
|
foreach (var type in FullEquipTypeExtensions.OffhandTypes)
|
||||||
|
{
|
||||||
|
var list = items[(int)type];
|
||||||
|
foreach (var item in list)
|
||||||
|
dict.TryAdd(item.Item2, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
dict.TrimExcess();
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
|
||||||
public ItemData(DalamudPluginInterface pluginInterface, DataManager dataManager, ClientLanguage language)
|
public ItemData(DalamudPluginInterface pluginInterface, DataManager dataManager, ClientLanguage language)
|
||||||
: base(pluginInterface, language, 1)
|
: base(pluginInterface, language, 1)
|
||||||
{
|
{
|
||||||
_items = TryCatchData("ItemList", () => CreateItems(dataManager, language));
|
_byType = TryCatchData("ItemList", () => CreateItems(dataManager, language));
|
||||||
|
_mainItems = TryCatchData("ItemDictMain", () => CreateMainItems(_byType));
|
||||||
|
_offItems = TryCatchData("ItemDictOff", () => CreateOffItems(_byType));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void DisposeInternal()
|
protected override void DisposeInternal()
|
||||||
=> DisposeTag("ItemList");
|
{
|
||||||
|
DisposeTag("ItemList");
|
||||||
|
DisposeTag("ItemDictMain");
|
||||||
|
DisposeTag("ItemDictOff");
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerator<KeyValuePair<FullEquipType, IReadOnlyList<EquipItem>>> GetEnumerator()
|
public IEnumerator<KeyValuePair<FullEquipType, IReadOnlyList<EquipItem>>> GetEnumerator()
|
||||||
{
|
{
|
||||||
for (var i = 1; i < _items.Count; ++i)
|
for (var i = 1; i < _byType.Count; ++i)
|
||||||
yield return new KeyValuePair<FullEquipType, IReadOnlyList<EquipItem>>((FullEquipType)i, _items[i]);
|
yield return new KeyValuePair<FullEquipType, IReadOnlyList<EquipItem>>((FullEquipType)i, new EquipItemList(_byType[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
=> GetEnumerator();
|
=> GetEnumerator();
|
||||||
|
|
||||||
public int Count
|
public int Count
|
||||||
=> _items.Count - 1;
|
=> _byType.Count - 1;
|
||||||
|
|
||||||
public bool ContainsKey(FullEquipType key)
|
public bool ContainsKey(FullEquipType key)
|
||||||
=> (int)key < _items.Count && key != FullEquipType.Unknown;
|
=> (int)key < _byType.Count && key != FullEquipType.Unknown;
|
||||||
|
|
||||||
public bool TryGetValue(FullEquipType key, out IReadOnlyList<EquipItem> value)
|
public bool TryGetValue(FullEquipType key, out IReadOnlyList<EquipItem> value)
|
||||||
{
|
{
|
||||||
if (ContainsKey(key))
|
if (ContainsKey(key))
|
||||||
{
|
{
|
||||||
value = _items[(int)key];
|
value = new EquipItemList(_byType[(int)key]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = _items[0];
|
value = Array.Empty<EquipItem>();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyList<EquipItem> this[FullEquipType key]
|
public IReadOnlyList<EquipItem> this[FullEquipType key]
|
||||||
=> TryGetValue(key, out var ret) ? ret : throw new IndexOutOfRangeException();
|
=> TryGetValue(key, out var ret) ? ret : throw new IndexOutOfRangeException();
|
||||||
|
|
||||||
|
public bool ContainsKey(uint key, bool main = true)
|
||||||
|
=> main ? _mainItems.ContainsKey(key) : _offItems.ContainsKey(key);
|
||||||
|
|
||||||
|
public bool TryGetValue(uint key, out EquipItem value)
|
||||||
|
{
|
||||||
|
if (_mainItems.TryGetValue(key, out var v))
|
||||||
|
{
|
||||||
|
value = v;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = default;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<(uint, EquipItem)> AllItems(bool main)
|
||||||
|
=> (main ? _mainItems : _offItems).Select(i => (i.Key, (EquipItem)i.Value));
|
||||||
|
|
||||||
|
public bool TryGetValue(uint key, bool main, out EquipItem value)
|
||||||
|
{
|
||||||
|
var dict = main ? _mainItems : _offItems;
|
||||||
|
if (dict.TryGetValue(key, out var v))
|
||||||
|
{
|
||||||
|
value = v;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = default;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<FullEquipType> Keys
|
public IEnumerable<FullEquipType> Keys
|
||||||
=> Enum.GetValues<FullEquipType>().Skip(1);
|
=> Enum.GetValues<FullEquipType>().Skip(1);
|
||||||
|
|
||||||
public IEnumerable<IReadOnlyList<EquipItem>> Values
|
public IEnumerable<IReadOnlyList<EquipItem>> Values
|
||||||
=> _items.Skip(1);
|
=> _byType.Skip(1).Select(l => (IReadOnlyList<EquipItem>)new EquipItemList(l));
|
||||||
|
|
||||||
|
private readonly struct EquipItemList : IReadOnlyList<EquipItem>
|
||||||
|
{
|
||||||
|
private readonly IReadOnlyList<PseudoEquipItem> _items;
|
||||||
|
|
||||||
|
public EquipItemList(IReadOnlyList<PseudoEquipItem> items)
|
||||||
|
=> _items = items;
|
||||||
|
|
||||||
|
public IEnumerator<EquipItem> GetEnumerator()
|
||||||
|
=> _items.Select(i => (EquipItem)i).GetEnumerator();
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
=> GetEnumerator();
|
||||||
|
|
||||||
|
public int Count
|
||||||
|
=> _items.Count;
|
||||||
|
|
||||||
|
public EquipItem this[int index]
|
||||||
|
=> _items[index];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,11 @@ using Dalamud.Plugin;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
using PseudoEquipItem = System.ValueTuple<string, uint, ushort, ushort, ushort, byte, byte>;
|
||||||
|
|
||||||
namespace Penumbra.GameData.Data;
|
namespace Penumbra.GameData.Data;
|
||||||
|
|
||||||
internal sealed class WeaponIdentificationList : KeyList<EquipItem>
|
internal sealed class WeaponIdentificationList : KeyList<PseudoEquipItem>
|
||||||
{
|
{
|
||||||
private const string Tag = "WeaponIdentification";
|
private const string Tag = "WeaponIdentification";
|
||||||
private const int Version = 1;
|
private const int Version = 1;
|
||||||
|
|
@ -19,16 +20,16 @@ internal sealed class WeaponIdentificationList : KeyList<EquipItem>
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public IEnumerable<EquipItem> Between(SetId modelId)
|
public IEnumerable<EquipItem> Between(SetId modelId)
|
||||||
=> Between(ToKey(modelId, 0, 0), ToKey(modelId, 0xFFFF, 0xFF));
|
=> Between(ToKey(modelId, 0, 0), ToKey(modelId, 0xFFFF, 0xFF)).Select(e => (EquipItem)e);
|
||||||
|
|
||||||
public IEnumerable<EquipItem> Between(SetId modelId, WeaponType type, byte variant = 0)
|
public IEnumerable<EquipItem> Between(SetId modelId, WeaponType type, byte variant = 0)
|
||||||
{
|
{
|
||||||
if (type == 0)
|
if (type == 0)
|
||||||
return Between(ToKey(modelId, 0, 0), ToKey(modelId, 0xFFFF, 0xFF));
|
return Between(ToKey(modelId, 0, 0), ToKey(modelId, 0xFFFF, 0xFF)).Select(e => (EquipItem)e);
|
||||||
if (variant == 0)
|
if (variant == 0)
|
||||||
return Between(ToKey(modelId, type, 0), ToKey(modelId, type, 0xFF));
|
return Between(ToKey(modelId, type, 0), ToKey(modelId, type, 0xFF)).Select(e => (EquipItem)e);
|
||||||
|
|
||||||
return Between(ToKey(modelId, type, variant), ToKey(modelId, type, variant));
|
return Between(ToKey(modelId, type, variant), ToKey(modelId, type, variant)).Select(e => (EquipItem)e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose(DalamudPluginInterface pi, ClientLanguage language)
|
public void Dispose(DalamudPluginInterface pi, ClientLanguage language)
|
||||||
|
|
@ -40,7 +41,7 @@ internal sealed class WeaponIdentificationList : KeyList<EquipItem>
|
||||||
public static ulong ToKey(EquipItem i)
|
public static ulong ToKey(EquipItem i)
|
||||||
=> ToKey(i.ModelId, i.WeaponType, i.Variant);
|
=> ToKey(i.ModelId, i.WeaponType, i.Variant);
|
||||||
|
|
||||||
protected override IEnumerable<ulong> ToKeys(EquipItem data)
|
protected override IEnumerable<ulong> ToKeys(PseudoEquipItem data)
|
||||||
{
|
{
|
||||||
yield return ToKey(data);
|
yield return ToKey(data);
|
||||||
}
|
}
|
||||||
|
|
@ -48,20 +49,20 @@ internal sealed class WeaponIdentificationList : KeyList<EquipItem>
|
||||||
protected override bool ValidKey(ulong key)
|
protected override bool ValidKey(ulong key)
|
||||||
=> key != 0;
|
=> key != 0;
|
||||||
|
|
||||||
protected override int ValueKeySelector(EquipItem data)
|
protected override int ValueKeySelector(PseudoEquipItem data)
|
||||||
=> (int)data.Id;
|
=> (int)data.Item2;
|
||||||
|
|
||||||
private static IEnumerable<EquipItem> CreateWeaponList(DataManager gameData, ClientLanguage language)
|
private static IEnumerable<PseudoEquipItem> CreateWeaponList(DataManager gameData, ClientLanguage language)
|
||||||
=> gameData.GetExcelSheet<Item>(language)!.SelectMany(ToEquipItems);
|
=> gameData.GetExcelSheet<Item>(language)!.SelectMany(ToEquipItems);
|
||||||
|
|
||||||
private static IEnumerable<EquipItem> ToEquipItems(Item item)
|
private static IEnumerable<PseudoEquipItem> ToEquipItems(Item item)
|
||||||
{
|
{
|
||||||
if ((EquipSlot)item.EquipSlotCategory.Row is not (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;
|
yield break;
|
||||||
|
|
||||||
if (item.ModelMain != 0)
|
if (item.ModelMain != 0)
|
||||||
yield return EquipItem.FromMainhand(item);
|
yield return (PseudoEquipItem)EquipItem.FromMainhand(item);
|
||||||
if (item.ModelSub != 0)
|
if (item.ModelSub != 0)
|
||||||
yield return EquipItem.FromOffhand(item);
|
yield return (PseudoEquipItem)EquipItem.FromOffhand(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -403,4 +403,7 @@ public static class FullEquipTypeExtensions
|
||||||
|
|
||||||
public static readonly IReadOnlyList<FullEquipType> AccessoryTypes
|
public static readonly IReadOnlyList<FullEquipType> AccessoryTypes
|
||||||
= Enum.GetValues<FullEquipType>().Where(v => v.IsAccessory()).ToArray();
|
= Enum.GetValues<FullEquipType>().Where(v => v.IsAccessory()).ToArray();
|
||||||
|
|
||||||
|
public static readonly IReadOnlyList<FullEquipType> OffhandTypes
|
||||||
|
= Enum.GetValues<FullEquipType>().Where(v => v.OffhandTypeSuffix().Length > 0).ToArray();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
using Dalamud.Utility;
|
using Dalamud.Utility;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
using PseudoEquipItem = System.ValueTuple<string, uint, ushort, ushort, ushort, byte, byte>;
|
||||||
|
|
||||||
namespace Penumbra.GameData.Structs;
|
namespace Penumbra.GameData.Structs;
|
||||||
|
|
||||||
|
|
@ -15,7 +16,6 @@ public readonly struct EquipItem
|
||||||
public readonly WeaponType WeaponType;
|
public readonly WeaponType WeaponType;
|
||||||
public readonly byte Variant;
|
public readonly byte Variant;
|
||||||
public readonly FullEquipType Type;
|
public readonly FullEquipType Type;
|
||||||
public readonly EquipSlot Slot;
|
|
||||||
|
|
||||||
public bool Valid
|
public bool Valid
|
||||||
=> Type != FullEquipType.Unknown;
|
=> Type != FullEquipType.Unknown;
|
||||||
|
|
@ -35,8 +35,7 @@ public readonly struct EquipItem
|
||||||
public EquipItem()
|
public EquipItem()
|
||||||
=> Name = string.Empty;
|
=> Name = string.Empty;
|
||||||
|
|
||||||
public EquipItem(string name, uint id, ushort iconId, SetId modelId, WeaponType weaponType, byte variant, FullEquipType type,
|
public EquipItem(string name, uint id, ushort iconId, SetId modelId, WeaponType weaponType, byte variant, FullEquipType type)
|
||||||
EquipSlot slot)
|
|
||||||
{
|
{
|
||||||
Name = string.Intern(name);
|
Name = string.Intern(name);
|
||||||
Id = id;
|
Id = id;
|
||||||
|
|
@ -45,20 +44,24 @@ public readonly struct EquipItem
|
||||||
WeaponType = weaponType;
|
WeaponType = weaponType;
|
||||||
Variant = variant;
|
Variant = variant;
|
||||||
Type = type;
|
Type = type;
|
||||||
Slot = slot;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static implicit operator EquipItem(PseudoEquipItem it)
|
||||||
|
=> new(it.Item1, it.Item2, it.Item3, it.Item4, it.Item5, it.Item6, (FullEquipType)it.Item7);
|
||||||
|
|
||||||
|
public static explicit operator PseudoEquipItem(EquipItem it)
|
||||||
|
=> (it.Name, it.Id, it.IconId, (ushort)it.ModelId, (ushort)it.WeaponType, it.Variant, (byte)it.Type);
|
||||||
|
|
||||||
public static EquipItem FromArmor(Item item)
|
public static EquipItem FromArmor(Item item)
|
||||||
{
|
{
|
||||||
var type = item.ToEquipType();
|
var type = item.ToEquipType();
|
||||||
var slot = type.ToSlot();
|
|
||||||
var name = item.Name.ToDalamudString().TextValue;
|
var name = item.Name.ToDalamudString().TextValue;
|
||||||
var id = item.RowId;
|
var id = item.RowId;
|
||||||
var icon = item.Icon;
|
var icon = item.Icon;
|
||||||
var model = (SetId)item.ModelMain;
|
var model = (SetId)item.ModelMain;
|
||||||
var weapon = (WeaponType)0;
|
var weapon = (WeaponType)0;
|
||||||
var variant = (byte)(item.ModelMain >> 16);
|
var variant = (byte)(item.ModelMain >> 16);
|
||||||
return new EquipItem(name, id, icon, model, weapon, variant, type, slot);
|
return new EquipItem(name, id, icon, model, weapon, variant, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquipItem FromMainhand(Item item)
|
public static EquipItem FromMainhand(Item item)
|
||||||
|
|
@ -70,7 +73,7 @@ public readonly struct EquipItem
|
||||||
var model = (SetId)item.ModelMain;
|
var model = (SetId)item.ModelMain;
|
||||||
var weapon = (WeaponType)(item.ModelMain >> 16);
|
var weapon = (WeaponType)(item.ModelMain >> 16);
|
||||||
var variant = (byte)(item.ModelMain >> 32);
|
var variant = (byte)(item.ModelMain >> 32);
|
||||||
return new EquipItem(name, id, icon, model, weapon, variant, type, EquipSlot.MainHand);
|
return new EquipItem(name, id, icon, model, weapon, variant, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquipItem FromOffhand(Item item)
|
public static EquipItem FromOffhand(Item item)
|
||||||
|
|
@ -82,6 +85,6 @@ public readonly struct EquipItem
|
||||||
var model = (SetId)item.ModelSub;
|
var model = (SetId)item.ModelSub;
|
||||||
var weapon = (WeaponType)(item.ModelSub >> 16);
|
var weapon = (WeaponType)(item.ModelSub >> 16);
|
||||||
var variant = (byte)(item.ModelSub >> 32);
|
var variant = (byte)(item.ModelSub >> 32);
|
||||||
return new EquipItem(name, id, icon, model, weapon, variant, type, EquipSlot.OffHand);
|
return new EquipItem(name, id, icon, model, weapon, variant, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -242,10 +242,10 @@ public static class EquipmentSwap
|
||||||
|
|
||||||
private static void LookupItem(EquipItem i, out EquipSlot slot, out SetId modelId, out byte variant)
|
private static void LookupItem(EquipItem i, out EquipSlot slot, out SetId modelId, out byte variant)
|
||||||
{
|
{
|
||||||
if (!i.Slot.IsEquipmentPiece())
|
slot = i.Type.ToSlot();
|
||||||
|
if (!slot.IsEquipmentPiece())
|
||||||
throw new ItemSwap.InvalidItemTypeException();
|
throw new ItemSwap.InvalidItemTypeException();
|
||||||
|
|
||||||
slot = i.Slot;
|
|
||||||
modelId = i.ModelId;
|
modelId = i.ModelId;
|
||||||
variant = i.Variant;
|
variant = i.Variant;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Services;
|
namespace Penumbra.Services;
|
||||||
|
|
||||||
public abstract class SyncServiceWrapper<T>
|
public abstract class SyncServiceWrapper<T> : IDisposable
|
||||||
{
|
{
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
public T Service { get; }
|
public T Service { get; }
|
||||||
|
|
@ -34,7 +34,7 @@ public abstract class SyncServiceWrapper<T>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class AsyncServiceWrapper<T>
|
public abstract class AsyncServiceWrapper<T> : IDisposable
|
||||||
{
|
{
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
public T? Service { get; private set; }
|
public T? Service { get; private set; }
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@ public class ChangedItemDrawer : IDisposable
|
||||||
switch (obj)
|
switch (obj)
|
||||||
{
|
{
|
||||||
case EquipItem it:
|
case EquipItem it:
|
||||||
iconType = it.Slot switch
|
iconType = it.Type.ToSlot() switch
|
||||||
{
|
{
|
||||||
EquipSlot.MainHand => ChangedItemIcon.Mainhand,
|
EquipSlot.MainHand => ChangedItemIcon.Mainhand,
|
||||||
EquipSlot.OffHand => ChangedItemIcon.Offhand,
|
EquipSlot.OffHand => ChangedItemIcon.Offhand,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue