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 )