Add using game base state as base for fixed design sets.

This commit is contained in:
Ottermandias 2023-07-19 16:43:54 +02:00
parent 8f9beed6f8
commit c909510edc
11 changed files with 69 additions and 18 deletions

View file

@ -1,6 +1,7 @@
using System.Collections.Generic;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Plugin;
using Glamourer.Events;
using Penumbra.Api.Helpers;
using Penumbra.GameData.Actors;
@ -31,9 +32,7 @@ public partial class GlamourerIpc
foreach (var id in actors)
{
if (_stateManager.TryGetValue(id, out var state))
{
_stateManager.ResetState(state, 0xDEADBEEF);
}
_stateManager.ResetState(state, StateChanged.Source.Ipc, 0xDEADBEEF);
}
}
}

View file

@ -116,11 +116,12 @@ public class AutoDesignApplier : IDisposable
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!;
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.ChangedBase:
case AutomationChanged.Type.AddedDesign:
case AutomationChanged.Type.MovedDesign:
case AutomationChanged.Type.ChangedDesign:
@ -193,7 +194,9 @@ public class AutoDesignApplier : IDisposable
EquipFlag totalEquipFlags = 0;
CustomizeFlag totalCustomizeFlags = 0;
byte totalMetaFlags = 0;
if (!respectManual)
if (set.BaseState == AutoDesignSet.Base.Game)
_state.ResetState(state, StateChanged.Source.Fixed);
else if (!respectManual)
state.RemoveFixedDesignSources();
foreach (var design in set.Designs)
{

View file

@ -209,6 +209,22 @@ public class AutoDesignManager : ISavable, IReadOnlyList<AutoDesignSet>
_event.Invoke(AutomationChanged.Type.ToggleSet, set, oldEnabled);
}
public void ChangeBaseState(int whichSet, AutoDesignSet.Base newBase)
{
if (whichSet >= _data.Count || whichSet < 0)
return;
var set = _data[whichSet];
if (newBase == set.BaseState)
return;
var old = set.BaseState;
set.BaseState = newBase;
Save();
Glamourer.Log.Debug($"Changed base state of set {whichSet + 1} from {old} to {newBase}.");
_event.Invoke(AutomationChanged.Type.ChangedBase, set, (old, newBase));
}
public void AddDesign(AutoDesignSet set, Design design)
{
var newDesign = new AutoDesign()
@ -375,6 +391,7 @@ public class AutoDesignManager : ISavable, IReadOnlyList<AutoDesignSet>
var set = new AutoDesignSet(name, id)
{
Enabled = obj["Enabled"]?.ToObject<bool>() ?? false,
BaseState = obj["BaseState"]?.ToObject<AutoDesignSet.Base>() ?? AutoDesignSet.Base.Current,
};
if (set.Enabled)

View file

@ -1,4 +1,7 @@
using System.Collections.Generic;
using System.Reflection.Metadata.Ecma335;
using Glamourer.Designs;
using Glamourer.State;
using Newtonsoft.Json.Linq;
using Penumbra.GameData.Actors;
@ -11,6 +14,7 @@ public class AutoDesignSet
public string Name;
public ActorIdentifier[] Identifiers;
public bool Enabled;
public Base BaseState = Base.Current;
public JObject Serialize()
{
@ -23,6 +27,7 @@ public class AutoDesignSet
["Name"] = Name,
["Identifier"] = Identifiers[0].ToJson(),
["Enabled"] = Enabled,
["BaseState"] = BaseState.ToString(),
["Designs"] = list,
};
}
@ -37,4 +42,10 @@ public class AutoDesignSet
Identifiers = identifiers;
Designs = designs;
}
public enum Base : byte
{
Current,
Game,
}
}

View file

@ -35,6 +35,9 @@ public sealed class AutomationChanged : EventWrapper<Action<AutomationChanged.Ty
/// <summary> Toggle the enabled state of a given set. Additional data is the thus disabled other set, if any [AutoDesignSet?]. </summary>
ToggleSet,
/// <summary> Change the used base state of a given set. Additional data is prior and new base. [(AutoDesignSet.Base, AutoDesignSet.Base)]. </summary>
ChangedBase,
/// <summary> Add a new associated design to a given set. Additional data is the index it got added at [int]. </summary>
AddedDesign,

View file

