From 2a067ef60b9b345b1903b4e246d48dfdea900138 Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Thu, 30 Jan 2025 13:36:06 +0100 Subject: [PATCH] Accept all existing facepaints. --- Glamourer/GameData/CustomizeSet.cs | 4 +- Glamourer/GameData/CustomizeSetFactory.cs | 1 - Glamourer/GameData/NpcCustomizeSet.cs | 45 ++++++++++++------- .../DebugTab/CustomizationServicePanel.cs | 34 ++++++++++++-- Penumbra.GameData | 2 +- 5 files changed, 63 insertions(+), 23 deletions(-) diff --git a/Glamourer/GameData/CustomizeSet.cs b/Glamourer/GameData/CustomizeSet.cs index 178ef07..d0193aa 100644 --- a/Glamourer/GameData/CustomizeSet.cs +++ b/Glamourer/GameData/CustomizeSet.cs @@ -11,7 +11,7 @@ namespace Glamourer.GameData; /// public class CustomizeSet { - private NpcCustomizeSet _npcCustomizations; + private readonly NpcCustomizeSet _npcCustomizations; internal CustomizeSet(NpcCustomizeSet npcCustomizations, SubRace clan, Gender gender) { @@ -88,7 +88,7 @@ public class CustomizeSet { if (IsAvailable(index)) return DataByValue(index, value, out custom, face) >= 0 - || _npcCustomizations.CheckColor(index, value) + || _npcCustomizations.CheckValue(index, value) || NpcOptions.Any(t => t.Type == index && t.Value == value); custom = null; diff --git a/Glamourer/GameData/CustomizeSetFactory.cs b/Glamourer/GameData/CustomizeSetFactory.cs index 13a9865..77a6973 100644 --- a/Glamourer/GameData/CustomizeSetFactory.cs +++ b/Glamourer/GameData/CustomizeSetFactory.cs @@ -76,7 +76,6 @@ internal class CustomizeSetFactory( CustomizeIndex.Hairstyle, CustomizeIndex.LipColor, CustomizeIndex.SkinColor, - CustomizeIndex.FacePaint, CustomizeIndex.TailShape, }; diff --git a/Glamourer/GameData/NpcCustomizeSet.cs b/Glamourer/GameData/NpcCustomizeSet.cs index 4dbfd83..3cc19cd 100644 --- a/Glamourer/GameData/NpcCustomizeSet.cs +++ b/Glamourer/GameData/NpcCustomizeSet.cs @@ -3,6 +3,7 @@ using Dalamud.Utility; using FFXIVClientStructs.FFXIV.Client.Game.Object; using Lumina.Excel.Sheets; using OtterGui.Services; +using Penumbra.GameData.Data; using Penumbra.GameData.DataContainers; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; @@ -40,17 +41,19 @@ public class NpcCustomizeSet : IAsyncDataContainer, IReadOnlyList private readonly BitArray _eyeColors = new(256); private readonly BitArray _facepaintColors = new(256); private readonly BitArray _tattooColors = new(256); + private readonly BitArray _facepaints = new(128); - public bool CheckColor(CustomizeIndex type, CustomizeValue value) + public bool CheckValue(CustomizeIndex type, CustomizeValue value) => type switch { - CustomizeIndex.HairColor => _hairColors[value.Value], - CustomizeIndex.HighlightsColor => _hairColors[value.Value], - CustomizeIndex.EyeColorLeft => _eyeColors[value.Value], - CustomizeIndex.EyeColorRight => _eyeColors[value.Value], - CustomizeIndex.FacePaintColor => _facepaintColors[value.Value], - CustomizeIndex.TattooColor => _tattooColors[value.Value], - _ => false, + CustomizeIndex.HairColor => _hairColors[value.Value], + CustomizeIndex.HighlightsColor => _hairColors[value.Value], + CustomizeIndex.EyeColorLeft => _eyeColors[value.Value], + CustomizeIndex.EyeColorRight => _eyeColors[value.Value], + CustomizeIndex.FacePaintColor => _facepaintColors[value.Value], + CustomizeIndex.TattooColor => _tattooColors[value.Value], + CustomizeIndex.FacePaint when value.Value < 128 => _facepaints[value.Value], + _ => false, }; /// Create the data when ready. @@ -58,13 +61,14 @@ public class NpcCustomizeSet : IAsyncDataContainer, IReadOnlyList { var waitTask = Task.WhenAll(eNpcs.Awaiter, bNpcs.Awaiter, bNpcNames.Awaiter); Awaiter = waitTask.ContinueWith(_ => - { - var watch = Stopwatch.StartNew(); - var eNpcTask = Task.Run(() => CreateEnpcData(data, eNpcs)); - var bNpcTask = Task.Run(() => CreateBnpcData(data, bNpcs, bNpcNames)); - FilterAndOrderNpcData(eNpcTask.Result, bNpcTask.Result); - Time = watch.ElapsedMilliseconds; - }); + { + var watch = Stopwatch.StartNew(); + var eNpcTask = Task.Run(() => CreateEnpcData(data, eNpcs)); + var bNpcTask = Task.Run(() => CreateBnpcData(data, bNpcs, bNpcNames)); + FilterAndOrderNpcData(eNpcTask.Result, bNpcTask.Result); + Time = watch.ElapsedMilliseconds; + }) + .ContinueWith(_ => CheckFacepaintFiles(data, _facepaints)); } /// Create data from event NPCs. @@ -323,6 +327,17 @@ public class NpcCustomizeSet : IAsyncDataContainer, IReadOnlyList return (true, customize); } + /// Check decal files for existence. + private static void CheckFacepaintFiles(IDataManager data, BitArray facepaints) + { + for (var i = 0; i < 128; ++i) + { + var path = GamePaths.Character.Tex.DecalPath("face", (PrimaryId)i); + if (data.FileExists(path)) + facepaints[i] = true; + } + } + /// public IEnumerator GetEnumerator() => _data.GetEnumerator(); diff --git a/Glamourer/Gui/Tabs/DebugTab/CustomizationServicePanel.cs b/Glamourer/Gui/Tabs/DebugTab/CustomizationServicePanel.cs index afc7d56..565b6ba 100644 --- a/Glamourer/Gui/Tabs/DebugTab/CustomizationServicePanel.cs +++ b/Glamourer/Gui/Tabs/DebugTab/CustomizationServicePanel.cs @@ -28,9 +28,35 @@ public class CustomizationServicePanel(CustomizeService customize) : IGameDataDr DrawNpcCustomizationInfo(set); } + DrawFacepaintInfo(); DrawColorInfo(); } + private void DrawFacepaintInfo() + { + using var tree = ImUtf8.TreeNode("NPC Facepaints"u8); + if (!tree) + return; + + using var table = ImUtf8.Table("data"u8, 2, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg); + if (!table) + return; + + ImGui.TableNextColumn(); + ImUtf8.TableHeader("Id"u8); + ImGui.TableNextColumn(); + ImUtf8.TableHeader("Facepaint"u8); + + for (var i = 0; i < 128; ++i) + { + var index = new CustomizeValue((byte)i); + ImUtf8.DrawTableColumn($"{i:D3}"); + using var font = ImRaii.PushFont(UiBuilder.IconFont); + ImUtf8.DrawTableColumn(customize.NpcCustomizeSet.CheckValue(CustomizeIndex.FacePaint, index) + ? FontAwesomeIcon.Check.ToIconString() + : FontAwesomeIcon.Times.ToIconString()); + } + } private void DrawColorInfo() { using var tree = ImUtf8.TreeNode("NPC Colors"u8); @@ -57,16 +83,16 @@ public class CustomizationServicePanel(CustomizeService customize) : IGameDataDr var index = new CustomizeValue((byte)i); ImUtf8.DrawTableColumn($"{i:D3}"); using var font = ImRaii.PushFont(UiBuilder.IconFont); - ImUtf8.DrawTableColumn(customize.NpcCustomizeSet.CheckColor(CustomizeIndex.HairColor, index) + ImUtf8.DrawTableColumn(customize.NpcCustomizeSet.CheckValue(CustomizeIndex.HairColor, index) ? FontAwesomeIcon.Check.ToIconString() : FontAwesomeIcon.Times.ToIconString()); - ImUtf8.DrawTableColumn(customize.NpcCustomizeSet.CheckColor(CustomizeIndex.EyeColorLeft, index) + ImUtf8.DrawTableColumn(customize.NpcCustomizeSet.CheckValue(CustomizeIndex.EyeColorLeft, index) ? FontAwesomeIcon.Check.ToIconString() : FontAwesomeIcon.Times.ToIconString()); - ImUtf8.DrawTableColumn(customize.NpcCustomizeSet.CheckColor(CustomizeIndex.FacePaintColor, index) + ImUtf8.DrawTableColumn(customize.NpcCustomizeSet.CheckValue(CustomizeIndex.FacePaintColor, index) ? FontAwesomeIcon.Check.ToIconString() : FontAwesomeIcon.Times.ToIconString()); - ImUtf8.DrawTableColumn(customize.NpcCustomizeSet.CheckColor(CustomizeIndex.TattooColor, index) + ImUtf8.DrawTableColumn(customize.NpcCustomizeSet.CheckValue(CustomizeIndex.TattooColor, index) ? FontAwesomeIcon.Check.ToIconString() : FontAwesomeIcon.Times.ToIconString()); } diff --git a/Penumbra.GameData b/Penumbra.GameData index bb59614..4880433 160000 --- a/Penumbra.GameData +++ b/Penumbra.GameData @@ -1 +1 @@ -Subproject commit bb596141bb582505ae9fae1dd2914773503f4fe7 +Subproject commit 488043381efd42238e9c1328ccab3b80abd81ea7