Add a button to revert advanced customizations only to game state.

This commit is contained in:
Ottermandias 2024-01-17 15:21:29 +01:00
parent 8b8f85dd85
commit 42aa4fb4a2
5 changed files with 134 additions and 70 deletions

View file

@ -18,27 +18,28 @@ public class Configuration : IPluginConfiguration, ISavable
[JsonIgnore] [JsonIgnore]
public readonly EphemeralConfig Ephemeral; public readonly EphemeralConfig Ephemeral;
public bool UseRestrictedGearProtection { get; set; } = false; public bool UseRestrictedGearProtection { get; set; } = false;
public bool OpenFoldersByDefault { get; set; } = false; public bool OpenFoldersByDefault { get; set; } = false;
public bool AutoRedrawEquipOnChanges { get; set; } = false; public bool AutoRedrawEquipOnChanges { get; set; } = false;
public bool EnableAutoDesigns { get; set; } = true; public bool EnableAutoDesigns { get; set; } = true;
public bool HideApplyCheckmarks { get; set; } = false; public bool HideApplyCheckmarks { get; set; } = false;
public bool SmallEquip { get; set; } = false; public bool SmallEquip { get; set; } = false;
public bool UnlockedItemMode { get; set; } = false; public bool UnlockedItemMode { get; set; } = false;
public byte DisableFestivals { get; set; } = 1; public byte DisableFestivals { get; set; } = 1;
public bool EnableGameContextMenu { get; set; } = true; public bool EnableGameContextMenu { get; set; } = true;
public bool HideWindowInCutscene { get; set; } = false; public bool HideWindowInCutscene { get; set; } = false;
public bool ShowAutomationSetEditing { get; set; } = true; public bool ShowAutomationSetEditing { get; set; } = true;
public bool ShowAllAutomatedApplicationRules { get; set; } = true; public bool ShowAllAutomatedApplicationRules { get; set; } = true;
public bool ShowUnlockedItemWarnings { get; set; } = true; public bool ShowUnlockedItemWarnings { get; set; } = true;
public bool RevertManualChangesOnZoneChange { get; set; } = false; public bool RevertManualChangesOnZoneChange { get; set; } = false;
public bool ShowQuickBarInTabs { get; set; } = true; public bool ShowQuickBarInTabs { get; set; } = true;
public bool OpenWindowAtStart { get; set; } = false; public bool OpenWindowAtStart { get; set; } = false;
public bool UseAdvancedParameters { get; set; } = true; public bool UseAdvancedParameters { get; set; } = true;
public bool ShowPalettePlusImport { get; set; } = true; public bool ShowRevertAdvancedParametersButton { get; set; } = true;
public ModifiableHotkey ToggleQuickDesignBar { get; set; } = new(VirtualKey.NO_KEY); public bool ShowPalettePlusImport { get; set; } = true;
public DoubleModifier DeleteDesignModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift); public ModifiableHotkey ToggleQuickDesignBar { get; set; } = new(VirtualKey.NO_KEY);
public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New; public DoubleModifier DeleteDesignModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift);
public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New;
[JsonConverter(typeof(SortModeConverter))] [JsonConverter(typeof(SortModeConverter))]
[JsonProperty(Order = int.MaxValue)] [JsonProperty(Order = int.MaxValue)]

View file

