diff --git a/OtterGui b/OtterGui index 49f5aaa7..3a9cafae 160000 --- a/OtterGui +++ b/OtterGui @@ -1 +1 @@ -Subproject commit 49f5aaa7733fc74d77435e9b84ce347eb06f61be +Subproject commit 3a9cafaeb21e156d1bb96e94125205fcdb331189 diff --git a/Penumbra.GameData/Actors/ActorManager.Identifiers.cs b/Penumbra.GameData/Actors/ActorManager.Identifiers.cs index b8c9640b..4caba6e5 100644 --- a/Penumbra.GameData/Actors/ActorManager.Identifiers.cs +++ b/Penumbra.GameData/Actors/ActorManager.Identifiers.cs @@ -194,6 +194,16 @@ public partial class ActorManager public unsafe ActorIdentifier FromObject(GameObject? actor) => FromObject((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)(actor?.Address ?? IntPtr.Zero)); + public ActorIdentifier CreateIndividual(IdentifierType type, ByteString name, ushort homeWorld, ObjectKind kind, uint dataId) + => type switch + { + IdentifierType.Player => CreatePlayer(name, homeWorld), + IdentifierType.Owned => CreateOwned(name, homeWorld, kind, dataId), + IdentifierType.Special => CreateSpecial((SpecialActor)homeWorld), + IdentifierType.Npc => CreateNpc(kind, dataId, homeWorld), + _ => ActorIdentifier.Invalid, + }; + public ActorIdentifier CreatePlayer(ByteString name, ushort homeWorld) { if (!VerifyWorld(homeWorld) || !VerifyPlayerName(name)) diff --git a/Penumbra.GameData/ObjectIdentification.cs b/Penumbra.GameData/ObjectIdentification.cs index 6d1e8595..d958f62c 100644 --- a/Penumbra.GameData/ObjectIdentification.cs +++ b/Penumbra.GameData/ObjectIdentification.cs @@ -7,6 +7,7 @@ using Penumbra.GameData.Structs; using System.Collections.Generic; using System.ComponentModel; using System.Linq; +using Dalamud.Game.ClientState.Objects.Enums; using Dalamud.Logging; using Dalamud.Plugin; using Dalamud.Utility; @@ -66,10 +67,11 @@ internal class ObjectIdentification : IObjectIdentifier private readonly DalamudPluginInterface _pluginInterface; private readonly ClientLanguage _language; - private readonly IReadOnlyList<(ulong Key, IReadOnlyList Values)> _weapons; - private readonly IReadOnlyList<(ulong Key, IReadOnlyList Values)> _equipment; - private readonly IReadOnlyDictionary> _actions; - private bool _disposed = false; + private readonly IReadOnlyList<(ulong Key, IReadOnlyList Values)> _weapons; + private readonly IReadOnlyList<(ulong Key, IReadOnlyList Values)> _equipment; + private readonly IReadOnlyList<(ulong Key, IReadOnlyList<(ObjectKind Kind, uint Id)>)> _models; + private readonly IReadOnlyDictionary> _actions; + private bool _disposed = false; public ObjectIdentification(DalamudPluginInterface pluginInterface, DataManager dataManager, ClientLanguage language) { @@ -80,6 +82,7 @@ internal class ObjectIdentification : IObjectIdentifier _weapons = TryCatchData("Weapons", CreateWeaponList); _equipment = TryCatchData("Equipment", CreateEquipmentList); _actions = TryCatchData("Actions", CreateActionList); + _models = TryCatchData("Models", CreateModelList); } public void Dispose() @@ -91,6 +94,7 @@ internal class ObjectIdentification : IObjectIdentifier _pluginInterface.RelinquishData(GetVersionedTag("Weapons")); _pluginInterface.RelinquishData(GetVersionedTag("Equipment")); _pluginInterface.RelinquishData(GetVersionedTag("Actions")); + _pluginInterface.RelinquishData(GetVersionedTag("Models")); _disposed = true; } @@ -221,6 +225,31 @@ internal class ObjectIdentification : IObjectIdentifier return storage.ToDictionary(kvp => kvp.Key, kvp => (IReadOnlyList)kvp.Value.ToArray()); } + private static ulong ModelValue(ModelChara row) + => row.Type | ((ulong) row.Model << 8) | ((ulong) row.Base << 24) | ((ulong) row.Variant << 32); + + private static IEnumerable<(ulong, ObjectKind, uint)> BattleNpcToName(ulong model, uint bNpc) + => Enumerable.Repeat((model, ObjectKind.BattleNpc, bNpc), 1); + + private IReadOnlyList<(ulong Key, IReadOnlyList<(ObjectKind Kind, uint Id)>)> CreateModelList() + { + var sheetBNpc = _dataManager.GetExcelSheet(_language)!; + var sheetENpc = _dataManager.GetExcelSheet(_language)!; + var sheetCompanion = _dataManager.GetExcelSheet(_language)!; + var sheetMount = _dataManager.GetExcelSheet(_language)!; + var sheetModel = _dataManager.GetExcelSheet(_language)!; + + var modelCharaToModel = sheetModel.ToDictionary(m => m.RowId, ModelValue); + + return sheetENpc.Select(e => (modelCharaToModel[e.ModelChara.Row], ObjectKind.EventNpc, e.RowId)) + .Concat(sheetCompanion.Select(c => (modelCharaToModel[c.Model.Row], ObjectKind.Companion, c.RowId))) + .Concat(sheetMount.Select(c => (modelCharaToModel[c.ModelChara.Row], ObjectKind.MountType, c.RowId))) + .Concat(sheetBNpc.SelectMany(c => BattleNpcToName(modelCharaToModel[c.ModelChara.Row], c.RowId))) + .GroupBy(t => t.Item1) + .Select(g => (g.Key, (IReadOnlyList<(ObjectKind, uint)>)g.Select(p => (p.Item2, p.Item3)).ToArray())) + .ToArray(); + } + private class Comparer : IComparer<(ulong, IReadOnlyList)> { public int Compare((ulong, IReadOnlyList) x, (ulong, IReadOnlyList) y) diff --git a/Penumbra/Collections/CollectionManager.Active.cs b/Penumbra/Collections/CollectionManager.Active.cs index 1e211076..624be9cc 100644 --- a/Penumbra/Collections/CollectionManager.Active.cs +++ b/Penumbra/Collections/CollectionManager.Active.cs @@ -8,9 +8,34 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; +using Dalamud.Game.ClientState.Objects.Enums; +using Penumbra.GameData.Actors; namespace Penumbra.Collections; +public class IndividualCollections +{ + private readonly ActorManager _manager; + public readonly List< (string DisplayName, ModCollection Collection, IReadOnlyList< ActorIdentifier > Identifiers) > Assignments; + public readonly Dictionary< ActorIdentifier, ModCollection > Individuals; + + public IndividualCollections( ActorManager manager ) + { + _manager = manager; + } + + public bool CanAdd( IdentifierType type, string name, ushort homeWorld, ObjectKind kind, uint dataId ) + { + _manager. + } + + public bool CanAdd( IdentifierType type, string name, ushort homeWorld, ObjectKind kind, IReadOnlyList< uint > dataIds ) + { + + } + +} + public partial class ModCollection { public sealed partial class Manager