diff --git a/Glamourer/ActorExtensions.cs b/Glamourer/ActorExtensions.cs index b2456dd..158c0c2 100644 --- a/Glamourer/ActorExtensions.cs +++ b/Glamourer/ActorExtensions.cs @@ -67,7 +67,7 @@ namespace Glamourer *((byte*) a.Address + WeaponHiddenOffset) = (byte) (val | WeaponHiddenFlag); else *((byte*) a.Address + WeaponHiddenOffset) = (byte) (val & ~WeaponHiddenFlag); - return ret || ((val & WeaponHiddenFlag) != 0) != value; + return ret || (val & WeaponHiddenFlag) != 0 != value; } public static bool SetVisorToggled(this Actor a, bool value) diff --git a/Glamourer/CharacterSave.cs b/Glamourer/CharacterSave.cs index 19fd66a..2107caf 100644 --- a/Glamourer/CharacterSave.cs +++ b/Glamourer/CharacterSave.cs @@ -74,25 +74,25 @@ namespace Glamourer public bool SetHatState { get => (_bytes[1] & 0x04) != 0; - set => _bytes[1] = (byte)(value ? _bytes[1] | 0x04 : _bytes[1] & ~0x04); + set => _bytes[1] = (byte) (value ? _bytes[1] | 0x04 : _bytes[1] & ~0x04); } public bool SetWeaponState { get => (_bytes[1] & 0x08) != 0; - set => _bytes[1] = (byte)(value ? _bytes[1] | 0x08 : _bytes[1] & ~0x08); + set => _bytes[1] = (byte) (value ? _bytes[1] | 0x08 : _bytes[1] & ~0x08); } public bool SetVisorState { get => (_bytes[1] & 0x10) != 0; - set => _bytes[1] = (byte)(value ? _bytes[1] | 0x10 : _bytes[1] & ~0x10); + set => _bytes[1] = (byte) (value ? _bytes[1] | 0x10 : _bytes[1] & ~0x10); } public bool WriteProtected { get => (_bytes[1] & 0x20) != 0; - set => _bytes[1] = (byte)(value ? _bytes[1] | 0x20 : _bytes[1] & ~0x20); + set => _bytes[1] = (byte) (value ? _bytes[1] | 0x20 : _bytes[1] & ~0x20); } public byte StateFlags @@ -110,13 +110,13 @@ namespace Glamourer public bool VisorState { get => (StateFlags & 0x10) != 0; - set => StateFlags = (byte)(value ? StateFlags | 0x10 : StateFlags & ~0x10); + set => StateFlags = (byte) (value ? StateFlags | 0x10 : StateFlags & ~0x10); } public bool WeaponState { get => (StateFlags & 0x02) == 0; - set => StateFlags = (byte)(value ? StateFlags & ~0x02 : StateFlags | 0x02); + set => StateFlags = (byte) (value ? StateFlags & ~0x02 : StateFlags | 0x02); } public ActorEquipMask WriteEquipment @@ -181,7 +181,7 @@ namespace Glamourer private static void CheckActorMask(byte val1, byte val2) { - var mask = (ActorEquipMask)((ushort)val1 | ((ushort)val2 << 8)); + var mask = (ActorEquipMask) ((ushort) val1 | ((ushort) val2 << 8)); if (mask > ActorEquipMask.All) throw new Exception($"Can not parse Base64 string into CharacterSave:\n\tInvalid value {mask} in byte 3 and 4."); } @@ -193,13 +193,13 @@ namespace Glamourer Load(new ActorEquipment(a), ActorEquipMask.All); - SetHatState = true; - SetVisorState = true; - SetWeaponState = true; - StateFlags = a.StateFlags(); + SetHatState = true; + SetVisorState = true; + SetWeaponState = true; + StateFlags = a.StateFlags(); - IsWet = a.IsWet(); - Alpha = a.Alpha(); + IsWet = a.IsWet(); + Alpha = a.Alpha(); } public void Apply(Actor a) @@ -211,7 +211,9 @@ namespace Glamourer a.SetWetness(IsWet); a.Alpha() = Alpha; if ((_bytes[1] & 0b11100) == 0b11100) + { a.StateFlags() = StateFlags; + } else { if (SetHatState) @@ -240,6 +242,7 @@ namespace Glamourer break; default: throw new Exception($"Can not parse Base64 string into CharacterSave:\n\tInvalid Version {bytes[0]}."); } + CheckActorMask(bytes[2], bytes[3]); bytes.CopyTo(_bytes, 0); } @@ -257,7 +260,7 @@ namespace Glamourer { fixed (byte* ptr = _bytes) { - return ref *((ActorCustomization*) (ptr + 4)); + return ref *(ActorCustomization*) (ptr + 4); } } } diff --git a/Glamourer/Designs/DesignManager.cs b/Glamourer/Designs/DesignManager.cs index 908776f..73d9a96 100644 --- a/Glamourer/Designs/DesignManager.cs +++ b/Glamourer/Designs/DesignManager.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.ComponentModel; using System.IO; using System.Linq; using Dalamud.Plugin; @@ -84,10 +83,8 @@ namespace Glamourer.Designs public void DeleteAllChildren(IFileSystemBase root, bool deleteEmpty) { if (root is Folder f) - { foreach (var child in f.AllLeaves(SortMode.Lexicographical)) Designs.Remove(child.FullName()); - } var fullPath = root.FullName(); root.Parent.RemoveChild(root, deleteEmpty); Designs.Remove(fullPath); diff --git a/Glamourer/GlamourerConfig.cs b/Glamourer/GlamourerConfig.cs new file mode 100644 index 0000000..14f2495 --- /dev/null +++ b/Glamourer/GlamourerConfig.cs @@ -0,0 +1,36 @@ +using Dalamud.Configuration; + +namespace Glamourer +{ + public class GlamourerConfig : IPluginConfiguration + { + public int Version { get; set; } = 1; + + public const uint DefaultCustomizationColor = 0xFFC000C0; + public const uint DefaultStateColor = 0xFF00C0C0; + public const uint DefaultEquipmentColor = 0xFF00C000; + + public bool FoldersFirst { get; set; } = false; + public bool ColorDesigns { get; set; } = true; + public bool ShowLocks { get; set; } = true; + + public uint CustomizationColor { get; set; } = DefaultCustomizationColor; + public uint StateColor { get; set; } = DefaultStateColor; + public uint EquipmentColor { get; set; } = DefaultEquipmentColor; + + public void Save() + => Glamourer.PluginInterface.SavePluginConfig(this); + + public static GlamourerConfig Create() + { + var config = Glamourer.PluginInterface.GetPluginConfig() as GlamourerConfig; + if (config == null) + { + config = new GlamourerConfig(); + Glamourer.PluginInterface.SavePluginConfig(config); + } + + return config; + } + } +} diff --git a/Glamourer/Gui/Interface.cs b/Glamourer/Gui/Interface.cs index 60456a3..02c9c96 100644 --- a/Glamourer/Gui/Interface.cs +++ b/Glamourer/Gui/Interface.cs @@ -25,31 +25,31 @@ namespace Glamourer.Gui private readonly ImGuiScene.TextureWrap? _legacyTattooIcon; private readonly Dictionary _equipSlotNames; private readonly DesignManager _designs; - private readonly GlamourerPlugin _plugin; + private readonly Glamourer _plugin; private bool _visible = false; private bool _inGPose = false; - public Interface(GlamourerPlugin plugin) + public Interface(Glamourer plugin) { _plugin = plugin; _designs = plugin.Designs; - _glamourerHeader = GlamourerPlugin.Version.Length > 0 - ? $"{PluginName} v{GlamourerPlugin.Version}###{PluginName}Main" + _glamourerHeader = Glamourer.Version.Length > 0 + ? $"{PluginName} v{Glamourer.Version}###{PluginName}Main" : $"{PluginName}###{PluginName}Main"; - GlamourerPlugin.PluginInterface.UiBuilder.DisableGposeUiHide = true; - GlamourerPlugin.PluginInterface.UiBuilder.OnBuildUi += Draw; - GlamourerPlugin.PluginInterface.UiBuilder.OnOpenConfigUi += ToggleVisibility; + Glamourer.PluginInterface.UiBuilder.DisableGposeUiHide = true; + Glamourer.PluginInterface.UiBuilder.OnBuildUi += Draw; + Glamourer.PluginInterface.UiBuilder.OnOpenConfigUi += ToggleVisibility; _equipSlotNames = GetEquipSlotNames(); - _stains = GameData.Stains(GlamourerPlugin.PluginInterface); - _identifier = Penumbra.GameData.GameData.GetIdentifier(GlamourerPlugin.PluginInterface); - _actors = GlamourerPlugin.PluginInterface.ClientState.Actors; + _stains = GameData.Stains(Glamourer.PluginInterface); + _identifier = Penumbra.GameData.GameData.GetIdentifier(Glamourer.PluginInterface); + _actors = Glamourer.PluginInterface.ClientState.Actors; var stainCombo = CreateDefaultStainCombo(_stains.Values.ToArray()); - var equip = GameData.ItemsBySlot(GlamourerPlugin.PluginInterface); + var equip = GameData.ItemsBySlot(Glamourer.PluginInterface); _combos = equip.ToDictionary(kvp => kvp.Key, kvp => CreateCombos(kvp.Key, kvp.Value, stainCombo)); _legacyTattooIcon = GetLegacyTattooIcon(); } @@ -60,8 +60,8 @@ namespace Glamourer.Gui public void Dispose() { _legacyTattooIcon?.Dispose(); - GlamourerPlugin.PluginInterface.UiBuilder.OnBuildUi -= Draw; - GlamourerPlugin.PluginInterface.UiBuilder.OnOpenConfigUi -= ToggleVisibility; + Glamourer.PluginInterface.UiBuilder.OnBuildUi -= Draw; + Glamourer.PluginInterface.UiBuilder.OnOpenConfigUi -= ToggleVisibility; } private void Draw() @@ -91,6 +91,7 @@ namespace Glamourer.Gui DrawActorTab(); DrawSaves(); + DrawConfigTab(); } finally { diff --git a/Glamourer/Gui/InterfaceActorPanel.cs b/Glamourer/Gui/InterfaceActorPanel.cs index 589a4d5..fac7506 100644 --- a/Glamourer/Gui/InterfaceActorPanel.cs +++ b/Glamourer/Gui/InterfaceActorPanel.cs @@ -88,7 +88,7 @@ namespace Glamourer.Gui private void DrawTargetPlayerButton() { if (ImGui.Button("Target Player")) - GlamourerPlugin.PluginInterface.ClientState.Targets.SetCurrentTarget(_player); + Glamourer.PluginInterface.ClientState.Targets.SetCurrentTarget(_player); } private void DrawApplyToPlayerButton(CharacterSave save) @@ -96,9 +96,9 @@ namespace Glamourer.Gui if (ImGui.Button("Apply to Self")) { var player = _inGPose - ? GlamourerPlugin.PluginInterface.ClientState.Actors[GPoseActorId] - : GlamourerPlugin.PluginInterface.ClientState.LocalPlayer; - var fallback = _inGPose ? GlamourerPlugin.PluginInterface.ClientState.LocalPlayer : null; + ? Glamourer.PluginInterface.ClientState.Actors[GPoseActorId] + : Glamourer.PluginInterface.ClientState.LocalPlayer; + var fallback = _inGPose ? Glamourer.PluginInterface.ClientState.LocalPlayer : null; if (player != null) { save.Apply(player); @@ -113,7 +113,7 @@ namespace Glamourer.Gui { if (ImGui.Button("Apply to Target")) { - var player = GlamourerPlugin.PluginInterface.ClientState.Targets.CurrentTarget; + var player = Glamourer.PluginInterface.ClientState.Targets.CurrentTarget; if (player != null) { var fallBackActor = _playerNames[player.Name]; diff --git a/Glamourer/Gui/InterfaceActorSelector.cs b/Glamourer/Gui/InterfaceActorSelector.cs index b8dc648..889b01a 100644 --- a/Glamourer/Gui/InterfaceActorSelector.cs +++ b/Glamourer/Gui/InterfaceActorSelector.cs @@ -66,7 +66,7 @@ namespace Glamourer.Gui Actor? select = null; var buttonWidth = Vector2.UnitX * SelectorWidth / 2; if (ImGui.Button(FontAwesomeIcon.UserCircle.ToIconString(), buttonWidth)) - select = GlamourerPlugin.PluginInterface.ClientState.LocalPlayer; + select = Glamourer.PluginInterface.ClientState.LocalPlayer; raii.PopFonts(); if (ImGui.IsItemHovered()) ImGui.SetTooltip("Select the local player character."); @@ -81,7 +81,7 @@ namespace Glamourer.Gui else { if (ImGui.Button(FontAwesomeIcon.HandPointer.ToIconString(), buttonWidth)) - select = GlamourerPlugin.PluginInterface.ClientState.Targets.CurrentTarget; + select = Glamourer.PluginInterface.ClientState.Targets.CurrentTarget; } raii.PopFonts(); diff --git a/Glamourer/Gui/InterfaceConfig.cs b/Glamourer/Gui/InterfaceConfig.cs new file mode 100644 index 0000000..a7de996 --- /dev/null +++ b/Glamourer/Gui/InterfaceConfig.cs @@ -0,0 +1,73 @@ +using System; +using System.Numerics; +using ImGuiNET; + +namespace Glamourer.Gui +{ + internal partial class Interface + { + private static void DrawConfigCheckMark(string label, string tooltip, bool value, Action setter) + { + if (DrawCheckMark(label, value, setter)) + Glamourer.Config.Save(); + + if (ImGui.IsItemHovered()) + ImGui.SetTooltip(tooltip); + } + + private static void ChangeAndSave(T value, T currentValue, Action setter) where T : IEquatable + { + if (value.Equals(currentValue)) + return; + + setter(value); + Glamourer.Config.Save(); + } + + private static void DrawColorPicker(string name, string tooltip, uint value, uint defaultValue, Action setter) + { + const ImGuiColorEditFlags flags = ImGuiColorEditFlags.AlphaPreviewHalf | ImGuiColorEditFlags.NoInputs; + + var tmp = ImGui.ColorConvertU32ToFloat4(value); + if (ImGui.ColorEdit4($"##{name}", ref tmp, flags)) + ChangeAndSave(ImGui.ColorConvertFloat4ToU32(tmp), value, setter); + ImGui.SameLine(); + if (ImGui.Button($"Default##{name}")) + ChangeAndSave(defaultValue, value, setter); + if (ImGui.IsItemHovered()) + ImGui.SetTooltip( + $"Reset to default: #{defaultValue & 0xFF:X2}{(defaultValue >> 8) & 0xFF:X2}{(defaultValue >> 16) & 0xFF:X2}{defaultValue >> 24:X2}"); + ImGui.SameLine(); + ImGui.Text(name); + if (ImGui.IsItemHovered()) + ImGui.SetTooltip(tooltip); + } + + private void DrawConfigTab() + { + using var raii = new ImGuiRaii(); + if (!raii.Begin(() => ImGui.BeginTabItem("Config"), ImGui.EndTabItem)) + return; + + var cfg = Glamourer.Config; + ImGui.Dummy(Vector2.UnitY * ImGui.GetTextLineHeightWithSpacing() / 2); + + DrawConfigCheckMark("Folders First", "Sort Folders before all designs instead of lexicographically.", cfg.FoldersFirst, + v => cfg.FoldersFirst = v); + DrawConfigCheckMark("Color Designs", "Color the names of designs in the selector using the colors from below for the given cases.", + cfg.ColorDesigns, + v => cfg.ColorDesigns = v); + DrawConfigCheckMark("Show Locks", "Write-protected Designs show a lock besides their name in the selector.", cfg.ShowLocks, + v => cfg.ShowLocks = v); + + ImGui.Dummy(Vector2.UnitY * ImGui.GetTextLineHeightWithSpacing() / 2); + + DrawColorPicker("Customization Color", "The color for designs that only apply their character customization.", + cfg.CustomizationColor, GlamourerConfig.DefaultCustomizationColor, c => cfg.CustomizationColor = c); + DrawColorPicker("Equipment Color", "The color for designs that only apply some or all of their equipment slots and stains.", + cfg.EquipmentColor, GlamourerConfig.DefaultEquipmentColor, c => cfg.EquipmentColor = c); + DrawColorPicker("State Color", "The color for designs that only apply some state modification.", + cfg.StateColor, GlamourerConfig.DefaultStateColor, c => cfg.StateColor = c); + } + } +} diff --git a/Glamourer/Gui/InterfaceCustomization.cs b/Glamourer/Gui/InterfaceCustomization.cs index ab4a911..2ce7660 100644 --- a/Glamourer/Gui/InterfaceCustomization.cs +++ b/Glamourer/Gui/InterfaceCustomization.cs @@ -170,8 +170,8 @@ namespace Glamourer.Gui var enabled = customization.FacialFeature(i); var feature = set.FacialFeature(set.Race == Race.Hrothgar ? customization.Hairstyle : customization.Face, i); var icon = i == count - 1 - ? _legacyTattooIcon ?? GlamourerPlugin.Customization.GetIcon(feature.IconId) - : GlamourerPlugin.Customization.GetIcon(feature.IconId); + ? _legacyTattooIcon ?? Glamourer.Customization.GetIcon(feature.IconId) + : Glamourer.Customization.GetIcon(feature.IconId); if (ImGui.ImageButton(icon.ImGuiHandle, _iconSize, Vector2.Zero, Vector2.One, (int) ImGui.GetStyle().FramePadding.X, Vector4.Zero, enabled ? NoColor : RedColor)) @@ -220,7 +220,7 @@ namespace Glamourer.Gui for (var i = 0; i < count; ++i) { var custom = set.Data(id, i); - var icon = GlamourerPlugin.Customization.GetIcon(custom.IconId); + var icon = Glamourer.Customization.GetIcon(custom.IconId); if (ImGui.ImageButton(icon.ImGuiHandle, _iconSize)) { value = custom; @@ -258,7 +258,7 @@ namespace Glamourer.Gui } var popupName = $"Style Picker##{id}"; - var icon = GlamourerPlugin.Customization.GetIcon(custom!.Value.IconId); + var icon = Glamourer.Customization.GetIcon(custom!.Value.IconId); if (ImGui.ImageButton(icon.ImGuiHandle, _iconSize)) ImGui.OpenPopup(popupName); @@ -340,7 +340,7 @@ namespace Glamourer.Gui } ImGui.Text( - $"{GlamourerPlugin.Customization.GetName(CustomName.Gender)} & {GlamourerPlugin.Customization.GetName(CustomName.Clan)}"); + $"{Glamourer.Customization.GetName(CustomName.Gender)} & {Glamourer.Customization.GetName(CustomName.Clan)}"); return ret; } @@ -403,7 +403,7 @@ namespace Glamourer.Gui ImGui.SameLine(); ret |= DrawRaceSelector(ref custom); - var set = GlamourerPlugin.Customization.GetList(custom.Clan, custom.Gender); + var set = Glamourer.Customization.GetList(custom.Clan, custom.Gender); foreach (var id in AllCustomizations.Where(c => set.Type(c) == CharaMakeParams.MenuType.Percentage)) ret |= DrawPicker(set, id, ref custom); @@ -447,7 +447,7 @@ namespace Glamourer.Gui var xPos = _inputIntSize + _actualIconSize.X + 3 * ImGui.GetStyle().ItemSpacing.X; ImGui.SameLine(xPos); tmp = custom.FacePaintReversed; - if (ImGui.Checkbox($"{GlamourerPlugin.Customization.GetName(CustomName.Reverse)} {set.Option(CustomizationId.FacePaint)}", ref tmp) + if (ImGui.Checkbox($"{Glamourer.Customization.GetName(CustomName.Reverse)} {set.Option(CustomizationId.FacePaint)}", ref tmp) && tmp != custom.FacePaintReversed) { custom.FacePaintReversed = tmp; @@ -455,7 +455,7 @@ namespace Glamourer.Gui } tmp = custom.SmallIris; - if (ImGui.Checkbox($"{GlamourerPlugin.Customization.GetName(CustomName.IrisSmall)} {set.Option(CustomizationId.EyeColorL)}", + if (ImGui.Checkbox($"{Glamourer.Customization.GetName(CustomName.IrisSmall)} {set.Option(CustomizationId.EyeColorL)}", ref tmp) && tmp != custom.SmallIris) { diff --git a/Glamourer/Gui/InterfaceDesigns.cs b/Glamourer/Gui/InterfaceDesigns.cs index e81a16f..6116e87 100644 --- a/Glamourer/Gui/InterfaceDesigns.cs +++ b/Glamourer/Gui/InterfaceDesigns.cs @@ -21,13 +21,14 @@ namespace Glamourer.Gui { _totalObject = 0; ImGui.BeginGroup(); - if (ImGui.BeginChild("##selector", new Vector2(SelectorWidth * ImGui.GetIO().FontGlobalScale, - ImGui.GetFrameHeight() - 1) , true)) + if (ImGui.BeginChild("##selector", new Vector2(SelectorWidth * ImGui.GetIO().FontGlobalScale, -ImGui.GetFrameHeight() - 1), true)) { - DrawFolderContent(_designs.FileSystem.Root, SortMode.FoldersFirst); + DrawFolderContent(_designs.FileSystem.Root, Glamourer.Config.FoldersFirst ? SortMode.FoldersFirst : SortMode.Lexicographical); ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero); ImGui.EndChild(); ImGui.PopStyleVar(); } + DrawDesignSelectorButtons(); ImGui.EndGroup(); } @@ -138,10 +139,10 @@ namespace Glamourer.Gui private void DrawDesignSelectorButtons() { using var raii = new ImGuiRaii() - .PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero) + .PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero) .PushStyle(ImGuiStyleVar.FrameRounding, 0f); - DrawNewFolderButton(); + DrawNewFolderButton(); ImGui.SameLine(); DrawNewDesignButton(); ImGui.SameLine(); @@ -206,7 +207,7 @@ namespace Glamourer.Gui private void DrawSaves() { using var raii = new ImGuiRaii(); - raii.PushStyle(ImGuiStyleVar.IndentSpacing, 25f); + raii.PushStyle(ImGuiStyleVar.IndentSpacing, 12.5f * ImGui.GetIO().FontGlobalScale); if (!raii.Begin(() => ImGui.BeginTabItem("Saves"), ImGui.EndTabItem)) return; @@ -300,6 +301,26 @@ namespace Glamourer.Gui } } + private static uint GetDesignColor(CharacterSave save) + { + const uint white = 0xFFFFFFFF; + const uint grey = 0xFF808080; + if (!Glamourer.Config.ColorDesigns) + return white; + + var changesStates = save.SetHatState || save.SetVisorState || save.SetWeaponState || save.IsWet || save.Alpha != 1.0f; + if (save.WriteCustomizations) + if (save.WriteEquipment != ActorEquipMask.None) + return white; + else + return changesStates ? white : Glamourer.Config.CustomizationColor; + + if (save.WriteEquipment != ActorEquipMask.None) + return changesStates ? white : Glamourer.Config.EquipmentColor; + + return changesStates ? Glamourer.Config.StateColor : grey; + } + private void DrawFolderContent(Folder folder, SortMode mode) { foreach (var child in folder.AllChildren(mode).ToArray()) @@ -321,13 +342,28 @@ namespace Glamourer.Gui } else { + if (child is not Design d) + continue; + ++_totalObject; + var color = GetDesignColor(d.Data); + using var raii = new ImGuiRaii() + .PushColor(ImGuiCol.Text, color); + var selected = ImGui.Selectable($"{child.Name}##{_totalObject}", ReferenceEquals(child, _selection)); + raii.PopColors(); DrawOrnaments(child); + if (Glamourer.Config.ShowLocks && d.Data.WriteProtected) + { + ImGui.SameLine(); + raii.PushFont(UiBuilder.IconFont) + .PushColor(ImGuiCol.Text, color); + ImGui.Text(FontAwesomeIcon.Lock.ToIconString()); + } + if (selected) - if (child is Design d) - _selection = d; + _selection = d; } } } diff --git a/Glamourer/Gui/InterfaceHelpers.cs b/Glamourer/Gui/InterfaceHelpers.cs index a7e2036..84c0c5f 100644 --- a/Glamourer/Gui/InterfaceHelpers.cs +++ b/Glamourer/Gui/InterfaceHelpers.cs @@ -29,7 +29,7 @@ namespace Glamourer.Gui // Go through a whole customization struct and fix up all settings that need fixing. private static void FixUpAttributes(ref ActorCustomization customization) { - var set = GlamourerPlugin.Customization.GetList(customization.Clan, customization.Gender); + var set = Glamourer.Customization.GetList(customization.Clan, customization.Gender); foreach (CustomizationId id in Enum.GetValues(typeof(CustomizationId))) { switch (id) @@ -95,43 +95,43 @@ namespace Glamourer.Gui if (gender == Gender.Female) return race switch { - SubRace.Midlander => GlamourerPlugin.Customization.GetName(CustomName.MidlanderM), - SubRace.Highlander => GlamourerPlugin.Customization.GetName(CustomName.HighlanderM), - SubRace.Wildwood => GlamourerPlugin.Customization.GetName(CustomName.WildwoodM), - SubRace.Duskwight => GlamourerPlugin.Customization.GetName(CustomName.DuskwightM), - SubRace.Plainsfolk => GlamourerPlugin.Customization.GetName(CustomName.PlainsfolkM), - SubRace.Dunesfolk => GlamourerPlugin.Customization.GetName(CustomName.DunesfolkM), - SubRace.SeekerOfTheSun => GlamourerPlugin.Customization.GetName(CustomName.SeekerOfTheSunM), - SubRace.KeeperOfTheMoon => GlamourerPlugin.Customization.GetName(CustomName.KeeperOfTheMoonM), - SubRace.Seawolf => GlamourerPlugin.Customization.GetName(CustomName.SeawolfM), - SubRace.Hellsguard => GlamourerPlugin.Customization.GetName(CustomName.HellsguardM), - SubRace.Raen => GlamourerPlugin.Customization.GetName(CustomName.RaenM), - SubRace.Xaela => GlamourerPlugin.Customization.GetName(CustomName.XaelaM), - SubRace.Helion => GlamourerPlugin.Customization.GetName(CustomName.HelionM), - SubRace.Lost => GlamourerPlugin.Customization.GetName(CustomName.LostM), - SubRace.Rava => GlamourerPlugin.Customization.GetName(CustomName.RavaF), - SubRace.Veena => GlamourerPlugin.Customization.GetName(CustomName.VeenaF), + SubRace.Midlander => Glamourer.Customization.GetName(CustomName.MidlanderM), + SubRace.Highlander => Glamourer.Customization.GetName(CustomName.HighlanderM), + SubRace.Wildwood => Glamourer.Customization.GetName(CustomName.WildwoodM), + SubRace.Duskwight => Glamourer.Customization.GetName(CustomName.DuskwightM), + SubRace.Plainsfolk => Glamourer.Customization.GetName(CustomName.PlainsfolkM), + SubRace.Dunesfolk => Glamourer.Customization.GetName(CustomName.DunesfolkM), + SubRace.SeekerOfTheSun => Glamourer.Customization.GetName(CustomName.SeekerOfTheSunM), + SubRace.KeeperOfTheMoon => Glamourer.Customization.GetName(CustomName.KeeperOfTheMoonM), + SubRace.Seawolf => Glamourer.Customization.GetName(CustomName.SeawolfM), + SubRace.Hellsguard => Glamourer.Customization.GetName(CustomName.HellsguardM), + SubRace.Raen => Glamourer.Customization.GetName(CustomName.RaenM), + SubRace.Xaela => Glamourer.Customization.GetName(CustomName.XaelaM), + SubRace.Helion => Glamourer.Customization.GetName(CustomName.HelionM), + SubRace.Lost => Glamourer.Customization.GetName(CustomName.LostM), + SubRace.Rava => Glamourer.Customization.GetName(CustomName.RavaF), + SubRace.Veena => Glamourer.Customization.GetName(CustomName.VeenaF), _ => throw new ArgumentOutOfRangeException(nameof(race), race, null), }; return race switch { - SubRace.Midlander => GlamourerPlugin.Customization.GetName(CustomName.MidlanderF), - SubRace.Highlander => GlamourerPlugin.Customization.GetName(CustomName.HighlanderF), - SubRace.Wildwood => GlamourerPlugin.Customization.GetName(CustomName.WildwoodF), - SubRace.Duskwight => GlamourerPlugin.Customization.GetName(CustomName.DuskwightF), - SubRace.Plainsfolk => GlamourerPlugin.Customization.GetName(CustomName.PlainsfolkF), - SubRace.Dunesfolk => GlamourerPlugin.Customization.GetName(CustomName.DunesfolkF), - SubRace.SeekerOfTheSun => GlamourerPlugin.Customization.GetName(CustomName.SeekerOfTheSunF), - SubRace.KeeperOfTheMoon => GlamourerPlugin.Customization.GetName(CustomName.KeeperOfTheMoonF), - SubRace.Seawolf => GlamourerPlugin.Customization.GetName(CustomName.SeawolfF), - SubRace.Hellsguard => GlamourerPlugin.Customization.GetName(CustomName.HellsguardF), - SubRace.Raen => GlamourerPlugin.Customization.GetName(CustomName.RaenF), - SubRace.Xaela => GlamourerPlugin.Customization.GetName(CustomName.XaelaF), - SubRace.Helion => GlamourerPlugin.Customization.GetName(CustomName.HelionM), - SubRace.Lost => GlamourerPlugin.Customization.GetName(CustomName.LostM), - SubRace.Rava => GlamourerPlugin.Customization.GetName(CustomName.RavaF), - SubRace.Veena => GlamourerPlugin.Customization.GetName(CustomName.VeenaF), + SubRace.Midlander => Glamourer.Customization.GetName(CustomName.MidlanderF), + SubRace.Highlander => Glamourer.Customization.GetName(CustomName.HighlanderF), + SubRace.Wildwood => Glamourer.Customization.GetName(CustomName.WildwoodF), + SubRace.Duskwight => Glamourer.Customization.GetName(CustomName.DuskwightF), + SubRace.Plainsfolk => Glamourer.Customization.GetName(CustomName.PlainsfolkF), + SubRace.Dunesfolk => Glamourer.Customization.GetName(CustomName.DunesfolkF), + SubRace.SeekerOfTheSun => Glamourer.Customization.GetName(CustomName.SeekerOfTheSunF), + SubRace.KeeperOfTheMoon => Glamourer.Customization.GetName(CustomName.KeeperOfTheMoonF), + SubRace.Seawolf => Glamourer.Customization.GetName(CustomName.SeawolfF), + SubRace.Hellsguard => Glamourer.Customization.GetName(CustomName.HellsguardF), + SubRace.Raen => Glamourer.Customization.GetName(CustomName.RaenF), + SubRace.Xaela => Glamourer.Customization.GetName(CustomName.XaelaF), + SubRace.Helion => Glamourer.Customization.GetName(CustomName.HelionM), + SubRace.Lost => Glamourer.Customization.GetName(CustomName.LostM), + SubRace.Rava => Glamourer.Customization.GetName(CustomName.RavaF), + SubRace.Veena => Glamourer.Customization.GetName(CustomName.VeenaF), _ => throw new ArgumentOutOfRangeException(nameof(race), race, null), }; } @@ -155,7 +155,7 @@ namespace Glamourer.Gui switch (use) { case DesignNameUse.SaveCurrent: - SaveNewDesign(_currentSave); + SaveNewDesign(_currentSave.Copy()); break; case DesignNameUse.NewDesign: var empty = new CharacterSave(); @@ -167,7 +167,8 @@ namespace Glamourer.Gui SaveNewDesign(_selection!.Data.Copy()); break; case DesignNameUse.NewFolder: - _designs.FileSystem.CreateAllFolders($"{_newDesignName}/a"); // Filename is just ignored, but all folders are created. + _designs.FileSystem + .CreateAllFolders($"{_newDesignName}/a"); // Filename is just ignored, but all folders are created. break; case DesignNameUse.FromClipboard: try diff --git a/Glamourer/Gui/InterfaceInitialization.cs b/Glamourer/Gui/InterfaceInitialization.cs index c393ac3..4c279a6 100644 --- a/Glamourer/Gui/InterfaceInitialization.cs +++ b/Glamourer/Gui/InterfaceInitialization.cs @@ -53,7 +53,7 @@ namespace Glamourer.Gui { var rawImage = new byte[resource.Length]; resource.Read(rawImage, 0, (int) resource.Length); - return GlamourerPlugin.PluginInterface.UiBuilder.LoadImageRaw(rawImage, 192, 192, 4); + return Glamourer.PluginInterface.UiBuilder.LoadImageRaw(rawImage, 192, 192, 4); } return null; @@ -61,7 +61,7 @@ namespace Glamourer.Gui private static Dictionary GetEquipSlotNames() { - var sheet = GlamourerPlugin.PluginInterface.Data.GetExcelSheet(); + var sheet = Glamourer.PluginInterface.Data.GetExcelSheet(); var ret = new Dictionary(12) { [EquipSlot.MainHand] = sheet.GetRow(738)?.Text.ToString() ?? "Main Hand", diff --git a/Glamourer/Gui/InterfaceMiscellaneous.cs b/Glamourer/Gui/InterfaceMiscellaneous.cs index b14850d..f2ba9f6 100644 --- a/Glamourer/Gui/InterfaceMiscellaneous.cs +++ b/Glamourer/Gui/InterfaceMiscellaneous.cs @@ -51,9 +51,9 @@ namespace Glamourer.Gui var alpha = save.Alpha; if (ImGui.DragFloat("Alpha", ref alpha, 0.01f, 0f, 1f, "%.2f") && alpha != save.Alpha) { - alpha = (float) Math.Round(alpha > 1 ? 1 : alpha < 0 ? 0 : alpha, 2); - save.Alpha = alpha; - ret = true; + alpha = (float) Math.Round(alpha > 1 ? 1 : alpha < 0 ? 0 : alpha, 2); + save.Alpha = alpha; + ret = true; if (player != null) player.Alpha() = alpha; } diff --git a/Glamourer/Main.cs b/Glamourer/Main.cs index 3a6b063..8281164 100644 --- a/Glamourer/Main.cs +++ b/Glamourer/Main.cs @@ -11,13 +11,12 @@ using Glamourer.Designs; using Glamourer.FileSystem; using Glamourer.Gui; using ImGuiNET; -using Lumina.Data; using Penumbra.Api; using Penumbra.PlayerWatch; namespace Glamourer { - public class GlamourerPlugin : IDalamudPlugin + public class Glamourer : IDalamudPlugin { public const int RequiredPenumbraShareVersion = 1; @@ -27,6 +26,7 @@ namespace Glamourer => "Glamourer"; public static DalamudPluginInterface PluginInterface = null!; + public static GlamourerConfig Config = null!; private Interface _interface = null!; public static ICustomizationManager Customization = null!; public DesignManager Designs = null!; @@ -48,7 +48,7 @@ namespace Glamourer _dalamud = dalamud ?? throw new Exception("Could not obtain Dalamud."); } - private void PenumbraTooltip(object? it) + private static void PenumbraTooltip(object? it) { if (it is Lumina.Excel.GeneratedSheets.Item) ImGui.Text("Right click to apply to current Glamourer Set. [Glamourer]"); @@ -139,6 +139,7 @@ namespace Glamourer { Version = Assembly.GetExecutingAssembly()?.GetName().Version.ToString() ?? ""; PluginInterface = pluginInterface; + Config = GlamourerConfig.Create(); Customization = CustomizationManager.Create(PluginInterface); SetDalamud(PluginInterface); SetPlugins(PluginInterface);