From 58b867bd1e66190607a4837ac13268ad63b6455e Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Sun, 16 Jul 2023 02:45:47 +0200 Subject: [PATCH] Handle losing fixed design state better. --- Glamourer/Automation/AutoDesignApplier.cs | 92 +++++++++++++++------- Glamourer/Events/AutomationChanged.cs | 2 +- Glamourer/Interop/DatFileService.cs | 25 +----- Glamourer/Services/CustomizationService.cs | 2 +- Glamourer/State/ActorState.cs | 9 +++ 5 files changed, 78 insertions(+), 52 deletions(-) diff --git a/Glamourer/Automation/AutoDesignApplier.cs b/Glamourer/Automation/AutoDesignApplier.cs index b1f3c8b..5341551 100644 --- a/Glamourer/Automation/AutoDesignApplier.cs +++ b/Glamourer/Automation/AutoDesignApplier.cs @@ -11,6 +11,7 @@ using Glamourer.Structs; using Glamourer.Unlocks; using Penumbra.GameData.Actors; using Penumbra.GameData.Enums; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace Glamourer.Automation; @@ -53,46 +54,79 @@ public class AutoDesignApplier : IDisposable _jobs.JobChanged -= OnJobChange; } - private void OnAutomationChange(AutomationChanged.Type type, AutoDesignSet? set, object? _) + private void OnAutomationChange(AutomationChanged.Type type, AutoDesignSet? set, object? bonusData) { - if (!_config.EnableAutoDesigns || set is not { Enabled: true }) + if (!_config.EnableAutoDesigns || set == null) return; - switch (type) + void RemoveOld(ActorIdentifier[]? identifiers) { - case AutomationChanged.Type.ChangeIdentifier: - case AutomationChanged.Type.ToggleSet: - case AutomationChanged.Type.AddedDesign: - case AutomationChanged.Type.DeletedDesign: - case AutomationChanged.Type.MovedDesign: - case AutomationChanged.Type.ChangedDesign: - case AutomationChanged.Type.ChangedConditions: - _objects.Update(); - foreach (var id1 in set.Identifiers) + if (identifiers == null) + return; + + foreach (var id in identifiers) + { + if (_state.TryGetValue(id, out var state)) + state.RemoveFixedDesignSources(); + } + } + + void ApplyNew(AutoDesignSet? newSet) + { + if (newSet is not { Enabled: true }) + return; + + _objects.Update(); + foreach (var id in newSet.Identifiers) + { + if (_objects.TryGetValue(id, out var data)) { - if (_objects.TryGetValue(id1, out var data)) - { - if (_state.GetOrCreate(id1, data.Objects[0], out var state)) - { - Reduce(data.Objects[0], state, set, false); - foreach (var actor in data.Objects) - _state.ReapplyState(actor); - } - } - else if (_objects.TryGetValueAllWorld(id1, out data)) + if (_state.GetOrCreate(id, data.Objects[0], out var state)) { + Reduce(data.Objects[0], state, newSet, false); foreach (var actor in data.Objects) + _state.ReapplyState(actor); + } + } + else if (_objects.TryGetValueAllWorld(id, out data)) + { + foreach (var actor in data.Objects) + { + var specificId = actor.GetIdentifier(_actors.AwaitedService); + if (_state.GetOrCreate(specificId, actor, out var state)) { - var id = actor.GetIdentifier(_actors.AwaitedService); - if (_state.GetOrCreate(id, actor, out var state)) - { - Reduce(actor, state, set, false); - _state.ReapplyState(actor); - } + Reduce(actor, state, newSet, false); + _state.ReapplyState(actor); } } } + else if (_state.TryGetValue(id, out var state)) + { + state.RemoveFixedDesignSources(); + } + } + } + switch (type) + { + case AutomationChanged.Type.ToggleSet when !set.Enabled: + case AutomationChanged.Type.DeletedDesign when set.Enabled: + // The automation set was disabled or deleted, no other for those identifiers can be enabled, remove existing Fixed Locks. + RemoveOld(set.Identifiers); + break; + case AutomationChanged.Type.ChangeIdentifier when set.Enabled: + // Remove fixed state from the old identifiers assigned and the old enabled set, if any. + var (oldIds, _, oldSet) = ((ActorIdentifier[], ActorIdentifier, AutoDesignSet?)) bonusData!; + RemoveOld(oldIds); + ApplyNew(set); // Does not need to disable oldSet because same identifiers. + break; + case AutomationChanged.Type.ToggleSet: // Does not need to disable old states because same identifiers. + case AutomationChanged.Type.AddedDesign: + case AutomationChanged.Type.MovedDesign: + case AutomationChanged.Type.ChangedDesign: + case AutomationChanged.Type.ChangedConditions: + case AutomationChanged.Type.ChangedType: + ApplyNew(set); break; } } @@ -159,6 +193,8 @@ public class AutoDesignApplier : IDisposable EquipFlag totalEquipFlags = 0; CustomizeFlag totalCustomizeFlags = 0; byte totalMetaFlags = 0; + if (!respectManual) + state.RemoveFixedDesignSources(); foreach (var design in set.Designs) { if (!design.IsActive(actor)) diff --git a/Glamourer/Events/AutomationChanged.cs b/Glamourer/Events/AutomationChanged.cs index c38658a..ce4de43 100644 --- a/Glamourer/Events/AutomationChanged.cs +++ b/Glamourer/Events/AutomationChanged.cs @@ -29,7 +29,7 @@ public sealed class AutomationChanged : EventWrapper Move a given set to a different position. Additional data is the old index of the set and the new index of the set [(int, int)]. MovedSet, - /// Change the identifier a given set is associated with to another one. Additional data is the old identifier and the new one, and a potentially disabled other design set. [(ActorIdentifier, ActorIdentifier, AutoDesignSet?)]. + /// Change the identifier a given set is associated with to another one. Additional data is the old identifier and the new one, and a potentially disabled other design set. [(ActorIdentifier[], ActorIdentifier, AutoDesignSet?)]. ChangeIdentifier, /// Toggle the enabled state of a given set. Additional data is the thus disabled other set, if any [AutoDesignSet?]. diff --git a/Glamourer/Interop/DatFileService.cs b/Glamourer/Interop/DatFileService.cs index 12cfd11..12d8939 100644 --- a/Glamourer/Interop/DatFileService.cs +++ b/Glamourer/Interop/DatFileService.cs @@ -115,29 +115,10 @@ public class DatFileService if (inputVoice.HasValue && !set.Voices.Contains(inputVoice.Value)) return false; - foreach (var index in Enum.GetValues()) + foreach (var index in CustomizationExtensions.AllBasic) { - switch (index) - { - case CustomizeIndex.Race: - case CustomizeIndex.BodyType: - case CustomizeIndex.Gender: - case CustomizeIndex.Clan: - continue; - case CustomizeIndex.Hairstyle: - case CustomizeIndex.FacePaint: - if (set.DataByValue(index, input[index], out var data, input.Face) < 0 - || data == null - || _unlocks.Unlockable.ContainsKey(data.Value)) - return false; - - break; - default: - if (!CustomizationService.IsCustomizationValid(set, input.Face, index, input[index])) - return false; - - break; - } + if (!CustomizationService.IsCustomizationValid(set, input.Face, index, input[index])) + return false; } if (input[CustomizeIndex.LegacyTattoo].Value != 0) diff --git a/Glamourer/Services/CustomizationService.cs b/Glamourer/Services/CustomizationService.cs index f169628..ef2c138 100644 --- a/Glamourer/Services/CustomizationService.cs +++ b/Glamourer/Services/CustomizationService.cs @@ -39,7 +39,7 @@ public sealed class CustomizationService : AsyncServiceWrapper()) + foreach (var index in CustomizationExtensions.AllBasic) { var flag = index.ToFlag(); if (!applyWhich.HasFlag(flag)) diff --git a/Glamourer/State/ActorState.cs b/Glamourer/State/ActorState.cs index 53955c8..a770ee3 100644 --- a/Glamourer/State/ActorState.cs +++ b/Glamourer/State/ActorState.cs @@ -77,4 +77,13 @@ public class ActorState public ref StateChanged.Source this[MetaIndex index] => ref _sources[(int)index]; + + public void RemoveFixedDesignSources() + { + for (var i = 0; i < _sources.Length; ++i) + { + if (_sources[i] is StateChanged.Source.Fixed) + _sources[i] = StateChanged.Source.Manual; + } + } }