@ -344,7 +344,7 @@ public class ActorPanel
{
if (ImGuiUtil.DrawDisabledButton("Revert to Game", Vector2.Zero, "Revert the character to its actual state in the game.",
_state!.IsLocked))
_stateManager.ResetState(_state!);
_stateManager.ResetState(_state!, StateChanged.Source.Manual);
ImGui.SameLine();
if (ImGuiUtil.DrawDisabledButton("Reapply State", Vector2.Zero, "Try to reapply the configured state if something went wrong.",

View file

@ -73,8 +73,17 @@ public class SetPanel
if (!child || !_selector.HasSelection)
return;
var enabled = Selection.Enabled;
if (ImGui.Checkbox("Enabled", ref enabled))
_manager.SetState(_selector.SelectionIndex, enabled);
var useGame = _selector.Selection!.BaseState is AutoDesignSet.Base.Game;
if (ImGui.Checkbox("Use Game State as Base", ref useGame))
_manager.ChangeBaseState(_selector.SelectionIndex, useGame ? AutoDesignSet.Base.Game : AutoDesignSet.Base.Current);
var name = _tempName ?? Selection.Name;
var flags = _selector.IncognitoMode ? ImGuiInputTextFlags.ReadOnly | ImGuiInputTextFlags.Password : ImGuiInputTextFlags.None;
ImGui.SetNextItemWidth(220 * ImGuiHelpers.GlobalScale);
if (ImGui.InputText("##Name", ref name, 128, flags))
_tempName = name;
@ -84,11 +93,6 @@ public class SetPanel
_tempName = null;
}
ImGui.SameLine();
var enabled = Selection.Enabled;
if (ImGui.Checkbox("Enabled", ref enabled))
_manager.SetState(_selector.SelectionIndex, enabled);
ImGui.Separator();
DrawIdentifierSelection(_selector.SelectionIndex);

View file

@ -1083,7 +1083,7 @@ public unsafe class DebugTab : ITab
ImGuiUtil.DrawTableColumn(state.Identifier.ToString());
ImGui.TableNextColumn();
if (ImGui.Button("Reset"))
_state.ResetState(state);
_state.ResetState(state, StateChanged.Source.Manual);
ImGui.TableNextRow();

View file

@ -150,7 +150,7 @@ public class CommandService : IDisposable
return false;
if (_stateManager.TryGetValue(identifier, out var state))
_stateManager.ResetState(state);
_stateManager.ResetState(state, StateChanged.Source.Manual);
return true;
}

View file

@ -50,7 +50,11 @@ public class StateApplier
{
var data = GetData(state);
if (apply)
{
state.TempLock();
ForceRedraw(data);
}
return data;
}
@ -58,7 +62,7 @@ public class StateApplier
/// Change the customization values of actors either by applying them via update or redrawing,
/// this depends on whether the changes include changes to Race, Gender, Body Type or Face.
/// </summary>
public void ChangeCustomize(ActorData data, in Customize customize)
public void ChangeCustomize(ActorData data, in Customize customize, ActorState? state = null)
{
foreach (var actor in data.Objects)
{
@ -68,9 +72,14 @@ public class StateApplier
var flags = Customize.Compare(mdl.GetCustomize(), customize);
if (!flags.RequiresRedraw() || !mdl.IsHuman)
{
_changeCustomize.UpdateCustomize(mdl, customize.Data);
}
else
{
state?.TempLock();
_penumbra.RedrawObject(actor, RedrawType.Redraw);
}
}
}
@ -79,7 +88,8 @@ public class StateApplier
{
var data = GetData(state);
if (apply)
ChangeCustomize(data, state.ModelData.Customize);
ChangeCustomize(data, state.ModelData.Customize, state);
return data;
}
@ -111,6 +121,7 @@ public class StateApplier
var data = GetData(state);
if (apply)
ChangeArmor(data, slot, state.ModelData.Armor(slot), state.ModelData.IsHatVisible());
return data;
}
@ -145,6 +156,7 @@ public class StateApplier
var data = GetData(state);
if (apply)
ChangeStain(data, slot, state.ModelData.Stain(slot));
return data;
}
@ -164,6 +176,7 @@ public class StateApplier
var data = GetData(state);
if (apply)
ChangeWeapon(data, slot, state.ModelData.Item(slot), state.ModelData.Stain(slot));
return data;
}
@ -183,6 +196,7 @@ public class StateApplier
var data = GetData(state);
if (apply)
ChangeMainhand(data, state.ModelData.Item(EquipSlot.MainHand), state.ModelData.Stain(EquipSlot.MainHand));
return data;
}

View file

@ -399,7 +399,7 @@ public class StateManager : IReadOnlyDictionary<ActorIdentifier, ActorState>
return actors;
}
public void ResetState(ActorState state, uint key = 0)
public void ResetState(ActorState state, StateChanged.Source source, uint key = 0)
{
if (!state.Unlock(key))
return;
@ -419,10 +419,10 @@ public class StateManager : IReadOnlyDictionary<ActorIdentifier, ActorState>
foreach (var type in Enum.GetValues<ActorState.MetaIndex>())
state[type] = StateChanged.Source.Game;
var actors = ApplyAll(state, redraw);
var actors = source is StateChanged.Source.Manual or StateChanged.Source.Ipc ? ApplyAll(state, redraw) : ActorData.Invalid;
Glamourer.Log.Verbose(
$"Reset entire state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]");
_event.Invoke(StateChanged.Type.Design, state[ActorState.MetaIndex.Wetness], state, actors, null);
_event.Invoke(StateChanged.Type.Design, StateChanged.Source.Manual, state, actors, null);
}
public void ReapplyState(Actor actor)