From 0b1a11132b3ea596d8535ca4a0998a122762d1af Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Wed, 9 Nov 2022 16:55:08 +0100 Subject: [PATCH] Update to current state of ActorIdentification, add start of collection management. --- Penumbra.GameData/Actors/ActorManager.Data.cs | 92 +++++++------------ .../Actors/ActorManager.Identifiers.cs | 3 - .../Collections/CollectionManager.Active.cs | 57 +++++++++++- 3 files changed, 85 insertions(+), 67 deletions(-) diff --git a/Penumbra.GameData/Actors/ActorManager.Data.cs b/Penumbra.GameData/Actors/ActorManager.Data.cs index 9cf233c4..c00e6dd2 100644 --- a/Penumbra.GameData/Actors/ActorManager.Data.cs +++ b/Penumbra.GameData/Actors/ActorManager.Data.cs @@ -6,14 +6,14 @@ using Dalamud; using Dalamud.Data; using Dalamud.Game.ClientState; using Dalamud.Game.ClientState.Objects; -using Dalamud.Logging; using Dalamud.Plugin; using Dalamud.Utility; using Lumina.Excel.GeneratedSheets; +using Penumbra.GameData.Data; namespace Penumbra.GameData.Actors; -public partial class ActorManager : IDisposable +public sealed partial class ActorManager : DataSharer { /// Worlds available for players. public IReadOnlyDictionary Worlds { get; } @@ -30,95 +30,67 @@ public partial class ActorManager : IDisposable /// Valid ENPC names in title case by ENPC id. public IReadOnlyDictionary ENpcs { get; } - public ActorManager(DalamudPluginInterface pluginInterface, ObjectTable objects, ClientState state, DataManager gameData, Func toParentIdx) + public ActorManager(DalamudPluginInterface pluginInterface, ObjectTable objects, ClientState state, DataManager gameData, + Func toParentIdx) : this(pluginInterface, objects, state, gameData, gameData.Language, toParentIdx) - {} + { } public ActorManager(DalamudPluginInterface pluginInterface, ObjectTable objects, ClientState state, DataManager gameData, ClientLanguage language, Func toParentIdx) + : base(pluginInterface, language, 1) { - _pluginInterface = pluginInterface; - _objects = objects; - _clientState = state; - _gameData = gameData; - _language = language; - _toParentIdx = toParentIdx; + _objects = objects; + _clientState = state; + _toParentIdx = toParentIdx; - Worlds = TryCatchData("Worlds", CreateWorldData); - Mounts = TryCatchData("Mounts", CreateMountData); - Companions = TryCatchData("Companions", CreateCompanionData); - BNpcs = TryCatchData("BNpcs", CreateBNpcData); - ENpcs = TryCatchData("ENpcs", CreateENpcData); + Worlds = TryCatchData("Worlds", () => CreateWorldData(gameData)); + Mounts = TryCatchData("Mounts", () => CreateMountData(gameData)); + Companions = TryCatchData("Companions", () => CreateCompanionData(gameData)); + BNpcs = TryCatchData("BNpcs", () => CreateBNpcData(gameData)); + ENpcs = TryCatchData("ENpcs", () => CreateENpcData(gameData)); ActorIdentifier.Manager = this; } - public void Dispose() + protected override void DisposeInternal() { - if (_disposed) - return; - - GC.SuppressFinalize(this); - _pluginInterface.RelinquishData(GetVersionedTag("Worlds")); - _pluginInterface.RelinquishData(GetVersionedTag("Mounts")); - _pluginInterface.RelinquishData(GetVersionedTag("Companions")); - _pluginInterface.RelinquishData(GetVersionedTag("BNpcs")); - _pluginInterface.RelinquishData(GetVersionedTag("ENpcs")); - _disposed = true; + DisposeTag("Worlds"); + DisposeTag("Mounts"); + DisposeTag("Companions"); + DisposeTag("BNpcs"); + DisposeTag("ENpcs"); } ~ActorManager() => Dispose(); - private const int Version = 1; - - private readonly DalamudPluginInterface _pluginInterface; - private readonly ObjectTable _objects; - private readonly ClientState _clientState; - private readonly DataManager _gameData; - private readonly ClientLanguage _language; - private bool _disposed; + private readonly ObjectTable _objects; + private readonly ClientState _clientState; private readonly Func _toParentIdx; - private IReadOnlyDictionary CreateWorldData() - => _gameData.GetExcelSheet(_language)! + private IReadOnlyDictionary CreateWorldData(DataManager gameData) + => gameData.GetExcelSheet(Language)! .Where(w => w.IsPublic && !w.Name.RawData.IsEmpty) .ToDictionary(w => (ushort)w.RowId, w => w.Name.ToString()); - private IReadOnlyDictionary CreateMountData() - => _gameData.GetExcelSheet(_language)! + private IReadOnlyDictionary CreateMountData(DataManager gameData) + => gameData.GetExcelSheet(Language)! .Where(m => m.Singular.RawData.Length > 0 && m.Order >= 0) .ToDictionary(m => m.RowId, m => CultureInfo.InvariantCulture.TextInfo.ToTitleCase(m.Singular.ToDalamudString().ToString())); - private IReadOnlyDictionary CreateCompanionData() - => _gameData.GetExcelSheet(_language)! + private IReadOnlyDictionary CreateCompanionData(DataManager gameData) + => gameData.GetExcelSheet(Language)! .Where(c => c.Singular.RawData.Length > 0 && c.Order < ushort.MaxValue) .ToDictionary(c => c.RowId, c => CultureInfo.InvariantCulture.TextInfo.ToTitleCase(c.Singular.ToDalamudString().ToString())); - private IReadOnlyDictionary CreateBNpcData() - => _gameData.GetExcelSheet(_language)! + private IReadOnlyDictionary CreateBNpcData(DataManager gameData) + => gameData.GetExcelSheet(Language)! .Where(n => n.Singular.RawData.Length > 0) .ToDictionary(n => n.RowId, n => CultureInfo.InvariantCulture.TextInfo.ToTitleCase(n.Singular.ToDalamudString().ToString())); - private IReadOnlyDictionary CreateENpcData() - => _gameData.GetExcelSheet(_language)! + private IReadOnlyDictionary CreateENpcData(DataManager gameData) + => gameData.GetExcelSheet(Language)! .Where(e => e.Singular.RawData.Length > 0) .ToDictionary(e => e.RowId, e => CultureInfo.InvariantCulture.TextInfo.ToTitleCase(e.Singular.ToDalamudString().ToString())); - - private string GetVersionedTag(string tag) - => $"Penumbra.Actors.{tag}.{_language}.V{Version}"; - - private T TryCatchData(string tag, Func func) where T : class - { - try - { - return _pluginInterface.GetOrCreateData(GetVersionedTag(tag), func); - } - catch (Exception ex) - { - PluginLog.Error($"Error creating shared actor data for {tag}:\n{ex}"); - return func(); - } - } } diff --git a/Penumbra.GameData/Actors/ActorManager.Identifiers.cs b/Penumbra.GameData/Actors/ActorManager.Identifiers.cs index c504470e..eb2a73b4 100644 --- a/Penumbra.GameData/Actors/ActorManager.Identifiers.cs +++ b/Penumbra.GameData/Actors/ActorManager.Identifiers.cs @@ -1,10 +1,7 @@ using System; using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Runtime.Serialization; using Dalamud.Game.ClientState.Objects.Enums; using Dalamud.Game.ClientState.Objects.Types; -using Lumina.Excel.GeneratedSheets; using Newtonsoft.Json.Linq; using Penumbra.String; diff --git a/Penumbra/Collections/CollectionManager.Active.cs b/Penumbra/Collections/CollectionManager.Active.cs index 0e6e1730..99ba3398 100644 --- a/Penumbra/Collections/CollectionManager.Active.cs +++ b/Penumbra/Collections/CollectionManager.Active.cs @@ -17,15 +17,64 @@ 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; + private readonly List< (string DisplayName, ModCollection Collection, IReadOnlyList< ActorIdentifier > Identifiers) > _assignments = new(); + private readonly Dictionary< ActorIdentifier, ModCollection > _individuals = new(); + + public IReadOnlyList< (string DisplayName, ModCollection Collection, IReadOnlyList< ActorIdentifier > Identifiers) > Assignments + => _assignments; + + public IReadOnlyDictionary< ActorIdentifier, ModCollection > Individuals + => _individuals; public IndividualCollections( ActorManager manager ) => _manager = manager; - public bool CanAdd( IdentifierType type, string name, ushort homeWorld, ObjectKind kind, uint dataId ) + public bool CanAdd( ActorIdentifier identifier ) + => identifier.IsValid && !Individuals.ContainsKey( identifier ); + + public bool CanAdd( IdentifierType type, string name, ushort homeWorld, ObjectKind kind, IEnumerable< uint > dataIds, out ActorIdentifier[] identifiers ) { - return false; + identifiers = Array.Empty< ActorIdentifier >(); + + switch( type ) + { + case IdentifierType.Player: + { + if( !ByteString.FromString( name, out var playerName ) ) + { + return false; + } + + var identifier = _manager.CreatePlayer( playerName, homeWorld ); + if( !CanAdd( identifier ) ) + { + return false; + } + + identifiers = new[] { identifier }; + return true; + } + //case IdentifierType.Owned: + //{ + // if( !ByteString.FromString( name, out var ownerName ) ) + // { + // return false; + // } + // + // identifiers = dataIds.Select( id => _manager.CreateOwned( ownerName, homeWorld, kind, id ) ).ToArray(); + // return + // identifier = _manager.CreateIndividual( type, byteName, homeWorld, kind, dataId ); + // return CanAdd( identifier ); + //} + //case IdentifierType.Npc: + //{ + // identifier = _manager.CreateIndividual( IdentifierType.Npc, ByteString.Empty, ushort.MaxValue, kind, dataId ); + // return CanAdd( identifier ); + //} + default: + identifiers = Array.Empty< ActorIdentifier >(); + return false; + } } public bool Add( string displayName, ActorIdentifier identifier, ModCollection collection )