Move MetaIndex to its first class enum.

This commit is contained in:
Ottermandias 2024-01-22 23:49:56 +01:00
parent e4fc86ca38
commit 4f9e224494
10 changed files with 147 additions and 148 deletions

View file

@ -1,6 +1,7 @@
using Dalamud.Interface.Internal.Notifications;
using Glamourer.GameData;
using Glamourer.Services;
using Glamourer.State;
using Newtonsoft.Json.Linq;
using OtterGui.Classes;
using Penumbra.GameData.Enums;
@ -34,7 +35,7 @@ public class DesignBase
_designData = designData;
ApplyCustomize = customizeFlags & CustomizeFlagExtensions.AllRelevant;
ApplyEquip = equipFlags & EquipFlagExtensions.All;
_designFlags = 0;
ApplyMeta = 0;
CustomizeSet = SetCustomizationSet(customize);
}
@ -45,7 +46,7 @@ public class DesignBase
ApplyCustomize = clone.ApplyCustomizeRaw;
ApplyEquip = clone.ApplyEquip & EquipFlagExtensions.All;
ApplyParameters = clone.ApplyParameters & CustomizeParameterExtensions.All;
_designFlags = clone._designFlags & (DesignFlags)0x0F;
ApplyMeta = clone.ApplyMeta & MetaExtensions.All;
}
/// <summary> Ensure that the customization set is updated when the design data changes. </summary>
@ -57,16 +58,6 @@ public class DesignBase
#region Application Data
[Flags]
private enum DesignFlags : byte
{
ApplyHatVisible = 0x01,
ApplyVisorState = 0x02,
ApplyWeaponVisible = 0x04,
ApplyWetness = 0x08,
WriteProtected = 0x10,
}
private CustomizeFlag _applyCustomize = CustomizeFlagExtensions.AllRelevant;
public CustomizeSet CustomizeSet { get; private set; }
@ -84,9 +75,10 @@ public class DesignBase
internal CustomizeFlag ApplyCustomizeRaw
=> _applyCustomize;
internal EquipFlag ApplyEquip = EquipFlagExtensions.All;
internal CrestFlag ApplyCrest = CrestExtensions.AllRelevant;
private DesignFlags _designFlags = DesignFlags.ApplyHatVisible | DesignFlags.ApplyVisorState | DesignFlags.ApplyWeaponVisible;
internal EquipFlag ApplyEquip = EquipFlagExtensions.All;
internal CrestFlag ApplyCrest = CrestExtensions.AllRelevant;
internal MetaFlag ApplyMeta = MetaFlag.HatState | MetaFlag.VisorState | MetaFlag.WeaponState;
private bool _writeProtected;
public bool SetCustomize(CustomizeService customizeService, CustomizeArray customize)
{
@ -98,69 +90,30 @@ public class DesignBase
return true;
}
public bool DoApplyHatVisible()
=> _designFlags.HasFlag(DesignFlags.ApplyHatVisible);
public bool DoApplyVisorToggle()
=> _designFlags.HasFlag(DesignFlags.ApplyVisorState);
public bool DoApplyWeaponVisible()
=> _designFlags.HasFlag(DesignFlags.ApplyWeaponVisible);
public bool DoApplyWetness()
=> _designFlags.HasFlag(DesignFlags.ApplyWetness);
public bool DoApplyMeta(MetaIndex index)
=> ApplyMeta.HasFlag(index.ToFlag());
public bool WriteProtected()
=> _designFlags.HasFlag(DesignFlags.WriteProtected);
=> _writeProtected;
public bool SetApplyHatVisible(bool value)
public bool SetApplyMeta(MetaIndex index, bool value)
{
var newFlag = value ? _designFlags | DesignFlags.ApplyHatVisible : _designFlags & ~DesignFlags.ApplyHatVisible;
if (newFlag == _designFlags)
var newFlag = value ? ApplyMeta | index.ToFlag() : ApplyMeta & ~index.ToFlag();
if (newFlag == ApplyMeta)
return false;
_designFlags = newFlag;
return true;
}
public bool SetApplyVisorToggle(bool value)
{
var newFlag = value ? _designFlags | DesignFlags.ApplyVisorState : _designFlags & ~DesignFlags.ApplyVisorState;
if (newFlag == _designFlags)
return false;
_designFlags = newFlag;
return true;
}
public bool SetApplyWeaponVisible(bool value)
{
var newFlag = value ? _designFlags | DesignFlags.ApplyWeaponVisible : _designFlags & ~DesignFlags.ApplyWeaponVisible;
if (newFlag == _designFlags)
return false;
_designFlags = newFlag;
return true;
}
public bool SetApplyWetness(bool value)
{
var newFlag = value ? _designFlags | DesignFlags.ApplyWetness : _designFlags & ~DesignFlags.ApplyWetness;
if (newFlag == _designFlags)
return false;
_designFlags = newFlag;
ApplyMeta = newFlag;
return true;
}
public bool SetWriteProtected(bool value)
{
var newFlag = value ? _designFlags | DesignFlags.WriteProtected : _designFlags & ~DesignFlags.WriteProtected;
if (newFlag == _designFlags)
if (value == _writeProtected)
return false;
_designFlags = newFlag;
_writeProtected = value;
return true;
}
public bool DoApplyEquip(EquipSlot slot)
@ -298,9 +251,9 @@ public class DesignBase
ret[slot.ToString()] = Serialize(item.Id, stain, crest, DoApplyEquip(slot), DoApplyStain(slot), DoApplyCrest(crestSlot));
}
ret["Hat"] = new QuadBool(_designData.IsHatVisible(), DoApplyHatVisible()).ToJObject("Show", "Apply");
ret["Visor"] = new QuadBool(_designData.IsVisorToggled(), DoApplyVisorToggle()).ToJObject("IsToggled", "Apply");
ret["Weapon"] = new QuadBool(_designData.IsWeaponVisible(), DoApplyWeaponVisible()).ToJObject("Show", "Apply");
ret["Hat"] = new QuadBool(_designData.IsHatVisible(), DoApplyMeta(MetaIndex.HatState)).ToJObject("Show", "Apply");
ret["Visor"] = new QuadBool(_designData.IsVisorToggled(), DoApplyMeta(MetaIndex.VisorState)).ToJObject("IsToggled", "Apply");
ret["Weapon"] = new QuadBool(_designData.IsWeaponVisible(), DoApplyMeta(MetaIndex.WeaponState)).ToJObject("Show", "Apply");
}
else
{
@ -344,7 +297,7 @@ public class DesignBase
ret["Wetness"] = new JObject()
{
["Value"] = _designData.IsWet(),
["Apply"] = DoApplyWetness(),
["Apply"] = DoApplyMeta(MetaIndex.Wetness),
};
return ret;
@ -478,7 +431,7 @@ public class DesignBase
// Load the token and set application.
bool TryGetToken(CustomizeParameterFlag flag, [NotNullWhen(true)] out JToken? token)
{
token = parameters![flag.ToString()];
token = parameters[flag.ToString()];
if (token != null)
{
var apply = token["Apply"]?.ToObject<bool>() ?? false;
@ -493,8 +446,8 @@ public class DesignBase
void MigrateLipOpacity()
{
var token = parameters!["LipOpacity"]?["Percentage"]?.ToObject<float>();
var actualToken = parameters![CustomizeParameterFlag.LipDiffuse.ToString()]?["Alpha"];
var token = parameters["LipOpacity"]?["Percentage"]?.ToObject<float>();
var actualToken = parameters[CustomizeParameterFlag.LipDiffuse.ToString()]?["Alpha"];
if (token != null && actualToken == null)
design.GetDesignDataRef().Parameters.LipDiffuse.W = token.Value;
}
@ -575,15 +528,15 @@ public class DesignBase
design.SetApplyCrest(CrestFlag.OffHand, applyCrestOff);
}
var metaValue = QuadBool.FromJObject(equip["Hat"], "Show", "Apply", QuadBool.NullFalse);
design.SetApplyHatVisible(metaValue.Enabled);
design.SetApplyMeta(MetaIndex.HatState, metaValue.Enabled);
design._designData.SetHatVisible(metaValue.ForcedValue);
metaValue = QuadBool.FromJObject(equip["Weapon"], "Show", "Apply", QuadBool.NullFalse);
design.SetApplyWeaponVisible(metaValue.Enabled);
design.SetApplyMeta(MetaIndex.WeaponState, metaValue.Enabled);
design._designData.SetWeaponVisible(metaValue.ForcedValue);
metaValue = QuadBool.FromJObject(equip["Visor"], "IsToggled", "Apply", QuadBool.NullFalse);
design.SetApplyVisorToggle(metaValue.Enabled);
design.SetApplyMeta(MetaIndex.VisorState, metaValue.Enabled);
design._designData.SetVisor(metaValue.ForcedValue);
}
@ -610,7 +563,7 @@ public class DesignBase
var wetness = QuadBool.FromJObject(json["Wetness"], "Value", "Apply", QuadBool.NullFalse);
design._designData.SetIsWet(wetness.ForcedValue);
design.SetApplyWetness(wetness.Enabled);
design.SetApplyMeta(MetaIndex.Wetness, wetness.Enabled);
design._designData.ModelId = json["ModelId"]?.ToObject<uint>() ?? 0;
PrintWarning(customizations.ValidateModelId(design._designData.ModelId, out design._designData.ModelId,
@ -664,17 +617,13 @@ public class DesignBase
try
{
_designData = DesignBase64Migration.MigrateBase64(items, humans, base64, out var equipFlags, out var customizeFlags,
out var writeProtected,
out var applyHat, out var applyVisor, out var applyWeapon);
out var writeProtected, out var applyMeta);
ApplyEquip = equipFlags;
ApplyCustomize = customizeFlags;
ApplyParameters = 0;
ApplyCrest = 0;
ApplyMeta = applyMeta;
SetWriteProtected(writeProtected);
SetApplyHatVisible(applyHat);
SetApplyVisorToggle(applyVisor);
SetApplyWeaponVisible(applyWeapon);
SetApplyWetness(true);
CustomizeSet = SetCustomizationSet(customize);
}
catch (Exception ex)

View file

@ -1,4 +1,5 @@
using Glamourer.Services;
using Glamourer.State;
using OtterGui;
using Penumbra.GameData.DataContainers;
using Penumbra.GameData.Enums;
@ -13,7 +14,7 @@ public class DesignBase64Migration
public const int Base64SizeV4 = 95;
public static unsafe DesignData MigrateBase64(ItemManager items, HumanModelList humans, string base64, out EquipFlag equipFlags,
out CustomizeFlag customizeFlags, out bool writeProtected, out bool applyHat, out bool applyVisor, out bool applyWeapon)
out CustomizeFlag customizeFlags, out bool writeProtected, out MetaFlag metaFlags)
{
static void CheckSize(int length, int requiredLength)
{
@ -25,9 +26,7 @@ public class DesignBase64Migration
byte applicationFlags;
ushort equipFlagsS;
var bytes = Convert.FromBase64String(base64);
applyHat = false;
applyVisor = false;
applyWeapon = false;
metaFlags = MetaFlag.Wetness;
var data = new DesignData();
switch (bytes[0])
{
@ -77,9 +76,12 @@ public class DesignBase64Migration
customizeFlags = (applicationFlags & 0x01) != 0 ? CustomizeFlagExtensions.All : 0;
data.SetIsWet((applicationFlags & 0x02) != 0);
applyHat = (applicationFlags & 0x04) != 0;
applyWeapon = (applicationFlags & 0x08) != 0;
applyVisor = (applicationFlags & 0x10) != 0;
if ((applicationFlags & 0x04) != 0)
metaFlags |= MetaFlag.HatState;
if ((applicationFlags & 0x08) != 0)
metaFlags |= MetaFlag.WeaponState;
if ((applicationFlags & 0x10) != 0)
metaFlags |= MetaFlag.VisorState;
writeProtected = (applicationFlags & 0x20) != 0;
equipFlags = 0;

View file

@ -186,6 +186,26 @@ public unsafe struct DesignData
return true;
}
public readonly bool GetMeta(MetaIndex index)
=> index switch
{
MetaIndex.Wetness => IsWet(),
MetaIndex.HatState => IsHatVisible(),
MetaIndex.VisorState => IsVisorToggled(),
MetaIndex.WeaponState => IsWeaponVisible(),
_ => false,
};
public bool SetMeta(MetaIndex index, bool value)
=> index switch
{
MetaIndex.Wetness => SetIsWet(value),
MetaIndex.HatState => SetHatVisible(value),
MetaIndex.VisorState => SetVisor(value),
MetaIndex.WeaponState => SetWeaponVisible(value),
_ => false,
};
public readonly bool IsWet()
=> (_states & 0x01) == 0x01;

View file

@ -6,50 +6,9 @@ using Glamourer.State;
using Glamourer.Unlocks;
using OtterGui.Services;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
namespace Glamourer.Designs.Links;
using WeaponDict = Dictionary<FullEquipType, (EquipItem, StateChanged.Source)>;
public sealed class MergedDesign
{
public MergedDesign(DesignManager designManager)
{
Design = designManager.CreateTemporary();
Design.ApplyEquip = 0;
Design.ApplyCustomize = 0;
Design.ApplyCrest = 0;
Design.ApplyParameters = 0;
Design.SetApplyWetness(false);
Design.SetApplyVisorToggle(false);
Design.SetApplyWeaponVisible(false);
Design.SetApplyHatVisible(false);
}
public readonly DesignBase Design;
public readonly WeaponDict Weapons = new(4);
public readonly StateSource Source = new();
public StateChanged.Source GetSource(EquipSlot slot, bool stain, StateChanged.Source actualSource)
=> GetSource(Source[slot, stain], actualSource);
public StateChanged.Source GetSource(CrestFlag slot, StateChanged.Source actualSource)
=> GetSource(Source[slot], actualSource);
public StateChanged.Source GetSource(CustomizeIndex type, StateChanged.Source actualSource)
=> GetSource(Source[type], actualSource);
public StateChanged.Source GetSource(MetaIndex index, StateChanged.Source actualSource)
=> GetSource(Source[index], actualSource);
public StateChanged.Source GetSource(CustomizeParameterFlag flag, StateChanged.Source actualSource)
=> GetSource(Source[flag], actualSource);
public static StateChanged.Source GetSource(StateChanged.Source given, StateChanged.Source actualSource)
=> given is StateChanged.Source.Game ? StateChanged.Source.Game : actualSource;
}
public class DesignMerger(
DesignManager designManager,
CustomizeService _customize,
@ -57,7 +16,8 @@ public class DesignMerger(
ItemUnlockManager _itemUnlocks,
CustomizeUnlockManager _customizeUnlocks) : IService
{
public MergedDesign Merge(IEnumerable<(DesignBase?, ApplicationType)> designs, in DesignData baseRef, bool respectOwnership)
public MergedDesign Merge(IEnumerable<(DesignBase?, ApplicationType)> designs, in DesignData baseRef, bool respectOwnership,
bool modAssociations)
{
var ret = new MergedDesign(designManager);
CustomizeFlag fixFlags = 0;
@ -81,6 +41,7 @@ public class DesignMerger(
ReduceOffhands(data, equipFlags, ret, source, respectOwnership);
ReduceCrests(data, crestFlags, ret, source);
ReduceParameters(data, parameterFlags, ret, source);
ReduceMods(design as Design, ret, modAssociations);
}
ApplyFixFlags(ret, fixFlags);
@ -88,6 +49,15 @@ public class DesignMerger(
}
private static void ReduceMods(Design? design, MergedDesign ret, bool modAssociations)
{
if (design == null || !modAssociations)
return;
foreach (var (mod, settings) in design.AssociatedMods)
ret.AssociatedMods.TryAdd(mod, settings);
}
private static void ReduceMeta(in DesignData design, bool applyHat, bool applyVisor, bool applyWeapon, bool applyWet, MergedDesign ret,
StateChanged.Source source)
{
@ -196,7 +166,8 @@ public class DesignMerger(
}
}
private void ReduceMainhands(in DesignData design, EquipFlag equipFlags, MergedDesign ret, StateChanged.Source source, bool respectOwnership)
private void ReduceMainhands(in DesignData design, EquipFlag equipFlags, MergedDesign ret, StateChanged.Source source,
bool respectOwnership)
{
if (!equipFlags.HasFlag(EquipFlag.Mainhand))
return;
@ -271,7 +242,7 @@ public class DesignMerger(
ret.Source[CustomizeIndex.Face] = source;
}
var set = _customize.Manager.GetSet(customize.Clan, customize.Gender);
var set = ret.Design.CustomizeSet;
var face = customize.Face;
foreach (var index in Enum.GetValues<CustomizeIndex>())
{
@ -291,6 +262,8 @@ public class DesignMerger(
ret.Source[index] = source;
fixFlags &= ~flag;
}
ret.Design.SetCustomize(_customize, customize);
}
private static void ApplyFixFlags(MergedDesign ret, CustomizeFlag fixFlags)

View file

@ -1,5 +1,6 @@
using Glamourer.Events;
using Glamourer.GameData;
using Glamourer.Interop.Penumbra;
using Glamourer.State;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
@ -15,15 +16,38 @@ public sealed class MergedDesign
Design.ApplyCustomize = 0;
Design.ApplyCrest = 0;
Design.ApplyParameters = 0;
Design.SetApplyWetness(false);
Design.SetApplyVisorToggle(false);
Design.SetApplyWeaponVisible(false);
Design.SetApplyHatVisible(false);
Design.ApplyMeta = 0;
}
public MergedDesign(DesignBase design)
{
Design = design;
if (design.DoApplyEquip(EquipSlot.MainHand))
{
var weapon = design.DesignData.Item(EquipSlot.MainHand);
if (weapon.Valid)
Weapons.TryAdd(weapon.Type, (weapon, StateChanged.Source.Manual));
}
if (design.DoApplyEquip(EquipSlot.OffHand))
{
var weapon = design.DesignData.Item(EquipSlot.OffHand);
if (weapon.Valid)
Weapons.TryAdd(weapon.Type, (weapon, StateChanged.Source.Manual));
}
}
public MergedDesign(Design design)
: this((DesignBase)design)
{
foreach (var (mod, settings) in design.AssociatedMods)
AssociatedMods[mod] = settings;
}
public readonly DesignBase Design;
public readonly Dictionary<FullEquipType, (EquipItem, StateChanged.Source)> Weapons = new(4);
public readonly StateSource Source = new();
public readonly Dictionary<FullEquipType, (EquipItem, StateChanged.Source)> Weapons = new(4);
public readonly StateSource Source = new();
public readonly SortedList<Mod, ModSettings> AssociatedMods = [];
public StateChanged.Source GetSource(EquipSlot slot, bool stain, StateChanged.Source actualSource)
=> GetSource(Source[slot, stain], actualSource);

View file

@ -0,0 +1,39 @@
using Penumbra.GameData.Enums;
namespace Glamourer.State;
public enum MetaIndex
{
Wetness = EquipFlagExtensions.NumEquipFlags + CustomizationExtensions.NumIndices,
HatState,
VisorState,
WeaponState,
ModelId,
}
[Flags]
public enum MetaFlag : byte
{
Wetness = 0x01,
HatState = 0x02,
VisorState = 0x04,
WeaponState = 0x08,
}
public static class MetaExtensions
{
public static readonly IReadOnlyList<MetaIndex> AllRelevant =
[MetaIndex.Wetness, MetaIndex.HatState, MetaIndex.VisorState, MetaIndex.WeaponState];
public const MetaFlag All = MetaFlag.Wetness | MetaFlag.HatState | MetaFlag.VisorState | MetaFlag.WeaponState;
public static MetaFlag ToFlag(this MetaIndex index)
=> index switch
{
MetaIndex.Wetness => MetaFlag.Wetness,
MetaIndex.HatState => MetaFlag.HatState,
MetaIndex.VisorState => MetaFlag.VisorState,
MetaIndex.WeaponState => MetaFlag.WeaponState,
_ => (MetaFlag) byte.MaxValue,
};
}

View file

@ -1,7 +1,6 @@
using Dalamud.Plugin;
using Glamourer.Designs;
using Glamourer.GameData;
using Glamourer.State;
using Newtonsoft.Json.Linq;
using OtterGui.Services;

View file

@ -1,4 +1,5 @@
using Dalamud.Plugin.Services;
using Glamourer.Designs;
using Glamourer.Events;
using Glamourer.GameData;
using Glamourer.Services;

View file

@ -11,6 +11,7 @@ using Dalamud.Game.ClientState.Conditions;
using Dalamud.Plugin.Services;
using Glamourer.GameData;
using Penumbra.GameData.DataContainers;
using Glamourer.Designs;
namespace Glamourer.State;

View file

@ -4,15 +4,6 @@ using static Glamourer.Events.StateChanged;
namespace Glamourer.State;
public enum MetaIndex
{
Wetness = EquipFlagExtensions.NumEquipFlags + CustomizationExtensions.NumIndices,
HatState,
VisorState,
WeaponState,
ModelId,
}
public readonly struct StateSource
{
public static readonly int Size = EquipFlagExtensions.NumEquipFlags