Fix owned NPCs not working with automation and some NPC customizations not working with automation.

This commit is contained in:
Ottermandias 2023-07-24 14:49:02 +02:00
parent 662ec617dc
commit 01431381c5
2 changed files with 58 additions and 26 deletions

View file

@ -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
/// <summary> Get world-specific first and all-world afterwards. </summary>
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;

View file

@ -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<ActorIdentifier, ActorData>
private readonly Dictionary<ActorIdentifier, ActorData> _identifiers = new(200);
private readonly Dictionary<ActorIdentifier, ActorData> _allWorldIdentifiers = new(200);
private readonly Dictionary<ActorIdentifier, ActorData> _nonOwnedIdentifiers = new(200);
public IReadOnlyDictionary<ActorIdentifier, ActorData> Identifiers
=> _identifiers;
@ -110,21 +112,35 @@ public class ObjectManager : IReadOnlyDictionary<ActorIdentifier, ActorData>
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<ActorIdentifier, ActorData>
public int Count
=> Identifiers.Count;
/// <summary> Also handles All Worlds players. </summary>
/// <summary> Also handles All Worlds players and non-owned NPCs. </summary>
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<ActorIdentifier, ActorData>
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];