diff --git a/Glamourer/Automation/AutoDesignApplier.cs b/Glamourer/Automation/AutoDesignApplier.cs
index 02e7887..68a55ce 100644
--- a/Glamourer/Automation/AutoDesignApplier.cs
+++ b/Glamourer/Automation/AutoDesignApplier.cs
@@ -85,7 +85,7 @@ public class AutoDesignApplier : IDisposable
_state.ReapplyState(actor);
}
}
- else if (_objects.TryGetValueAllWorld(id, out data))
+ else if (_objects.TryGetValueAllWorld(id, out data) || _objects.TryGetValueNonOwned(id, out data))
{
foreach (var actor in data.Objects)
{
@@ -210,7 +210,7 @@ public class AutoDesignApplier : IDisposable
continue;
var (equipFlags, customizeFlags, applyHat, applyVisor, applyWeapon, applyWet) = design.ApplyWhat();
- Reduce(state, data, applyHat, applyVisor, applyWeapon, applyWet, ref totalMetaFlags, respectManual, source);
+ Reduce(state, data, applyHat, applyVisor, applyWeapon, applyWet, ref totalMetaFlags, respectManual, source);
Reduce(state, data, customizeFlags, ref totalCustomizeFlags, respectManual, source);
Reduce(state, data, equipFlags, ref totalEquipFlags, respectManual, source);
}
@@ -219,17 +219,28 @@ public class AutoDesignApplier : IDisposable
/// Get world-specific first and all-world afterwards.
private bool GetPlayerSet(ActorIdentifier identifier, [NotNullWhen(true)] out AutoDesignSet? set)
{
- if (identifier.Type is not IdentifierType.Player)
- return _manager.EnabledSets.TryGetValue(identifier, out set);
+ switch (identifier.Type)
+ {
+ case IdentifierType.Player:
+ if (_manager.EnabledSets.TryGetValue(identifier, out set))
+ return true;
- if (_manager.EnabledSets.TryGetValue(identifier, out set))
- return true;
-
- identifier = _actors.AwaitedService.CreatePlayer(identifier.PlayerName, ushort.MaxValue);
- return _manager.EnabledSets.TryGetValue(identifier, out set);
+ identifier = _actors.AwaitedService.CreatePlayer(identifier.PlayerName, ushort.MaxValue);
+ return _manager.EnabledSets.TryGetValue(identifier, out set);
+ case IdentifierType.Retainer:
+ case IdentifierType.Special:
+ return _manager.EnabledSets.TryGetValue(identifier, out set);
+ case IdentifierType.Owned:
+ identifier = _actors.AwaitedService.CreateNpc(identifier.Kind, identifier.DataId);
+ return _manager.EnabledSets.TryGetValue(identifier, out set);
+ default:
+ set = null;
+ return false;
+ }
}
- private void Reduce(ActorState state, in DesignData design, EquipFlag equipFlags, ref EquipFlag totalEquipFlags, bool respectManual, StateChanged.Source source)
+ private void Reduce(ActorState state, in DesignData design, EquipFlag equipFlags, ref EquipFlag totalEquipFlags, bool respectManual,
+ StateChanged.Source source)
{
equipFlags &= ~totalEquipFlags;
if (equipFlags == 0)
@@ -347,9 +358,11 @@ public class AutoDesignApplier : IDisposable
continue;
var value = design.Customize[index];
- if (CustomizationService.IsCustomizationValid(set, face, index, value, out var data)
- && (data.HasValue && (!_config.UnlockedItemMode || _customizeUnlocks.IsUnlocked(data.Value, out _))))
+ if (CustomizationService.IsCustomizationValid(set, face, index, value, out var data))
{
+ if (data.HasValue && _config.UnlockedItemMode && !_customizeUnlocks.IsUnlocked(data.Value, out _))
+ continue;
+
if (!respectManual || state[index] is not StateChanged.Source.Manual)
_state.ChangeCustomize(state, index, value, source);
totalCustomizeFlags |= flag;
diff --git a/Glamourer/Interop/ObjectManager.cs b/Glamourer/Interop/ObjectManager.cs
index 328c4c6..3995076 100644
--- a/Glamourer/Interop/ObjectManager.cs
+++ b/Glamourer/Interop/ObjectManager.cs
@@ -7,6 +7,7 @@ using Dalamud.Game.ClientState.Objects;
using Glamourer.Interop.Structs;
using Glamourer.Services;
using Penumbra.GameData.Actors;
+using Penumbra.String;
namespace Glamourer.Interop;
@@ -34,6 +35,7 @@ public class ObjectManager : IReadOnlyDictionary
private readonly Dictionary _identifiers = new(200);
private readonly Dictionary _allWorldIdentifiers = new(200);
+ private readonly Dictionary _nonOwnedIdentifiers = new(200);
public IReadOnlyDictionary Identifiers
=> _identifiers;
@@ -110,21 +112,35 @@ public class ObjectManager : IReadOnlyDictionary
data.Objects.Add(character);
}
- if (identifier.Type is not (IdentifierType.Player or IdentifierType.Owned))
- return;
-
- var allWorld = _actors.AwaitedService.CreateIndividualUnchecked(identifier.Type, identifier.PlayerName, ushort.MaxValue,
- identifier.Kind,
- identifier.DataId);
-
- if (!_allWorldIdentifiers.TryGetValue(allWorld, out var allWorldData))
+ if (identifier.Type is IdentifierType.Player or IdentifierType.Owned)
{
- allWorldData = new ActorData(character, allWorld.ToString());
- _allWorldIdentifiers[allWorld] = allWorldData;
+ var allWorld = _actors.AwaitedService.CreateIndividualUnchecked(identifier.Type, identifier.PlayerName, ushort.MaxValue,
+ identifier.Kind,
+ identifier.DataId);
+
+ if (!_allWorldIdentifiers.TryGetValue(allWorld, out var allWorldData))
+ {
+ allWorldData = new ActorData(character, allWorld.ToString());
+ _allWorldIdentifiers[allWorld] = allWorldData;
+ }
+ else
+ {
+ allWorldData.Objects.Add(character);
+ }
}
- else
+
+ if (identifier.Type is IdentifierType.Owned)
{
- allWorldData.Objects.Add(character);
+ var nonOwned = _actors.AwaitedService.CreateNpc(identifier.Kind, identifier.DataId);
+ if (!_nonOwnedIdentifiers.TryGetValue(nonOwned, out var allWorldData))
+ {
+ allWorldData = new ActorData(character, nonOwned.ToString());
+ _allWorldIdentifiers[nonOwned] = allWorldData;
+ }
+ else
+ {
+ allWorldData.Objects.Add(character);
+ }
}
}
@@ -174,9 +190,9 @@ public class ObjectManager : IReadOnlyDictionary
public int Count
=> Identifiers.Count;
- /// Also handles All Worlds players.
+ /// Also handles All Worlds players and non-owned NPCs.
public bool ContainsKey(ActorIdentifier key)
- => Identifiers.ContainsKey(key) || _allWorldIdentifiers.ContainsKey(key);
+ => Identifiers.ContainsKey(key) || _allWorldIdentifiers.ContainsKey(key) || _nonOwnedIdentifiers.ContainsKey(key);
public bool TryGetValue(ActorIdentifier key, out ActorData value)
=> Identifiers.TryGetValue(key, out value);
@@ -184,6 +200,9 @@ public class ObjectManager : IReadOnlyDictionary
public bool TryGetValueAllWorld(ActorIdentifier key, out ActorData value)
=> _allWorldIdentifiers.TryGetValue(key, out value);
+ public bool TryGetValueNonOwned(ActorIdentifier key, out ActorData value)
+ => _nonOwnedIdentifiers.TryGetValue(key, out value);
+
public ActorData this[ActorIdentifier key]
=> Identifiers[key];