Improve QDB.

This commit is contained in:
Ottermandias 2024-03-01 14:29:36 +01:00
parent 436a975a44
commit ed6f32f757
7 changed files with 299 additions and 87 deletions

View file

@ -18,35 +18,38 @@ public class Configuration : IPluginConfiguration, ISavable
[JsonIgnore]
public readonly EphemeralConfig Ephemeral;
public bool UseRestrictedGearProtection { get; set; } = false;
public bool OpenFoldersByDefault { get; set; } = false;
public bool AutoRedrawEquipOnChanges { get; set; } = false;
public bool EnableAutoDesigns { get; set; } = true;
public bool HideApplyCheckmarks { get; set; } = false;
public bool SmallEquip { get; set; } = false;
public bool UnlockedItemMode { get; set; } = false;
public byte DisableFestivals { get; set; } = 1;
public bool EnableGameContextMenu { get; set; } = true;
public bool HideWindowInCutscene { get; set; } = false;
public bool ShowAutomationSetEditing { get; set; } = true;
public bool ShowAllAutomatedApplicationRules { get; set; } = true;
public bool ShowUnlockedItemWarnings { get; set; } = true;
public bool RevertManualChangesOnZoneChange { get; set; } = false;
public bool ShowQuickBarInTabs { get; set; } = true;
public bool OpenWindowAtStart { get; set; } = false;
public bool UseAdvancedParameters { get; set; } = true;
public bool UseAdvancedDyes { get; set; } = true;
public bool KeepAdvancedDyesAttached { get; set; } = true;
public bool ShowRevertAdvancedParametersButton { get; set; } = true;
public bool ShowPalettePlusImport { get; set; } = true;
public bool UseFloatForColors { get; set; } = true;
public bool UseRgbForColors { get; set; } = true;
public bool ShowColorConfig { get; set; } = true;
public bool ChangeEntireItem { get; set; } = false;
public bool AlwaysApplyAssociatedMods { get; set; } = false;
public ModifiableHotkey ToggleQuickDesignBar { get; set; } = new(VirtualKey.NO_KEY);
public DoubleModifier DeleteDesignModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift);
public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New;
public bool UseRestrictedGearProtection { get; set; } = false;
public bool OpenFoldersByDefault { get; set; } = false;
public bool AutoRedrawEquipOnChanges { get; set; } = false;
public bool EnableAutoDesigns { get; set; } = true;
public bool HideApplyCheckmarks { get; set; } = false;
public bool SmallEquip { get; set; } = false;
public bool UnlockedItemMode { get; set; } = false;
public byte DisableFestivals { get; set; } = 1;
public bool EnableGameContextMenu { get; set; } = true;
public bool HideWindowInCutscene { get; set; } = false;
public bool ShowAutomationSetEditing { get; set; } = true;
public bool ShowAllAutomatedApplicationRules { get; set; } = true;
public bool ShowUnlockedItemWarnings { get; set; } = true;
public bool RevertManualChangesOnZoneChange { get; set; } = false;
public bool ShowQuickBarInTabs { get; set; } = true;
public bool OpenWindowAtStart { get; set; } = false;
public bool ShowWindowWhenUiHidden { get; set; } = false;
public bool UseAdvancedParameters { get; set; } = true;
public bool UseAdvancedDyes { get; set; } = true;
public bool KeepAdvancedDyesAttached { get; set; } = true;
public bool ShowPalettePlusImport { get; set; } = true;
public bool UseFloatForColors { get; set; } = true;
public bool UseRgbForColors { get; set; } = true;
public bool ShowColorConfig { get; set; } = true;
public bool ChangeEntireItem { get; set; } = false;
public bool AlwaysApplyAssociatedMods { get; set; } = false;
public ModifiableHotkey ToggleQuickDesignBar { get; set; } = new(VirtualKey.NO_KEY);
public DoubleModifier DeleteDesignModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift);
public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New;
public QdbButtons QdbButtons { get; set; } =
QdbButtons.ApplyDesign | QdbButtons.RevertAll | QdbButtons.RevertAutomation | QdbButtons.RevertAdvanced;
[JsonConverter(typeof(SortModeConverter))]
[JsonProperty(Order = int.MaxValue)]
@ -78,15 +81,8 @@ public class Configuration : IPluginConfiguration, ISavable
public void Save()
=> _saveService.DelaySave(this);
public void Load(ConfigMigrationService migrator)
private void Load(ConfigMigrationService migrator)
{
static void HandleDeserializationError(object? sender, ErrorEventArgs errorArgs)
{
Glamourer.Log.Error(
$"Error parsing Configuration at {errorArgs.ErrorContext.Path}, using default or migrating:\n{errorArgs.ErrorContext.Error}");
errorArgs.ErrorContext.Handled = true;
}
if (!File.Exists(_saveService.FileNames.ConfigFile))
return;
@ -107,6 +103,14 @@ public class Configuration : IPluginConfiguration, ISavable
}
migrator.Migrate(this);
return;
static void HandleDeserializationError(object? sender, ErrorEventArgs errorArgs)
{
Glamourer.Log.Error(
$"Error parsing Configuration at {errorArgs.ErrorContext.Path}, using default or migrating:\n{errorArgs.ErrorContext.Error}");
errorArgs.ErrorContext.Handled = true;
}
}
public string ToFilename(FilenameService fileNames)
@ -114,14 +118,15 @@ public class Configuration : IPluginConfiguration, ISavable
public void Save(StreamWriter writer)
{
using var jWriter = new JsonTextWriter(writer) { Formatting = Formatting.Indented };
var serializer = new JsonSerializer { Formatting = Formatting.Indented };
using var jWriter = new JsonTextWriter(writer);
jWriter.Formatting = Formatting.Indented;
var serializer = new JsonSerializer { Formatting = Formatting.Indented };
serializer.Serialize(jWriter, this);
}
public static class Constants
{
public const int CurrentVersion = 5;
public const int CurrentVersion = 6;
public static readonly ISortMode<Design>[] ValidSortModes =
{

View file

@ -16,6 +16,17 @@ using Penumbra.GameData.Actors;
namespace Glamourer.Gui;
[Flags]
public enum QdbButtons
{
ApplyDesign = 0x01,
RevertAll = 0x02,
RevertAutomation = 0x04,
RevertAdvanced = 0x08,
RevertEquip = 0x10,
RevertCustomize = 0x20,
}
public sealed class DesignQuickBar : Window, IDisposable
{
private ImGuiWindowFlags GetFlags
@ -55,7 +66,7 @@ public sealed class DesignQuickBar : Window, IDisposable
public override void PreOpenCheck()
{
CheckHotkeys();
IsOpen = _config.Ephemeral.ShowDesignQuickBar;
IsOpen = _config.Ephemeral.ShowDesignQuickBar && _config.QdbButtons != 0;
}
public override void PreDraw()
@ -93,15 +104,20 @@ public sealed class DesignQuickBar : Window, IDisposable
var spacing = ImGui.GetStyle().ItemInnerSpacing;
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing);
var buttonSize = new Vector2(ImGui.GetFrameHeight());
var comboSize = width - _numButtons * (buttonSize.X + spacing.X);
_designCombo.Draw(comboSize);
PrepareButtons();
ImGui.SameLine();
DrawApplyButton(buttonSize);
ImGui.SameLine();
if (_config.QdbButtons.HasFlag(QdbButtons.ApplyDesign))
{
var comboSize = width - _numButtons * (buttonSize.X + spacing.X);
_designCombo.Draw(comboSize);
ImGui.SameLine();
DrawApplyButton(buttonSize);
}
DrawRevertButton(buttonSize);
DrawRevertAutomationButton(buttonSize);
DrawRevertEquipButton(buttonSize);
DrawRevertCustomizeButton(buttonSize);
DrawRevertAdvancedCustomization(buttonSize);
DrawRevertAutomationButton(buttonSize);
}
private ActorIdentifier _playerIdentifier;
@ -152,12 +168,14 @@ public sealed class DesignQuickBar : Window, IDisposable
var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.PlayCircle, size, tooltip, available);
ImGui.SameLine();
if (!clicked)
return;
if (state == null && !_stateManager.GetOrCreate(id, data.Objects[0], out state))
{
Glamourer.Messager.NotificationMessage($"Could not apply {design!.ResolveName(true)} to {id.Incognito(null)}: Failed to create state.");
Glamourer.Messager.NotificationMessage(
$"Could not apply {design!.ResolveName(true)} to {id.Incognito(null)}: Failed to create state.");
return;
}
@ -166,8 +184,11 @@ public sealed class DesignQuickBar : Window, IDisposable
_stateManager.ApplyDesign(state, design, ApplySettings.ManualWithLinks);
}
public void DrawRevertButton(Vector2 buttonSize)
private void DrawRevertButton(Vector2 buttonSize)
{
if (!_config.QdbButtons.HasFlag(QdbButtons.RevertAll))
return;
var available = 0;
var tooltip = string.Empty;
if (_playerIdentifier.IsValid && _playerState is { IsLocked: false })
@ -188,15 +209,19 @@ public sealed class DesignQuickBar : Window, IDisposable
tooltip = "Neither player character nor target are available, have state modified by Glamourer, or their state is locked.";
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.UndoAlt, buttonSize, tooltip, available);
ImGui.SameLine();
if (clicked)
_stateManager.ResetState(state!, StateSource.Manual);
}
public void DrawRevertAutomationButton(Vector2 buttonSize)
private void DrawRevertAutomationButton(Vector2 buttonSize)
{
if (!_config.EnableAutoDesigns)
return;
if (!_config.QdbButtons.HasFlag(QdbButtons.RevertAutomation))
return;
var available = 0;
var tooltip = string.Empty;
@ -217,8 +242,8 @@ public sealed class DesignQuickBar : Window, IDisposable
if (available == 0)
tooltip = "Neither player character nor target are available, have state modified by Glamourer, or their state is locked.";
ImGui.SameLine();
var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.SyncAlt, buttonSize, tooltip, available);
ImGui.SameLine();
if (!clicked)
return;
@ -229,9 +254,12 @@ public sealed class DesignQuickBar : Window, IDisposable
}
}
public void DrawRevertAdvancedCustomization(Vector2 buttonSize)
private void DrawRevertAdvancedCustomization(Vector2 buttonSize)
{
if (!_config.ShowRevertAdvancedParametersButton || !_config.UseAdvancedParameters)
if (!_config.UseAdvancedParameters)
return;
if (!_config.QdbButtons.HasFlag(QdbButtons.RevertAdvanced))
return;
var available = 0;
@ -254,12 +282,74 @@ public sealed class DesignQuickBar : Window, IDisposable
if (available == 0)
tooltip = "Neither player character nor target are available or their state is locked.";
ImGui.SameLine();
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.Palette, buttonSize, tooltip, available);
ImGui.SameLine();
if (clicked)
_stateManager.ResetAdvancedState(state!, StateSource.Manual);
}
private void DrawRevertCustomizeButton(Vector2 buttonSize)
{
if (!_config.QdbButtons.HasFlag(QdbButtons.RevertCustomize))
return;
var available = 0;
var tooltip = string.Empty;
if (_playerIdentifier.IsValid && _playerState is { IsLocked: false } && _playerData.Valid)
{
available |= 1;
tooltip = "Left-Click: Revert the customizations of the player character to their game state.";
}
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid)
{
if (available != 0)
tooltip += '\n';
available |= 2;
tooltip += $"Right-Click: Revert the customizations of {_targetIdentifier} to their game state.";
}
if (available == 0)
tooltip = "Neither player character nor target are available or their state is locked.";
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.User, buttonSize, tooltip, available);
ImGui.SameLine();
if (clicked)
_stateManager.ResetCustomize(state!, StateSource.Manual);
}
private void DrawRevertEquipButton(Vector2 buttonSize)
{
if (!_config.QdbButtons.HasFlag(QdbButtons.RevertEquip))
return;
var available = 0;
var tooltip = string.Empty;
if (_playerIdentifier.IsValid && _playerState is { IsLocked: false } && _playerData.Valid)
{
available |= 1;
tooltip = "Left-Click: Revert the equipment of the player character to its game state.";
}
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid)
{
if (available != 0)
tooltip += '\n';
available |= 2;
tooltip += $"Right-Click: Revert the equipment of {_targetIdentifier} to its game state.";
}
if (available == 0)
tooltip = "Neither player character nor target are available or their state is locked.";
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.Vest, buttonSize, tooltip, available);
ImGui.SameLine();
if (clicked)
_stateManager.ResetEquip(state!, StateSource.Manual);
}
private (bool, ActorIdentifier, ActorData, ActorState?) ResolveTarget(FontAwesomeIcon icon, Vector2 buttonSize, string tooltip,
int available)
{
@ -292,15 +382,32 @@ public sealed class DesignQuickBar : Window, IDisposable
private float UpdateWidth()
{
_numButtons = (_config.EnableAutoDesigns, _config is { ShowRevertAdvancedParametersButton: true, UseAdvancedParameters: true }) switch
_numButtons = 0;
if (_config.QdbButtons.HasFlag(QdbButtons.RevertAll))
++_numButtons;
if (_config.EnableAutoDesigns && _config.QdbButtons.HasFlag(QdbButtons.RevertAutomation))
++_numButtons;
if ((_config.UseAdvancedParameters || _config.UseAdvancedDyes) && _config.QdbButtons.HasFlag(QdbButtons.RevertAdvanced))
++_numButtons;
if (_config.QdbButtons.HasFlag(QdbButtons.RevertCustomize))
++_numButtons;
if (_config.QdbButtons.HasFlag(QdbButtons.RevertEquip))
++_numButtons;
if (_config.QdbButtons.HasFlag(QdbButtons.ApplyDesign))
{
(true, true) => 4,
(false, true) => 3,
(true, false) => 3,
(false, false) => 2,
};
Size = new Vector2((7 + _numButtons) * ImGui.GetFrameHeight() + _numButtons * ImGui.GetStyle().ItemInnerSpacing.X,
ImGui.GetFrameHeight());
++_numButtons;
Size = new Vector2((7 + _numButtons) * ImGui.GetFrameHeight() + _numButtons * ImGui.GetStyle().ItemInnerSpacing.X,
ImGui.GetFrameHeight());
}
else
{
Size = new Vector2(
_numButtons * ImGui.GetFrameHeight()
+ (_numButtons - 1) * ImGui.GetStyle().ItemInnerSpacing.X
+ ImGui.GetStyle().WindowPadding.X * 2,
ImGui.GetFrameHeight());
}
return Size.Value.X;
}
}