@ -16,7 +16,7 @@ using Penumbra.GameData.Actors;
namespace Glamourer.Gui; namespace Glamourer.Gui;
public class DesignQuickBar : Window, IDisposable public sealed class DesignQuickBar : Window, IDisposable
{ {
private ImGuiWindowFlags GetFlags private ImGuiWindowFlags GetFlags
=> _config.Ephemeral.LockDesignQuickBar => _config.Ephemeral.LockDesignQuickBar
@ -32,6 +32,7 @@ public class DesignQuickBar : Window, IDisposable
private readonly ImRaii.Style _windowPadding = new(); private readonly ImRaii.Style _windowPadding = new();
private readonly ImRaii.Color _windowColor = new(); private readonly ImRaii.Color _windowColor = new();
private DateTime _keyboardToggle = DateTime.UnixEpoch; private DateTime _keyboardToggle = DateTime.UnixEpoch;
private int _numButtons = 0;
public DesignQuickBar(Configuration config, DesignCombo designCombo, StateManager stateManager, IKeyState keyState, public DesignQuickBar(Configuration config, DesignCombo designCombo, StateManager stateManager, IKeyState keyState,
ObjectManager objects, AutoDesignApplier autoDesignApplier) ObjectManager objects, AutoDesignApplier autoDesignApplier)
@ -60,7 +61,7 @@ public class DesignQuickBar : Window, IDisposable
public override void PreDraw() public override void PreDraw()
{ {
Flags = GetFlags; Flags = GetFlags;
Size = new Vector2(12 * ImGui.GetFrameHeight(), ImGui.GetFrameHeight()); UpdateWidth();
_windowPadding.Push(ImGuiStyleVar.WindowPadding, new Vector2(ImGuiHelpers.GlobalScale * 4)) _windowPadding.Push(ImGuiStyleVar.WindowPadding, new Vector2(ImGuiHelpers.GlobalScale * 4))
.Push(ImGuiStyleVar.WindowBorderSize, 0); .Push(ImGuiStyleVar.WindowBorderSize, 0);
@ -75,6 +76,12 @@ public class DesignQuickBar : Window, IDisposable
_windowColor.Dispose(); _windowColor.Dispose();
} }
public void DrawAtEnd(float yPos)
{
var width = UpdateWidth();
ImGui.SetCursorPos(new Vector2(ImGui.GetWindowContentRegionMax().X - width, yPos - ImGuiHelpers.GlobalScale));
Draw();
}
public override void Draw() public override void Draw()
=> Draw(ImGui.GetContentRegionAvail().X); => Draw(ImGui.GetContentRegionAvail().X);
@ -82,20 +89,19 @@ public class DesignQuickBar : Window, IDisposable
private void Draw(float width) private void Draw(float width)
{ {
_objects.Update(); _objects.Update();
using var group = ImRaii.Group(); using var group = ImRaii.Group();
var spacing = ImGui.GetStyle().ItemInnerSpacing; var spacing = ImGui.GetStyle().ItemInnerSpacing;
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing); using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing);
var contentRegion = width; var buttonSize = new Vector2(ImGui.GetFrameHeight());
var buttonSize = new Vector2(ImGui.GetFrameHeight()); var comboSize = width - _numButtons * (buttonSize.X + spacing.X);
var comboSize = contentRegion - 3 * buttonSize.X - 3 * spacing.X;
_designCombo.Draw(comboSize); _designCombo.Draw(comboSize);
PrepareButtons(); PrepareButtons();
ImGui.SameLine(); ImGui.SameLine();
DrawApplyButton(buttonSize); DrawApplyButton(buttonSize);
ImGui.SameLine(); ImGui.SameLine();
DrawRevertButton(buttonSize); DrawRevertButton(buttonSize);
ImGui.SameLine();
DrawRevertAutomationButton(buttonSize); DrawRevertAutomationButton(buttonSize);
DrawRevertAdvancedCustomization(buttonSize);
} }
private ActorIdentifier _playerIdentifier; private ActorIdentifier _playerIdentifier;
@ -111,10 +117,8 @@ public class DesignQuickBar : Window, IDisposable
_objects.Update(); _objects.Update();
(_playerIdentifier, _playerData) = _objects.PlayerData; (_playerIdentifier, _playerData) = _objects.PlayerData;
(_targetIdentifier, _targetData) = _objects.TargetData; (_targetIdentifier, _targetData) = _objects.TargetData;
if (!_stateManager.TryGetValue(_playerIdentifier, out _playerState)) _playerState = _stateManager.GetValueOrDefault(_playerIdentifier);
_playerState = null; _targetState = _stateManager.GetValueOrDefault(_targetIdentifier);
if (!_stateManager.TryGetValue(_targetIdentifier, out _targetState))
_targetState = null;
} }
private void DrawApplyButton(Vector2 size) private void DrawApplyButton(Vector2 size)
@ -183,52 +187,79 @@ public class DesignQuickBar : Window, IDisposable
if (available == 0) if (available == 0)
tooltip = "Neither player character nor target are available, have state modified by Glamourer, or their state is locked."; tooltip = "Neither player character nor target are available, have state modified by Glamourer, or their state is locked.";
var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.UndoAlt, buttonSize, tooltip, available); var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.UndoAlt, buttonSize, tooltip, available);
if (clicked) if (clicked)
_stateManager.ResetState(state!, StateChanged.Source.Manual); _stateManager.ResetState(state!, StateChanged.Source.Manual);
} }
public void DrawRevertAutomationButton(Vector2 buttonSize) public void DrawRevertAutomationButton(Vector2 buttonSize)
{ {
if (!_config.EnableAutoDesigns)
return;
var available = 0; var available = 0;
var tooltip = string.Empty; var tooltip = string.Empty;
if (!_config.EnableAutoDesigns)
{
tooltip = "Automation is not enabled, you can not reset to automation state.";
}
else
{
if (_playerIdentifier.IsValid && _playerState is { IsLocked: false } && _playerData.Valid)
{
available |= 1;
tooltip = "Left-Click: Revert the player character to their automation state.";
}
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid) if (_playerIdentifier.IsValid && _playerState is { IsLocked: false } && _playerData.Valid)
{ {
if (available != 0) available |= 1;
tooltip += '\n'; tooltip = "Left-Click: Revert the player character to their automation state.";
available |= 2;
tooltip += $"Right-Click: Revert {_targetIdentifier} to their automation state.";
}
if (available == 0)
tooltip = "Neither player character nor target are available, have state modified by Glamourer, or their state is locked.";
} }
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid)
{
if (available != 0)
tooltip += '\n';
available |= 2;
tooltip += $"Right-Click: Revert {_targetIdentifier} to their automation state.";
}
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); var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.SyncAlt, buttonSize, tooltip, available);
if (!clicked) if (!clicked)
{ } return;
else
foreach (var actor in data.Objects)
{ {
foreach (var actor in data.Objects) _autoDesignApplier.ReapplyAutomation(actor, id, state!);
{ _stateManager.ReapplyState(actor);
_autoDesignApplier.ReapplyAutomation(actor, id, state!);
_stateManager.ReapplyState(actor);
}
} }
} }
public void DrawRevertAdvancedCustomization(Vector2 buttonSize)
{
if (!_config.ShowRevertAdvancedParametersButton || !_config.UseAdvancedParameters)
return;
var available = 0;
var tooltip = string.Empty;
if (_playerIdentifier.IsValid && _playerState is { IsLocked: false } && _playerData.Valid)
{
available |= 1;
tooltip = "Left-Click: Revert the advanced 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 advanced customizations of {_targetIdentifier} to their game state.";
}
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);
if (clicked)
_stateManager.ResetAdvancedState(state!, StateChanged.Source.Manual);
}
private (bool, ActorIdentifier, ActorData, ActorState?) ResolveTarget(FontAwesomeIcon icon, Vector2 buttonSize, string tooltip, private (bool, ActorIdentifier, ActorData, ActorState?) ResolveTarget(FontAwesomeIcon icon, Vector2 buttonSize, string tooltip,
int available) int available)
{ {
@ -251,11 +282,24 @@ public class DesignQuickBar : Window, IDisposable
_config.Ephemeral.Save(); _config.Ephemeral.Save();
} }
public bool CheckKeyState(ModifiableHotkey key, bool noKey) private bool CheckKeyState(ModifiableHotkey key, bool noKey)
{ {
if (key.Hotkey == VirtualKey.NO_KEY) if (key.Hotkey == VirtualKey.NO_KEY)
return noKey; return noKey;
return _keyState[key.Hotkey] && key.Modifier1.IsActive() && key.Modifier2.IsActive(); return _keyState[key.Hotkey] && key.Modifier1.IsActive() && key.Modifier2.IsActive();
} }
private float UpdateWidth()
{
_numButtons = (_config.EnableAutoDesigns, _config is { ShowRevertAdvancedParametersButton: true, UseAdvancedParameters: true }) switch
{
(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());
return Size.Value.X;
}
} }

