Change some item data.

This commit is contained in:
Ottermandias 2023-07-23 16:13:21 +02:00
parent 774f93f962
commit 4f2a14c9ee
5 changed files with 61 additions and 60 deletions

View file

@ -1,9 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Dalamud; using Dalamud;
using Dalamud.Data;
using Dalamud.Plugin; using Dalamud.Plugin;
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, ulong, ushort, ushort, ushort, byte, byte>; using PseudoEquipItem = System.ValueTuple<string, ulong, ushort, ushort, ushort, byte, byte>;
@ -14,8 +12,8 @@ internal sealed class EquipmentIdentificationList : KeyList<PseudoEquipItem>
{ {
private const string Tag = "EquipmentIdentification"; private const string Tag = "EquipmentIdentification";
public EquipmentIdentificationList(DalamudPluginInterface pi, ClientLanguage language, DataManager gameData) public EquipmentIdentificationList(DalamudPluginInterface pi, ClientLanguage language, ItemData data)
: base(pi, Tag, language, ObjectIdentification.IdentificationVersion, CreateEquipmentList(gameData, language)) : base(pi, Tag, language, ObjectIdentification.IdentificationVersion, CreateEquipmentList(data))
{ } { }
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)
@ -48,7 +46,7 @@ internal sealed class EquipmentIdentificationList : KeyList<PseudoEquipItem>
protected override int ValueKeySelector(PseudoEquipItem data) protected override int ValueKeySelector(PseudoEquipItem data)
=> (int)data.Item2; => (int)data.Item2;
private static IEnumerable<PseudoEquipItem> CreateEquipmentList(DataManager gameData, ClientLanguage language) private static IEnumerable<PseudoEquipItem> CreateEquipmentList(ItemData data)
{ {
var items = gameData.GetExcelSheet<Item>(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())
@ -59,6 +57,13 @@ internal sealed class EquipmentIdentificationList : KeyList<PseudoEquipItem>
private static IEnumerable<PseudoEquipItem> CustomList private static IEnumerable<PseudoEquipItem> CustomList
=> new[] => new[]
{ {
(PseudoEquipItem)EquipItem.FromIds(0, 0, 8100, 0, 1, FullEquipType.Body, "Reaper Shroud"), (PseudoEquipItem)EquipItem.FromIds(0, 0, 8100, 0, 1, FullEquipType.Body, "Reaper Shroud"),
(PseudoEquipItem)EquipItem.FromIds(0, 0, 9041, 0, 1, FullEquipType.Head, "Cid's Bandana (9041)"),
(PseudoEquipItem)EquipItem.FromIds(0, 0, 9041, 0, 1, FullEquipType.Body, "Cid's Body (9041)"),
(PseudoEquipItem)EquipItem.FromIds(0, 0, 9903, 0, 1, FullEquipType.Head, "Smallclothes (NPC, 9903)"),
(PseudoEquipItem)EquipItem.FromIds(0, 0, 9903, 0, 1, FullEquipType.Body, "Smallclothes (NPC, 9903)"),
(PseudoEquipItem)EquipItem.FromIds(0, 0, 9903, 0, 1, FullEquipType.Hands, "Smallclothes (NPC, 9903)"),
(PseudoEquipItem)EquipItem.FromIds(0, 0, 9903, 0, 1, FullEquipType.Legs, "Smallclothes (NPC, 9903)"),
(PseudoEquipItem)EquipItem.FromIds(0, 0, 9903, 0, 1, FullEquipType.Feet, "Smallclothes (NPC, 9903)"),
}; };
} }

View file

@ -16,6 +16,7 @@ public sealed class ItemData : DataSharer, IReadOnlyDictionary<FullEquipType, IR
{ {
private readonly IReadOnlyDictionary<uint, PseudoEquipItem> _mainItems; private readonly IReadOnlyDictionary<uint, PseudoEquipItem> _mainItems;
private readonly IReadOnlyDictionary<uint, PseudoEquipItem> _offItems; private readonly IReadOnlyDictionary<uint, PseudoEquipItem> _offItems;
private readonly IReadOnlyDictionary<uint, PseudoEquipItem> _gauntlets;
private readonly IReadOnlyList<IReadOnlyList<PseudoEquipItem>> _byType; private readonly IReadOnlyList<IReadOnlyList<PseudoEquipItem>> _byType;
private static IReadOnlyList<IReadOnlyList<PseudoEquipItem>> CreateItems(DataManager dataManager, ClientLanguage language) private static IReadOnlyList<IReadOnlyList<PseudoEquipItem>> CreateItems(DataManager dataManager, ClientLanguage language)
@ -28,10 +29,23 @@ public sealed class ItemData : DataSharer, IReadOnlyDictionary<FullEquipType, IR
var type = item.ToEquipType(); var type = item.ToEquipType();
if (type.IsWeapon() || type.IsTool()) if (type.IsWeapon() || type.IsTool())
{ {
var mh = EquipItem.FromMainhand(item);
if (item.ModelMain != 0) if (item.ModelMain != 0)
tmp[(int)type].Add(EquipItem.FromMainhand(item)); tmp[(int)type].Add(mh);
if (item.ModelSub != 0) if (item.ModelSub != 0)
tmp[(int)type.ValidOffhand()].Add(EquipItem.FromOffhand(item)); {
if (type is FullEquipType.Fists && item.ModelSub < 0x100000000)
{
tmp[(int)FullEquipType.Hands].Add(new EquipItem(mh.Name + $" (Gauntlets)", mh.Id, mh.IconId, (SetId)item.ModelSub, 0,
(byte)(item.ModelSub >> 16), FullEquipType.Hands));
tmp[(int)FullEquipType.FistsOff].Add(new EquipItem(mh.Name + FullEquipType.FistsOff.OffhandTypeSuffix(), mh.Id,
mh.IconId, (SetId)(mh.ModelId.Value + 50), mh.WeaponType, mh.Variant, FullEquipType.FistsOff));
}
else
{
tmp[(int)type.ValidOffhand()].Add(EquipItem.FromOffhand(item));
}
}
} }
else if (type != FullEquipType.Unknown) else if (type != FullEquipType.Unknown)
{ {
@ -47,18 +61,26 @@ public sealed class ItemData : DataSharer, IReadOnlyDictionary<FullEquipType, IR
return ret; return ret;
} }
private static IReadOnlyDictionary<uint, PseudoEquipItem> CreateMainItems(IReadOnlyList<IReadOnlyList<PseudoEquipItem>> items) private static Tuple<IReadOnlyDictionary<uint, PseudoEquipItem>, IReadOnlyDictionary<uint, PseudoEquipItem>> CreateMainItems(
IReadOnlyList<IReadOnlyList<PseudoEquipItem>> items)
{ {
var dict = new Dictionary<uint, PseudoEquipItem>(1024 * 4); var dict = new Dictionary<uint, PseudoEquipItem>(1024 * 4);
foreach (var fistWeapon in items[(int)FullEquipType.Fists])
dict.TryAdd((uint)fistWeapon.Item2, fistWeapon);
var gauntlets = items[(int)FullEquipType.Hands].Where(g => dict.ContainsKey((uint)g.Item2)).ToDictionary(g => (uint)g.Item2, g => g);
gauntlets.TrimExcess();
foreach (var type in Enum.GetValues<FullEquipType>().Where(v => !FullEquipTypeExtensions.OffhandTypes.Contains(v))) foreach (var type in Enum.GetValues<FullEquipType>().Where(v => !FullEquipTypeExtensions.OffhandTypes.Contains(v)))
{ {
var list = items[(int)type]; var list = items[(int)type];
foreach (var item in list) foreach (var item in list)
dict.TryAdd((uint) item.Item2, item); dict.TryAdd((uint)item.Item2, item);
} }
dict.TrimExcess(); dict.TrimExcess();
return dict; return new Tuple<IReadOnlyDictionary<uint, (string, ulong, ushort, ushort, ushort, byte, byte)>,
IReadOnlyDictionary<uint, (string, ulong, ushort, ushort, ushort, byte, byte)>>(dict, gauntlets);
} }
private static IReadOnlyDictionary<uint, PseudoEquipItem> CreateOffItems(IReadOnlyList<IReadOnlyList<PseudoEquipItem>> items) private static IReadOnlyDictionary<uint, PseudoEquipItem> CreateOffItems(IReadOnlyList<IReadOnlyList<PseudoEquipItem>> items)
@ -68,7 +90,7 @@ public sealed class ItemData : DataSharer, IReadOnlyDictionary<FullEquipType, IR
{ {
var list = items[(int)type]; var list = items[(int)type];
foreach (var item in list) foreach (var item in list)
dict.TryAdd((uint) item.Item2, item); dict.TryAdd((uint)item.Item2, item);
} }
dict.TrimExcess(); dict.TrimExcess();
@ -76,11 +98,11 @@ public sealed class ItemData : DataSharer, IReadOnlyDictionary<FullEquipType, IR
} }
public ItemData(DalamudPluginInterface pluginInterface, DataManager dataManager, ClientLanguage language) public ItemData(DalamudPluginInterface pluginInterface, DataManager dataManager, ClientLanguage language)
: base(pluginInterface, language, 2) : base(pluginInterface, language, 4)
{ {
_byType = TryCatchData("ItemList", () => CreateItems(dataManager, language)); _byType = TryCatchData("ItemList", () => CreateItems(dataManager, language));
_mainItems = TryCatchData("ItemDictMain", () => CreateMainItems(_byType)); (_mainItems, _gauntlets) = TryCatchData("ItemDictMain", () => CreateMainItems(_byType));
_offItems = TryCatchData("ItemDictOff", () => CreateOffItems(_byType)); _offItems = TryCatchData("ItemDictOff", () => CreateOffItems(_byType));
} }
protected override void DisposeInternal() protected override void DisposeInternal()
@ -120,31 +142,16 @@ public sealed class ItemData : DataSharer, IReadOnlyDictionary<FullEquipType, IR
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) public IEnumerable<(uint, EquipItem)> AllItems(bool main)
=> (main ? _mainItems : _offItems).Select(i => (i.Key, (EquipItem)i.Value)); => (main ? _mainItems : _offItems).Select(i => (i.Key, (EquipItem)i.Value));
public int TotalItemCount(bool main) public int TotalItemCount(bool main)
=> main ? _mainItems.Count : _offItems.Count; => main ? _mainItems.Count : _offItems.Count;
public bool TryGetValue(uint key, bool main, out EquipItem value) public bool TryGetValue(uint key, EquipSlot slot, out EquipItem value)
{ {
var dict = main ? _mainItems : _offItems; var dict = slot is EquipSlot.OffHand ? _offItems : _mainItems;
if (dict.TryGetValue(key, out var v)) if (slot is EquipSlot.Hands && _gauntlets.TryGetValue(key, out var v) || dict.TryGetValue(key, out v))
{ {
value = v; value = v;
return true; return true;

View file

@ -20,7 +20,7 @@ namespace Penumbra.GameData.Data;
internal sealed class ObjectIdentification : DataSharer, IObjectIdentifier internal sealed class ObjectIdentification : DataSharer, IObjectIdentifier
{ {
public const int IdentificationVersion = 2; public const int IdentificationVersion = 3;
public IGamePathParser GamePathParser { get; } = new GamePathParser(); public IGamePathParser GamePathParser { get; } = new GamePathParser();
public readonly IReadOnlyList<IReadOnlyList<uint>> BnpcNames; public readonly IReadOnlyList<IReadOnlyList<uint>> BnpcNames;
@ -32,12 +32,12 @@ internal sealed class ObjectIdentification : DataSharer, IObjectIdentifier
private readonly WeaponIdentificationList _weapons; private readonly WeaponIdentificationList _weapons;
private readonly ModelIdentificationList _modelIdentifierToModelChara; private readonly ModelIdentificationList _modelIdentifierToModelChara;
public ObjectIdentification(DalamudPluginInterface pluginInterface, DataManager dataManager, ClientLanguage language) public ObjectIdentification(DalamudPluginInterface pluginInterface, DataManager dataManager, ItemData itemData, ClientLanguage language)
: base(pluginInterface, language, IdentificationVersion) : base(pluginInterface, language, IdentificationVersion)
{ {
_actorData = new ActorManager.ActorManagerData(pluginInterface, dataManager, language); _actorData = new ActorManager.ActorManagerData(pluginInterface, dataManager, language);
_equipment = new EquipmentIdentificationList(pluginInterface, language, dataManager); _equipment = new EquipmentIdentificationList(pluginInterface, language, itemData);
_weapons = new WeaponIdentificationList(pluginInterface, language, dataManager); _weapons = new WeaponIdentificationList(pluginInterface, language, itemData);
Actions = TryCatchData("Actions", () => CreateActionList(dataManager)); Actions = TryCatchData("Actions", () => CreateActionList(dataManager));
_modelIdentifierToModelChara = new ModelIdentificationList(pluginInterface, language, dataManager); _modelIdentifierToModelChara = new ModelIdentificationList(pluginInterface, language, dataManager);

View file

@ -1,9 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Dalamud; using Dalamud;
using Dalamud.Data;
using Dalamud.Plugin; using Dalamud.Plugin;
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, ulong, ushort, ushort, ushort, byte, byte>; using PseudoEquipItem = System.ValueTuple<string, ulong, ushort, ushort, ushort, byte, byte>;
@ -13,10 +11,10 @@ namespace Penumbra.GameData.Data;
internal sealed class WeaponIdentificationList : KeyList<PseudoEquipItem> 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 = 2;
public WeaponIdentificationList(DalamudPluginInterface pi, ClientLanguage language, DataManager gameData) public WeaponIdentificationList(DalamudPluginInterface pi, ClientLanguage language, ItemData data)
: base(pi, Tag, language, Version, CreateWeaponList(gameData, language)) : base(pi, Tag, language, Version, CreateWeaponList(data))
{ } { }
public IEnumerable<EquipItem> Between(SetId modelId) public IEnumerable<EquipItem> Between(SetId modelId)
@ -52,17 +50,8 @@ internal sealed class WeaponIdentificationList : KeyList<PseudoEquipItem>
protected override int ValueKeySelector(PseudoEquipItem data) protected override int ValueKeySelector(PseudoEquipItem data)
=> (int)data.Item2; => (int)data.Item2;
private static IEnumerable<PseudoEquipItem> CreateWeaponList(DataManager gameData, ClientLanguage language) private static IEnumerable<PseudoEquipItem> CreateWeaponList(ItemData data)
=> gameData.GetExcelSheet<Item>(language)!.SelectMany(ToEquipItems); => data.Where(kvp => !kvp.Key.IsEquipment() && !kvp.Key.IsAccessory())
.SelectMany(kvp => kvp.Value)
private static IEnumerable<PseudoEquipItem> ToEquipItems(Item item) .Select(i => (PseudoEquipItem)i);
{
if ((EquipSlot)item.EquipSlotCategory.Row is not (EquipSlot.MainHand or EquipSlot.OffHand or EquipSlot.BothHand))
yield break;
if (item.ModelMain != 0)
yield return (PseudoEquipItem)EquipItem.FromMainhand(item);
if (item.ModelSub != 0)
yield return (PseudoEquipItem)EquipItem.FromOffhand(item);
}
} }

View file

@ -15,14 +15,14 @@ public static class GameData
/// <summary> /// <summary>
/// Obtain an object identifier that can link a game path to game objects that use it, using your client language. /// Obtain an object identifier that can link a game path to game objects that use it, using your client language.
/// </summary> /// </summary>
public static IObjectIdentifier GetIdentifier(DalamudPluginInterface pluginInterface, DataManager dataManager) public static IObjectIdentifier GetIdentifier(DalamudPluginInterface pluginInterface, DataManager dataManager, ItemData itemData)
=> new ObjectIdentification(pluginInterface, dataManager, dataManager.Language); => new ObjectIdentification(pluginInterface, dataManager, itemData, dataManager.Language);
/// <summary> /// <summary>
/// Obtain an object identifier that can link a game path to game objects that use it using the given language. /// Obtain an object identifier that can link a game path to game objects that use it using the given language.
/// </summary> /// </summary>
public static IObjectIdentifier GetIdentifier(DalamudPluginInterface pluginInterface, DataManager dataManager, ClientLanguage language) public static IObjectIdentifier GetIdentifier(DalamudPluginInterface pluginInterface, DataManager dataManager, ItemData itemData, ClientLanguage language)
=> new ObjectIdentification(pluginInterface, dataManager, language); => new ObjectIdentification(pluginInterface, dataManager, itemData, language);
/// <summary> /// <summary>
/// Obtain a parser for game paths. /// Obtain a parser for game paths.