Handle losing fixed design state better.

This commit is contained in:
Ottermandias 2023-07-16 02:45:47 +02:00
parent 0d8ccd43b7
commit 58b867bd1e
5 changed files with 78 additions and 52 deletions

View file

@ -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))

View file

@ -29,7 +29,7 @@ public sealed class AutomationChanged : EventWrapper<Action<AutomationChanged.Ty
/// <summary> 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)]. </summary>
MovedSet,
/// <summary> 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?)]. </summary>
/// <summary> 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?)]. </summary>
ChangeIdentifier,
/// <summary> Toggle the enabled state of a given set. Additional data is the thus disabled other set, if any [AutoDesignSet?]. </summary>

View file

@ -115,29 +115,10 @@ public class DatFileService
if (inputVoice.HasValue && !set.Voices.Contains(inputVoice.Value))
return false;
foreach (var index in Enum.GetValues<CustomizeIndex>())
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)

View file

@ -39,7 +39,7 @@ public sealed class CustomizationService : AsyncServiceWrapper<ICustomizationMan
}
var set = AwaitedService.GetList(ret.Clan, ret.Gender);
foreach (var index in Enum.GetValues<CustomizeIndex>())
foreach (var index in CustomizationExtensions.AllBasic)
{
var flag = index.ToFlag();
if (!applyWhich.HasFlag(flag))

View file

@ -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;
}
}
}