View file

@ -105,10 +105,7 @@ public class MainWindow : Window, IDisposable
} }
if (_config.ShowQuickBarInTabs) if (_config.ShowQuickBarInTabs)
{ _quickBar.DrawAtEnd(yPos);
ImGui.SetCursorPos(new Vector2(ImGui.GetWindowContentRegionMax().X - 10 * ImGui.GetFrameHeight(), yPos - ImGuiHelpers.GlobalScale));
_quickBar.Draw();
}
} }
private ReadOnlySpan<byte> ToLabel(TabType type) private ReadOnlySpan<byte> ToLabel(TabType type)

View file

@ -164,6 +164,9 @@ public class SettingsTab(
config.ShowUnlockedItemWarnings, v => config.ShowUnlockedItemWarnings = v); config.ShowUnlockedItemWarnings, v => config.ShowUnlockedItemWarnings = v);
if (config.UseAdvancedParameters) 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 Palette+ Import Button", Checkbox("Show Palette+ Import Button",
"Show the import button that allows you to import Palette+ palettes onto a design in the Advanced Customization options section for designs.", "Show the import button that allows you to import Palette+ palettes onto a design in the Advanced Customization options section for designs.",
config.ShowPalettePlusImport, v => config.ShowPalettePlusImport = v); config.ShowPalettePlusImport, v => config.ShowPalettePlusImport = v);

