From 987c26a51d619700cfc3ddc0b0ff276c8291b3aa Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Fri, 22 Dec 2023 14:20:50 +0100 Subject: [PATCH] Remove GameData, move a bunch of customization data to Penumbra.GameData and the rest to Glamourer, update accordingly. Some reformatting and cleanup. --- Glamourer.GameData/Customization/CmpFile.cs | 46 ----- Glamourer.GameData/Customization/Customize.cs | 124 ------------ .../Customization/CustomizeFlag.cs | 114 ----------- .../Customization/CustomizeIndex.cs | 183 ------------------ .../Customization/CustomizeValue.cs | 34 ---- .../Customization/DatCharacterFile.cs | 149 -------------- Glamourer.GameData/GameData.cs | 88 --------- .../Glamourer - Backup.GameData.csproj | 61 ------ Glamourer.GameData/Glamourer.GameData.csproj | 72 ------- Glamourer.GameData/Offsets.cs | 7 - Glamourer.GameData/Structs/CrestFlag.cs | 102 ---------- Glamourer.GameData/Structs/EquipFlag.cs | 93 --------- Glamourer.GameData/Structs/Job.cs | 29 --- Glamourer.GameData/Structs/JobGroup.cs | 61 ------ Glamourer.sln | 6 - .../Api/GlamourerIpc.GetCustomization.cs | 6 +- Glamourer/Automation/AutoDesign.cs | 6 +- Glamourer/Automation/AutoDesignApplier.cs | 4 +- Glamourer/Automation/AutoDesignManager.cs | 3 +- Glamourer/Automation/FixedDesignMigrator.cs | 26 +-- Glamourer/Designs/DesignBase.cs | 9 +- Glamourer/Designs/DesignBase64Migration.cs | 12 +- Glamourer/Designs/DesignConverter.cs | 4 +- Glamourer/Designs/DesignData.cs | 56 +++--- Glamourer/Designs/DesignManager.cs | 10 +- .../GameData}/CharaMakeParams.cs | 8 +- Glamourer/GameData/ColorParameters.cs | 50 +++++ .../GameData}/CustomName.cs | 4 +- .../GameData}/CustomizationManager.cs | 2 +- .../GameData}/CustomizationNpcOptions.cs | 6 +- .../GameData}/CustomizationOptions.cs | 56 +++--- .../GameData}/CustomizationSet.cs | 10 +- .../GameData}/CustomizeData.cs | 4 +- .../GameData}/ICustomizationManager.cs | 2 +- .../GameData}/NpcCustomizeSet.cs | 120 ++++++------ .../GameData}/NpcData.cs | 4 +- Glamourer/Glamourer.csproj | 5 +- .../CustomizationDrawer.Color.cs | 12 +- .../CustomizationDrawer.GenderRace.cs | 2 +- .../Customization/CustomizationDrawer.Icon.cs | 20 +- .../CustomizationDrawer.Simple.cs | 8 +- .../Gui/Customization/CustomizationDrawer.cs | 29 ++- Glamourer/Gui/DesignCombo.cs | 3 +- Glamourer/Gui/PenumbraChangedItemTooltip.cs | 5 +- Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs | 28 ++- Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs | 95 ++++----- .../Gui/Tabs/DebugTab/ActiveStatePanel.cs | 2 +- .../DebugTab/CustomizationServicePanel.cs | 3 +- .../Tabs/DebugTab/CustomizationUnlockPanel.cs | 2 +- Glamourer/Gui/Tabs/DebugTab/DatFilePanel.cs | 5 +- .../Gui/Tabs/DebugTab/DesignManagerPanel.cs | 2 - .../Gui/Tabs/DebugTab/DesignTesterPanel.cs | 8 +- Glamourer/Gui/Tabs/DebugTab/JobPanel.cs | 4 +- .../Gui/Tabs/DebugTab/ModelEvaluationPanel.cs | 30 ++- .../Gui/Tabs/DebugTab/NpcAppearancePanel.cs | 17 +- Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs | 2 - Glamourer/Gui/Tabs/NpcCombo.cs | 2 +- .../Gui/Tabs/UnlocksTab/UnlockOverview.cs | 2 +- Glamourer/Gui/Tabs/UnlocksTab/UnlockTable.cs | 1 - Glamourer/Gui/ToggleDrawData.cs | 1 - Glamourer/Gui/UiHelpers.cs | 4 +- Glamourer/Interop/ChangeCustomizeService.cs | 8 +- Glamourer/Interop/CharaFile/CharaFile.cs | 16 +- Glamourer/Interop/CharaFile/CmaFile.cs | 4 +- Glamourer/Interop/CrestService.cs | 2 - Glamourer/Interop/ImportService.cs | 9 +- Glamourer/Interop/JobService.cs | 19 +- Glamourer/Interop/Structs/Actor.cs | 6 +- Glamourer/Interop/Structs/Model.cs | 5 +- Glamourer/Interop/UpdateSlotService.cs | 1 + Glamourer/Interop/WeaponService.cs | 10 +- Glamourer/Services/CommandService.cs | 2 - Glamourer/Services/CustomizationService.cs | 14 +- Glamourer/Services/ServiceManager.cs | 2 +- Glamourer/State/ActorState.cs | 8 +- Glamourer/State/FunModule.cs | 13 +- Glamourer/State/StateApplier.cs | 14 +- Glamourer/State/StateEditor.cs | 10 +- Glamourer/State/StateListener.cs | 14 +- Glamourer/State/StateManager.cs | 36 ++-- Glamourer/State/WorldSets.cs | 1 - Glamourer/Unlocks/CustomizeUnlockManager.cs | 5 +- Penumbra.GameData | 2 +- 83 files changed, 444 insertions(+), 1620 deletions(-) delete mode 100644 Glamourer.GameData/Customization/CmpFile.cs delete mode 100644 Glamourer.GameData/Customization/Customize.cs delete mode 100644 Glamourer.GameData/Customization/CustomizeFlag.cs delete mode 100644 Glamourer.GameData/Customization/CustomizeIndex.cs delete mode 100644 Glamourer.GameData/Customization/CustomizeValue.cs delete mode 100644 Glamourer.GameData/Customization/DatCharacterFile.cs delete mode 100644 Glamourer.GameData/GameData.cs delete mode 100644 Glamourer.GameData/Glamourer - Backup.GameData.csproj delete mode 100644 Glamourer.GameData/Glamourer.GameData.csproj delete mode 100644 Glamourer.GameData/Offsets.cs delete mode 100644 Glamourer.GameData/Structs/CrestFlag.cs delete mode 100644 Glamourer.GameData/Structs/EquipFlag.cs delete mode 100644 Glamourer.GameData/Structs/Job.cs delete mode 100644 Glamourer.GameData/Structs/JobGroup.cs rename {Glamourer.GameData/Customization => Glamourer/GameData}/CharaMakeParams.cs (94%) create mode 100644 Glamourer/GameData/ColorParameters.cs rename {Glamourer.GameData/Customization => Glamourer/GameData}/CustomName.cs (78%) rename {Glamourer.GameData/Customization => Glamourer/GameData}/CustomizationManager.cs (93%) rename {Glamourer.GameData/Customization => Glamourer/GameData}/CustomizationNpcOptions.cs (92%) rename {Glamourer.GameData/Customization => Glamourer/GameData}/CustomizationOptions.cs (94%) rename {Glamourer.GameData/Customization => Glamourer/GameData}/CustomizationSet.cs (95%) rename {Glamourer.GameData/Customization => Glamourer/GameData}/CustomizeData.cs (89%) rename {Glamourer.GameData/Customization => Glamourer/GameData}/ICustomizationManager.cs (90%) rename {Glamourer.GameData/Customization => Glamourer/GameData}/NpcCustomizeSet.cs (63%) rename {Glamourer.GameData/Customization => Glamourer/GameData}/NpcData.cs (93%) diff --git a/Glamourer.GameData/Customization/CmpFile.cs b/Glamourer.GameData/Customization/CmpFile.cs deleted file mode 100644 index d62e5da..0000000 --- a/Glamourer.GameData/Customization/CmpFile.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Dalamud.Logging; -using Dalamud.Plugin.Services; - -namespace Glamourer.Customization; - -// Convert the Human.Cmp file into color sets. -// If the file can not be read due to TexTools corruption, create a 0-array of size MinSize. -internal class CmpFile -{ - private readonly Lumina.Data.FileResource? _file; - private readonly uint[] _rgbaColors; - - // No error checking since only called internally. - public IEnumerable GetSlice(int offset, int count) - => _rgbaColors.Length >= offset + count ? _rgbaColors.Skip(offset).Take(count) : Enumerable.Repeat(0u, count); - - public bool Valid - => _file != null; - - public CmpFile(IDataManager gameData, IPluginLog log) - { - try - { - _file = gameData.GetFile("chara/xls/charamake/human.cmp")!; - _rgbaColors = new uint[_file.Data.Length >> 2]; - for (var i = 0; i < _file.Data.Length; i += 4) - { - _rgbaColors[i >> 2] = _file.Data[i] - | (uint)(_file.Data[i + 1] << 8) - | (uint)(_file.Data[i + 2] << 16) - | (uint)(_file.Data[i + 3] << 24); - } - } - catch (Exception e) - { - log.Error("READ THIS\n======== Could not obtain the human.cmp file which is necessary for color sets.\n" - + "======== This usually indicates an error with your index files caused by TexTools modifications.\n" - + "======== If you have used TexTools before, you will probably need to start over in it to use Glamourer.", e); - _file = null; - _rgbaColors = Array.Empty(); - } - } -} diff --git a/Glamourer.GameData/Customization/Customize.cs b/Glamourer.GameData/Customization/Customize.cs deleted file mode 100644 index b19ef22..0000000 --- a/Glamourer.GameData/Customization/Customize.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System; -using Penumbra.GameData.Enums; -using Penumbra.GameData.Structs; - -namespace Glamourer.Customization; - -public unsafe struct Customize -{ - public CustomizeArray Data; - - public Customize(in CustomizeArray data) - { - Data = data.Clone(); - } - - public Race Race - { - get => (Race)Data.Get(CustomizeIndex.Race).Value; - set => Data.Set(CustomizeIndex.Race, (CustomizeValue)(byte)value); - } - - public Gender Gender - { - get => (Gender)Data.Get(CustomizeIndex.Gender).Value + 1; - set => Data.Set(CustomizeIndex.Gender, (CustomizeValue)(byte)value - 1); - } - - public CustomizeValue BodyType - { - get => Data.Get(CustomizeIndex.BodyType); - set => Data.Set(CustomizeIndex.BodyType, value); - } - - public SubRace Clan - { - get => (SubRace)Data.Get(CustomizeIndex.Clan).Value; - set => Data.Set(CustomizeIndex.Clan, (CustomizeValue)(byte)value); - } - - public CustomizeValue Face - { - get => Data.Get(CustomizeIndex.Face); - set => Data.Set(CustomizeIndex.Face, value); - } - - - public static readonly Customize Default = GenerateDefault(); - public static readonly Customize Empty = new(); - - public CustomizeValue Get(CustomizeIndex index) - => Data.Get(index); - - public bool Set(CustomizeIndex flag, CustomizeValue index) - => Data.Set(flag, index); - - public bool Equals(Customize other) - => Equals(Data, other.Data); - - public CustomizeValue this[CustomizeIndex index] - { - get => Get(index); - set => Set(index, value); - } - - private static Customize GenerateDefault() - { - var ret = new Customize - { - Race = Race.Hyur, - Clan = SubRace.Midlander, - Gender = Gender.Male, - }; - ret.Set(CustomizeIndex.BodyType, (CustomizeValue)1); - ret.Set(CustomizeIndex.Height, (CustomizeValue)50); - ret.Set(CustomizeIndex.Face, (CustomizeValue)1); - ret.Set(CustomizeIndex.Hairstyle, (CustomizeValue)1); - ret.Set(CustomizeIndex.SkinColor, (CustomizeValue)1); - ret.Set(CustomizeIndex.EyeColorRight, (CustomizeValue)1); - ret.Set(CustomizeIndex.HighlightsColor, (CustomizeValue)1); - ret.Set(CustomizeIndex.TattooColor, (CustomizeValue)1); - ret.Set(CustomizeIndex.Eyebrows, (CustomizeValue)1); - ret.Set(CustomizeIndex.EyeColorLeft, (CustomizeValue)1); - ret.Set(CustomizeIndex.EyeShape, (CustomizeValue)1); - ret.Set(CustomizeIndex.Nose, (CustomizeValue)1); - ret.Set(CustomizeIndex.Jaw, (CustomizeValue)1); - ret.Set(CustomizeIndex.Mouth, (CustomizeValue)1); - ret.Set(CustomizeIndex.LipColor, (CustomizeValue)1); - ret.Set(CustomizeIndex.MuscleMass, (CustomizeValue)50); - ret.Set(CustomizeIndex.TailShape, (CustomizeValue)1); - ret.Set(CustomizeIndex.BustSize, (CustomizeValue)50); - ret.Set(CustomizeIndex.FacePaint, (CustomizeValue)1); - ret.Set(CustomizeIndex.FacePaintColor, (CustomizeValue)1); - return ret; - } - - public void Load(Customize other) - => Data.Read(&other.Data); - - public readonly void Write(nint target) - => Data.Write((void*)target); - - public bool LoadBase64(string data) - => Data.LoadBase64(data); - - public readonly string WriteBase64() - => Data.WriteBase64(); - - public static CustomizeFlag Compare(Customize lhs, Customize rhs) - { - CustomizeFlag ret = 0; - foreach (var idx in Enum.GetValues()) - { - var l = lhs[idx]; - var r = rhs[idx]; - if (l.Value != r.Value) - ret |= idx.ToFlag(); - } - - return ret; - } - - public override string ToString() - => Data.ToString(); -} diff --git a/Glamourer.GameData/Customization/CustomizeFlag.cs b/Glamourer.GameData/Customization/CustomizeFlag.cs deleted file mode 100644 index 44b6cee..0000000 --- a/Glamourer.GameData/Customization/CustomizeFlag.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System; -using System.Runtime.CompilerServices; - -namespace Glamourer.Customization; - -[Flags] -public enum CustomizeFlag : ulong -{ - Invalid = 0, - Race = 1ul << CustomizeIndex.Race, - Gender = 1ul << CustomizeIndex.Gender, - BodyType = 1ul << CustomizeIndex.BodyType, - Height = 1ul << CustomizeIndex.Height, - Clan = 1ul << CustomizeIndex.Clan, - Face = 1ul << CustomizeIndex.Face, - Hairstyle = 1ul << CustomizeIndex.Hairstyle, - Highlights = 1ul << CustomizeIndex.Highlights, - SkinColor = 1ul << CustomizeIndex.SkinColor, - EyeColorRight = 1ul << CustomizeIndex.EyeColorRight, - HairColor = 1ul << CustomizeIndex.HairColor, - HighlightsColor = 1ul << CustomizeIndex.HighlightsColor, - FacialFeature1 = 1ul << CustomizeIndex.FacialFeature1, - FacialFeature2 = 1ul << CustomizeIndex.FacialFeature2, - FacialFeature3 = 1ul << CustomizeIndex.FacialFeature3, - FacialFeature4 = 1ul << CustomizeIndex.FacialFeature4, - FacialFeature5 = 1ul << CustomizeIndex.FacialFeature5, - FacialFeature6 = 1ul << CustomizeIndex.FacialFeature6, - FacialFeature7 = 1ul << CustomizeIndex.FacialFeature7, - LegacyTattoo = 1ul << CustomizeIndex.LegacyTattoo, - TattooColor = 1ul << CustomizeIndex.TattooColor, - Eyebrows = 1ul << CustomizeIndex.Eyebrows, - EyeColorLeft = 1ul << CustomizeIndex.EyeColorLeft, - EyeShape = 1ul << CustomizeIndex.EyeShape, - SmallIris = 1ul << CustomizeIndex.SmallIris, - Nose = 1ul << CustomizeIndex.Nose, - Jaw = 1ul << CustomizeIndex.Jaw, - Mouth = 1ul << CustomizeIndex.Mouth, - Lipstick = 1ul << CustomizeIndex.Lipstick, - LipColor = 1ul << CustomizeIndex.LipColor, - MuscleMass = 1ul << CustomizeIndex.MuscleMass, - TailShape = 1ul << CustomizeIndex.TailShape, - BustSize = 1ul << CustomizeIndex.BustSize, - FacePaint = 1ul << CustomizeIndex.FacePaint, - FacePaintReversed = 1ul << CustomizeIndex.FacePaintReversed, - FacePaintColor = 1ul << CustomizeIndex.FacePaintColor, -} - -public static class CustomizeFlagExtensions -{ - public const CustomizeFlag All = (CustomizeFlag)(((ulong)CustomizeFlag.FacePaintColor << 1) - 1ul); - public const CustomizeFlag AllRelevant = All & ~CustomizeFlag.BodyType & ~CustomizeFlag.Race; - - public const CustomizeFlag RedrawRequired = - CustomizeFlag.Race | CustomizeFlag.Clan | CustomizeFlag.Gender | CustomizeFlag.Face | CustomizeFlag.BodyType; - - public static CustomizeFlag FixApplication(this CustomizeFlag flag, CustomizationSet set) - => flag & (set.SettingAvailable | CustomizeFlag.Clan | CustomizeFlag.Gender); - - public static bool RequiresRedraw(this CustomizeFlag flags) - => (flags & RedrawRequired) != 0; - - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static CustomizeIndex ToIndex(this CustomizeFlag flag) - => flag switch - { - CustomizeFlag.Race => CustomizeIndex.Race, - CustomizeFlag.Gender => CustomizeIndex.Gender, - CustomizeFlag.BodyType => CustomizeIndex.BodyType, - CustomizeFlag.Height => CustomizeIndex.Height, - CustomizeFlag.Clan => CustomizeIndex.Clan, - CustomizeFlag.Face => CustomizeIndex.Face, - CustomizeFlag.Hairstyle => CustomizeIndex.Hairstyle, - CustomizeFlag.Highlights => CustomizeIndex.Highlights, - CustomizeFlag.SkinColor => CustomizeIndex.SkinColor, - CustomizeFlag.EyeColorRight => CustomizeIndex.EyeColorRight, - CustomizeFlag.HairColor => CustomizeIndex.HairColor, - CustomizeFlag.HighlightsColor => CustomizeIndex.HighlightsColor, - CustomizeFlag.FacialFeature1 => CustomizeIndex.FacialFeature1, - CustomizeFlag.FacialFeature2 => CustomizeIndex.FacialFeature2, - CustomizeFlag.FacialFeature3 => CustomizeIndex.FacialFeature3, - CustomizeFlag.FacialFeature4 => CustomizeIndex.FacialFeature4, - CustomizeFlag.FacialFeature5 => CustomizeIndex.FacialFeature5, - CustomizeFlag.FacialFeature6 => CustomizeIndex.FacialFeature6, - CustomizeFlag.FacialFeature7 => CustomizeIndex.FacialFeature7, - CustomizeFlag.LegacyTattoo => CustomizeIndex.LegacyTattoo, - CustomizeFlag.TattooColor => CustomizeIndex.TattooColor, - CustomizeFlag.Eyebrows => CustomizeIndex.Eyebrows, - CustomizeFlag.EyeColorLeft => CustomizeIndex.EyeColorLeft, - CustomizeFlag.EyeShape => CustomizeIndex.EyeShape, - CustomizeFlag.SmallIris => CustomizeIndex.SmallIris, - CustomizeFlag.Nose => CustomizeIndex.Nose, - CustomizeFlag.Jaw => CustomizeIndex.Jaw, - CustomizeFlag.Mouth => CustomizeIndex.Mouth, - CustomizeFlag.Lipstick => CustomizeIndex.Lipstick, - CustomizeFlag.LipColor => CustomizeIndex.LipColor, - CustomizeFlag.MuscleMass => CustomizeIndex.MuscleMass, - CustomizeFlag.TailShape => CustomizeIndex.TailShape, - CustomizeFlag.BustSize => CustomizeIndex.BustSize, - CustomizeFlag.FacePaint => CustomizeIndex.FacePaint, - CustomizeFlag.FacePaintReversed => CustomizeIndex.FacePaintReversed, - CustomizeFlag.FacePaintColor => CustomizeIndex.FacePaintColor, - _ => (CustomizeIndex)byte.MaxValue, - }; - - public static bool SetIfDifferent(ref this CustomizeFlag flags, CustomizeFlag flag, bool value) - { - var newValue = value ? flags | flag : flags & ~flag; - if (newValue == flags) - return false; - - flags = newValue; - return true; - } -} diff --git a/Glamourer.GameData/Customization/CustomizeIndex.cs b/Glamourer.GameData/Customization/CustomizeIndex.cs deleted file mode 100644 index cbd22ed..0000000 --- a/Glamourer.GameData/Customization/CustomizeIndex.cs +++ /dev/null @@ -1,183 +0,0 @@ -using System; -using System.Linq; -using System.Runtime.CompilerServices; - -namespace Glamourer.Customization; - -public enum CustomizeIndex : byte -{ - Race, - Gender, - BodyType, - Height, - Clan, - Face, - Hairstyle, - Highlights, - SkinColor, - EyeColorRight, - HairColor, - HighlightsColor, - FacialFeature1, - FacialFeature2, - FacialFeature3, - FacialFeature4, - FacialFeature5, - FacialFeature6, - FacialFeature7, - LegacyTattoo, - TattooColor, - Eyebrows, - EyeColorLeft, - EyeShape, - SmallIris, - Nose, - Jaw, - Mouth, - Lipstick, - LipColor, - MuscleMass, - TailShape, - BustSize, - FacePaint, - FacePaintReversed, - FacePaintColor, -} - -public static class CustomizationExtensions -{ - public const int NumIndices = (int)CustomizeIndex.FacePaintColor + 1; - - public static readonly CustomizeIndex[] All = Enum.GetValues() - .Where(v => v is not CustomizeIndex.Race and not CustomizeIndex.BodyType).ToArray(); - - public static readonly CustomizeIndex[] AllBasic = All - .Where(v => v is not CustomizeIndex.Gender and not CustomizeIndex.Clan).ToArray(); - - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static (int ByteIdx, byte Mask) ToByteAndMask(this CustomizeIndex index) - => index switch - { - CustomizeIndex.Race => (0, 0xFF), - CustomizeIndex.Gender => (1, 0xFF), - CustomizeIndex.BodyType => (2, 0xFF), - CustomizeIndex.Height => (3, 0xFF), - CustomizeIndex.Clan => (4, 0xFF), - CustomizeIndex.Face => (5, 0xFF), - CustomizeIndex.Hairstyle => (6, 0xFF), - CustomizeIndex.Highlights => (7, 0x80), - CustomizeIndex.SkinColor => (8, 0xFF), - CustomizeIndex.EyeColorRight => (9, 0xFF), - CustomizeIndex.HairColor => (10, 0xFF), - CustomizeIndex.HighlightsColor => (11, 0xFF), - CustomizeIndex.FacialFeature1 => (12, 0x01), - CustomizeIndex.FacialFeature2 => (12, 0x02), - CustomizeIndex.FacialFeature3 => (12, 0x04), - CustomizeIndex.FacialFeature4 => (12, 0x08), - CustomizeIndex.FacialFeature5 => (12, 0x10), - CustomizeIndex.FacialFeature6 => (12, 0x20), - CustomizeIndex.FacialFeature7 => (12, 0x40), - CustomizeIndex.LegacyTattoo => (12, 0x80), - CustomizeIndex.TattooColor => (13, 0xFF), - CustomizeIndex.Eyebrows => (14, 0xFF), - CustomizeIndex.EyeColorLeft => (15, 0xFF), - CustomizeIndex.EyeShape => (16, 0x7F), - CustomizeIndex.SmallIris => (16, 0x80), - CustomizeIndex.Nose => (17, 0xFF), - CustomizeIndex.Jaw => (18, 0xFF), - CustomizeIndex.Mouth => (19, 0x7F), - CustomizeIndex.Lipstick => (19, 0x80), - CustomizeIndex.LipColor => (20, 0xFF), - CustomizeIndex.MuscleMass => (21, 0xFF), - CustomizeIndex.TailShape => (22, 0xFF), - CustomizeIndex.BustSize => (23, 0xFF), - CustomizeIndex.FacePaint => (24, 0x7F), - CustomizeIndex.FacePaintReversed => (24, 0x80), - CustomizeIndex.FacePaintColor => (25, 0xFF), - _ => (0, 0x00), - }; - - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static CustomizeFlag ToFlag(this CustomizeIndex index) - => (CustomizeFlag)(1ul << (int)index); - - public static string ToDefaultName(this CustomizeIndex customizeIndex) - => customizeIndex switch - { - CustomizeIndex.Race => "Race", - CustomizeIndex.Gender => "Gender", - CustomizeIndex.BodyType => "Body Type", - CustomizeIndex.Height => "Height", - CustomizeIndex.Clan => "Clan", - CustomizeIndex.Face => "Head Style", - CustomizeIndex.Hairstyle => "Hair Style", - CustomizeIndex.Highlights => "Enable Highlights", - CustomizeIndex.SkinColor => "Skin Color", - CustomizeIndex.EyeColorRight => "Left Eye", // inverted due to compatibility fuckup. - CustomizeIndex.HairColor => "Hair Color", - CustomizeIndex.HighlightsColor => "Highlights Color", - CustomizeIndex.TattooColor => "Tattoo Color", - CustomizeIndex.Eyebrows => "Eyebrow Style", - CustomizeIndex.EyeColorLeft => "Right Eye", // inverted due to compatibility fuckup. - CustomizeIndex.EyeShape => "Small Pupils", - CustomizeIndex.Nose => "Nose Style", - CustomizeIndex.Jaw => "Jaw Style", - CustomizeIndex.Mouth => "Mouth Style", - CustomizeIndex.MuscleMass => "Muscle Tone", - CustomizeIndex.TailShape => "Tail Shape", - CustomizeIndex.BustSize => "Bust Size", - CustomizeIndex.FacePaint => "Face Paint", - CustomizeIndex.FacePaintColor => "Face Paint Color", - CustomizeIndex.LipColor => "Lip Color", - CustomizeIndex.FacialFeature1 => "Facial Feature 1", - CustomizeIndex.FacialFeature2 => "Facial Feature 2", - CustomizeIndex.FacialFeature3 => "Facial Feature 3", - CustomizeIndex.FacialFeature4 => "Facial Feature 4", - CustomizeIndex.FacialFeature5 => "Facial Feature 5", - CustomizeIndex.FacialFeature6 => "Facial Feature 6", - CustomizeIndex.FacialFeature7 => "Facial Feature 7", - CustomizeIndex.LegacyTattoo => "Legacy Tattoo", - CustomizeIndex.SmallIris => "Small Iris", - CustomizeIndex.Lipstick => "Enable Lipstick", - CustomizeIndex.FacePaintReversed => "Reverse Face Paint", - _ => string.Empty, - }; - - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static unsafe CustomizeValue Get(this in Penumbra.GameData.Structs.CustomizeArray data, CustomizeIndex index) - { - var (offset, mask) = index.ToByteAndMask(); - return (CustomizeValue)(data.Data[offset] & mask); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static unsafe bool Set(this ref Penumbra.GameData.Structs.CustomizeArray data, CustomizeIndex index, CustomizeValue value) - { - var (offset, mask) = index.ToByteAndMask(); - return mask != 0xFF - ? SetIfDifferentMasked(ref data.Data[offset], value, mask) - : SetIfDifferent(ref data.Data[offset], value); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - private static bool SetIfDifferentMasked(ref byte oldValue, CustomizeValue newValue, byte mask) - { - var tmp = (byte)(newValue.Value & mask); - tmp = (byte)(tmp | (oldValue & ~mask)); - if (oldValue == tmp) - return false; - - oldValue = tmp; - return true; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - private static bool SetIfDifferent(ref byte oldValue, CustomizeValue newValue) - { - if (oldValue == newValue.Value) - return false; - - oldValue = newValue.Value; - return true; - } -} diff --git a/Glamourer.GameData/Customization/CustomizeValue.cs b/Glamourer.GameData/Customization/CustomizeValue.cs deleted file mode 100644 index 25b3406..0000000 --- a/Glamourer.GameData/Customization/CustomizeValue.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace Glamourer.Customization; - -public record struct CustomizeValue(byte Value) -{ - public static readonly CustomizeValue Zero = new(0); - public static readonly CustomizeValue Max = new(0xFF); - - public static CustomizeValue Bool(bool b) - => b ? Max : Zero; - - public static explicit operator CustomizeValue(byte value) - => new(value); - - public static CustomizeValue operator ++(CustomizeValue v) - => new(++v.Value); - - public static CustomizeValue operator --(CustomizeValue v) - => new(--v.Value); - - public static bool operator <(CustomizeValue v, int count) - => v.Value < count; - - public static bool operator >(CustomizeValue v, int count) - => v.Value > count; - - public static CustomizeValue operator +(CustomizeValue v, int rhs) - => new((byte)(v.Value + rhs)); - - public static CustomizeValue operator -(CustomizeValue v, int rhs) - => new((byte)(v.Value - rhs)); - - public override string ToString() - => Value.ToString(); -} diff --git a/Glamourer.GameData/Customization/DatCharacterFile.cs b/Glamourer.GameData/Customization/DatCharacterFile.cs deleted file mode 100644 index f33af69..0000000 --- a/Glamourer.GameData/Customization/DatCharacterFile.cs +++ /dev/null @@ -1,149 +0,0 @@ -using System; -using System.IO; -using System.Runtime.InteropServices; -using System.Text; -using Dalamud.Memory; -using Penumbra.GameData.Structs; - -namespace Glamourer.Customization; - -[StructLayout(LayoutKind.Explicit, Size = Size)] -public unsafe struct DatCharacterFile -{ - public const int Size = 4 + 4 + 4 + 4 + CustomizeArray.Size + 2 + 4 + 41 * 4; // 212 - - [FieldOffset(0)] - private fixed byte _data[Size]; - - [FieldOffset(0)] - public readonly uint Magic = 0x2013FF14; - - [FieldOffset(4)] - public readonly uint Version = 0x05; - - [FieldOffset(8)] - private uint _checksum; - - [FieldOffset(12)] - private readonly uint _padding = 0; - - [FieldOffset(16)] - private CustomizeArray _customize; - - [FieldOffset(16 + CustomizeArray.Size)] - private ushort _voice; - - [FieldOffset(16 + CustomizeArray.Size + 2)] - private uint _timeStamp; - - [FieldOffset(Size - 41 * 4)] - private fixed byte _description[41 * 4]; - - public readonly void Write(Stream stream) - { - for (var i = 0; i < Size; ++i) - stream.WriteByte(_data[i]); - } - - public static bool Read(Stream stream, out DatCharacterFile file) - { - if (stream.Length - stream.Position != Size) - { - file = default; - return false; - } - - file = new DatCharacterFile(stream); - return true; - } - - private DatCharacterFile(Stream stream) - { - for (var i = 0; i < Size; ++i) - _data[i] = (byte)stream.ReadByte(); - } - - public DatCharacterFile(in Customize customize, byte voice, string text) - { - SetCustomize(customize); - SetVoice(voice); - SetTime(DateTimeOffset.UtcNow); - SetDescription(text); - _checksum = CalculateChecksum(); - } - - public readonly uint CalculateChecksum() - { - var ret = 0u; - for (var i = 16; i < Size; i++) - ret ^= (uint)(_data[i] << ((i - 16) % 24)); - return ret; - } - - public readonly uint Checksum - => _checksum; - - public Customize Customize - { - readonly get => new(_customize); - set - { - SetCustomize(value); - _checksum = CalculateChecksum(); - } - } - - public ushort Voice - { - readonly get => _voice; - set - { - SetVoice(value); - _checksum = CalculateChecksum(); - } - } - - public string Description - { - readonly get - { - fixed (byte* ptr = _description) - { - return MemoryHelper.ReadStringNullTerminated((nint)ptr); - } - } - set - { - SetDescription(value); - _checksum = CalculateChecksum(); - } - } - - public DateTimeOffset Time - { - readonly get => DateTimeOffset.FromUnixTimeSeconds(_timeStamp); - set - { - SetTime(value); - _checksum = CalculateChecksum(); - } - } - - private void SetTime(DateTimeOffset time) - => _timeStamp = (uint)time.ToUnixTimeSeconds(); - - private void SetCustomize(in Customize customize) - => _customize = customize.Data.Clone(); - - private void SetVoice(ushort voice) - => _voice = voice; - - private void SetDescription(string text) - { - fixed (byte* ptr = _description) - { - var span = new Span(ptr, 41 * 4); - Encoding.UTF8.GetBytes(text.AsSpan(0, Math.Min(40, text.Length)), span); - } - } -} diff --git a/Glamourer.GameData/GameData.cs b/Glamourer.GameData/GameData.cs deleted file mode 100644 index d5638b0..0000000 --- a/Glamourer.GameData/GameData.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Dalamud; -using Dalamud.Plugin.Services; -using Glamourer.Structs; -using Lumina.Excel.GeneratedSheets; - -namespace Glamourer; - -public static class GameData -{ - private static Dictionary? _jobs; - private static Dictionary? _jobGroups; - private static JobGroup[]? _allJobGroups; - - public static IReadOnlyDictionary Jobs(IDataManager dataManager) - { - if (_jobs != null) - return _jobs; - - var sheet = dataManager.GetExcelSheet()!; - _jobs = sheet.Where(j => j.Abbreviation.RawData.Length > 0).ToDictionary(j => (byte)j.RowId, j => new Job(j)); - return _jobs; - } - - public static IReadOnlyList AllJobGroups(IDataManager dataManager) - { - if (_allJobGroups != null) - return _allJobGroups; - - var sheet = dataManager.GetExcelSheet()!; - var jobs = dataManager.GetExcelSheet(ClientLanguage.English)!; - _allJobGroups = sheet.Select(j => new JobGroup(j, jobs)).ToArray(); - return _allJobGroups; - } - - public static IReadOnlyDictionary JobGroups(IDataManager dataManager) - { - if (_jobGroups != null) - return _jobGroups; - - static bool ValidIndex(uint idx) - { - if (idx is > 0 and < 36) - return true; - - return idx switch - { - // Single jobs and big groups - 91 => true, - 92 => true, - 96 => true, - 98 => true, - 99 => true, - 111 => true, - 112 => true, - 129 => true, - 149 => true, - 150 => true, - 156 => true, - 157 => true, - 158 => true, - 159 => true, - 180 => true, - 181 => true, - 188 => true, - 189 => true, - - // Class + Job - 38 => true, - 41 => true, - 44 => true, - 47 => true, - 50 => true, - 53 => true, - 55 => true, - 69 => true, - 68 => true, - 93 => true, - _ => false, - }; - } - - _jobGroups = AllJobGroups(dataManager).Where(j => ValidIndex(j.Id)) - .ToDictionary(j => (ushort) j.Id, j => j); - return _jobGroups; - } -} diff --git a/Glamourer.GameData/Glamourer - Backup.GameData.csproj b/Glamourer.GameData/Glamourer - Backup.GameData.csproj deleted file mode 100644 index 74d1588..0000000 --- a/Glamourer.GameData/Glamourer - Backup.GameData.csproj +++ /dev/null @@ -1,61 +0,0 @@ - - - net472 - preview - Glamourer - Glamourer.GameData - 1.0.0.0 - 1.0.0.0 - SoftOtter - Glamourer - Copyright © 2020 - true - Library - 4 - true - enable - bin\$(Configuration)\ - $(MSBuildWarningsAsMessages);MSB3277 - - - - full - DEBUG;TRACE - - - - pdbonly - - - - $(MSBuildWarningsAsMessages);MSB3277 - - - - - $(DALAMUD_ROOT)\Dalamud.dll - ..\libs\Dalamud.dll - $(AppData)\XIVLauncher\addon\Hooks\dev\Dalamud.dll - False - - - $(DALAMUD_ROOT)\Lumina.dll - ..\libs\Lumina.dll - $(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.dll - False - - - $(DALAMUD_ROOT)\Lumina.Excel.dll - ..\libs\Lumina.Excel.dll - $(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.Excel.dll - False - - - ..\..\Penumbra\Penumbra\bin\$(Configuration)\net472\Penumbra.GameData.dll - - - - - - - diff --git a/Glamourer.GameData/Glamourer.GameData.csproj b/Glamourer.GameData/Glamourer.GameData.csproj deleted file mode 100644 index 92bf301..0000000 --- a/Glamourer.GameData/Glamourer.GameData.csproj +++ /dev/null @@ -1,72 +0,0 @@ - - - net7.0-windows - preview - x64 - Glamourer - Glamourer.GameData - 1.0.0.0 - 1.0.0.0 - SoftOtter - Glamourer - Copyright © 2020 - true - Library - 4 - true - enable - bin\$(Configuration)\ - $(MSBuildWarningsAsMessages);MSB3277 - false - false - - - - full - DEBUG;TRACE - - - - pdbonly - - - - $(MSBuildWarningsAsMessages);MSB3277 - - - - $(AppData)\XIVLauncher\addon\Hooks\dev\ - - - - - $(DalamudLibPath)Dalamud.dll - False - - - $(DalamudLibPath)FFXIVClientStructs.dll - False - - - $(DalamudLibPath)Lumina.dll - False - - - $(DalamudLibPath)Lumina.Excel.dll - False - - - $(DalamudLibPath)Newtonsoft.Json.dll - False - - - $(DalamudLibPath)ImGuiScene.dll - False - - - - - - - - \ No newline at end of file diff --git a/Glamourer.GameData/Offsets.cs b/Glamourer.GameData/Offsets.cs deleted file mode 100644 index 71151d9..0000000 --- a/Glamourer.GameData/Offsets.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Glamourer; - -public static class Sigs -{ - public const string ChangeJob = "48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 56 41 57 48 83 EC ?? 80 61"; - public const string FlagSlotForUpdate = "48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 8B DA 49 8B F0 48 8B F9 83 FA 0A"; -} diff --git a/Glamourer.GameData/Structs/CrestFlag.cs b/Glamourer.GameData/Structs/CrestFlag.cs deleted file mode 100644 index 61ccc7e..0000000 --- a/Glamourer.GameData/Structs/CrestFlag.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Penumbra.GameData.Enums; - -namespace Glamourer.Structs; - -[Flags] -public enum CrestFlag : ushort -{ - OffHand = 0x0001, - Head = 0x0002, - Body = 0x0004, - Hands = 0x0008, - Legs = 0x0010, - Feet = 0x0020, - Ears = 0x0040, - Neck = 0x0080, - Wrists = 0x0100, - RFinger = 0x0200, - LFinger = 0x0400, - MainHand = 0x0800, -} - -public enum CrestType : byte -{ - None, - Human, - Mainhand, - Offhand, -}; - -public static class CrestExtensions -{ - public const CrestFlag All = (CrestFlag)(((ulong)EquipFlag.Mainhand << 1) - 1); - public const CrestFlag AllRelevant = CrestFlag.Head | CrestFlag.Body | CrestFlag.OffHand; - - public static readonly IReadOnlyList AllRelevantSet = Enum.GetValues().Where(f => AllRelevant.HasFlag(f)).ToArray(); - - public static int ToInternalIndex(this CrestFlag flag) - => flag switch - { - CrestFlag.Head => 0, - CrestFlag.Body => 1, - CrestFlag.OffHand => 2, - _ => -1, - }; - - public static (CrestType Type, byte Index) ToIndex(this CrestFlag flag) - => flag switch - { - CrestFlag.Head => (CrestType.Human, 0), - CrestFlag.Body => (CrestType.Human, 1), - CrestFlag.Hands => (CrestType.Human, 2), - CrestFlag.Legs => (CrestType.Human, 3), - CrestFlag.Feet => (CrestType.Human, 4), - CrestFlag.Ears => (CrestType.None, 0), - CrestFlag.Neck => (CrestType.None, 0), - CrestFlag.Wrists => (CrestType.None, 0), - CrestFlag.RFinger => (CrestType.None, 0), - CrestFlag.LFinger => (CrestType.None, 0), - CrestFlag.MainHand => (CrestType.None, 0), - CrestFlag.OffHand => (CrestType.Offhand, 0), - _ => (CrestType.None, 0), - }; - - public static CrestFlag ToCrestFlag(this EquipSlot slot) - => slot switch - { - EquipSlot.MainHand => CrestFlag.MainHand, - EquipSlot.OffHand => CrestFlag.OffHand, - EquipSlot.Head => CrestFlag.Head, - EquipSlot.Body => CrestFlag.Body, - EquipSlot.Hands => CrestFlag.Hands, - EquipSlot.Legs => CrestFlag.Legs, - EquipSlot.Feet => CrestFlag.Feet, - EquipSlot.Ears => CrestFlag.Ears, - EquipSlot.Neck => CrestFlag.Neck, - EquipSlot.Wrists => CrestFlag.Wrists, - EquipSlot.RFinger => CrestFlag.RFinger, - EquipSlot.LFinger => CrestFlag.LFinger, - _ => 0, - }; - - public static string ToLabel(this CrestFlag flag) - => flag switch - { - CrestFlag.Head => "Head", - CrestFlag.Body => "Chest", - CrestFlag.Hands => "Gauntlets", - CrestFlag.Legs => "Pants", - CrestFlag.Feet => "Boot", - CrestFlag.Ears => "Earrings", - CrestFlag.Neck => "Necklace", - CrestFlag.Wrists => "Bracelet", - CrestFlag.RFinger => "Right Ring", - CrestFlag.LFinger => "Left Ring", - CrestFlag.MainHand => "Weapon", - CrestFlag.OffHand => "Shield", - _ => string.Empty, - }; -} diff --git a/Glamourer.GameData/Structs/EquipFlag.cs b/Glamourer.GameData/Structs/EquipFlag.cs deleted file mode 100644 index eaacbac..0000000 --- a/Glamourer.GameData/Structs/EquipFlag.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System; -using Penumbra.GameData.Enums; - -namespace Glamourer.Structs; - -[Flags] -public enum EquipFlag : uint -{ - Head = 0x00000001, - Body = 0x00000002, - Hands = 0x00000004, - Legs = 0x00000008, - Feet = 0x00000010, - Ears = 0x00000020, - Neck = 0x00000040, - Wrist = 0x00000080, - RFinger = 0x00000100, - LFinger = 0x00000200, - Mainhand = 0x00000400, - Offhand = 0x00000800, - HeadStain = 0x00001000, - BodyStain = 0x00002000, - HandsStain = 0x00004000, - LegsStain = 0x00008000, - FeetStain = 0x00010000, - EarsStain = 0x00020000, - NeckStain = 0x00040000, - WristStain = 0x00080000, - RFingerStain = 0x00100000, - LFingerStain = 0x00200000, - MainhandStain = 0x00400000, - OffhandStain = 0x00800000, -} - -public static class EquipFlagExtensions -{ - public const EquipFlag All = (EquipFlag)(((uint)EquipFlag.OffhandStain << 1) - 1); - public const int NumEquipFlags = 24; - - public static EquipFlag ToFlag(this EquipSlot slot) - => slot switch - { - EquipSlot.MainHand => EquipFlag.Mainhand, - EquipSlot.OffHand => EquipFlag.Offhand, - EquipSlot.Head => EquipFlag.Head, - EquipSlot.Body => EquipFlag.Body, - EquipSlot.Hands => EquipFlag.Hands, - EquipSlot.Legs => EquipFlag.Legs, - EquipSlot.Feet => EquipFlag.Feet, - EquipSlot.Ears => EquipFlag.Ears, - EquipSlot.Neck => EquipFlag.Neck, - EquipSlot.Wrists => EquipFlag.Wrist, - EquipSlot.RFinger => EquipFlag.RFinger, - EquipSlot.LFinger => EquipFlag.LFinger, - _ => 0, - }; - - public static EquipFlag ToStainFlag(this EquipSlot slot) - => slot switch - { - EquipSlot.MainHand => EquipFlag.MainhandStain, - EquipSlot.OffHand => EquipFlag.OffhandStain, - EquipSlot.Head => EquipFlag.HeadStain, - EquipSlot.Body => EquipFlag.BodyStain, - EquipSlot.Hands => EquipFlag.HandsStain, - EquipSlot.Legs => EquipFlag.LegsStain, - EquipSlot.Feet => EquipFlag.FeetStain, - EquipSlot.Ears => EquipFlag.EarsStain, - EquipSlot.Neck => EquipFlag.NeckStain, - EquipSlot.Wrists => EquipFlag.WristStain, - EquipSlot.RFinger => EquipFlag.RFingerStain, - EquipSlot.LFinger => EquipFlag.LFingerStain, - _ => 0, - }; - - public static EquipFlag ToBothFlags(this EquipSlot slot) - => slot switch - { - EquipSlot.MainHand => EquipFlag.Mainhand | EquipFlag.MainhandStain, - EquipSlot.OffHand => EquipFlag.Offhand | EquipFlag.OffhandStain, - EquipSlot.Head => EquipFlag.Head | EquipFlag.HeadStain, - EquipSlot.Body => EquipFlag.Body | EquipFlag.BodyStain, - EquipSlot.Hands => EquipFlag.Hands | EquipFlag.HandsStain, - EquipSlot.Legs => EquipFlag.Legs | EquipFlag.LegsStain, - EquipSlot.Feet => EquipFlag.Feet | EquipFlag.FeetStain, - EquipSlot.Ears => EquipFlag.Ears | EquipFlag.EarsStain, - EquipSlot.Neck => EquipFlag.Neck | EquipFlag.NeckStain, - EquipSlot.Wrists => EquipFlag.Wrist | EquipFlag.WristStain, - EquipSlot.RFinger => EquipFlag.RFinger | EquipFlag.RFingerStain, - EquipSlot.LFinger => EquipFlag.LFinger | EquipFlag.LFingerStain, - _ => 0, - }; -} diff --git a/Glamourer.GameData/Structs/Job.cs b/Glamourer.GameData/Structs/Job.cs deleted file mode 100644 index 1d2873d..0000000 --- a/Glamourer.GameData/Structs/Job.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Dalamud.Utility; -using Lumina.Excel.GeneratedSheets; - -namespace Glamourer.Structs; - -// A struct containing the different jobs the game supports. -// Also contains the jobs Name and Abbreviation as strings. -public readonly struct Job -{ - public readonly string Name; - public readonly string Abbreviation; - public readonly ClassJob Base; - - public uint Id - => Base.RowId; - - public JobFlag Flag - => (JobFlag)(1ul << (int)Base.RowId); - - public Job(ClassJob job) - { - Base = job; - Name = job.Name.ToDalamudString().ToString(); - Abbreviation = job.Abbreviation.ToDalamudString().ToString(); - } - - public override string ToString() - => Name; -} diff --git a/Glamourer.GameData/Structs/JobGroup.cs b/Glamourer.GameData/Structs/JobGroup.cs deleted file mode 100644 index 5471e7f..0000000 --- a/Glamourer.GameData/Structs/JobGroup.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Diagnostics; -using Lumina.Excel; -using Lumina.Excel.GeneratedSheets; - -namespace Glamourer.Structs; - -[Flags] -public enum JobFlag : ulong -{ } - -// The game specifies different job groups that can contain specific jobs or not. -public readonly struct JobGroup -{ - public readonly string Name; - public readonly int Count; - public readonly uint Id; - private readonly JobFlag _flags; - - // Create a job group from a given category and the ClassJob sheet. - // It looks up the different jobs contained in the category and sets the flags appropriately. - public JobGroup(ClassJobCategory group, ExcelSheet jobs) - { - Count = 0; - _flags = 0ul; - Id = group.RowId; - Name = group.Name.ToString(); - - Debug.Assert(jobs.RowCount < 64, $"Number of Jobs exceeded 63 ({jobs.RowCount})."); - foreach (var job in jobs) - { - var abbr = job.Abbreviation.ToString(); - if (abbr.Length == 0) - continue; - - var prop = group.GetType().GetProperty(abbr); - Debug.Assert(prop != null, $"Could not get job abbreviation {abbr} property."); - - if (!(bool)prop.GetValue(group)!) - continue; - - ++Count; - _flags |= (JobFlag)(1ul << (int)job.RowId); - } - } - - // Check if a job is contained inside this group. - public bool Fits(Job job) - => _flags.HasFlag(job.Flag); - - // Check if any of the jobs in the given flags fit this group. - public bool Fits(JobFlag flag) - => (_flags & flag) != 0; - - // Check if a job is contained inside this group. - public bool Fits(uint jobId) - { - var flag = (JobFlag)(1ul << (int)jobId); - return _flags.HasFlag(flag); - } -} diff --git a/Glamourer.sln b/Glamourer.sln index 5f555ca..9acdd6c 100644 --- a/Glamourer.sln +++ b/Glamourer.sln @@ -9,8 +9,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution repo.json = repo.json EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Glamourer.GameData", "Glamourer.GameData\Glamourer.GameData.csproj", "{51F4DDB0-1FA0-4629-9CFE-C55B6062907B}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Glamourer", "Glamourer\Glamourer.csproj", "{01EB903D-871F-4285-A8CF-6486561D5B5B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra.Api", "Penumbra.Api\Penumbra.Api.csproj", "{29C589ED-7AF1-4DE9-82EF-33EBEF19AAFA}" @@ -27,10 +25,6 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {51F4DDB0-1FA0-4629-9CFE-C55B6062907B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {51F4DDB0-1FA0-4629-9CFE-C55B6062907B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {51F4DDB0-1FA0-4629-9CFE-C55B6062907B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {51F4DDB0-1FA0-4629-9CFE-C55B6062907B}.Release|Any CPU.Build.0 = Release|Any CPU {01EB903D-871F-4285-A8CF-6486561D5B5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {01EB903D-871F-4285-A8CF-6486561D5B5B}.Debug|Any CPU.Build.0 = Debug|Any CPU {01EB903D-871F-4285-A8CF-6486561D5B5B}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/Glamourer/Api/GlamourerIpc.GetCustomization.cs b/Glamourer/Api/GlamourerIpc.GetCustomization.cs index 3e8794c..cdec349 100644 --- a/Glamourer/Api/GlamourerIpc.GetCustomization.cs +++ b/Glamourer/Api/GlamourerIpc.GetCustomization.cs @@ -1,11 +1,7 @@ -using System.Buffers.Text; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Plugin; -using Glamourer.Customization; -using Glamourer.Designs; -using Glamourer.Structs; using Penumbra.Api.Helpers; using Penumbra.GameData.Actors; diff --git a/Glamourer/Automation/AutoDesign.cs b/Glamourer/Automation/AutoDesign.cs index 0a26759..029a2ec 100644 --- a/Glamourer/Automation/AutoDesign.cs +++ b/Glamourer/Automation/AutoDesign.cs @@ -1,10 +1,10 @@ using System; -using Glamourer.Customization; using Glamourer.Designs; using Glamourer.Interop.Structs; using Glamourer.State; -using Glamourer.Structs; using Newtonsoft.Json.Linq; +using Penumbra.GameData.Enums; +using Penumbra.GameData.Structs; namespace Glamourer.Automation; @@ -74,7 +74,7 @@ public class AutoDesign var ret = new JObject { ["Gearset"] = GearsetIndex, - ["JobGroup"] = Jobs.Id, + ["JobGroup"] = Jobs.Id.Id, }; return ret; diff --git a/Glamourer/Automation/AutoDesignApplier.cs b/Glamourer/Automation/AutoDesignApplier.cs index 023b2c0..9f3e286 100644 --- a/Glamourer/Automation/AutoDesignApplier.cs +++ b/Glamourer/Automation/AutoDesignApplier.cs @@ -4,14 +4,12 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.UI.Misc; -using Glamourer.Customization; using Glamourer.Designs; using Glamourer.Events; using Glamourer.Interop; using Glamourer.Interop.Structs; using Glamourer.Services; using Glamourer.State; -using Glamourer.Structs; using Glamourer.Unlocks; using OtterGui.Classes; using Penumbra.GameData.Actors; @@ -209,7 +207,7 @@ public class AutoDesignApplier : IDisposable if (!GetPlayerSet(id, out var set)) { if (_state.TryGetValue(id, out var s)) - s.LastJob = (byte)newJob.Id; + s.LastJob = newJob.Id; return; } diff --git a/Glamourer/Automation/AutoDesignManager.cs b/Glamourer/Automation/AutoDesignManager.cs index e997a78..e205784 100644 --- a/Glamourer/Automation/AutoDesignManager.cs +++ b/Glamourer/Automation/AutoDesignManager.cs @@ -10,7 +10,6 @@ using Glamourer.Designs; using Glamourer.Events; using Glamourer.Interop; using Glamourer.Services; -using Glamourer.Structs; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OtterGui; @@ -516,7 +515,7 @@ public class AutoDesignManager : ISavable, IReadOnlyList, IDispos var jobs = conditions["JobGroup"]?.ToObject() ?? -1; if (jobs >= 0) { - if (!_jobs.JobGroups.TryGetValue((ushort)jobs, out var jobGroup)) + if (!_jobs.JobGroups.TryGetValue((JobGroupId)jobs, out var jobGroup)) { Glamourer.Messager.NotificationMessage( $"Error parsing automatically applied design for set {setName}: The job condition {jobs} does not exist.", diff --git a/Glamourer/Automation/FixedDesignMigrator.cs b/Glamourer/Automation/FixedDesignMigrator.cs index d30271e..4ed98d3 100644 --- a/Glamourer/Automation/FixedDesignMigrator.cs +++ b/Glamourer/Automation/FixedDesignMigrator.cs @@ -3,37 +3,30 @@ using System.Linq; using Dalamud.Interface.Internal.Notifications; using Glamourer.Designs; using Glamourer.Interop; -using Glamourer.Services; -using Glamourer.Structs; using Newtonsoft.Json.Linq; using OtterGui.Classes; using Penumbra.GameData.Actors; +using Penumbra.GameData.Structs; using Penumbra.String; namespace Glamourer.Automation; -public class FixedDesignMigrator +public class FixedDesignMigrator(JobService jobs) { - private readonly JobService _jobs; - private List<(string Name, List<(string, JobGroup, bool)> Data)>? _migratedData; - - public FixedDesignMigrator(JobService jobs) - => _jobs = jobs; + private List<(string Name, List<(string, JobGroup, bool)> Data)>? _migratedData; public void ConsumeMigratedData(ActorManager actors, DesignFileSystem designFileSystem, AutoDesignManager autoManager) { if (_migratedData == null) return; - foreach (var data in _migratedData) + foreach (var (name, data) in _migratedData) { - var allEnabled = true; - var name = data.Name; if (autoManager.Any(d => name == d.Name)) continue; var id = ActorIdentifier.Invalid; - if (ByteString.FromString(data.Name, out var byteString, false)) + if (ByteString.FromString(name, out var byteString)) { id = actors.CreatePlayer(byteString, ushort.MaxValue); if (!id.IsValid) @@ -46,16 +39,15 @@ public class FixedDesignMigrator id = actors.CreatePlayer(byteString, actors.Data.Worlds.First().Key); if (!id.IsValid) { - Glamourer.Messager.NotificationMessage($"Could not migrate fixed design {data.Name}.", NotificationType.Error); - allEnabled = false; + Glamourer.Messager.NotificationMessage($"Could not migrate fixed design {name}.", NotificationType.Error); continue; } } autoManager.AddDesignSet(name, id); - autoManager.SetState(autoManager.Count - 1, allEnabled); + autoManager.SetState(autoManager.Count - 1, true); var set = autoManager[^1]; - foreach (var design in data.Data.AsEnumerable().Reverse()) + foreach (var design in data.AsEnumerable().Reverse()) { if (!designFileSystem.Find(design.Item1, out var child) || child is not DesignFileSystem.Leaf leaf) { @@ -96,7 +88,7 @@ public class FixedDesignMigrator } var job = obj["JobGroups"]?.ToObject() ?? -1; - if (job < 0 || !_jobs.JobGroups.TryGetValue((ushort)job, out var group)) + if (job < 0 || !jobs.JobGroups.TryGetValue((JobGroupId)job, out var group)) { Glamourer.Messager.NotificationMessage("Could not semi-migrate fixed design: Invalid job group specified.", NotificationType.Warning); diff --git a/Glamourer/Designs/DesignBase.cs b/Glamourer/Designs/DesignBase.cs index c9662ef..8e11ad8 100644 --- a/Glamourer/Designs/DesignBase.cs +++ b/Glamourer/Designs/DesignBase.cs @@ -1,7 +1,6 @@ using Dalamud.Interface.Internal.Notifications; -using Glamourer.Customization; +using Glamourer.GameData; using Glamourer.Services; -using Glamourer.Structs; using Newtonsoft.Json.Linq; using OtterGui.Classes; using Penumbra.GameData.Enums; @@ -85,12 +84,12 @@ public class DesignBase internal CrestFlag ApplyCrest = CrestExtensions.AllRelevant; private DesignFlags _designFlags = DesignFlags.ApplyHatVisible | DesignFlags.ApplyVisorState | DesignFlags.ApplyWeaponVisible; - public bool SetCustomize(CustomizationService customizationService, Customize customize) + public bool SetCustomize(CustomizationService customizationService, CustomizeArray customize) { if (customize.Equals(_designData.Customize)) return false; - _designData.Customize.Load(customize); + _designData.Customize = customize; CustomizationSet = customizationService.Service.GetList(customize.Clan, customize.Gender); return true; } @@ -443,7 +442,7 @@ public class DesignBase { design._designData.ModelId = 0; design._designData.IsHuman = true; - design.SetCustomize(customizations, Customize.Default); + design.SetCustomize(customizations, CustomizeArray.Default); Glamourer.Messager.NotificationMessage("The loaded design does not contain any customization data, reset to default.", NotificationType.Warning); return; diff --git a/Glamourer/Designs/DesignBase64Migration.cs b/Glamourer/Designs/DesignBase64Migration.cs index c36c1ea..d4352e6 100644 --- a/Glamourer/Designs/DesignBase64Migration.cs +++ b/Glamourer/Designs/DesignBase64Migration.cs @@ -1,7 +1,5 @@ using System; -using Glamourer.Customization; using Glamourer.Services; -using Glamourer.Structs; using OtterGui; using Penumbra.GameData.DataContainers; using Penumbra.GameData.Enums; @@ -62,7 +60,7 @@ public class DesignBase64Migration data.SetHatVisible((bytes[90] & 0x01) == 0); data.SetVisor((bytes[90] & 0x10) != 0); data.SetWeaponVisible((bytes[90] & 0x02) == 0); - data.ModelId = (uint)bytes[91] | ((uint)bytes[92] << 8) | ((uint)bytes[93] << 16) | ((uint)bytes[94] << 24); + data.ModelId = bytes[91] | ((uint)bytes[92] << 8) | ((uint)bytes[93] << 16) | ((uint)bytes[94] << 24); break; } case 5: @@ -73,7 +71,7 @@ public class DesignBase64Migration data.SetHatVisible((bytes[90] & 0x01) == 0); data.SetVisor((bytes[90] & 0x10) != 0); data.SetWeaponVisible((bytes[90] & 0x02) == 0); - data.ModelId = (uint)bytes[91] | ((uint)bytes[92] << 8) | ((uint)bytes[93] << 16) | ((uint)bytes[94] << 24); + data.ModelId = bytes[91] | ((uint)bytes[92] << 8) | ((uint)bytes[93] << 16) | ((uint)bytes[94] << 24); break; default: throw new Exception($"Can not parse Base64 string into design for migration:\n\tInvalid Version {bytes[0]}."); } @@ -102,11 +100,11 @@ public class DesignBase64Migration if (!humans.IsHuman(data.ModelId)) { - data.LoadNonHuman(data.ModelId, *(Customize*)(ptr + 4), (nint)eq); + data.LoadNonHuman(data.ModelId, *(CustomizeArray*)(ptr + 4), (nint)eq); return data; } - data.Customize.Load(*(Customize*)(ptr + 4)); + data.Customize = *(CustomizeArray*)(ptr + 4); foreach (var (slot, idx) in EquipSlotExtensions.EqdpSlots.WithIndex()) { var mdl = eq[idx]; @@ -187,7 +185,7 @@ public class DesignBase64Migration | (equipFlags.HasFlag(EquipFlag.Wrist) ? 0x02 : 0) | (equipFlags.HasFlag(EquipFlag.RFinger) ? 0x04 : 0) | (equipFlags.HasFlag(EquipFlag.LFinger) ? 0x08 : 0)); - save.Customize.Write((nint)data + 4); + save.Customize.Write(data + 4); ((CharacterWeapon*)(data + 30))[0] = save.Item(EquipSlot.MainHand).Weapon(save.Stain(EquipSlot.MainHand)); ((CharacterWeapon*)(data + 30))[1] = save.Item(EquipSlot.OffHand).Weapon(save.Stain(EquipSlot.OffHand)); foreach (var slot in EquipSlotExtensions.EqdpSlots) diff --git a/Glamourer/Designs/DesignConverter.cs b/Glamourer/Designs/DesignConverter.cs index 86fd0ce..282ab0a 100644 --- a/Glamourer/Designs/DesignConverter.cs +++ b/Glamourer/Designs/DesignConverter.cs @@ -2,10 +2,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.Text; -using Glamourer.Customization; using Glamourer.Services; using Glamourer.State; -using Glamourer.Structs; using Glamourer.Utility; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -165,7 +163,7 @@ public class DesignConverter(ItemManager _items, DesignManager _designs, Customi yield return (slot, item, armor.Stain); } - var mh = _items.Identify(EquipSlot.MainHand, mainhand.Skeleton, mainhand.Weapon, mainhand.Variant, FullEquipType.Unknown); + var mh = _items.Identify(EquipSlot.MainHand, mainhand.Skeleton, mainhand.Weapon, mainhand.Variant); if (!mh.Valid) { Glamourer.Log.Warning($"Appearance data {mainhand} for mainhand weapon invalid, item could not be identified."); diff --git a/Glamourer/Designs/DesignData.cs b/Glamourer/Designs/DesignData.cs index 68fa154..9e324ae 100644 --- a/Glamourer/Designs/DesignData.cs +++ b/Glamourer/Designs/DesignData.cs @@ -1,8 +1,6 @@ using System; using System.Runtime.CompilerServices; -using Glamourer.Customization; using Glamourer.Services; -using Glamourer.Structs; using OtterGui.Classes; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; @@ -12,30 +10,30 @@ namespace Glamourer.Designs; public unsafe struct DesignData { - private string _nameHead = string.Empty; - private string _nameBody = string.Empty; - private string _nameHands = string.Empty; - private string _nameLegs = string.Empty; - private string _nameFeet = string.Empty; - private string _nameEars = string.Empty; - private string _nameNeck = string.Empty; - private string _nameWrists = string.Empty; - private string _nameRFinger = string.Empty; - private string _nameLFinger = string.Empty; - private string _nameMainhand = string.Empty; - private string _nameOffhand = string.Empty; - private fixed uint _itemIds[12]; - private fixed ushort _iconIds[12]; - private fixed byte _equipmentBytes[48]; - public Customize Customize = Customize.Default; - public uint ModelId; - public CrestFlag CrestVisibility; - private SecondaryId _secondaryMainhand; - private SecondaryId _secondaryOffhand; - private FullEquipType _typeMainhand; - private FullEquipType _typeOffhand; - private byte _states; - public bool IsHuman = true; + private string _nameHead = string.Empty; + private string _nameBody = string.Empty; + private string _nameHands = string.Empty; + private string _nameLegs = string.Empty; + private string _nameFeet = string.Empty; + private string _nameEars = string.Empty; + private string _nameNeck = string.Empty; + private string _nameWrists = string.Empty; + private string _nameRFinger = string.Empty; + private string _nameLFinger = string.Empty; + private string _nameMainhand = string.Empty; + private string _nameOffhand = string.Empty; + private fixed uint _itemIds[12]; + private fixed ushort _iconIds[12]; + private fixed byte _equipmentBytes[48]; + public CustomizeArray Customize = CustomizeArray.Default; + public uint ModelId; + public CrestFlag CrestVisibility; + private SecondaryId _secondaryMainhand; + private SecondaryId _secondaryOffhand; + private FullEquipType _typeMainhand; + private FullEquipType _typeOffhand; + private byte _states; + public bool IsHuman = true; public DesignData() { } @@ -255,11 +253,11 @@ public unsafe struct DesignData } - public bool LoadNonHuman(uint modelId, Customize customize, nint equipData) + public bool LoadNonHuman(uint modelId, CustomizeArray customize, nint equipData) { ModelId = modelId; IsHuman = false; - Customize.Load(customize); + Customize.Read(customize.Data); fixed (byte* ptr = _equipmentBytes) { MemoryUtility.MemCpyUnchecked(ptr, (byte*)equipData, 40); @@ -294,7 +292,7 @@ public unsafe struct DesignData public readonly byte[] GetCustomizeBytes() { var ret = new byte[CustomizeArray.Size]; - fixed (byte* retPtr = ret, inPtr = Customize.Data.Data) + fixed (byte* retPtr = ret, inPtr = Customize.Data) { MemoryUtility.MemCpyUnchecked(retPtr, inPtr, ret.Length); } diff --git a/Glamourer/Designs/DesignManager.cs b/Glamourer/Designs/DesignManager.cs index 6b8578e..1320d6a 100644 --- a/Glamourer/Designs/DesignManager.cs +++ b/Glamourer/Designs/DesignManager.cs @@ -3,12 +3,10 @@ using System.Collections.Generic; using System.IO; using System.Linq; using Dalamud.Utility; -using Glamourer.Customization; using Glamourer.Events; using Glamourer.Interop.Penumbra; using Glamourer.Services; using Glamourer.State; -using Glamourer.Structs; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OtterGui; @@ -25,8 +23,8 @@ public class DesignManager private readonly HumanModelList _humans; private readonly SaveService _saveService; private readonly DesignChanged _event; - private readonly List _designs = new(); - private readonly Dictionary _undoStore = new(); + private readonly List _designs = []; + private readonly Dictionary _undoStore = []; public IReadOnlyList Designs => _designs; @@ -298,7 +296,7 @@ public class DesignManager return; case CustomizeIndex.Clan: { - var customize = new Customize(design.DesignData.Customize.Data.Clone()); + var customize = design.DesignData.Customize; if (_customizations.ChangeClan(ref customize, (SubRace)value.Value) == 0) return; if (!design.SetCustomize(_customizations, customize)) @@ -308,7 +306,7 @@ public class DesignManager } case CustomizeIndex.Gender: { - var customize = new Customize(design.DesignData.Customize.Data.Clone()); + var customize = design.DesignData.Customize; if (_customizations.ChangeGender(ref customize, (Gender)(value.Value + 1)) == 0) return; if (!design.SetCustomize(_customizations, customize)) diff --git a/Glamourer.GameData/Customization/CharaMakeParams.cs b/Glamourer/GameData/CharaMakeParams.cs similarity index 94% rename from Glamourer.GameData/Customization/CharaMakeParams.cs rename to Glamourer/GameData/CharaMakeParams.cs index 63806c0..12dedf9 100644 --- a/Glamourer.GameData/Customization/CharaMakeParams.cs +++ b/Glamourer/GameData/CharaMakeParams.cs @@ -2,9 +2,11 @@ using Lumina.Excel; using Lumina.Excel.GeneratedSheets; -namespace Glamourer.Customization; +namespace Glamourer.GameData; -// A custom version of CharaMakeParams that is easier to parse. +/// +/// A custom version of CharaMakeParams that is easier to parse. +/// [Sheet("CharaMakeParams")] public class CharaMakeParams : ExcelRow { @@ -64,7 +66,7 @@ public class CharaMakeParams : ExcelRow Race = new LazyRow(gameData, parser.ReadColumn(0), language); Tribe = new LazyRow(gameData, parser.ReadColumn(1), language); Gender = parser.ReadColumn(2); - var currentOffset = 0; + int currentOffset; for (var i = 0; i < NumMenus; ++i) { currentOffset = 3 + i; diff --git a/Glamourer/GameData/ColorParameters.cs b/Glamourer/GameData/ColorParameters.cs new file mode 100644 index 0000000..630a5a7 --- /dev/null +++ b/Glamourer/GameData/ColorParameters.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Dalamud.Plugin.Services; +using Penumbra.String.Functions; + +namespace Glamourer.GameData; + +public class ColorParameters : IReadOnlyList +{ + private readonly uint[] _rgbaColors; + + public ReadOnlySpan GetSlice(int offset, int count) + => _rgbaColors.AsSpan(offset, count); + + public unsafe ColorParameters(IDataManager gameData, IPluginLog log) + { + try + { + var file = gameData.GetFile("chara/xls/charamake/human.cmp")!; + _rgbaColors = new uint[file.Data.Length >> 2]; + fixed (byte* ptr1 = file.Data) + { + fixed (uint* ptr2 = _rgbaColors) + { + MemoryUtility.MemCpyUnchecked(ptr2, ptr1, file.Data.Length); + } + } + } + catch (Exception e) + { + log.Error("READ THIS\n======== Could not obtain the human.cmp file which is necessary for color sets.\n" + + "======== This usually indicates an error with your index files caused by TexTools modifications.\n" + + "======== If you have used TexTools before, you will probably need to start over in it to use Glamourer.", e); + _rgbaColors = Array.Empty(); + } + } + + public IEnumerator GetEnumerator() + => (IEnumerator)_rgbaColors.GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); + + public int Count + => _rgbaColors.Length; + + public uint this[int index] + => _rgbaColors[index]; +} diff --git a/Glamourer.GameData/Customization/CustomName.cs b/Glamourer/GameData/CustomName.cs similarity index 78% rename from Glamourer.GameData/Customization/CustomName.cs rename to Glamourer/GameData/CustomName.cs index 040c476..c7d74a1 100644 --- a/Glamourer.GameData/Customization/CustomName.cs +++ b/Glamourer/GameData/CustomName.cs @@ -1,6 +1,6 @@ -namespace Glamourer.Customization; +namespace Glamourer.GameData; -// Localization from the game files directly. +/// For localization from the game files directly. public enum CustomName { MidlanderM, diff --git a/Glamourer.GameData/Customization/CustomizationManager.cs b/Glamourer/GameData/CustomizationManager.cs similarity index 93% rename from Glamourer.GameData/Customization/CustomizationManager.cs rename to Glamourer/GameData/CustomizationManager.cs index b02498c..f249bf6 100644 --- a/Glamourer.GameData/Customization/CustomizationManager.cs +++ b/Glamourer/GameData/CustomizationManager.cs @@ -3,7 +3,7 @@ using Dalamud.Interface.Internal; using Dalamud.Plugin.Services; using Penumbra.GameData.Enums; -namespace Glamourer.Customization; +namespace Glamourer.GameData; public class CustomizationManager : ICustomizationManager { diff --git a/Glamourer.GameData/Customization/CustomizationNpcOptions.cs b/Glamourer/GameData/CustomizationNpcOptions.cs similarity index 92% rename from Glamourer.GameData/Customization/CustomizationNpcOptions.cs rename to Glamourer/GameData/CustomizationNpcOptions.cs index 043ccf8..84509be 100644 --- a/Glamourer.GameData/Customization/CustomizationNpcOptions.cs +++ b/Glamourer/GameData/CustomizationNpcOptions.cs @@ -1,12 +1,14 @@ using Penumbra.GameData.Enums; using System.Collections.Generic; using System.Linq; +using Penumbra.GameData.Structs; -namespace Glamourer.Customization; +namespace Glamourer.GameData; public static class CustomizationNpcOptions { - public static Dictionary<(SubRace, Gender), IReadOnlyList<(CustomizeIndex, CustomizeValue)>> CreateNpcData(CustomizationSet[] sets, NpcCustomizeSet npcCustomizeSet) + public static Dictionary<(SubRace, Gender), IReadOnlyList<(CustomizeIndex, CustomizeValue)>> CreateNpcData(CustomizationSet[] sets, + NpcCustomizeSet npcCustomizeSet) { var dict = new Dictionary<(SubRace, Gender), HashSet<(CustomizeIndex, CustomizeValue)>>(); var customizeIndices = new[] diff --git a/Glamourer.GameData/Customization/CustomizationOptions.cs b/Glamourer/GameData/CustomizationOptions.cs similarity index 94% rename from Glamourer.GameData/Customization/CustomizationOptions.cs rename to Glamourer/GameData/CustomizationOptions.cs index 3580ef8..6fc3b03 100644 --- a/Glamourer.GameData/Customization/CustomizationOptions.cs +++ b/Glamourer/GameData/CustomizationOptions.cs @@ -10,9 +10,10 @@ using Lumina.Excel; using Lumina.Excel.GeneratedSheets; using OtterGui.Classes; using Penumbra.GameData.Enums; +using Penumbra.GameData.Structs; using Race = Penumbra.GameData.Enums.Race; -namespace Glamourer.Customization; +namespace Glamourer.GameData; // Generate everything about customization per tribe and gender. public partial class CustomizationOptions @@ -66,7 +67,7 @@ public partial class CustomizationOptions { var tmp = new TemporaryData(gameData, this, log); _icons = new IconStorage(textures, gameData); - SetNames(gameData, tmp); + SetNames(gameData); foreach (var race in Clans) { foreach (var gender in Genders) @@ -79,7 +80,7 @@ public partial class CustomizationOptions // Obtain localized names of customization options and race names from the game data. private readonly string[] _names = new string[Enum.GetValues().Length]; - private void SetNames(IDataManager gameData, TemporaryData tmp) + private void SetNames(IDataManager gameData) { var subRace = gameData.GetExcelSheet()!; @@ -122,9 +123,6 @@ public partial class CustomizationOptions private class TemporaryData { - public bool Valid - => _cmpFile.Valid; - public CustomizationSet GetSet(SubRace race, Gender gender) { var (skin, hair) = GetColors(race, gender); @@ -177,10 +175,8 @@ public partial class CustomizationOptions public TemporaryData(IDataManager gameData, CustomizationOptions options, IPluginLog log) { _options = options; - _cmpFile = new CmpFile(gameData, log); + _cmpFile = new ColorParameters(gameData, log); _customizeSheet = gameData.GetExcelSheet(ClientLanguage.English)!; - _bnpcCustomize = gameData.GetExcelSheet(ClientLanguage.English)!; - _enpcBase = gameData.GetExcelSheet(ClientLanguage.English)!; Lobby = gameData.GetExcelSheet(ClientLanguage.English)!; var tmp = gameData.Excel.GetType().GetMethod("GetSheet", BindingFlags.Instance | BindingFlags.NonPublic)? .MakeGenericMethod(typeof(CharaMakeParams)).Invoke(gameData.Excel, new object?[] @@ -204,10 +200,8 @@ public partial class CustomizationOptions private readonly ExcelSheet _customizeSheet; private readonly ExcelSheet _listSheet; private readonly ExcelSheet _hairSheet; - private readonly ExcelSheet _bnpcCustomize; - private readonly ExcelSheet _enpcBase; public readonly ExcelSheet Lobby; - private readonly CmpFile _cmpFile; + private readonly ColorParameters _cmpFile; // Those values are shared between all races. private readonly CustomizeData[] _highlightPicker; @@ -222,9 +216,17 @@ public partial class CustomizationOptions private CustomizeData[] CreateColorPicker(CustomizeIndex index, int offset, int num, bool light = false) - => _cmpFile.GetSlice(offset, num) - .Select((c, i) => new CustomizeData(index, (CustomizeValue)(light ? 128 + i : 0 + i), c, (ushort)(offset + i))) - .ToArray(); + { + var ret = new CustomizeData[num]; + var idx = 0; + foreach (var value in _cmpFile.GetSlice(offset, num)) + { + ret[idx] = new CustomizeData(index, (CustomizeValue)(light ? 128 + idx : idx), value, (ushort)(offset + idx)); + ++idx; + } + + return ret; + } private void SetHairByFace(CustomizationSet set) @@ -299,15 +301,9 @@ public partial class CustomizationOptions // Set customizations available if they have any options. private static void SetAvailability(CustomizationSet set, CharaMakeParams row) { - if (set.Race == Race.Hrothgar && set.Gender == Gender.Female) + if (set is { Race: Race.Hrothgar, Gender: Gender.Female }) return; - void Set(bool available, CustomizeIndex flag) - { - if (available) - set.SetAvailable(flag); - } - Set(true, CustomizeIndex.Height); Set(set.Faces.Count > 0, CustomizeIndex.Face); Set(true, CustomizeIndex.Hairstyle); @@ -340,6 +336,13 @@ public partial class CustomizationOptions Set(true, CustomizeIndex.SmallIris); Set(set.Race != Race.Hrothgar, CustomizeIndex.Lipstick); Set(set.FacePaints.Count > 0, CustomizeIndex.FacePaintReversed); + return; + + void Set(bool available, CustomizeIndex flag) + { + if (available) + set.SetAvailable(flag); + } } // Create a list of lists of facial features and the legacy tattoo. @@ -348,9 +351,6 @@ public partial class CustomizationOptions var count = set.Faces.Count; set.FacialFeature1 = new List<(CustomizeData, CustomizeData)>(count); - static (CustomizeData, CustomizeData) Create(CustomizeIndex i, uint data) - => (new CustomizeData(i, CustomizeValue.Zero, data, 0), new CustomizeData(i, CustomizeValue.Max, data, 1)); - set.LegacyTattoo = Create(CustomizeIndex.LegacyTattoo, 137905); var tmp = Enumerable.Repeat(0, 7).Select(_ => new (CustomizeData, CustomizeData)[count + 1]).ToArray(); @@ -373,6 +373,10 @@ public partial class CustomizationOptions set.FacialFeature5 = tmp[4]; set.FacialFeature6 = tmp[5]; set.FacialFeature7 = tmp[6]; + return; + + static (CustomizeData, CustomizeData) Create(CustomizeIndex i, uint data) + => (new CustomizeData(i, CustomizeValue.Zero, data), new CustomizeData(i, CustomizeValue.Max, data, 1)); } // Set the names for the given set of parameters. @@ -414,7 +418,7 @@ public partial class CustomizationOptions nameArray[(int)CustomizeIndex.SmallIris] = CustomizeIndex.SmallIris.ToDefaultName(); nameArray[(int)CustomizeIndex.Lipstick] = CustomizeIndex.Lipstick.ToDefaultName(); nameArray[(int)CustomizeIndex.FacePaintReversed] = CustomizeIndex.FacePaintReversed.ToDefaultName(); - set.OptionName = nameArray; + set.OptionName = nameArray; } // Obtain available skin and hair colors for the given subrace and gender. diff --git a/Glamourer.GameData/Customization/CustomizationSet.cs b/Glamourer/GameData/CustomizationSet.cs similarity index 95% rename from Glamourer.GameData/Customization/CustomizationSet.cs rename to Glamourer/GameData/CustomizationSet.cs index b958fdc..2a79c66 100644 --- a/Glamourer.GameData/Customization/CustomizationSet.cs +++ b/Glamourer/GameData/CustomizationSet.cs @@ -4,8 +4,9 @@ using System.Linq; using System.Runtime.CompilerServices; using OtterGui; using Penumbra.GameData.Enums; +using Penumbra.GameData.Structs; -namespace Glamourer.Customization; +namespace Glamourer.GameData; // Each Subrace and Gender combo has a customization set. // This describes the available customizations, their types and their names. @@ -300,3 +301,10 @@ public class CustomizationSet private CustomizeValue HrothgarFaceHack(CustomizeValue value) => Race == Race.Hrothgar && value.Value is > 4 and < 9 ? value - 4 : value; } + +public static class CustomizationSetExtensions +{ + /// Return only the available customizations in this set and Clan or Gender. + public static CustomizeFlag FixApplication(this CustomizeFlag flag, CustomizationSet set) + => flag & (set.SettingAvailable | CustomizeFlag.Clan | CustomizeFlag.Gender); +} diff --git a/Glamourer.GameData/Customization/CustomizeData.cs b/Glamourer/GameData/CustomizeData.cs similarity index 89% rename from Glamourer.GameData/Customization/CustomizeData.cs rename to Glamourer/GameData/CustomizeData.cs index 8e9f914..3a3e89c 100644 --- a/Glamourer.GameData/Customization/CustomizeData.cs +++ b/Glamourer/GameData/CustomizeData.cs @@ -1,7 +1,9 @@ using System; using System.Runtime.InteropServices; +using Penumbra.GameData.Enums; +using Penumbra.GameData.Structs; -namespace Glamourer.Customization; +namespace Glamourer.GameData; // Any customization value can be represented in 8 bytes by its ID, // a byte value, an optional value-id and an optional icon or color. diff --git a/Glamourer.GameData/Customization/ICustomizationManager.cs b/Glamourer/GameData/ICustomizationManager.cs similarity index 90% rename from Glamourer.GameData/Customization/ICustomizationManager.cs rename to Glamourer/GameData/ICustomizationManager.cs index e946e3d..2d884cd 100644 --- a/Glamourer.GameData/Customization/ICustomizationManager.cs +++ b/Glamourer/GameData/ICustomizationManager.cs @@ -2,7 +2,7 @@ using Dalamud.Interface.Internal; using Penumbra.GameData.Enums; -namespace Glamourer.Customization; +namespace Glamourer.GameData; public interface ICustomizationManager { diff --git a/Glamourer.GameData/Customization/NpcCustomizeSet.cs b/Glamourer/GameData/NpcCustomizeSet.cs similarity index 63% rename from Glamourer.GameData/Customization/NpcCustomizeSet.cs rename to Glamourer/GameData/NpcCustomizeSet.cs index 3ba64a0..fd261c6 100644 --- a/Glamourer.GameData/Customization/NpcCustomizeSet.cs +++ b/Glamourer/GameData/NpcCustomizeSet.cs @@ -11,7 +11,7 @@ using OtterGui.Services; using Penumbra.GameData.DataContainers; using Penumbra.GameData.Structs; -namespace Glamourer.Customization; +namespace Glamourer.GameData; public class NpcCustomizeSet : IAsyncDataContainer, IReadOnlyList { @@ -187,83 +187,83 @@ public class NpcCustomizeSet : IAsyncDataContainer, IReadOnlyList data.VisorToggled = row.Visor; } - private static (bool, Customize) FromBnpcCustomize(BNpcCustomize bnpcCustomize) + private static (bool, CustomizeArray) FromBnpcCustomize(BNpcCustomize bnpcCustomize) { - var customize = new Customize(); - customize.Data.Set(0, (byte)bnpcCustomize.Race.Row); - customize.Data.Set(1, bnpcCustomize.Gender); - customize.Data.Set(2, bnpcCustomize.BodyType); - customize.Data.Set(3, bnpcCustomize.Height); - customize.Data.Set(4, (byte)bnpcCustomize.Tribe.Row); - customize.Data.Set(5, bnpcCustomize.Face); - customize.Data.Set(6, bnpcCustomize.HairStyle); - customize.Data.Set(7, bnpcCustomize.HairHighlight); - customize.Data.Set(8, bnpcCustomize.SkinColor); - customize.Data.Set(9, bnpcCustomize.EyeHeterochromia); - customize.Data.Set(10, bnpcCustomize.HairColor); - customize.Data.Set(11, bnpcCustomize.HairHighlightColor); - customize.Data.Set(12, bnpcCustomize.FacialFeature); - customize.Data.Set(13, bnpcCustomize.FacialFeatureColor); - customize.Data.Set(14, bnpcCustomize.Eyebrows); - customize.Data.Set(15, bnpcCustomize.EyeColor); - customize.Data.Set(16, bnpcCustomize.EyeShape); - customize.Data.Set(17, bnpcCustomize.Nose); - customize.Data.Set(18, bnpcCustomize.Jaw); - customize.Data.Set(19, bnpcCustomize.Mouth); - customize.Data.Set(20, bnpcCustomize.LipColor); - customize.Data.Set(21, bnpcCustomize.BustOrTone1); - customize.Data.Set(22, bnpcCustomize.ExtraFeature1); - customize.Data.Set(23, bnpcCustomize.ExtraFeature2OrBust); - customize.Data.Set(24, bnpcCustomize.FacePaint); - customize.Data.Set(25, bnpcCustomize.FacePaintColor); + var customize = new CustomizeArray(); + customize.SetByIndex(0, (CustomizeValue) (byte)bnpcCustomize.Race.Row); + customize.SetByIndex(1, (CustomizeValue) bnpcCustomize.Gender); + customize.SetByIndex(2, (CustomizeValue) bnpcCustomize.BodyType); + customize.SetByIndex(3, (CustomizeValue) bnpcCustomize.Height); + customize.SetByIndex(4, (CustomizeValue) (byte)bnpcCustomize.Tribe.Row); + customize.SetByIndex(5, (CustomizeValue) bnpcCustomize.Face); + customize.SetByIndex(6, (CustomizeValue) bnpcCustomize.HairStyle); + customize.SetByIndex(7, (CustomizeValue) bnpcCustomize.HairHighlight); + customize.SetByIndex(8, (CustomizeValue) bnpcCustomize.SkinColor); + customize.SetByIndex(9, (CustomizeValue) bnpcCustomize.EyeHeterochromia); + customize.SetByIndex(10, (CustomizeValue) bnpcCustomize.HairColor); + customize.SetByIndex(11, (CustomizeValue) bnpcCustomize.HairHighlightColor); + customize.SetByIndex(12, (CustomizeValue) bnpcCustomize.FacialFeature); + customize.SetByIndex(13, (CustomizeValue) bnpcCustomize.FacialFeatureColor); + customize.SetByIndex(14, (CustomizeValue) bnpcCustomize.Eyebrows); + customize.SetByIndex(15, (CustomizeValue) bnpcCustomize.EyeColor); + customize.SetByIndex(16, (CustomizeValue) bnpcCustomize.EyeShape); + customize.SetByIndex(17, (CustomizeValue) bnpcCustomize.Nose); + customize.SetByIndex(18, (CustomizeValue) bnpcCustomize.Jaw); + customize.SetByIndex(19, (CustomizeValue) bnpcCustomize.Mouth); + customize.SetByIndex(20, (CustomizeValue) bnpcCustomize.LipColor); + customize.SetByIndex(21, (CustomizeValue) bnpcCustomize.BustOrTone1); + customize.SetByIndex(22, (CustomizeValue) bnpcCustomize.ExtraFeature1); + customize.SetByIndex(23, (CustomizeValue) bnpcCustomize.ExtraFeature2OrBust); + customize.SetByIndex(24, (CustomizeValue) bnpcCustomize.FacePaint); + customize.SetByIndex(25, (CustomizeValue) bnpcCustomize.FacePaintColor); if (customize.BodyType.Value != 1 || !CustomizationOptions.Races.Contains(customize.Race) || !CustomizationOptions.Clans.Contains(customize.Clan) || !CustomizationOptions.Genders.Contains(customize.Gender)) - return (false, Customize.Default); + return (false, CustomizeArray.Default); return (true, customize); } - private static (bool, Customize) FromEnpcBase(ENpcBase enpcBase) + private static (bool, CustomizeArray) FromEnpcBase(ENpcBase enpcBase) { if (enpcBase.ModelChara.Value?.Type != 1) - return (false, Customize.Default); + return (false, CustomizeArray.Default); - var customize = new Customize(); - customize.Data.Set(0, (byte)enpcBase.Race.Row); - customize.Data.Set(1, enpcBase.Gender); - customize.Data.Set(2, enpcBase.BodyType); - customize.Data.Set(3, enpcBase.Height); - customize.Data.Set(4, (byte)enpcBase.Tribe.Row); - customize.Data.Set(5, enpcBase.Face); - customize.Data.Set(6, enpcBase.HairStyle); - customize.Data.Set(7, enpcBase.HairHighlight); - customize.Data.Set(8, enpcBase.SkinColor); - customize.Data.Set(9, enpcBase.EyeHeterochromia); - customize.Data.Set(10, enpcBase.HairColor); - customize.Data.Set(11, enpcBase.HairHighlightColor); - customize.Data.Set(12, enpcBase.FacialFeature); - customize.Data.Set(13, enpcBase.FacialFeatureColor); - customize.Data.Set(14, enpcBase.Eyebrows); - customize.Data.Set(15, enpcBase.EyeColor); - customize.Data.Set(16, enpcBase.EyeShape); - customize.Data.Set(17, enpcBase.Nose); - customize.Data.Set(18, enpcBase.Jaw); - customize.Data.Set(19, enpcBase.Mouth); - customize.Data.Set(20, enpcBase.LipColor); - customize.Data.Set(21, enpcBase.BustOrTone1); - customize.Data.Set(22, enpcBase.ExtraFeature1); - customize.Data.Set(23, enpcBase.ExtraFeature2OrBust); - customize.Data.Set(24, enpcBase.FacePaint); - customize.Data.Set(25, enpcBase.FacePaintColor); + var customize = new CustomizeArray(); + customize.SetByIndex(0, (CustomizeValue) (byte)enpcBase.Race.Row); + customize.SetByIndex(1, (CustomizeValue) enpcBase.Gender); + customize.SetByIndex(2, (CustomizeValue) enpcBase.BodyType); + customize.SetByIndex(3, (CustomizeValue) enpcBase.Height); + customize.SetByIndex(4, (CustomizeValue) (byte)enpcBase.Tribe.Row); + customize.SetByIndex(5, (CustomizeValue) enpcBase.Face); + customize.SetByIndex(6, (CustomizeValue) enpcBase.HairStyle); + customize.SetByIndex(7, (CustomizeValue) enpcBase.HairHighlight); + customize.SetByIndex(8, (CustomizeValue) enpcBase.SkinColor); + customize.SetByIndex(9, (CustomizeValue) enpcBase.EyeHeterochromia); + customize.SetByIndex(10, (CustomizeValue) enpcBase.HairColor); + customize.SetByIndex(11, (CustomizeValue) enpcBase.HairHighlightColor); + customize.SetByIndex(12, (CustomizeValue) enpcBase.FacialFeature); + customize.SetByIndex(13, (CustomizeValue) enpcBase.FacialFeatureColor); + customize.SetByIndex(14, (CustomizeValue) enpcBase.Eyebrows); + customize.SetByIndex(15, (CustomizeValue) enpcBase.EyeColor); + customize.SetByIndex(16, (CustomizeValue) enpcBase.EyeShape); + customize.SetByIndex(17, (CustomizeValue) enpcBase.Nose); + customize.SetByIndex(18, (CustomizeValue) enpcBase.Jaw); + customize.SetByIndex(19, (CustomizeValue) enpcBase.Mouth); + customize.SetByIndex(20, (CustomizeValue) enpcBase.LipColor); + customize.SetByIndex(21, (CustomizeValue) enpcBase.BustOrTone1); + customize.SetByIndex(22, (CustomizeValue) enpcBase.ExtraFeature1); + customize.SetByIndex(23, (CustomizeValue) enpcBase.ExtraFeature2OrBust); + customize.SetByIndex(24, (CustomizeValue) enpcBase.FacePaint); + customize.SetByIndex(25, (CustomizeValue) enpcBase.FacePaintColor); if (customize.BodyType.Value != 1 || !CustomizationOptions.Races.Contains(customize.Race) || !CustomizationOptions.Clans.Contains(customize.Clan) || !CustomizationOptions.Genders.Contains(customize.Gender)) - return (false, Customize.Default); + return (false, CustomizeArray.Default); return (true, customize); } diff --git a/Glamourer.GameData/Customization/NpcData.cs b/Glamourer/GameData/NpcData.cs similarity index 93% rename from Glamourer.GameData/Customization/NpcData.cs rename to Glamourer/GameData/NpcData.cs index 6942147..70bfe58 100644 --- a/Glamourer.GameData/Customization/NpcData.cs +++ b/Glamourer/GameData/NpcData.cs @@ -3,12 +3,12 @@ using System.Text; using FFXIVClientStructs.FFXIV.Client.Game.Object; using Penumbra.GameData.Structs; -namespace Glamourer.Customization; +namespace Glamourer.GameData; public unsafe struct NpcData { public string Name; - public Customize Customize; + public CustomizeArray Customize; private fixed byte _equip[40]; public CharacterWeapon Mainhand; public CharacterWeapon Offhand; diff --git a/Glamourer/Glamourer.csproj b/Glamourer/Glamourer.csproj index 12ec3a7..0d2bb36 100644 --- a/Glamourer/Glamourer.csproj +++ b/Glamourer/Glamourer.csproj @@ -84,7 +84,6 @@ - @@ -109,8 +108,8 @@ - - + + diff --git a/Glamourer/Gui/Customization/CustomizationDrawer.Color.cs b/Glamourer/Gui/Customization/CustomizationDrawer.Color.cs index 127d8c2..5fa28a6 100644 --- a/Glamourer/Gui/Customization/CustomizationDrawer.Color.cs +++ b/Glamourer/Gui/Customization/CustomizationDrawer.Color.cs @@ -1,11 +1,11 @@ using System.Numerics; using Dalamud.Interface; using Dalamud.Interface.Utility; -using Glamourer.Customization; +using Glamourer.GameData; using ImGuiNET; using OtterGui; using OtterGui.Raii; -using Penumbra.GameData; +using Penumbra.GameData.Enums; namespace Glamourer.Gui.Customization; @@ -15,12 +15,12 @@ public partial class CustomizationDrawer private void DrawColorPicker(CustomizeIndex index) { - using var _ = SetId(index); + using var id = SetId(index); var (current, custom) = GetCurrentCustomization(index); var color = ImGui.ColorConvertU32ToFloat4(current < 0 ? ImGui.GetColorU32(ImGuiCol.FrameBg) : custom.Color); - using (var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, 2 * ImGuiHelpers.GlobalScale, current < 0)) + using (_ = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, 2 * ImGuiHelpers.GlobalScale, current < 0)) { if (ImGui.ColorButton($"{_customize[index].Value}##color", color, ImGuiColorEditFlags.None, _framedIconSize)) ImGui.OpenPopup(ColorPickerPopupName); @@ -39,7 +39,7 @@ public partial class CustomizationDrawer ImGui.SameLine(); - using (var group = ImRaii.Group()) + using (_ = ImRaii.Group()) { DataInputInt(current, npc); if (_withApply) @@ -89,7 +89,7 @@ public partial class CustomizationDrawer { var current = _set.DataByValue(index, _customize[index], out var custom, _customize.Face); if (_set.IsAvailable(index) && current < 0) - return (current, new CustomizeData(index, _customize[index], 0, 0)); + return (current, new CustomizeData(index, _customize[index])); return (current, custom!.Value); } diff --git a/Glamourer/Gui/Customization/CustomizationDrawer.GenderRace.cs b/Glamourer/Gui/Customization/CustomizationDrawer.GenderRace.cs index 7866bda..097d99b 100644 --- a/Glamourer/Gui/Customization/CustomizationDrawer.GenderRace.cs +++ b/Glamourer/Gui/Customization/CustomizationDrawer.GenderRace.cs @@ -1,7 +1,7 @@ using System; using System.Linq; using Dalamud.Interface; -using Glamourer.Customization; +using Glamourer.GameData; using ImGuiNET; using OtterGui; using OtterGui.Raii; diff --git a/Glamourer/Gui/Customization/CustomizationDrawer.Icon.cs b/Glamourer/Gui/Customization/CustomizationDrawer.Icon.cs index f435ba8..939b0f6 100644 --- a/Glamourer/Gui/Customization/CustomizationDrawer.Icon.cs +++ b/Glamourer/Gui/Customization/CustomizationDrawer.Icon.cs @@ -1,9 +1,11 @@ using System; using System.Numerics; -using Glamourer.Customization; +using Glamourer.GameData; using ImGuiNET; using OtterGui; using OtterGui.Raii; +using Penumbra.GameData.Enums; +using Penumbra.GameData.Structs; namespace Glamourer.Gui.Customization; @@ -13,7 +15,7 @@ public partial class CustomizationDrawer private void DrawIconSelector(CustomizeIndex index) { - using var _ = SetId(index); + using var id = SetId(index); using var bigGroup = ImRaii.Group(); var label = _currentOption; @@ -28,7 +30,7 @@ public partial class CustomizationDrawer } var icon = _service.Service.GetIcon(custom!.Value.IconId); - using (var disabled = ImRaii.Disabled(_locked || _currentIndex is CustomizeIndex.Face && _lockedRedraw)) + using (_ = ImRaii.Disabled(_locked || _currentIndex is CustomizeIndex.Face && _lockedRedraw)) { if (ImGui.ImageButton(icon.ImGuiHandle, _iconSize)) ImGui.OpenPopup(IconSelectorPopup); @@ -37,7 +39,7 @@ public partial class CustomizationDrawer ImGuiUtil.HoverIconTooltip(icon, _iconSize); ImGui.SameLine(); - using (var group = ImRaii.Group()) + using (_ = ImRaii.Group()) { DataInputInt(current, npc); if (_lockedRedraw && ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) @@ -118,16 +120,16 @@ public partial class CustomizationDrawer ImGui.Dummy(new Vector2(ImGui.GetFrameHeight())); } - var oldValue = _customize.Data.At(_currentIndex.ToByteAndMask().ByteIdx); - var tmp = (int)oldValue; + var oldValue = _customize.AtIndex(_currentIndex.ToByteAndMask().ByteIdx); + var tmp = (int)oldValue.Value; ImGui.SetNextItemWidth(_inputIntSize); if (ImGui.InputInt("##text", ref tmp, 1, 1)) { tmp = Math.Clamp(tmp, 0, byte.MaxValue); - if (tmp != oldValue) + if (tmp != oldValue.Value) { - _customize.Data.Set(_currentIndex.ToByteAndMask().ByteIdx, (byte)tmp); - var changes = (byte)tmp ^ oldValue; + _customize.SetByIndex(_currentIndex.ToByteAndMask().ByteIdx, (CustomizeValue)tmp); + var changes = (byte)tmp ^ oldValue.Value; Changed |= ((changes & 0x01) == 0x01 ? CustomizeFlag.FacialFeature1 : 0) | ((changes & 0x02) == 0x02 ? CustomizeFlag.FacialFeature2 : 0) | ((changes & 0x04) == 0x04 ? CustomizeFlag.FacialFeature3 : 0) diff --git a/Glamourer/Gui/Customization/CustomizationDrawer.Simple.cs b/Glamourer/Gui/Customization/CustomizationDrawer.Simple.cs index e9ce9e9..e970fb3 100644 --- a/Glamourer/Gui/Customization/CustomizationDrawer.Simple.cs +++ b/Glamourer/Gui/Customization/CustomizationDrawer.Simple.cs @@ -1,10 +1,10 @@ using System; using System.Numerics; -using Glamourer.Customization; using ImGuiNET; using OtterGui; using OtterGui.Raii; using Penumbra.GameData.Enums; +using Penumbra.GameData.Structs; namespace Glamourer.Gui.Customization; @@ -91,10 +91,10 @@ public partial class CustomizationDrawer private void DrawListSelector(CustomizeIndex index, bool indexedBy1) { - using var _ = SetId(index); + using var id = SetId(index); using var bigGroup = ImRaii.Group(); - using (var disabled = ImRaii.Disabled(_locked)) + using (_ = ImRaii.Disabled(_locked)) { if (indexedBy1) { @@ -210,7 +210,7 @@ public partial class CustomizationDrawer } else { - using (var disabled = ImRaii.Disabled(_locked)) + using (_ = ImRaii.Disabled(_locked)) { if (ImGui.Checkbox("##toggle", ref tmp)) { diff --git a/Glamourer/Gui/Customization/CustomizationDrawer.cs b/Glamourer/Gui/Customization/CustomizationDrawer.cs index a288065..c131cf5 100644 --- a/Glamourer/Gui/Customization/CustomizationDrawer.cs +++ b/Glamourer/Gui/Customization/CustomizationDrawer.cs @@ -4,7 +4,7 @@ using System.Reflection; using Dalamud.Interface.Internal; using Dalamud.Interface.Utility; using Dalamud.Plugin; -using Glamourer.Customization; +using Glamourer.GameData; using Glamourer.Services; using ImGuiNET; using OtterGui; @@ -22,13 +22,12 @@ public partial class CustomizationDrawer(DalamudPluginInterface pi, Customizatio private Exception? _terminate; - private Customize _customize = Customize.Default; + private CustomizeArray _customize = CustomizeArray.Default; private CustomizationSet _set = null!; - public Customize Customize + public CustomizeArray Customize => _customize; - public CustomizeFlag CurrentFlag { get; private set; } public CustomizeFlag Changed { get; private set; } public CustomizeFlag ChangeApply { get; private set; } @@ -47,18 +46,16 @@ public partial class CustomizationDrawer(DalamudPluginInterface pi, Customizatio public void Dispose() => _legacyTattoo?.Dispose(); - public bool Draw(Customize current, bool locked, bool lockedRedraw) + public bool Draw(CustomizeArray current, bool locked, bool lockedRedraw) { - CurrentFlag = CustomizeFlagExtensions.All; _withApply = false; Init(current, locked, lockedRedraw); return DrawInternal(); } - public bool Draw(Customize current, CustomizeFlag apply, bool locked, bool lockedRedraw) + public bool Draw(CustomizeArray current, CustomizeFlag apply, bool locked, bool lockedRedraw) { - CurrentFlag = CustomizeFlagExtensions.All; ChangeApply = apply; _initialApply = apply; _withApply = !_config.HideApplyCheckmarks; @@ -66,12 +63,12 @@ public partial class CustomizationDrawer(DalamudPluginInterface pi, Customizatio return DrawInternal(); } - private void Init(Customize current, bool locked, bool lockedRedraw) + private void Init(CustomizeArray current, bool locked, bool lockedRedraw) { UpdateSizes(); - _terminate = null; - Changed = 0; - _customize.Load(current); + _terminate = null; + Changed = 0; + _customize = current; _locked = locked; _lockedRedraw = lockedRedraw; } @@ -156,20 +153,20 @@ public partial class CustomizationDrawer(DalamudPluginInterface pi, Customizatio for (var i = 0; i < CustomizeArray.Size; ++i) { using var id = ImRaii.PushId(i); - int value = _customize.Data.Data[i]; + int value = _customize.Data[i]; ImGui.SetNextItemWidth(40 * ImGuiHelpers.GlobalScale); if (ImGui.InputInt(string.Empty, ref value, 0, 0)) { var newValue = (byte)Math.Clamp(value, 0, byte.MaxValue); - if (newValue != _customize.Data.Data[i]) + if (newValue != _customize.Data[i]) foreach (var flag in Enum.GetValues()) { - var (j, mask) = flag.ToByteAndMask(); + var (j, _) = flag.ToByteAndMask(); if (j == i) Changed |= flag.ToFlag(); } - _customize.Data.Data[i] = newValue; + _customize.Data[i] = newValue; } } diff --git a/Glamourer/Gui/DesignCombo.cs b/Glamourer/Gui/DesignCombo.cs index 19d73c4..e82ab3c 100644 --- a/Glamourer/Gui/DesignCombo.cs +++ b/Glamourer/Gui/DesignCombo.cs @@ -4,7 +4,7 @@ using System.Linq; using Dalamud.Interface.Utility; using Dalamud.Interface.Utility.Raii; using Glamourer.Automation; -using Glamourer.Customization; +using Glamourer.GameData; using Glamourer.Designs; using Glamourer.Events; using Glamourer.Services; @@ -13,6 +13,7 @@ using OtterGui; using OtterGui.Classes; using OtterGui.Log; using OtterGui.Widgets; +using Penumbra.GameData.Enums; namespace Glamourer.Gui; diff --git a/Glamourer/Gui/PenumbraChangedItemTooltip.cs b/Glamourer/Gui/PenumbraChangedItemTooltip.cs index e70cd5d..b499bc1 100644 --- a/Glamourer/Gui/PenumbraChangedItemTooltip.cs +++ b/Glamourer/Gui/PenumbraChangedItemTooltip.cs @@ -7,7 +7,6 @@ using Glamourer.Interop; using Glamourer.Interop.Penumbra; using Glamourer.Services; using Glamourer.State; -using Glamourer.Structs; using ImGuiNET; using OtterGui.Raii; using Penumbra.Api.Enums; @@ -76,7 +75,7 @@ public class PenumbraChangedItemTooltip : IDisposable case EquipSlot.OffHand when !CanApplyWeapon(EquipSlot.OffHand, item): break; case EquipSlot.RFinger: - using (var tt = !openTooltip ? null : ImRaii.Tooltip()) + using (_ = !openTooltip ? null : ImRaii.Tooltip()) { ImGui.TextUnformatted($"{prefix}Right-Click to apply to current actor (Right Finger)."); ImGui.TextUnformatted($"{prefix}Shift + Right-Click to apply to current actor (Left Finger)."); @@ -92,7 +91,7 @@ public class PenumbraChangedItemTooltip : IDisposable break; default: - using (var tt = !openTooltip ? null : ImRaii.Tooltip()) + using (_ = !openTooltip ? null : ImRaii.Tooltip()) { ImGui.TextUnformatted($"{prefix}Right-Click to apply to current actor."); if (last.Valid) diff --git a/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs b/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs index 15d3725..b56b314 100644 --- a/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs +++ b/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs @@ -6,7 +6,6 @@ using Dalamud.Interface.Internal.Notifications; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Game; using Glamourer.Automation; -using Glamourer.Customization; using Glamourer.Designs; using Glamourer.Events; using Glamourer.Gui.Customization; @@ -14,7 +13,6 @@ using Glamourer.Gui.Equipment; using Glamourer.Interop; using Glamourer.Interop.Structs; using Glamourer.State; -using Glamourer.Structs; using ImGuiNET; using OtterGui; using OtterGui.Classes; @@ -173,21 +171,21 @@ public class ActorPanel( private void DrawEquipmentMetaToggles() { - using (var _ = ImRaii.Group()) + using (_ = ImRaii.Group()) { EquipmentDrawer.DrawMetaToggle(ToggleDrawData.FromState(ActorState.MetaIndex.HatState, _stateManager, _state!)); EquipmentDrawer.DrawMetaToggle(ToggleDrawData.CrestFromState(CrestFlag.Head, _stateManager, _state!)); } ImGui.SameLine(); - using (var _ = ImRaii.Group()) + using (_ = ImRaii.Group()) { EquipmentDrawer.DrawMetaToggle(ToggleDrawData.FromState(ActorState.MetaIndex.VisorState, _stateManager, _state!)); EquipmentDrawer.DrawMetaToggle(ToggleDrawData.CrestFromState(CrestFlag.Body, _stateManager, _state!)); } ImGui.SameLine(); - using (var _ = ImRaii.Group()) + using (_ = ImRaii.Group()) { EquipmentDrawer.DrawMetaToggle(ToggleDrawData.FromState(ActorState.MetaIndex.WeaponState, _stateManager, _state!)); EquipmentDrawer.DrawMetaToggle(ToggleDrawData.CrestFromState(CrestFlag.OffHand, _stateManager, _state!)); @@ -199,7 +197,7 @@ public class ActorPanel( var names = _modelChara[_state!.ModelData.ModelId]; var turnHuman = ImGui.Button("Turn Human"); ImGui.Separator(); - using (var box = ImRaii.ListBox("##MonsterList", + using (_ = ImRaii.ListBox("##MonsterList", new Vector2(ImGui.GetContentRegionAvail().X, 10 * ImGui.GetTextLineHeightWithSpacing()))) { if (names.Count == 0) @@ -211,14 +209,14 @@ public class ActorPanel( ImGui.Separator(); ImGui.TextUnformatted("Customization Data"); - using (var font = ImRaii.PushFont(UiBuilder.MonoFont)) + using (_ = ImRaii.PushFont(UiBuilder.MonoFont)) { - foreach (var b in _state.ModelData.Customize.Data) + foreach (var b in _state.ModelData.Customize) { - using (var g = ImRaii.Group()) + using (_ = ImRaii.Group()) { - ImGui.TextUnformatted($" {b:X2}"); - ImGui.TextUnformatted($"{b,3}"); + ImGui.TextUnformatted($" {b.Value:X2}"); + ImGui.TextUnformatted($"{b.Value,3}"); } ImGui.SameLine(); @@ -232,11 +230,11 @@ public class ActorPanel( ImGui.Separator(); ImGui.TextUnformatted("Equipment Data"); - using (var font = ImRaii.PushFont(UiBuilder.MonoFont)) + using (_ = ImRaii.PushFont(UiBuilder.MonoFont)) { foreach (var b in _state.ModelData.GetEquipmentBytes()) { - using (var g = ImRaii.Group()) + using (_ = ImRaii.Group()) { ImGui.TextUnformatted($" {b:X2}"); ImGui.TextUnformatted($"{b,3}"); @@ -298,8 +296,8 @@ public class ActorPanel( BorderColor = ColorId.ActorUnavailable.Value(), }; - private string _newName = string.Empty; - private DesignBase? _newDesign = null; + private string _newName = string.Empty; + private DesignBase? _newDesign; private void SaveDesignOpen() { diff --git a/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs b/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs index 3eba0cd..2a0453c 100644 --- a/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs +++ b/Glamourer/Gui/Tabs/AutomationTab/SetPanel.cs @@ -6,10 +6,8 @@ using System.Text; using Dalamud.Interface; using Dalamud.Interface.Utility; using Glamourer.Automation; -using Glamourer.Customization; using Glamourer.Interop; using Glamourer.Services; -using Glamourer.Structs; using Glamourer.Unlocks; using ImGuiNET; using OtterGui; @@ -17,44 +15,29 @@ using OtterGui.Log; using OtterGui.Raii; using OtterGui.Widgets; using Penumbra.GameData.Enums; +using Penumbra.GameData.Structs; using Action = System.Action; -using CustomizeIndex = Glamourer.Customization.CustomizeIndex; namespace Glamourer.Gui.Tabs.AutomationTab; -public class SetPanel +public class SetPanel( + SetSelector _selector, + AutoDesignManager _manager, + JobService _jobs, + ItemUnlockManager _itemUnlocks, + RevertDesignCombo _designCombo, + CustomizeUnlockManager _customizeUnlocks, + CustomizationService _customizations, + IdentifierDrawer _identifierDrawer, + Configuration _config) { - private readonly AutoDesignManager _manager; - private readonly SetSelector _selector; - private readonly ItemUnlockManager _itemUnlocks; - private readonly CustomizeUnlockManager _customizeUnlocks; - private readonly CustomizationService _customizations; - - private readonly Configuration _config; - private readonly RevertDesignCombo _designCombo; - private readonly JobGroupCombo _jobGroupCombo; - private readonly IdentifierDrawer _identifierDrawer; + private readonly JobGroupCombo _jobGroupCombo = new(_manager, _jobs, Glamourer.Log); private string? _tempName; private int _dragIndex = -1; private Action? _endAction; - public SetPanel(SetSelector selector, AutoDesignManager manager, JobService jobs, ItemUnlockManager itemUnlocks, - RevertDesignCombo designCombo, - CustomizeUnlockManager customizeUnlocks, CustomizationService customizations, IdentifierDrawer identifierDrawer, Configuration config) - { - _selector = selector; - _manager = manager; - _itemUnlocks = itemUnlocks; - _customizeUnlocks = customizeUnlocks; - _customizations = customizations; - _identifierDrawer = identifierDrawer; - _config = config; - _designCombo = designCombo; - _jobGroupCombo = new JobGroupCombo(manager, jobs, Glamourer.Log); - } - private AutoDesignSet Selection => _selector.Selection!; @@ -77,7 +60,7 @@ public class SetPanel var spacing = ImGui.GetStyle().ItemInnerSpacing with { Y = ImGui.GetStyle().ItemSpacing.Y }; - using (var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing)) + using (_ = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing)) { var enabled = Selection.Enabled; if (ImGui.Checkbox("##Enabled", ref enabled)) @@ -87,7 +70,7 @@ public class SetPanel } ImGui.SameLine(); - using (var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing)) + using (_ = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing)) { var useGame = _selector.Selection!.BaseState is AutoDesignSet.Base.Game; if (ImGui.Checkbox("##gameState", ref useGame)) @@ -98,7 +81,7 @@ public class SetPanel } ImGui.SameLine(); - using (var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing)) + using (_ = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing)) { var editing = _config.ShowAutomationSetEditing; if (ImGui.Checkbox("##Show Editing", ref editing)) @@ -230,7 +213,7 @@ public class SetPanel if (_config.ShowUnlockedItemWarnings) { ImGui.TableNextColumn(); - DrawWarnings(design, idx); + DrawWarnings(design); } } @@ -278,7 +261,7 @@ public class SetPanel } } - private void DrawWarnings(AutoDesign design, int idx) + private void DrawWarnings(AutoDesign design) { if (design.Revert) return; @@ -301,27 +284,6 @@ public class SetPanel using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, new Vector2(2 * ImGuiHelpers.GlobalScale, 0)); - - static void DrawWarning(StringBuilder sb, uint color, Vector2 size, string suffix, string good) - { - using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale); - if (sb.Length > 0) - { - sb.Append(suffix); - using (var font = ImRaii.PushFont(UiBuilder.IconFont)) - { - ImGuiUtil.DrawTextButton(FontAwesomeIcon.ExclamationCircle.ToIconString(), size, color); - } - - ImGuiUtil.HoverTooltip(sb.ToString()); - } - else - { - ImGuiUtil.DrawTextButton(string.Empty, size, 0); - ImGuiUtil.HoverTooltip(good); - } - } - var tt = _config.UnlockedItemMode ? "\nThese items will be skipped when applied automatically.\n\nTo change this, disable the Obtained Item Mode setting." : string.Empty; @@ -355,6 +317,27 @@ public class SetPanel : string.Empty; DrawWarning(sb2, _config.UnlockedItemMode ? 0xA03030F0 : 0x0, size, tt, "All customizations to be applied are unlocked."); ImGui.SameLine(); + return; + + static void DrawWarning(StringBuilder sb, uint color, Vector2 size, string suffix, string good) + { + using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale); + if (sb.Length > 0) + { + sb.Append(suffix); + using (_ = ImRaii.PushFont(UiBuilder.IconFont)) + { + ImGuiUtil.DrawTextButton(FontAwesomeIcon.ExclamationCircle.ToIconString(), size, color); + } + + ImGuiUtil.HoverTooltip(sb.ToString()); + } + else + { + ImGuiUtil.DrawTextButton(string.Empty, size, 0); + ImGuiUtil.HoverTooltip(good); + } + } } private void DrawDragDrop(AutoDesignSet set, int index) @@ -394,7 +377,7 @@ public class SetPanel var newType = design.ApplicationType; var newTypeInt = (uint)newType; style.Push(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale); - using (var c = ImRaii.PushColor(ImGuiCol.Border, ColorId.FolderLine.Value())) + using (_ = ImRaii.PushColor(ImGuiCol.Border, ColorId.FolderLine.Value())) { if (ImGui.CheckboxFlags("##all", ref newTypeInt, (uint)AutoDesign.Type.All)) newType = (AutoDesign.Type)newTypeInt; diff --git a/Glamourer/Gui/Tabs/DebugTab/ActiveStatePanel.cs b/Glamourer/Gui/Tabs/DebugTab/ActiveStatePanel.cs index 298fe0e..bbcfa32 100644 --- a/Glamourer/Gui/Tabs/DebugTab/ActiveStatePanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/ActiveStatePanel.cs @@ -2,7 +2,7 @@ using System.Linq; using System.Numerics; using Dalamud.Interface; -using Glamourer.Customization; +using Glamourer.GameData; using Glamourer.Designs; using Glamourer.Events; using Glamourer.Interop; diff --git a/Glamourer/Gui/Tabs/DebugTab/CustomizationServicePanel.cs b/Glamourer/Gui/Tabs/DebugTab/CustomizationServicePanel.cs index 9906387..c57c1b5 100644 --- a/Glamourer/Gui/Tabs/DebugTab/CustomizationServicePanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/CustomizationServicePanel.cs @@ -1,9 +1,10 @@ using System; -using Glamourer.Customization; +using Glamourer.GameData; using Glamourer.Services; using ImGuiNET; using OtterGui; using OtterGui.Raii; +using Penumbra.GameData.Enums; namespace Glamourer.Gui.Tabs.DebugTab; diff --git a/Glamourer/Gui/Tabs/DebugTab/CustomizationUnlockPanel.cs b/Glamourer/Gui/Tabs/DebugTab/CustomizationUnlockPanel.cs index f253923..b062980 100644 --- a/Glamourer/Gui/Tabs/DebugTab/CustomizationUnlockPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/CustomizationUnlockPanel.cs @@ -1,10 +1,10 @@ using System; using System.Numerics; -using Glamourer.Customization; using Glamourer.Unlocks; using ImGuiNET; using OtterGui; using OtterGui.Raii; +using Penumbra.GameData.Enums; namespace Glamourer.Gui.Tabs.DebugTab; diff --git a/Glamourer/Gui/Tabs/DebugTab/DatFilePanel.cs b/Glamourer/Gui/Tabs/DebugTab/DatFilePanel.cs index 85ba96c..ef76b09 100644 --- a/Glamourer/Gui/Tabs/DebugTab/DatFilePanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/DatFilePanel.cs @@ -1,10 +1,9 @@ using System.IO; using System.Numerics; -using Glamourer.Customization; using Glamourer.Interop; using ImGuiNET; using OtterGui; -using OtterGui.Raii; +using Penumbra.GameData.Files; namespace Glamourer.Gui.Tabs.DebugTab; @@ -35,7 +34,7 @@ public class DatFilePanel(ImportService _importService) : IDebugTabTree ImGui.TextUnformatted(_datFile.Value.Version.ToString()); ImGui.TextUnformatted(_datFile.Value.Time.LocalDateTime.ToString("g")); ImGui.TextUnformatted(_datFile.Value.Voice.ToString()); - ImGui.TextUnformatted(_datFile.Value.Customize.Data.ToString()); + ImGui.TextUnformatted(_datFile.Value.Customize.ToString()); ImGui.TextUnformatted(_datFile.Value.Description); } } diff --git a/Glamourer/Gui/Tabs/DebugTab/DesignManagerPanel.cs b/Glamourer/Gui/Tabs/DebugTab/DesignManagerPanel.cs index af4814a..8b7ae9a 100644 --- a/Glamourer/Gui/Tabs/DebugTab/DesignManagerPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/DesignManagerPanel.cs @@ -1,9 +1,7 @@ using System; using System.Linq; using Dalamud.Interface; -using Glamourer.Customization; using Glamourer.Designs; -using Glamourer.Structs; using ImGuiNET; using OtterGui; using OtterGui.Raii; diff --git a/Glamourer/Gui/Tabs/DebugTab/DesignTesterPanel.cs b/Glamourer/Gui/Tabs/DebugTab/DesignTesterPanel.cs index 03ba048..400b2b1 100644 --- a/Glamourer/Gui/Tabs/DebugTab/DesignTesterPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/DesignTesterPanel.cs @@ -1,10 +1,8 @@ using System; using System.Linq; using Dalamud.Interface; -using Glamourer.Customization; using Glamourer.Designs; using Glamourer.Services; -using Glamourer.Structs; using ImGuiNET; using OtterGui; using OtterGui.Raii; @@ -85,7 +83,7 @@ public class DesignTesterPanel(ItemManager _items, HumanModelList _humans) : IDe DrawDesignData(_parse64); using var font = ImRaii.PushFont(UiBuilder.MonoFont); ImGui.TextUnformatted(_base64); - using (var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, ImGui.GetStyle().ItemSpacing with { X = 0 })) + using (_ = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, ImGui.GetStyle().ItemSpacing with { X = 0 })) { foreach (var (c1, c2) in _restore.Zip(_base64)) { @@ -99,7 +97,7 @@ public class DesignTesterPanel(ItemManager _items, HumanModelList _humans) : IDe foreach (var ((b1, b2), idx) in _base64Bytes.Zip(_restoreBytes).WithIndex()) { - using (var group = ImRaii.Group()) + using (_ = ImRaii.Group()) { ImGui.TextUnformatted(idx.ToString("D2")); ImGui.TextUnformatted(b1.ToString("X2")); @@ -121,7 +119,7 @@ public class DesignTesterPanel(ItemManager _items, HumanModelList _humans) : IDe using var font = ImRaii.PushFont(UiBuilder.MonoFont); foreach (var (b, idx) in _base64Bytes.WithIndex()) { - using (var group = ImRaii.Group()) + using (_ = ImRaii.Group()) { ImGui.TextUnformatted(idx.ToString("D2")); ImGui.TextUnformatted(b.ToString("X2")); diff --git a/Glamourer/Gui/Tabs/DebugTab/JobPanel.cs b/Glamourer/Gui/Tabs/DebugTab/JobPanel.cs index 0fa8765..2318d98 100644 --- a/Glamourer/Gui/Tabs/DebugTab/JobPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/JobPanel.cs @@ -32,7 +32,7 @@ public class JobPanel(JobService _jobs) : IDebugTabTree foreach (var (id, job) in _jobs.Jobs) { - ImGuiUtil.DrawTableColumn(id.ToString("D3")); + ImGuiUtil.DrawTableColumn(id.Id.ToString("D3")); ImGuiUtil.DrawTableColumn(job.Name); ImGuiUtil.DrawTableColumn(job.Abbreviation); } @@ -68,7 +68,7 @@ public class JobPanel(JobService _jobs) : IDebugTabTree foreach (var (id, group) in _jobs.JobGroups) { - ImGuiUtil.DrawTableColumn(id.ToString("D3")); + ImGuiUtil.DrawTableColumn(id.Id.ToString("D3")); ImGuiUtil.DrawTableColumn(group.Name); ImGuiUtil.DrawTableColumn(group.Count.ToString()); } diff --git a/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs b/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs index e71c69a..596476b 100644 --- a/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/ModelEvaluationPanel.cs @@ -1,10 +1,8 @@ using System; using System.Numerics; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; -using Glamourer.Customization; using Glamourer.Interop; using Glamourer.Interop.Structs; -using Glamourer.Structs; using ImGuiNET; using OtterGui; using OtterGui.Raii; @@ -126,15 +124,14 @@ public unsafe class ModelEvaluationPanel( model.AsHuman->Head.Value == 0 ? actor.GetArmor(EquipSlot.Head) : CharacterArmor.Empty); } - private void DrawWeaponState(Actor actor, Model model) + private static void DrawWeaponState(Actor actor, Model model) { using var id = ImRaii.PushId("WeaponState"); ImGuiUtil.DrawTableColumn("Weapon State"); ImGuiUtil.DrawTableColumn(actor.IsCharacter ? actor.AsCharacter->DrawData.IsWeaponHidden ? "Hidden" : "Visible" : "No Character"); - var text = string.Empty; - + string text; if (!model.IsHuman) { text = "No Model"; @@ -146,19 +143,14 @@ public unsafe class ModelEvaluationPanel( else { var weapon = (DrawObject*)model.AsDrawObject->Object.ChildObject; - if ((weapon->Flags & 0x09) == 0x09) - text = "Visible"; - else - text = "Hidden"; + text = (weapon->Flags & 0x09) == 0x09 ? "Visible" : "Hidden"; } ImGuiUtil.DrawTableColumn(text); ImGui.TableNextColumn(); - if (!model.IsHuman) - return; } - private void DrawWetness(Actor actor, Model model) + private static void DrawWetness(Actor actor, Model model) { using var id = ImRaii.PushId("Wetness"); ImGuiUtil.DrawTableColumn("Wetness"); @@ -212,12 +204,12 @@ public unsafe class ModelEvaluationPanel( private void DrawCustomize(Actor actor, Model model) { using var id = ImRaii.PushId("Customize"); - var actorCustomize = new Customize(actor.IsCharacter + var actorCustomize = actor.IsCharacter ? *(CustomizeArray*)&actor.AsCharacter->DrawData.CustomizeData - : new CustomizeArray()); - var modelCustomize = new Customize(model.IsHuman + : new CustomizeArray(); + var modelCustomize = model.IsHuman ? *(CustomizeArray*)model.AsHuman->Customize.Data - : new CustomizeArray()); + : new CustomizeArray(); foreach (var type in Enum.GetValues()) { using var id2 = ImRaii.PushId((int)type); @@ -235,7 +227,7 @@ public unsafe class ModelEvaluationPanel( var shift = BitOperations.TrailingZeroCount(mask); var newValue = value + (1 << shift); modelCustomize.Set(type, (CustomizeValue)newValue); - _changeCustomizeService.UpdateCustomize(model, modelCustomize.Data); + _changeCustomizeService.UpdateCustomize(model, modelCustomize); } ImGui.SameLine(); @@ -246,14 +238,14 @@ public unsafe class ModelEvaluationPanel( var shift = BitOperations.TrailingZeroCount(mask); var newValue = value - (1 << shift); modelCustomize.Set(type, (CustomizeValue)newValue); - _changeCustomizeService.UpdateCustomize(model, modelCustomize.Data); + _changeCustomizeService.UpdateCustomize(model, modelCustomize); } ImGui.SameLine(); if (ImGui.SmallButton("Reset")) { modelCustomize.Set(type, actorCustomize[type]); - _changeCustomizeService.UpdateCustomize(model, modelCustomize.Data); + _changeCustomizeService.UpdateCustomize(model, modelCustomize); } } } diff --git a/Glamourer/Gui/Tabs/DebugTab/NpcAppearancePanel.cs b/Glamourer/Gui/Tabs/DebugTab/NpcAppearancePanel.cs index 90fc0f5..ffc4b72 100644 --- a/Glamourer/Gui/Tabs/DebugTab/NpcAppearancePanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/NpcAppearancePanel.cs @@ -3,14 +3,15 @@ using System.Numerics; using Dalamud.Interface; using Dalamud.Interface.Utility; using FFXIVClientStructs.FFXIV.Client.Game.Object; -using Glamourer.Customization; using Glamourer.Designs; using Glamourer.Events; +using Glamourer.GameData; using Glamourer.Interop; using Glamourer.State; using ImGuiNET; using OtterGui; using OtterGui.Raii; +using Penumbra.GameData.Enums; using ImGuiClip = OtterGui.ImGuiClip; namespace Glamourer.Gui.Tabs.DebugTab; @@ -24,7 +25,7 @@ public class NpcAppearancePanel(NpcCombo _npcCombo, StateManager _state, ObjectM => false; private string _npcFilter = string.Empty; - private bool _customizeOrGear = false; + private bool _customizeOrGear; public void Draw() { @@ -48,19 +49,17 @@ public class NpcAppearancePanel(NpcCombo _npcCombo, StateManager _state, ObjectM ImGui.TableNextRow(); var idx = 0; var remainder = ImGuiClip.FilteredClippedDraw(_npcCombo.Items, skips, - d => d.Name.Contains(_npcFilter, StringComparison.OrdinalIgnoreCase), Draw); + d => d.Name.Contains(_npcFilter, StringComparison.OrdinalIgnoreCase), DrawData); ImGui.TableNextColumn(); ImGuiClip.DrawEndDummy(remainder, ImGui.GetFrameHeightWithSpacing()); - - return; - void Draw(NpcData data) + void DrawData(NpcData data) { using var id = ImRaii.PushId(idx++); var disabled = !_state.GetOrCreate(_objectManager.Player, out var state); ImGui.TableNextColumn(); - if (ImGuiUtil.DrawDisabledButton("Apply", Vector2.Zero, string.Empty, disabled, false)) + if (ImGuiUtil.DrawDisabledButton("Apply", Vector2.Zero, string.Empty, disabled)) { foreach (var (slot, item, stain) in _designConverter.FromDrawData(data.Equip.ToArray(), data.Mainhand, data.Offhand)) _state.ChangeEquip(state!, slot, item, stain, StateChanged.Source.Manual); @@ -76,7 +75,7 @@ public class NpcAppearancePanel(NpcCombo _npcCombo, StateManager _state, ObjectM ImGui.AlignTextToFramePadding(); ImGui.TextUnformatted(data.Kind is ObjectKind.BattleNpc ? "B" : "E"); - using (var icon = ImRaii.PushFont(UiBuilder.IconFont)) + using (_ = ImRaii.PushFont(UiBuilder.IconFont)) { ImGui.TableNextColumn(); ImGui.AlignTextToFramePadding(); @@ -86,7 +85,7 @@ public class NpcAppearancePanel(NpcCombo _npcCombo, StateManager _state, ObjectM using var mono = ImRaii.PushFont(UiBuilder.MonoFont); ImGui.TableNextColumn(); ImGui.AlignTextToFramePadding(); - ImGui.TextUnformatted(_customizeOrGear ? data.Customize.Data.ToString() : data.WriteGear()); + ImGui.TextUnformatted(_customizeOrGear ? data.Customize.ToString() : data.WriteGear()); } } } diff --git a/Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs b/Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs index b6e5fa3..cd47606 100644 --- a/Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs +++ b/Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs @@ -7,14 +7,12 @@ using Dalamud.Interface.ImGuiFileDialog; using Dalamud.Interface.Internal.Notifications; using FFXIVClientStructs.FFXIV.Client.System.Framework; using Glamourer.Automation; -using Glamourer.Customization; using Glamourer.Designs; using Glamourer.Events; using Glamourer.Gui.Customization; using Glamourer.Gui.Equipment; using Glamourer.Interop; using Glamourer.State; -using Glamourer.Structs; using ImGuiNET; using OtterGui; using OtterGui.Classes; diff --git a/Glamourer/Gui/Tabs/NpcCombo.cs b/Glamourer/Gui/Tabs/NpcCombo.cs index 91f0db0..4b1274c 100644 --- a/Glamourer/Gui/Tabs/NpcCombo.cs +++ b/Glamourer/Gui/Tabs/NpcCombo.cs @@ -1,4 +1,4 @@ -using Glamourer.Customization; +using Glamourer.GameData; using OtterGui.Widgets; namespace Glamourer.Gui.Tabs; diff --git a/Glamourer/Gui/Tabs/UnlocksTab/UnlockOverview.cs b/Glamourer/Gui/Tabs/UnlocksTab/UnlockOverview.cs index 154e930..8953501 100644 --- a/Glamourer/Gui/Tabs/UnlocksTab/UnlockOverview.cs +++ b/Glamourer/Gui/Tabs/UnlocksTab/UnlockOverview.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Numerics; using Dalamud.Game.Text.SeStringHandling; using Dalamud.Interface.Utility; -using Glamourer.Customization; +using Glamourer.GameData; using Glamourer.Interop; using Glamourer.Services; using Glamourer.Unlocks; diff --git a/Glamourer/Gui/Tabs/UnlocksTab/UnlockTable.cs b/Glamourer/Gui/Tabs/UnlocksTab/UnlockTable.cs index 3f7531c..d7e1ce3 100644 --- a/Glamourer/Gui/Tabs/UnlocksTab/UnlockTable.cs +++ b/Glamourer/Gui/Tabs/UnlocksTab/UnlockTable.cs @@ -8,7 +8,6 @@ using Dalamud.Interface.Utility; using Glamourer.Events; using Glamourer.Interop; using Glamourer.Services; -using Glamourer.Structs; using Glamourer.Unlocks; using ImGuiNET; using OtterGui; diff --git a/Glamourer/Gui/ToggleDrawData.cs b/Glamourer/Gui/ToggleDrawData.cs index dda4584..5e7e813 100644 --- a/Glamourer/Gui/ToggleDrawData.cs +++ b/Glamourer/Gui/ToggleDrawData.cs @@ -2,7 +2,6 @@ using Glamourer.Designs; using Glamourer.Events; using Glamourer.State; -using Glamourer.Structs; using Penumbra.GameData.Enums; namespace Glamourer.Gui; diff --git a/Glamourer/Gui/UiHelpers.cs b/Glamourer/Gui/UiHelpers.cs index 2c64b42..d08fb18 100644 --- a/Glamourer/Gui/UiHelpers.cs +++ b/Glamourer/Gui/UiHelpers.cs @@ -1,9 +1,7 @@ using System.Numerics; using Dalamud.Interface; using Dalamud.Interface.Utility; -using Glamourer.Customization; using Glamourer.Services; -using Glamourer.Structs; using Glamourer.Unlocks; using ImGuiNET; using Lumina.Misc; @@ -61,7 +59,7 @@ public static class UiHelpers { var flags = (sbyte)(currentApply ? currentValue ? 1 : -1 : 0); using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, ImGui.GetStyle().ItemInnerSpacing); - using (var disabled = ImRaii.Disabled(locked)) + using (_ = ImRaii.Disabled(locked)) { if (new TristateCheckbox(ColorId.TriStateCross.Value(), ColorId.TriStateCheck.Value(), ColorId.TriStateNeutral.Value()).Draw( "##" + label, flags, out flags)) diff --git a/Glamourer/Interop/ChangeCustomizeService.cs b/Glamourer/Interop/ChangeCustomizeService.cs index ef7e762..947ce43 100644 --- a/Glamourer/Interop/ChangeCustomizeService.cs +++ b/Glamourer/Interop/ChangeCustomizeService.cs @@ -2,7 +2,6 @@ using Dalamud.Hooking; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; -using Glamourer.Customization; using Glamourer.Events; using Glamourer.Interop.Structs; using OtterGui.Classes; @@ -15,7 +14,7 @@ namespace Glamourer.Interop; /// Changes in Race, body type or Gender are probably ignored. /// This operates on draw objects, not game objects. /// -public unsafe class ChangeCustomizeService : EventWrapper>, ChangeCustomizeService.Priority> +public unsafe class ChangeCustomizeService : EventWrapper>, ChangeCustomizeService.Priority> { private readonly PenumbraReloaded _penumbraReloaded; private readonly IGameInteropProvider _interop; @@ -81,10 +80,11 @@ public unsafe class ChangeCustomizeService : EventWrapper(new Customize(*(CustomizeArray*)data)); + var customize = new Ref(*(CustomizeArray*)data); Invoke(this, (Model)human, customize); - ((Customize*)data)->Load(customize.Value); + *(CustomizeArray*)data = customize.Value; } + return _changeCustomizeHook.Original(human, data, skipEquipment); } } diff --git a/Glamourer/Interop/CharaFile/CharaFile.cs b/Glamourer/Interop/CharaFile/CharaFile.cs index 6a58809..9ddcc03 100644 --- a/Glamourer/Interop/CharaFile/CharaFile.cs +++ b/Glamourer/Interop/CharaFile/CharaFile.cs @@ -1,8 +1,6 @@ using System; -using Glamourer.Customization; using Glamourer.Designs; using Glamourer.Services; -using Glamourer.Structs; using Newtonsoft.Json.Linq; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; @@ -70,7 +68,7 @@ public sealed class CharaFile return; data.SetItem(slot, item); - data.SetStain(slot, (StainId)dye); + data.SetStain(slot, dye); flags |= slot.ToFlag(); flags |= slot.ToStainFlag(); } @@ -94,7 +92,7 @@ public sealed class CharaFile flags |= slot.ToStainFlag(); } - private static CustomizeFlag ParseCustomize(JObject jObj, ref Customize customize) + private static CustomizeFlag ParseCustomize(JObject jObj, ref CustomizeArray customize) { CustomizeFlag ret = 0; customize.Race = ParseRace(jObj, ref ret); @@ -149,7 +147,7 @@ public sealed class CharaFile return id; } - private static void ParseFacial(JObject jObj, ref Customize customize, ref CustomizeFlag application) + private static void ParseFacial(JObject jObj, ref CustomizeArray customize, ref CustomizeFlag application) { var jTok = jObj["FacialFeatures"]; if (jTok == null) @@ -186,7 +184,7 @@ public sealed class CharaFile customize[CustomizeIndex.LegacyTattoo] = CustomizeValue.Max; } - private static void ParseHighlights(JObject jObj, ref Customize customize, ref CustomizeFlag application) + private static void ParseHighlights(JObject jObj, ref CustomizeArray customize, ref CustomizeFlag application) { var jTok = jObj["EnableHighlights"]; if (jTok == null) @@ -242,15 +240,15 @@ public sealed class CharaFile throw new Exception($"Age {age} != Normal is not supported."); } - private static unsafe void ParseByte(JObject jObj, string property, CustomizeIndex idx, ref Customize customize, + private static unsafe void ParseByte(JObject jObj, string property, CustomizeIndex idx, ref CustomizeArray customize, ref CustomizeFlag application) { var jTok = jObj[property]; if (jTok == null) return; - customize.Data.Data[idx.ToByteAndMask().ByteIdx] = jTok.ToObject(); - application |= idx.ToFlag(); + customize.Data[idx.ToByteAndMask().ByteIdx] = jTok.ToObject(); + application |= idx.ToFlag(); } private static SubRace ParseTribe(JObject jObj, ref CustomizeFlag application) diff --git a/Glamourer/Interop/CharaFile/CmaFile.cs b/Glamourer/Interop/CharaFile/CmaFile.cs index c916ad8..e525e7e 100644 --- a/Glamourer/Interop/CharaFile/CmaFile.cs +++ b/Glamourer/Interop/CharaFile/CmaFile.cs @@ -42,7 +42,7 @@ public sealed class CmaFile var byteData = Convert.FromHexString(bytes); fixed (byte* ptr = byteData) { - data.Customize.Data.Read(ptr); + data.Customize.Read(ptr); } } @@ -64,7 +64,7 @@ public sealed class CmaFile data.SetStain(slot, armor.Stain); } - data.Customize.Data.Read(ptr); + data.Customize.Read(ptr); } } diff --git a/Glamourer/Interop/CrestService.cs b/Glamourer/Interop/CrestService.cs index 9285ec6..2bfa8d5 100644 --- a/Glamourer/Interop/CrestService.cs +++ b/Glamourer/Interop/CrestService.cs @@ -1,12 +1,10 @@ using System; -using System.Linq; using Dalamud.Hooking; using Dalamud.Plugin.Services; using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using Glamourer.Interop.Structs; -using Glamourer.Structs; using OtterGui.Classes; using Penumbra.GameData.Enums; diff --git a/Glamourer/Interop/ImportService.cs b/Glamourer/Interop/ImportService.cs index 86f2343..4cac25e 100644 --- a/Glamourer/Interop/ImportService.cs +++ b/Glamourer/Interop/ImportService.cs @@ -4,13 +4,14 @@ using System.IO; using System.Linq; using Dalamud.Interface.DragDrop; using Dalamud.Interface.Internal.Notifications; -using Glamourer.Customization; using Glamourer.Designs; using Glamourer.Interop.CharaFile; using Glamourer.Services; -using Glamourer.Structs; using ImGuiNET; using OtterGui.Classes; +using Penumbra.GameData.Enums; +using Penumbra.GameData.Files; +using Penumbra.GameData.Structs; namespace Glamourer.Interop; @@ -139,7 +140,7 @@ public class ImportService(CustomizationService _customizations, IDragDropManage return true; } - public bool SaveDesignAsDat(string path, in Customize input, string description) + public bool SaveDesignAsDat(string path, in CustomizeArray input, string description) { if (!Verify(input, out var voice)) return false; @@ -168,7 +169,7 @@ public class ImportService(CustomizationService _customizations, IDragDropManage } } - public bool Verify(in Customize input, out byte voice, byte? inputVoice = null) + public bool Verify(in CustomizeArray input, out byte voice, byte? inputVoice = null) { voice = 0; if (_customizations.ValidateClan(input.Clan, input.Race, out _, out _).Length > 0) diff --git a/Glamourer/Interop/JobService.cs b/Glamourer/Interop/JobService.cs index 2fe322f..5ee9cf6 100644 --- a/Glamourer/Interop/JobService.cs +++ b/Glamourer/Interop/JobService.cs @@ -6,7 +6,9 @@ using Dalamud.Plugin.Services; using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.Game.Character; using Glamourer.Interop.Structs; -using Glamourer.Structs; +using Penumbra.GameData; +using Penumbra.GameData.DataContainers; +using Penumbra.GameData.Structs; namespace Glamourer.Interop; @@ -14,19 +16,20 @@ public class JobService : IDisposable { private readonly nint _characterDataOffset; - public readonly IReadOnlyDictionary Jobs; - public readonly IReadOnlyDictionary JobGroups; - public readonly IReadOnlyList AllJobGroups; + public readonly DictJob Jobs; + public readonly DictJobGroup JobGroups; + + public IReadOnlyList AllJobGroups + => JobGroups.AllJobGroups; public event Action? JobChanged; - public JobService(IDataManager gameData, IGameInteropProvider interop) + public JobService(DictJob jobs, DictJobGroup jobGroups, IDataManager gameData, IGameInteropProvider interop) { interop.InitializeFromAttributes(this); _characterDataOffset = Marshal.OffsetOf(nameof(Character.CharacterData)); - Jobs = GameData.Jobs(gameData); - AllJobGroups = GameData.AllJobGroups(gameData); - JobGroups = GameData.JobGroups(gameData); + Jobs = jobs; + JobGroups = jobGroups; _changeJobHook.Enable(); } diff --git a/Glamourer/Interop/Structs/Actor.cs b/Glamourer/Interop/Structs/Actor.cs index 750527b..066d985 100644 --- a/Glamourer/Interop/Structs/Actor.cs +++ b/Glamourer/Interop/Structs/Actor.cs @@ -2,8 +2,6 @@ using System; using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Game.Object; -using Glamourer.Customization; -using Glamourer.Structs; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; using Penumbra.String; @@ -116,8 +114,8 @@ public readonly unsafe struct Actor : IEquatable public CharacterWeapon GetOffhand() => new(AsCharacter->DrawData.Weapon(DrawDataContainer.WeaponSlot.OffHand).ModelId.Value); - public Customize GetCustomize() - => *(Customize*)&AsCharacter->DrawData.CustomizeData; + public CustomizeArray GetCustomize() + => *(CustomizeArray*)&AsCharacter->DrawData.CustomizeData; // TODO remove this when available in ClientStructs internal ref CrestFlag CrestBitfield diff --git a/Glamourer/Interop/Structs/Model.cs b/Glamourer/Interop/Structs/Model.cs index 77bf24e..9705248 100644 --- a/Glamourer/Interop/Structs/Model.cs +++ b/Glamourer/Interop/Structs/Model.cs @@ -1,7 +1,6 @@ using System; using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; -using Glamourer.Customization; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; using Object = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.Object; @@ -91,8 +90,8 @@ public readonly unsafe struct Model : IEquatable public CharacterArmor GetArmor(EquipSlot slot) => ((CharacterArmor*)&AsHuman->Head)[slot.ToIndex()]; - public Customize GetCustomize() - => *(Customize*)&AsHuman->Customize; + public CustomizeArray GetCustomize() + => *(CustomizeArray*)&AsHuman->Customize; public (Model Address, CharacterWeapon Data) GetMainhand() { diff --git a/Glamourer/Interop/UpdateSlotService.cs b/Glamourer/Interop/UpdateSlotService.cs index f5a0ec0..31472ff 100644 --- a/Glamourer/Interop/UpdateSlotService.cs +++ b/Glamourer/Interop/UpdateSlotService.cs @@ -4,6 +4,7 @@ using Dalamud.Plugin.Services; using Dalamud.Utility.Signatures; using Glamourer.Events; using Glamourer.Interop.Structs; +using Penumbra.GameData; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; diff --git a/Glamourer/Interop/WeaponService.cs b/Glamourer/Interop/WeaponService.cs index 7ccf963..4c87430 100644 --- a/Glamourer/Interop/WeaponService.cs +++ b/Glamourer/Interop/WeaponService.cs @@ -5,7 +5,6 @@ using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Game.Character; using Glamourer.Events; using Glamourer.Interop.Structs; -using Glamourer.Structs; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; @@ -14,18 +13,15 @@ namespace Glamourer.Interop; public unsafe class WeaponService : IDisposable { private readonly WeaponLoading _event; - private readonly CrestService _crestService; private readonly ThreadLocal _inUpdate = new(() => false); private readonly delegate* unmanaged[Stdcall] _original; - - public WeaponService(WeaponLoading @event, IGameInteropProvider interop, CrestService crestService) + public WeaponService(WeaponLoading @event, IGameInteropProvider interop) { - _event = @event; - _crestService = crestService; + _event = @event; _loadWeaponHook = interop.HookFromAddress((nint)DrawDataContainer.MemberFunctionPointers.LoadWeapon, LoadWeaponDetour); _original = @@ -73,7 +69,7 @@ public unsafe class WeaponService : IDisposable _event.Invoke(actor, EquipSlot.MainHand, ref tmpWeapon); _loadWeaponHook.Original(drawData, slot, weapon.Value, redrawOnEquality, unk2, skipGameObject, unk4); - + if (tmpWeapon.Value != weapon.Value) { if (tmpWeapon.Skeleton.Id == 0) diff --git a/Glamourer/Services/CommandService.cs b/Glamourer/Services/CommandService.cs index 417f1b9..2135357 100644 --- a/Glamourer/Services/CommandService.cs +++ b/Glamourer/Services/CommandService.cs @@ -5,13 +5,11 @@ using Dalamud.Game.Command; using Dalamud.Game.Text.SeStringHandling; using Dalamud.Plugin.Services; using Glamourer.Automation; -using Glamourer.Customization; using Glamourer.Designs; using Glamourer.Events; using Glamourer.Gui; using Glamourer.Interop; using Glamourer.State; -using Glamourer.Structs; using ImGuiNET; using OtterGui; using OtterGui.Classes; diff --git a/Glamourer/Services/CustomizationService.cs b/Glamourer/Services/CustomizationService.cs index b5f474f..9e28e42 100644 --- a/Glamourer/Services/CustomizationService.cs +++ b/Glamourer/Services/CustomizationService.cs @@ -2,10 +2,11 @@ using System.Linq; using System.Runtime.CompilerServices; using System.Threading.Tasks; using Dalamud.Plugin.Services; -using Glamourer.Customization; +using Glamourer.GameData; using OtterGui.Services; using Penumbra.GameData.DataContainers; using Penumbra.GameData.Enums; +using Penumbra.GameData.Structs; namespace Glamourer.Services; @@ -30,13 +31,12 @@ public sealed class CustomizationService( public Task Awaiter => _task; - public (Customize NewValue, CustomizeFlag Applied, CustomizeFlag Changed) Combine(Customize oldValues, Customize newValues, + public (CustomizeArray NewValue, CustomizeFlag Applied, CustomizeFlag Changed) Combine(CustomizeArray oldValues, CustomizeArray newValues, CustomizeFlag applyWhich, bool allowUnknown) { CustomizeFlag applied = 0; CustomizeFlag changed = 0; - Customize ret = default; - ret.Load(oldValues); + var ret = oldValues; if (applyWhich.HasFlag(CustomizeFlag.Clan)) { changed |= ChangeClan(ref ret, newValues.Clan); @@ -247,7 +247,7 @@ public sealed class CustomizationService( } /// Change a clan while keeping all other customizations valid. - public CustomizeFlag ChangeClan(ref Customize customize, SubRace newClan) + public CustomizeFlag ChangeClan(ref CustomizeArray customize, SubRace newClan) { if (customize.Clan == newClan) return 0; @@ -271,7 +271,7 @@ public sealed class CustomizationService( } /// Change a gender while keeping all other customizations valid. - public CustomizeFlag ChangeGender(ref Customize customize, Gender newGender) + public CustomizeFlag ChangeGender(ref CustomizeArray customize, Gender newGender) { if (customize.Gender == newGender) return 0; @@ -288,7 +288,7 @@ public sealed class CustomizationService( return FixValues(set, ref customize) | CustomizeFlag.Gender; } - private static CustomizeFlag FixValues(CustomizationSet set, ref Customize customize) + private static CustomizeFlag FixValues(CustomizationSet set, ref CustomizeArray customize) { CustomizeFlag flags = 0; foreach (var idx in CustomizationExtensions.AllBasic) diff --git a/Glamourer/Services/ServiceManager.cs b/Glamourer/Services/ServiceManager.cs index d88a90c..3afe390 100644 --- a/Glamourer/Services/ServiceManager.cs +++ b/Glamourer/Services/ServiceManager.cs @@ -15,7 +15,6 @@ using Glamourer.Gui.Tabs.UnlocksTab; using Glamourer.Interop; using Glamourer.Interop.Penumbra; using Glamourer.State; -using Glamourer.Structs; using Glamourer.Unlocks; using Microsoft.Extensions.DependencyInjection; using OtterGui.Classes; @@ -24,6 +23,7 @@ using OtterGui.Services; using Penumbra.GameData.Actors; using Penumbra.GameData.Data; using Penumbra.GameData.DataContainers; +using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; namespace Glamourer.Services; diff --git a/Glamourer/State/ActorState.cs b/Glamourer/State/ActorState.cs index 3cd7cba..484d0a9 100644 --- a/Glamourer/State/ActorState.cs +++ b/Glamourer/State/ActorState.cs @@ -1,13 +1,11 @@ -using Glamourer.Customization; -using Glamourer.Designs; +using Glamourer.Designs; using Glamourer.Events; -using Glamourer.Structs; using Penumbra.GameData.Actors; using Penumbra.GameData.Enums; using System.Linq; using Dalamud.Game.ClientState.Conditions; using Dalamud.Plugin.Services; -using CustomizeIndex = Glamourer.Customization.CustomizeIndex; +using Penumbra.GameData.Structs; namespace Glamourer.State; @@ -34,7 +32,7 @@ public class ActorState public DesignData ModelData; /// The last seen job. - public byte LastJob; + public JobId LastJob; /// The Lock-Key locking this state. public uint Combination; diff --git a/Glamourer/State/FunModule.cs b/Glamourer/State/FunModule.cs index 5ab3f41..67c9e08 100644 --- a/Glamourer/State/FunModule.cs +++ b/Glamourer/State/FunModule.cs @@ -2,7 +2,6 @@ using System.Linq; using Dalamud.Game.ClientState.Objects.Enums; using Dalamud.Interface.Internal.Notifications; -using Glamourer.Customization; using Glamourer.Designs; using Glamourer.Gui; using Glamourer.Interop; @@ -12,7 +11,7 @@ using ImGuiNET; using OtterGui.Classes; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; -using CustomizeIndex = Glamourer.Customization.CustomizeIndex; +using CustomizeIndex = Penumbra.GameData.Enums.CustomizeIndex; namespace Glamourer.State; @@ -107,7 +106,7 @@ public unsafe class FunModule : IDisposable } } - public void ApplyFun(Actor actor, Span armor, ref Customize customize) + public void ApplyFun(Actor actor, Span armor, ref CustomizeArray customize) { if (!ValidFunTarget(actor)) return; @@ -181,7 +180,7 @@ public unsafe class FunModule : IDisposable } } - public void ApplyOops(ref Customize customize) + public void ApplyOops(ref CustomizeArray customize) { if (_codes.EnabledOops == Race.Unknown) return; @@ -193,7 +192,7 @@ public unsafe class FunModule : IDisposable _customizations.ChangeClan(ref customize, targetClan); } - public void ApplyIndividual(ref Customize customize) + public void ApplyIndividual(ref CustomizeArray customize) { if (!_codes.EnabledIndividual) return; @@ -209,7 +208,7 @@ public unsafe class FunModule : IDisposable } } - public void Apply63(ref Customize customize) + public void Apply63(ref CustomizeArray customize) { if (!_codes.Enabled63 || customize.Race is Race.Hrothgar) // TODO Female Hrothgar return; @@ -217,7 +216,7 @@ public unsafe class FunModule : IDisposable _customizations.ChangeGender(ref customize, customize.Gender is Gender.Male ? Gender.Female : Gender.Male); } - public void ApplySizing(Actor actor, ref Customize customize) + public void ApplySizing(Actor actor, ref CustomizeArray customize) { if (_codes.EnabledSizing == CodeService.Sizing.None) return; diff --git a/Glamourer/State/StateApplier.cs b/Glamourer/State/StateApplier.cs index a91a1eb..43c9097 100644 --- a/Glamourer/State/StateApplier.cs +++ b/Glamourer/State/StateApplier.cs @@ -1,11 +1,9 @@ using System.Linq; -using Glamourer.Customization; using Glamourer.Events; using Glamourer.Interop; using Glamourer.Interop.Penumbra; using Glamourer.Interop.Structs; using Glamourer.Services; -using Glamourer.Structs; using Penumbra.Api.Enums; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; @@ -40,7 +38,7 @@ public class StateApplier(UpdateSlotService _updateSlot, VisorService _visor, We /// 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. /// - public unsafe void ChangeCustomize(ActorData data, in Customize customize, ActorState? state = null) + public unsafe void ChangeCustomize(ActorData data, in CustomizeArray customize, ActorState? _ = null) { foreach (var actor in data.Objects) { @@ -48,15 +46,15 @@ public class StateApplier(UpdateSlotService _updateSlot, VisorService _visor, We if (!mdl.IsCharacterBase) continue; - var flags = Customize.Compare(mdl.GetCustomize(), customize); + var flags = CustomizeArray.Compare(mdl.GetCustomize(), customize); if (!flags.RequiresRedraw() || !mdl.IsHuman) { - _changeCustomize.UpdateCustomize(mdl, customize.Data); + _changeCustomize.UpdateCustomize(mdl, customize); } else if (data.Objects.Count > 1 && _objects.IsInGPose && !actor.IsGPoseOrCutscene) { - var mdlCustomize = (Customize*)&mdl.AsHuman->Customize; - mdlCustomize->Load(customize); + var mdlCustomize = (CustomizeArray*)&mdl.AsHuman->Customize; + *mdlCustomize = customize; _penumbra.RedrawObject(actor, RedrawType.AfterGPose); } else @@ -66,7 +64,7 @@ public class StateApplier(UpdateSlotService _updateSlot, VisorService _visor, We } } - /// + /// public ActorData ChangeCustomize(ActorState state, bool apply) { var data = GetData(state); diff --git a/Glamourer/State/StateEditor.cs b/Glamourer/State/StateEditor.cs index ebc2661..50b2605 100644 --- a/Glamourer/State/StateEditor.cs +++ b/Glamourer/State/StateEditor.cs @@ -1,10 +1,8 @@ using System; using System.Linq; using Dalamud.Plugin.Services; -using Glamourer.Customization; using Glamourer.Events; using Glamourer.Services; -using Glamourer.Structs; using Penumbra.GameData.DataContainers; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; @@ -30,7 +28,7 @@ public class StateEditor /// Change the model id. If the actor is changed from a human to another human, customize and equipData are unused. /// We currently only allow changing things to humans, not humans to monsters. - public bool ChangeModelId(ActorState state, uint modelId, in Customize customize, nint equipData, StateChanged.Source source, + public bool ChangeModelId(ActorState state, uint modelId, in CustomizeArray customize, nint equipData, StateChanged.Source source, out uint oldModelId, uint key = 0) { oldModelId = state.ModelData.ModelId; @@ -57,7 +55,7 @@ public class StateEditor return false; // Fix up everything else to make sure the result is a valid human. - state.ModelData.Customize = Customize.Default; + state.ModelData.Customize = CustomizeArray.Default; state.ModelData.SetDefaultEquipment(_items); state.ModelData.SetHatVisible(true); state.ModelData.SetWeaponVisible(true); @@ -104,8 +102,8 @@ public class StateEditor } /// Change an entire customization array according to flags. - public bool ChangeHumanCustomize(ActorState state, in Customize customizeInput, CustomizeFlag applyWhich, StateChanged.Source source, - out Customize old, out CustomizeFlag changed, uint key = 0) + public bool ChangeHumanCustomize(ActorState state, in CustomizeArray customizeInput, CustomizeFlag applyWhich, StateChanged.Source source, + out CustomizeArray old, out CustomizeFlag changed, uint key = 0) { old = state.ModelData.Customize; changed = 0; diff --git a/Glamourer/State/StateListener.cs b/Glamourer/State/StateListener.cs index f5f2e3b..d7f947f 100644 --- a/Glamourer/State/StateListener.cs +++ b/Glamourer/State/StateListener.cs @@ -1,5 +1,4 @@ using Glamourer.Automation; -using Glamourer.Customization; using Glamourer.Events; using Glamourer.Interop; using Glamourer.Interop.Penumbra; @@ -12,7 +11,6 @@ using Penumbra.GameData.Structs; using System; using Dalamud.Game.ClientState.Conditions; using Dalamud.Plugin.Services; -using Glamourer.Structs; using Penumbra.GameData.DataContainers; namespace Glamourer.State; @@ -114,7 +112,7 @@ public class StateListener : IDisposable _creatingIdentifier = actor.GetIdentifier(_actors); ref var modelId = ref *(uint*)modelPtr; - ref var customize = ref *(Customize*)customizePtr; + ref var customize = ref *(CustomizeArray*)customizePtr; if (_autoDesignApplier.Reduce(actor, _creatingIdentifier, out _creatingState)) { switch (UpdateBaseData(actor, _creatingState, modelId, customizePtr, equipDataPtr)) @@ -140,7 +138,7 @@ public class StateListener : IDisposable ProtectRestrictedGear(equipDataPtr, customize.Race, customize.Gender); } - private unsafe void OnCustomizeChange(Model model, Ref customize) + private unsafe void OnCustomizeChange(Model model, Ref customize) { if (!model.IsHuman) return; @@ -156,7 +154,7 @@ public class StateListener : IDisposable UpdateCustomize(actor, state, ref customize.Value, false); } - private void UpdateCustomize(Actor actor, ActorState state, ref Customize customize, bool checkTransform) + private void UpdateCustomize(Actor actor, ActorState state, ref CustomizeArray customize, bool checkTransform) { switch (UpdateBaseData(actor, state, customize, checkTransform)) { @@ -515,7 +513,7 @@ public class StateListener : IDisposable if (isHuman) state.BaseData = _manager.FromActor(actor, false, false); else - state.BaseData.LoadNonHuman(modelId, *(Customize*)customizeData, equipData); + state.BaseData.LoadNonHuman(modelId, *(CustomizeArray*)customizeData, equipData); return UpdateState.Change; } @@ -526,7 +524,7 @@ public class StateListener : IDisposable /// only if we kept track of state of someone who went to the aesthetician, /// or if they used other tools to change things. /// - private UpdateState UpdateBaseData(Actor actor, ActorState state, Customize customize, bool checkTransform) + private UpdateState UpdateBaseData(Actor actor, ActorState state, CustomizeArray customize, bool checkTransform) { // Customize array does not agree between game object and draw object => transformation. if (checkTransform && !actor.GetCustomize().Equals(customize)) @@ -537,7 +535,7 @@ public class StateListener : IDisposable return UpdateState.NoChange; // TODO: handle wrong base data. // Update customize base state. - state.BaseData.Customize.Load(customize); + state.BaseData.Customize = customize; return UpdateState.Change; } diff --git a/Glamourer/State/StateManager.cs b/Glamourer/State/StateManager.cs index 8446288..dc83305 100644 --- a/Glamourer/State/StateManager.cs +++ b/Glamourer/State/StateManager.cs @@ -4,13 +4,11 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using Dalamud.Plugin.Services; -using Glamourer.Customization; using Glamourer.Designs; using Glamourer.Events; using Glamourer.Interop; using Glamourer.Interop.Structs; using Glamourer.Services; -using Glamourer.Structs; using Penumbra.GameData.Actors; using Penumbra.GameData.DataContainers; using Penumbra.GameData.Enums; @@ -18,8 +16,15 @@ using Penumbra.GameData.Structs; namespace Glamourer.State; -public class StateManager(ActorManager _actors, ItemManager _items, StateChanged _event, StateApplier _applier, StateEditor _editor, - HumanModelList _humans, ICondition _condition, IClientState _clientState) +public class StateManager( + ActorManager _actors, + ItemManager _items, + StateChanged _event, + StateApplier _applier, + StateEditor _editor, + HumanModelList _humans, + ICondition _condition, + IClientState _clientState) : IReadOnlyDictionary { private readonly Dictionary _states = []; @@ -102,7 +107,7 @@ public class StateManager(ActorManager _actors, ItemManager _items, StateChanged // TODO reverse search model data to get model id from model. if (!_humans.IsHuman((uint)actor.AsCharacter->CharacterData.ModelCharaId)) { - ret.LoadNonHuman((uint)actor.AsCharacter->CharacterData.ModelCharaId, *(Customize*)&actor.AsCharacter->DrawData.CustomizeData, + ret.LoadNonHuman((uint)actor.AsCharacter->CharacterData.ModelCharaId, *(CustomizeArray*)&actor.AsCharacter->DrawData.CustomizeData, (nint)(&actor.AsCharacter->DrawData.Head)); return ret; } @@ -194,9 +199,9 @@ public class StateManager(ActorManager _actors, ItemManager _items, StateChanged return; var gauntlets = _items.Identify(EquipSlot.Hands, offhand.Skeleton, (Variant)offhand.Weapon.Id); - offhand.Skeleton = (PrimaryId)(mainhand.Skeleton.Id + 50); - offhand.Variant = mainhand.Variant; - offhand.Weapon = mainhand.Weapon; + offhand.Skeleton = (PrimaryId)(mainhand.Skeleton.Id + 50); + offhand.Variant = mainhand.Variant; + offhand.Weapon = mainhand.Weapon; ret.SetItem(EquipSlot.Hands, gauntlets); ret.SetStain(EquipSlot.Hands, mainhand.Stain); } @@ -205,10 +210,10 @@ public class StateManager(ActorManager _actors, ItemManager _items, StateChanged /// Turn an actor human. public void TurnHuman(ActorState state, StateChanged.Source source, uint key = 0) - => ChangeModelId(state, 0, Customize.Default, nint.Zero, source, key); + => ChangeModelId(state, 0, CustomizeArray.Default, nint.Zero, source, key); /// Turn an actor to. - public void ChangeModelId(ActorState state, uint modelId, Customize customize, nint equipData, StateChanged.Source source, + public void ChangeModelId(ActorState state, uint modelId, CustomizeArray customize, nint equipData, StateChanged.Source source, uint key = 0) { if (!_editor.ChangeModelId(state, modelId, customize, equipData, source, out var old, key)) @@ -233,7 +238,8 @@ public class StateManager(ActorManager _actors, ItemManager _items, StateChanged } /// Change an entire customization array according to flags. - public void ChangeCustomize(ActorState state, in Customize customizeInput, CustomizeFlag apply, StateChanged.Source source, uint key = 0) + public void ChangeCustomize(ActorState state, in CustomizeArray customizeInput, CustomizeFlag apply, StateChanged.Source source, + uint key = 0) { if (!_editor.ChangeHumanCustomize(state, customizeInput, apply, source, out var old, out var applied, key)) return; @@ -447,7 +453,7 @@ public class StateManager(ActorManager _actors, ItemManager _items, StateChanged var redraw = state.ModelData.ModelId != state.BaseData.ModelId || !state.ModelData.IsHuman - || Customize.Compare(state.ModelData.Customize, state.BaseData.Customize).RequiresRedraw(); + || CustomizeArray.Compare(state.ModelData.Customize, state.BaseData.Customize).RequiresRedraw(); state.ModelData = state.BaseData; state.ModelData.SetIsWet(false); foreach (var index in Enum.GetValues()) @@ -458,7 +464,7 @@ public class StateManager(ActorManager _actors, ItemManager _items, StateChanged state[slot, true] = StateChanged.Source.Game; state[slot, false] = StateChanged.Source.Game; } - + foreach (var type in Enum.GetValues()) state[type] = StateChanged.Source.Game; @@ -470,7 +476,7 @@ public class StateManager(ActorManager _actors, ItemManager _items, StateChanged actors = ApplyAll(state, redraw, true); Glamourer.Log.Verbose( $"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, StateChanged.Source.Manual, state, actors); } public void ResetStateFixed(ActorState state, uint key = 0) @@ -538,7 +544,7 @@ public class StateManager(ActorManager _actors, ItemManager _items, StateChanged if (!GetOrCreate(actor, out var state)) return; - ApplyAll(state, !actor.Model.IsHuman || Customize.Compare(actor.Model.GetCustomize(), state.ModelData.Customize).RequiresRedraw(), + ApplyAll(state, !actor.Model.IsHuman || CustomizeArray.Compare(actor.Model.GetCustomize(), state.ModelData.Customize).RequiresRedraw(), false); } diff --git a/Glamourer/State/WorldSets.cs b/Glamourer/State/WorldSets.cs index 3f694ee..4464aee 100644 --- a/Glamourer/State/WorldSets.cs +++ b/Glamourer/State/WorldSets.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using Glamourer.Interop.Structs; -using Glamourer.Structs; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; diff --git a/Glamourer/Unlocks/CustomizeUnlockManager.cs b/Glamourer/Unlocks/CustomizeUnlockManager.cs index 8764438..a1e95ef 100644 --- a/Glamourer/Unlocks/CustomizeUnlockManager.cs +++ b/Glamourer/Unlocks/CustomizeUnlockManager.cs @@ -8,10 +8,11 @@ using Dalamud.Plugin.Services; using Dalamud.Utility; using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.Game.UI; -using Glamourer.Customization; +using Glamourer.GameData; using Glamourer.Events; using Glamourer.Services; using Lumina.Excel.GeneratedSheets; +using Penumbra.GameData.Enums; namespace Glamourer.Unlocks; @@ -172,7 +173,7 @@ public class CustomizeUnlockManager : IDisposable, ISavable => UnlockDictionaryHelpers.Load(ToFilename(_saveService.FileNames), _unlocked, id => Unlockable.Any(c => c.Value.Data == id), "customization"); - /// Create a list of all unlockable hairstyles and facepaints. + /// Create a list of all unlockable hairstyles and face paints. private static Dictionary CreateUnlockableCustomizations(CustomizationService customizations, IDataManager gameData) { diff --git a/Penumbra.GameData b/Penumbra.GameData index 3787e82..d9a9627 160000 --- a/Penumbra.GameData +++ b/Penumbra.GameData @@ -1 +1 @@ -Subproject commit 3787e82d1b84d2542b6e4238060d75383a4b12a1 +Subproject commit d9a962748364b267df1b186cdaebb9ed9f3fceb6