View file

@ -25,6 +25,7 @@ public class GlamourerWindowSystem : IDisposable
_uiBuilder.Draw += _windowSystem.Draw;
_uiBuilder.OpenConfigUi += _ui.Toggle;
_uiBuilder.DisableCutsceneUiHide = !config.HideWindowInCutscene;
_uiBuilder.DisableUserUiHide = config.ShowWindowWhenUiHidden;
}
public void Dispose()

View file

@ -159,10 +159,6 @@ public class MainWindow : Window, IDisposable
{
var width = ImGui.CalcTextSize("Join Discord for Support").X + ImGui.GetStyle().FramePadding.X * 2;
var xPos = ImGui.GetWindowWidth() - width;
// Respect the scroll bar width.
if (ImGui.GetScrollMaxY() > 0)
xPos -= ImGui.GetStyle().ScrollbarSize + ImGui.GetStyle().FramePadding.X;
ImGui.SetCursorPos(new Vector2(xPos, 0));
CustomGui.DrawDiscordButton(Glamourer.Messager, width);

View file

@ -120,6 +120,7 @@ public class SettingsTab(
Checkbox("Show Quick Design Bar in Main Window",
"Show the quick design bar in the tab selection part of the main window, too.",
config.ShowQuickBarInTabs, v => config.ShowQuickBarInTabs = v);
DrawQuickDesignBoxes();
ImGui.Dummy(Vector2.Zero);
ImGui.Separator();
@ -134,6 +135,12 @@ public class SettingsTab(
else
contextMenuService.Disable();
});
Checkbox("Show Window when UI is Hidden", "Whether to show Glamourer windows even when the games UI is hidden.",
config.ShowWindowWhenUiHidden, v =>
{
config.ShowWindowWhenUiHidden = v;
uiBuilder.DisableUserUiHide = v;
});
Checkbox("Hide Window in Cutscenes", "Whether the main Glamourer window should automatically be hidden when entering cutscenes or not.",
config.HideWindowInCutscene,
v =>
@ -176,9 +183,9 @@ public class SettingsTab(
config.ShowUnlockedItemWarnings, v => config.ShowUnlockedItemWarnings = v);
if (config.UseAdvancedParameters)
{
Checkbox("Show Revert Advanced Customizations Button in Quick Design Bar",
"Show a button to revert only advanced customizations on your character or a target in the quick design bar.",
config.ShowRevertAdvancedParametersButton, v => config.ShowRevertAdvancedParametersButton = v);
//Checkbox("Show Revert Advanced Customizations Button in Quick Design Bar",
// "Show a button to revert only advanced customizations on your character or a target in the quick design bar.",
// config.ShowRevertAdvancedParametersButton, v => config.ShowRevertAdvancedParametersButton = v);
Checkbox("Show Color Display Config", "Show the Color Display configuration options in the Advanced Customization panels.",
config.ShowColorConfig, v => config.ShowColorConfig = v);
Checkbox("Show Palette+ Import Button",
@ -198,6 +205,52 @@ public class SettingsTab(
ImGui.NewLine();
}
private void DrawQuickDesignBoxes()
{
var showAuto = config.EnableAutoDesigns;
var showAdvanced = config.UseAdvancedParameters || config.UseAdvancedDyes;
var numColumns = 6 - (showAuto ? 0 : 1) - (showAdvanced ? 0 : 1);
ImGui.NewLine();
ImGui.TextUnformatted("Show the Following Buttons in the Quick Design Bar:");
ImGui.Dummy(Vector2.Zero);
using var table = ImRaii.Table("##tableQdb", numColumns, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.Borders | ImGuiTableFlags.NoHostExtendX);
if (!table)
return;
var columns = new[]
{
(" Apply Design ", true, QdbButtons.ApplyDesign),
(" Revert All ", true, QdbButtons.RevertAll),
(" Revert to Auto ", showAuto, QdbButtons.RevertAutomation),
(" Revert Equip ", true, QdbButtons.RevertEquip),
(" Revert Customization ", true, QdbButtons.RevertCustomize),
(" Revert Advanced ", showAdvanced, QdbButtons.RevertAdvanced),
};
foreach (var (label, _, _) in columns.Where(t => t.Item2))
{
ImGui.TableNextColumn();
ImGui.TableHeader(label);
}
foreach (var (_, _, flag) in columns.Where(t => t.Item2))
{
using var id = ImRaii.PushId((int)flag);
ImGui.TableNextColumn();
var offset = (ImGui.GetContentRegionAvail().X - ImGui.GetFrameHeight()) / 2;
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + offset);
var value = config.QdbButtons.HasFlag(flag);
if (!ImGui.Checkbox(string.Empty, ref value))
continue;
var buttons = value ? config.QdbButtons | flag : config.QdbButtons & ~flag;
if (buttons == config.QdbButtons)
continue;
config.QdbButtons = buttons;
config.Save();
}
}
private void PaletteImportButton()
{

View file

@ -4,38 +4,38 @@ using Newtonsoft.Json.Linq;
namespace Glamourer.Services;
public class ConfigMigrationService
public class ConfigMigrationService(SaveService saveService, FixedDesignMigrator fixedDesignMigrator, BackupService backupService)
{
private readonly SaveService _saveService;
private readonly FixedDesignMigrator _fixedDesignMigrator;
private readonly BackupService _backupService;
private Configuration _config = null!;
private JObject _data = null!;
public ConfigMigrationService(SaveService saveService, FixedDesignMigrator fixedDesignMigrator, BackupService backupService)
{
_saveService = saveService;
_fixedDesignMigrator = fixedDesignMigrator;
_backupService = backupService;
}
public void Migrate(Configuration config)
{
_config = config;
if (config.Version >= Configuration.Constants.CurrentVersion || !File.Exists(_saveService.FileNames.ConfigFile))
if (config.Version >= Configuration.Constants.CurrentVersion || !File.Exists(saveService.FileNames.ConfigFile))
{
AddColors(config, false);
return;
}
_data = JObject.Parse(File.ReadAllText(_saveService.FileNames.ConfigFile));
_data = JObject.Parse(File.ReadAllText(saveService.FileNames.ConfigFile));
MigrateV1To2();
MigrateV2To4();
MigrateV4To5();
MigrateV5To6();
AddColors(config, true);
}
private void MigrateV5To6()
{
if (_config.Version > 5)
return;
if (_data["ShowRevertAdvancedParametersButton"]?.ToObject<bool>() ?? true)
_config.QdbButtons |= QdbButtons.RevertAdvanced;
_config.Version = 6;
}
// Ephemeral Config.
private void MigrateV4To5()
{
@ -59,8 +59,8 @@ public class ConfigMigrationService
if (_config.Version > 1)
return;
_backupService.CreateMigrationBackup("pre_v1_to_v2_migration");
_fixedDesignMigrator.Migrate(_data["FixedDesigns"]);
backupService.CreateMigrationBackup("pre_v1_to_v2_migration");
fixedDesignMigrator.Migrate(_data["FixedDesigns"]);
_config.Version = 2;
var customizationColor = _data["CustomizationColor"]?.ToObject<uint>() ?? ColorId.CustomizationDesign.Data().DefaultColor;
_config.Colors[ColorId.CustomizationDesign] = customizationColor;

View file

@ -29,7 +29,8 @@ public sealed class StateManager(
DesignMerger merger,
ModSettingApplier modApplier,
GPoseService gPose)
: StateEditor(editor, applier, @event, jobChange, config, items, merger, modApplier, gPose), IReadOnlyDictionary<ActorIdentifier, ActorState>
: StateEditor(editor, applier, @event, jobChange, config, items, merger, modApplier, gPose),
IReadOnlyDictionary<ActorIdentifier, ActorState>
{
private readonly Dictionary<ActorIdentifier, ActorState> _states = [];
@ -225,7 +226,7 @@ public sealed class StateManager(
|| !state.ModelData.IsHuman
|| CustomizeArray.Compare(state.ModelData.Customize, state.BaseData.Customize).RequiresRedraw();
state.ModelData = state.BaseData;
state.ModelData = state.BaseData;
state.ModelData.SetIsWet(false);
foreach (var index in Enum.GetValues<CustomizeIndex>())
state.Sources[index] = StateSource.Game;
@ -281,6 +282,55 @@ public sealed class StateManager(
StateChanged.Invoke(StateChanged.Type.Reset, source, state, actors, null);
}
public void ResetCustomize(ActorState state, StateSource source, uint key = 0)
{
if (!state.Unlock(key) || !state.ModelData.IsHuman)
return;
foreach (var flag in CustomizationExtensions.All)
state.Sources[flag] = StateSource.Game;
state.ModelData = state.BaseData;
var actors = ActorData.Invalid;
if (source is not StateSource.Game)
actors = Applier.ChangeCustomize(state, true);
Glamourer.Log.Verbose(
$"Reset customization state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]");
}
public void ResetEquip(ActorState state, StateSource source, uint key = 0)
{
if (!state.Unlock(key))
return;
foreach (var slot in EquipSlotExtensions.FullSlots)
{
state.Sources[slot, true] = StateSource.Game;
state.Sources[slot, false] = StateSource.Game;
if (source is not StateSource.Game)
{
state.ModelData.SetItem(slot, state.BaseData.Item(slot));
state.ModelData.SetStain(slot, state.BaseData.Stain(slot));
}
}
var actors = ActorData.Invalid;
if (source is not StateSource.Game)
{
actors = Applier.ChangeArmor(state, EquipSlotExtensions.EqdpSlots[0], true);
foreach (var slot in EquipSlotExtensions.EqdpSlots.Skip(1))
Applier.ChangeArmor(actors, slot, state.ModelData.Armor(slot), !state.Sources[slot, false].IsIpc(),
state.ModelData.IsHatVisible());
var mainhandActors = state.ModelData.MainhandType != state.BaseData.MainhandType ? actors.OnlyGPose() : actors;
Applier.ChangeMainhand(mainhandActors, state.ModelData.Item(EquipSlot.MainHand), state.ModelData.Stain(EquipSlot.MainHand));
var offhandActors = state.ModelData.OffhandType != state.BaseData.OffhandType ? actors.OnlyGPose() : actors;
Applier.ChangeOffhand(offhandActors, state.ModelData.Item(EquipSlot.OffHand), state.ModelData.Stain(EquipSlot.OffHand));
}
Glamourer.Log.Verbose($"Reset equipment state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]");
}
public void ResetStateFixed(ActorState state, bool respectManualPalettes, uint key = 0)
{
if (!state.Unlock(key))