View file

@ -309,7 +309,8 @@ public class StateManager(
} }
/// <summary> Change the crest of an equipment piece. </summary> /// <summary> Change the crest of an equipment piece. </summary>
public void ChangeCustomizeParameter(ActorState state, CustomizeParameterFlag flag, CustomizeParameterValue value, StateChanged.Source source, uint key = 0) public void ChangeCustomizeParameter(ActorState state, CustomizeParameterFlag flag, CustomizeParameterValue value,
StateChanged.Source source, uint key = 0)
{ {
if (!_editor.ChangeParameter(state, flag, value, source, out var old, key)) if (!_editor.ChangeParameter(state, flag, value, source, out var old, key))
return; return;
@ -501,7 +502,25 @@ public class StateManager(
Glamourer.Log.Verbose( Glamourer.Log.Verbose(
$"Reset entire state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]"); $"Reset entire state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]");
_event.Invoke(StateChanged.Type.Reset, StateChanged.Source.Manual, state, actors, null); _event.Invoke(StateChanged.Type.Reset, source, state, actors, null);
}
public void ResetAdvancedState(ActorState state, StateChanged.Source source, uint key = 0)
{
if (!state.Unlock(key) || !state.ModelData.IsHuman)
return;
state.ModelData.Parameters = state.BaseData.Parameters;
foreach (var flag in CustomizeParameterExtensions.AllFlags)
state[flag] = StateChanged.Source.Game;
var actors = ActorData.Invalid;
if (source is StateChanged.Source.Manual or StateChanged.Source.Ipc)
actors = _applier.ChangeParameters(state, CustomizeParameterExtensions.All, true);
Glamourer.Log.Verbose(
$"Reset advanced customization state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]");
_event.Invoke(StateChanged.Type.Reset, source, state, actors, null);
} }
public void ResetStateFixed(ActorState state, bool respectManualPalettes, uint key = 0) public void ResetStateFixed(ActorState state, bool respectManualPalettes, uint key = 0)