Merge branch 'dev'

# Conflicts:
#	Penumbra/UI/AdvancedWindow/ModEditWindow.cs
This commit is contained in:
Ottermandias 2023-12-29 18:14:38 +01:00
commit b5c69b2946
85 changed files with 901 additions and 887 deletions

View file

@ -22,10 +22,10 @@ public class CollectionCache : IDisposable
private readonly CollectionCacheManager _manager;
private readonly ModCollection _collection;
public readonly CollectionModData ModData = new();
public readonly SortedList<string, (SingleArray<IMod>, object?)> _changedItems = new();
private readonly SortedList<string, (SingleArray<IMod>, object?)> _changedItems = [];
public readonly ConcurrentDictionary<Utf8GamePath, ModPath> ResolvedFiles = new();
public readonly MetaCache Meta;
public readonly Dictionary<IMod, SingleArray<ModConflicts>> _conflicts = new();
public readonly Dictionary<IMod, SingleArray<ModConflicts>> ConflictDict = [];
public int Calculating = -1;
@ -33,10 +33,10 @@ public class CollectionCache : IDisposable
=> _collection.AnonymizedName;
public IEnumerable<SingleArray<ModConflicts>> AllConflicts
=> _conflicts.Values;
=> ConflictDict.Values;
public SingleArray<ModConflicts> Conflicts(IMod mod)
=> _conflicts.TryGetValue(mod, out var c) ? c : new SingleArray<ModConflicts>();
=> ConflictDict.TryGetValue(mod, out SingleArray<ModConflicts> c) ? c : new SingleArray<ModConflicts>();
private int _changedItemsSaveCounter = -1;
@ -195,7 +195,7 @@ public class CollectionCache : IDisposable
$"Invalid mod state, removing {mod.Name} and associated manipulation {manipulation} returned current mod {mp.Name}.");
}
_conflicts.Remove(mod);
ConflictDict.Remove(mod);
foreach (var conflict in conflicts)
{
if (conflict.HasPriority)
@ -206,9 +206,9 @@ public class CollectionCache : IDisposable
{
var newConflicts = Conflicts(conflict.Mod2).Remove(c => c.Mod2 == mod);
if (newConflicts.Count > 0)
_conflicts[conflict.Mod2] = newConflicts;
ConflictDict[conflict.Mod2] = newConflicts;
else
_conflicts.Remove(conflict.Mod2);
ConflictDict.Remove(conflict.Mod2);
}
}
@ -336,9 +336,9 @@ public class CollectionCache : IDisposable
return false;
});
if (changedConflicts.Count == 0)
_conflicts.Remove(mod);
ConflictDict.Remove(mod);
else
_conflicts[mod] = changedConflicts;
ConflictDict[mod] = changedConflicts;
}
// Add a new conflict between the added mod and the existing mod.
@ -373,9 +373,9 @@ public class CollectionCache : IDisposable
{
// Add the same conflict list to both conflict directions.
var conflictList = new List<object> { data };
_conflicts[addedMod] = addedConflicts.Append(new ModConflicts(existingMod, conflictList, existingPriority < addedPriority,
ConflictDict[addedMod] = addedConflicts.Append(new ModConflicts(existingMod, conflictList, existingPriority < addedPriority,
existingPriority != addedPriority));
_conflicts[existingMod] = existingConflicts.Append(new ModConflicts(addedMod, conflictList,
ConflictDict[existingMod] = existingConflicts.Append(new ModConflicts(addedMod, conflictList,
existingPriority >= addedPriority,
existingPriority != addedPriority));
}
@ -426,7 +426,7 @@ public class CollectionCache : IDisposable
_changedItems.Clear();
// Skip IMCs because they would result in far too many false-positive items,
// since they are per set instead of per item-slot/item/variant.
var identifier = _manager.MetaFileManager.Identifier.AwaitedService;
var identifier = _manager.MetaFileManager.Identifier;
var items = new SortedList<string, object?>(512);
void AddItems(IMod mod)

View file

@ -159,7 +159,7 @@ public class CollectionCacheManager : IDisposable
null);
cache.ResolvedFiles.Clear();
cache.Meta.Reset();
cache._conflicts.Clear();
cache.ConflictDict.Clear();
// Add all forced redirects.
foreach (var tempMod in _tempMods.ModsForAllCollections
@ -372,7 +372,7 @@ public class CollectionCacheManager : IDisposable
{
collection._cache!.ResolvedFiles.Clear();
collection._cache!.Meta.Reset();
collection._cache!._conflicts.Clear();
collection._cache!.ConflictDict.Clear();
}
}

View file

@ -55,7 +55,7 @@ public readonly struct EqdpCache : IDisposable
foreach (var file in _eqdpFiles.OfType<ExpandedEqdpFile>())
{
var relevant = CharacterUtility.RelevantIndices[file.Index.Value];
file.Reset(_eqdpManipulations.Where(m => m.FileIndex() == relevant).Select(m => (SetId)m.SetId));
file.Reset(_eqdpManipulations.Where(m => m.FileIndex() == relevant).Select(m => (PrimaryId)m.SetId));
}
_eqdpManipulations.Clear();

View file

@ -74,12 +74,12 @@ public struct EstCache : IDisposable
};
}
internal ushort GetEstEntry(MetaFileManager manager, EstManipulation.EstType type, GenderRace genderRace, SetId setId)
internal ushort GetEstEntry(MetaFileManager manager, EstManipulation.EstType type, GenderRace genderRace, PrimaryId primaryId)
{
var file = GetEstFile(type);
return file != null
? file[genderRace, setId.Id]
: EstFile.GetDefault(manager, type, genderRace, setId);
? file[genderRace, primaryId.Id]
: EstFile.GetDefault(manager, type, genderRace, primaryId);
}
public void Reset()

View file

@ -187,17 +187,17 @@ public class MetaCache : IDisposable, IEnumerable<KeyValuePair<MetaManipulation,
public bool GetImcFile(Utf8GamePath path, [NotNullWhen(true)] out Meta.Files.ImcFile? file)
=> _imcCache.GetImcFile(path, out file);
internal EqdpEntry GetEqdpEntry(GenderRace race, bool accessory, SetId setId)
internal EqdpEntry GetEqdpEntry(GenderRace race, bool accessory, PrimaryId primaryId)
{
var eqdpFile = _eqdpCache.EqdpFile(race, accessory);
if (eqdpFile != null)
return setId.Id < eqdpFile.Count ? eqdpFile[setId] : default;
return primaryId.Id < eqdpFile.Count ? eqdpFile[primaryId] : default;
else
return Meta.Files.ExpandedEqdpFile.GetDefault(_manager, race, accessory, setId);
return Meta.Files.ExpandedEqdpFile.GetDefault(_manager, race, accessory, primaryId);
}
internal ushort GetEstEntry(EstManipulation.EstType type, GenderRace genderRace, SetId setId)
=> _estCache.GetEstEntry(_manager, type, genderRace, setId);
internal ushort GetEstEntry(EstManipulation.EstType type, GenderRace genderRace, PrimaryId primaryId)
=> _estCache.GetEstEntry(_manager, type, genderRace, primaryId);
/// <summary> Use this when CharacterUtility becomes ready. </summary>
private void ApplyStoredManipulations()

View file

@ -28,9 +28,9 @@ public class ActiveCollections : ISavable, IDisposable
private readonly CommunicatorService _communicator;
private readonly SaveService _saveService;
private readonly ActiveCollectionData _data;
private readonly ActorService _actors;
private readonly ActorManager _actors;
public ActiveCollections(Configuration config, CollectionStorage storage, ActorService actors, CommunicatorService communicator,
public ActiveCollections(Configuration config, CollectionStorage storage, ActorManager actors, CommunicatorService communicator,
SaveService saveService, ActiveCollectionData data)
{
_storage = storage;
@ -475,7 +475,7 @@ public class ActiveCollections : ISavable, IDisposable
{
case IdentifierType.Player when id.HomeWorld != ushort.MaxValue:
{
var global = ByType(CollectionType.Individual, _actors.AwaitedService.CreatePlayer(id.PlayerName, ushort.MaxValue));
var global = ByType(CollectionType.Individual, _actors.CreatePlayer(id.PlayerName, ushort.MaxValue));
return global?.Index == checkAssignment.Index
? "Assignment is redundant due to an identical Any-World assignment existing.\nYou can remove it."
: string.Empty;
@ -484,12 +484,12 @@ public class ActiveCollections : ISavable, IDisposable
if (id.HomeWorld != ushort.MaxValue)
{
var global = ByType(CollectionType.Individual,
_actors.AwaitedService.CreateOwned(id.PlayerName, ushort.MaxValue, id.Kind, id.DataId));
_actors.CreateOwned(id.PlayerName, ushort.MaxValue, id.Kind, id.DataId));
if (global?.Index == checkAssignment.Index)
return "Assignment is redundant due to an identical Any-World assignment existing.\nYou can remove it.";
}
var unowned = ByType(CollectionType.Individual, _actors.AwaitedService.CreateNpc(id.Kind, id.DataId));
var unowned = ByType(CollectionType.Individual, _actors.CreateNpc(id.Kind, id.DataId));
return unowned?.Index == checkAssignment.Index
? "Assignment is redundant due to an identical unowned NPC assignment existing.\nYou can remove it."
: string.Empty;

View file

@ -1,6 +1,7 @@
using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Game.ClientState.Objects.Types;
using Penumbra.GameData.Actors;
using Penumbra.GameData.Enums;
using Penumbra.String;
namespace Penumbra.Collections.Manager;
@ -36,7 +37,7 @@ public sealed partial class IndividualCollections : IReadOnlyList<(string Displa
return true;
if (identifier.Retainer is not ActorIdentifier.RetainerType.Mannequin && _config.UseOwnerNameForCharacterCollection)
return CheckWorlds(_actorService.AwaitedService.GetCurrentPlayer(), out collection);
return CheckWorlds(_actors.GetCurrentPlayer(), out collection);
break;
}
@ -46,7 +47,7 @@ public sealed partial class IndividualCollections : IReadOnlyList<(string Displa
return true;
// Handle generic NPC
var npcIdentifier = _actorService.AwaitedService.CreateIndividualUnchecked(IdentifierType.Npc, ByteString.Empty,
var npcIdentifier = _actors.CreateIndividualUnchecked(IdentifierType.Npc, ByteString.Empty,
ushort.MaxValue,
identifier.Kind, identifier.DataId);
if (npcIdentifier.IsValid && _individuals.TryGetValue(npcIdentifier, out collection))
@ -56,7 +57,7 @@ public sealed partial class IndividualCollections : IReadOnlyList<(string Displa
if (!_config.UseOwnerNameForCharacterCollection)
return false;
identifier = _actorService.AwaitedService.CreateIndividualUnchecked(IdentifierType.Player, identifier.PlayerName,
identifier = _actors.CreateIndividualUnchecked(IdentifierType.Player, identifier.PlayerName,
identifier.HomeWorld.Id,
ObjectKind.None, uint.MaxValue);
return CheckWorlds(identifier, out collection);
@ -89,37 +90,37 @@ public sealed partial class IndividualCollections : IReadOnlyList<(string Displa
if (identifier.Type != IdentifierType.Special)
return (identifier, SpecialResult.Invalid);
if (_actorService.AwaitedService.ResolvePartyBannerPlayer(identifier.Special, out var id))
if (_actors.ResolvePartyBannerPlayer(identifier.Special, out var id))
return _config.UseCharacterCollectionsInCards ? (id, SpecialResult.PartyBanner) : (identifier, SpecialResult.Invalid);
if (_actorService.AwaitedService.ResolvePvPBannerPlayer(identifier.Special, out id))
if (_actors.ResolvePvPBannerPlayer(identifier.Special, out id))
return _config.UseCharacterCollectionsInCards ? (id, SpecialResult.PvPBanner) : (identifier, SpecialResult.Invalid);
if (_actorService.AwaitedService.ResolveMahjongPlayer(identifier.Special, out id))
if (_actors.ResolveMahjongPlayer(identifier.Special, out id))
return _config.UseCharacterCollectionsInCards ? (id, SpecialResult.Mahjong) : (identifier, SpecialResult.Invalid);
switch (identifier.Special)
{
case ScreenActor.CharacterScreen when _config.UseCharacterCollectionInMainWindow:
return (_actorService.AwaitedService.GetCurrentPlayer(), SpecialResult.CharacterScreen);
return (_actors.GetCurrentPlayer(), SpecialResult.CharacterScreen);
case ScreenActor.FittingRoom when _config.UseCharacterCollectionInTryOn:
return (_actorService.AwaitedService.GetCurrentPlayer(), SpecialResult.FittingRoom);
return (_actors.GetCurrentPlayer(), SpecialResult.FittingRoom);
case ScreenActor.DyePreview when _config.UseCharacterCollectionInTryOn:
return (_actorService.AwaitedService.GetCurrentPlayer(), SpecialResult.DyePreview);
return (_actors.GetCurrentPlayer(), SpecialResult.DyePreview);
case ScreenActor.Portrait when _config.UseCharacterCollectionsInCards:
return (_actorService.AwaitedService.GetCurrentPlayer(), SpecialResult.Portrait);
return (_actors.GetCurrentPlayer(), SpecialResult.Portrait);
case ScreenActor.ExamineScreen:
{
identifier = _actorService.AwaitedService.GetInspectPlayer();
identifier = _actors.GetInspectPlayer();
if (identifier.IsValid)
return (_config.UseCharacterCollectionInInspect ? identifier : ActorIdentifier.Invalid, SpecialResult.Inspect);
identifier = _actorService.AwaitedService.GetCardPlayer();
identifier = _actors.GetCardPlayer();
if (identifier.IsValid)
return (_config.UseCharacterCollectionInInspect ? identifier : ActorIdentifier.Invalid, SpecialResult.Card);
return _config.UseCharacterCollectionInTryOn
? (_actorService.AwaitedService.GetGlamourPlayer(), SpecialResult.Glamour)
? (_actors.GetGlamourPlayer(), SpecialResult.Glamour)
: (identifier, SpecialResult.Invalid);
}
default: return (identifier, SpecialResult.Invalid);
@ -127,10 +128,10 @@ public sealed partial class IndividualCollections : IReadOnlyList<(string Displa
}
public bool TryGetCollection(GameObject? gameObject, out ModCollection? collection)
=> TryGetCollection(_actorService.AwaitedService.FromObject(gameObject, true, false, false), out collection);
=> TryGetCollection(_actors.FromObject(gameObject, true, false, false), out collection);
public unsafe bool TryGetCollection(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* gameObject, out ModCollection? collection)
=> TryGetCollection(_actorService.AwaitedService.FromObject(gameObject, out _, true, false, false), out collection);
=> TryGetCollection(_actors.FromObject(gameObject, out _, true, false, false), out collection);
private bool CheckWorlds(ActorIdentifier identifier, out ModCollection? collection)
{
@ -143,7 +144,7 @@ public sealed partial class IndividualCollections : IReadOnlyList<(string Displa
if (_individuals.TryGetValue(identifier, out collection))
return true;
identifier = _actorService.AwaitedService.CreateIndividualUnchecked(identifier.Type, identifier.PlayerName, ushort.MaxValue,
identifier = _actors.CreateIndividualUnchecked(identifier.Type, identifier.PlayerName, ushort.MaxValue,
identifier.Kind,
identifier.DataId);
if (identifier.IsValid && _individuals.TryGetValue(identifier, out collection))

View file

@ -3,6 +3,8 @@ using Dalamud.Interface.Internal.Notifications;
using Newtonsoft.Json.Linq;
using OtterGui.Classes;
using Penumbra.GameData.Actors;
using Penumbra.GameData.DataContainers.Bases;
using Penumbra.GameData.Structs;
using Penumbra.Services;
using Penumbra.String;
@ -26,23 +28,20 @@ public partial class IndividualCollections
public bool ReadJObject(SaveService saver, ActiveCollections parent, JArray? obj, CollectionStorage storage)
{
if (_actorService.Valid)
if (_actors.Awaiter.IsCompletedSuccessfully)
{
var ret = ReadJObjectInternal(obj, storage);
return ret;
}
void Func()
Penumbra.Log.Debug("[Collections] Delayed reading individual assignments until actor service is ready...");
_actors.Awaiter.ContinueWith(_ =>
{
if (ReadJObjectInternal(obj, storage))
saver.ImmediateSave(parent);
IsLoaded = true;
Loaded.Invoke();
_actorService.FinishedCreation -= Func;
}
Penumbra.Log.Debug("[Collections] Delayed reading individual assignments until actor service is ready...");
_actorService.FinishedCreation += Func;
});
return false;
}
@ -60,7 +59,7 @@ public partial class IndividualCollections
{
try
{
var identifier = _actorService.AwaitedService.FromJson(data as JObject);
var identifier = _actors.FromJson(data as JObject);
var group = GetGroup(identifier);
if (group.Length == 0 || group.Any(i => !i.IsValid))
{
@ -101,10 +100,10 @@ public partial class IndividualCollections
internal void Migrate0To1(Dictionary<string, ModCollection> old)
{
static bool FindDataId(string name, IReadOnlyDictionary<uint, string> data, out uint dataId)
static bool FindDataId(string name, NameDictionary data, out NpcId dataId)
{
var kvp = data.FirstOrDefault(kvp => kvp.Value.Equals(name, StringComparison.OrdinalIgnoreCase),
new KeyValuePair<uint, string>(uint.MaxValue, string.Empty));
new KeyValuePair<NpcId, string>(uint.MaxValue, string.Empty));
dataId = kvp.Key;
return kvp.Value.Length > 0;
}
@ -114,22 +113,22 @@ public partial class IndividualCollections
var kind = ObjectKind.None;
var lowerName = name.ToLowerInvariant();
// Prefer matching NPC names, fewer false positives than preferring players.
if (FindDataId(lowerName, _actorService.AwaitedService.Data.Companions, out var dataId))
if (FindDataId(lowerName, _actors.Data.Companions, out var dataId))
kind = ObjectKind.Companion;
else if (FindDataId(lowerName, _actorService.AwaitedService.Data.Mounts, out dataId))
else if (FindDataId(lowerName, _actors.Data.Mounts, out dataId))
kind = ObjectKind.MountType;
else if (FindDataId(lowerName, _actorService.AwaitedService.Data.BNpcs, out dataId))
else if (FindDataId(lowerName, _actors.Data.BNpcs, out dataId))
kind = ObjectKind.BattleNpc;
else if (FindDataId(lowerName, _actorService.AwaitedService.Data.ENpcs, out dataId))
else if (FindDataId(lowerName, _actors.Data.ENpcs, out dataId))
kind = ObjectKind.EventNpc;
var identifier = _actorService.AwaitedService.CreateNpc(kind, dataId);
var identifier = _actors.CreateNpc(kind, dataId);
if (identifier.IsValid)
{
// If the name corresponds to a valid npc, add it as a group. If this fails, notify users.
var group = GetGroup(identifier);
var ids = string.Join(", ", group.Select(i => i.DataId.ToString()));
if (Add($"{_actorService.AwaitedService.Data.ToName(kind, dataId)} ({kind.ToName()})", group, collection))
if (Add($"{_actors.Data.ToName(kind, dataId)} ({kind.ToName()})", group, collection))
Penumbra.Log.Information($"Migrated {name} ({kind.ToName()}) to NPC Identifiers [{ids}].");
else
Penumbra.Messager.NotificationMessage(
@ -137,15 +136,12 @@ public partial class IndividualCollections
NotificationType.Error);
}
// If it is not a valid NPC name, check if it can be a player name.
else if (ActorManager.VerifyPlayerName(name))
else if (ActorIdentifierFactory.VerifyPlayerName(name))
{
identifier = _actorService.AwaitedService.CreatePlayer(ByteString.FromStringUnsafe(name, false), ushort.MaxValue);
identifier = _actors.CreatePlayer(ByteString.FromStringUnsafe(name, false), ushort.MaxValue);
var shortName = string.Join(" ", name.Split().Select(n => $"{n[0]}."));
// Try to migrate the player name without logging full names.
if (Add($"{name} ({_actorService.AwaitedService.Data.ToWorldName(identifier.HomeWorld)})", new[]
{
identifier,
}, collection))
if (Add($"{name} ({_actors.Data.ToWorldName(identifier.HomeWorld)})", [identifier], collection))
Penumbra.Log.Information($"Migrated {shortName} ({collection.AnonymizedName}) to Player Identifier.");
else
Penumbra.Messager.NotificationMessage(

View file

@ -1,7 +1,9 @@
using Dalamud.Game.ClientState.Objects.Enums;
using OtterGui.Filesystem;
using Penumbra.GameData.Actors;
using Penumbra.Services;
using Penumbra.GameData.DataContainers.Bases;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
using Penumbra.String;
namespace Penumbra.Collections.Manager;
@ -11,9 +13,9 @@ public sealed partial class IndividualCollections
public record struct IndividualAssignment(string DisplayName, IReadOnlyList<ActorIdentifier> Identifiers, ModCollection Collection);
private readonly Configuration _config;
private readonly ActorService _actorService;
private readonly Dictionary<ActorIdentifier, ModCollection> _individuals = new();
private readonly List<IndividualAssignment> _assignments = new();
private readonly ActorManager _actors;
private readonly Dictionary<ActorIdentifier, ModCollection> _individuals = [];
private readonly List<IndividualAssignment> _assignments = [];
public event Action Loaded;
public bool IsLoaded { get; private set; }
@ -21,12 +23,12 @@ public sealed partial class IndividualCollections
public IReadOnlyList<IndividualAssignment> Assignments
=> _assignments;
public IndividualCollections(ActorService actorService, Configuration config, bool temporary)
public IndividualCollections(ActorManager actors, Configuration config, bool temporary)
{
_config = config;
_actorService = actorService;
IsLoaded = temporary;
Loaded += () => Penumbra.Log.Information($"{_assignments.Count} Individual Assignments loaded after delay.");
_config = config;
_actors = actors;
IsLoaded = temporary;
Loaded += () => Penumbra.Log.Information($"{_assignments.Count} Individual Assignments loaded after delay.");
}
public enum AddResult
@ -69,44 +71,34 @@ public sealed partial class IndividualCollections
return set ? AddResult.AlreadySet : AddResult.Valid;
}
public AddResult CanAdd(IdentifierType type, string name, ushort homeWorld, ObjectKind kind, IEnumerable<uint> dataIds,
public AddResult CanAdd(IdentifierType type, string name, WorldId homeWorld, ObjectKind kind, IEnumerable<NpcId> dataIds,
out ActorIdentifier[] identifiers)
{
identifiers = Array.Empty<ActorIdentifier>();
identifiers = [];
var manager = _actorService.AwaitedService;
switch (type)
{
case IdentifierType.Player:
if (!ByteString.FromString(name, out var playerName))
return AddResult.Invalid;
identifiers = new[]
{
manager.CreatePlayer(playerName, homeWorld),
};
identifiers = [_actors.CreatePlayer(playerName, homeWorld)];
break;
case IdentifierType.Retainer:
if (!ByteString.FromString(name, out var retainerName))
return AddResult.Invalid;
identifiers = new[]
{
manager.CreateRetainer(retainerName, ActorIdentifier.RetainerType.Both),
};
identifiers = [_actors.CreateRetainer(retainerName, ActorIdentifier.RetainerType.Both)];
break;
case IdentifierType.Owned:
if (!ByteString.FromString(name, out var ownerName))
return AddResult.Invalid;
identifiers = dataIds.Select(id => manager.CreateOwned(ownerName, homeWorld, kind, id)).ToArray();
identifiers = dataIds.Select(id => _actors.CreateOwned(ownerName, homeWorld, kind, id)).ToArray();
break;
case IdentifierType.Npc:
identifiers = dataIds
.Select(id => manager.CreateIndividual(IdentifierType.Npc, ByteString.Empty, ushort.MaxValue, kind, id)).ToArray();
break;
default:
identifiers = Array.Empty<ActorIdentifier>();
.Select(id => _actors.CreateIndividual(IdentifierType.Npc, ByteString.Empty, ushort.MaxValue, kind, id)).ToArray();
break;
}
@ -116,12 +108,22 @@ public sealed partial class IndividualCollections
public ActorIdentifier[] GetGroup(ActorIdentifier identifier)
{
if (!identifier.IsValid)
return Array.Empty<ActorIdentifier>();
return [];
return identifier.Type switch
{
IdentifierType.Player => [identifier.CreatePermanent()],
IdentifierType.Special => [identifier],
IdentifierType.Retainer => [identifier.CreatePermanent()],
IdentifierType.Owned => CreateNpcs(_actors, identifier.CreatePermanent()),
IdentifierType.Npc => CreateNpcs(_actors, identifier),
_ => [],
};
static ActorIdentifier[] CreateNpcs(ActorManager manager, ActorIdentifier identifier)
{
var name = manager.Data.ToName(identifier.Kind, identifier.DataId);
var table = identifier.Kind switch
NameDictionary table = identifier.Kind switch
{
ObjectKind.BattleNpc => manager.Data.BNpcs,
ObjectKind.EventNpc => manager.Data.ENpcs,
@ -134,25 +136,6 @@ public sealed partial class IndividualCollections
.Select(kvp => manager.CreateIndividualUnchecked(identifier.Type, identifier.PlayerName, identifier.HomeWorld.Id,
identifier.Kind, kvp.Key)).ToArray();
}
return identifier.Type switch
{
IdentifierType.Player => new[]
{
identifier.CreatePermanent(),
},
IdentifierType.Special => new[]
{
identifier,
},
IdentifierType.Retainer => new[]
{
identifier.CreatePermanent(),
},
IdentifierType.Owned => CreateNpcs(_actorService.AwaitedService, identifier.CreatePermanent()),
IdentifierType.Npc => CreateNpcs(_actorService.AwaitedService, identifier),
_ => Array.Empty<ActorIdentifier>(),
};
}
internal bool Add(ActorIdentifier[] identifiers, ModCollection collection)
@ -241,12 +224,12 @@ public sealed partial class IndividualCollections
{
return identifier.Type switch
{
IdentifierType.Player => $"{identifier.PlayerName} ({_actorService.AwaitedService.Data.ToWorldName(identifier.HomeWorld)})",
IdentifierType.Player => $"{identifier.PlayerName} ({_actors.Data.ToWorldName(identifier.HomeWorld)})",
IdentifierType.Retainer => $"{identifier.PlayerName} (Retainer)",
IdentifierType.Owned =>
$"{identifier.PlayerName} ({_actorService.AwaitedService.Data.ToWorldName(identifier.HomeWorld)})'s {_actorService.AwaitedService.Data.ToName(identifier.Kind, identifier.DataId)}",
$"{identifier.PlayerName} ({_actors.Data.ToWorldName(identifier.HomeWorld)})'s {_actors.Data.ToName(identifier.Kind, identifier.DataId)}",
IdentifierType.Npc =>
$"{_actorService.AwaitedService.Data.ToName(identifier.Kind, identifier.DataId)} ({identifier.Kind.ToName()})",
$"{_actors.Data.ToName(identifier.Kind, identifier.DataId)} ({identifier.Kind.ToName()})",
_ => string.Empty,
};
}

View file

@ -14,10 +14,10 @@ public class TempCollectionManager : IDisposable
private readonly CommunicatorService _communicator;
private readonly CollectionStorage _storage;
private readonly ActorService _actors;
private readonly ActorManager _actors;
private readonly Dictionary<string, ModCollection> _customCollections = new();
public TempCollectionManager(Configuration config, CommunicatorService communicator, ActorService actors, CollectionStorage storage)
public TempCollectionManager(Configuration config, CommunicatorService communicator, ActorManager actors, CollectionStorage storage)
{
_communicator = communicator;
_actors = actors;
@ -111,7 +111,7 @@ public class TempCollectionManager : IDisposable
if (!ByteString.FromString(characterName, out var byteString, false))
return false;
var identifier = _actors.AwaitedService.CreatePlayer(byteString, worldId);
var identifier = _actors.CreatePlayer(byteString, worldId);
if (!identifier.IsValid)
return false;
@ -123,7 +123,7 @@ public class TempCollectionManager : IDisposable
if (!ByteString.FromString(characterName, out var byteString, false))
return false;
var identifier = _actors.AwaitedService.CreatePlayer(byteString, worldId);
var identifier = _actors.CreatePlayer(byteString, worldId);
return Collections.TryGetValue(identifier, out var collection) && RemoveTemporaryCollection(collection.Name);
}
}