Accept more colors in designs as valid (independently of clan/gender and mixing highlights/hair and both eyes).

This commit is contained in:
Ottermandias 2024-12-29 15:48:54 +01:00
parent ebd3fb3fbf
commit 70cf21cf57
4 changed files with 85 additions and 18 deletions

View file

@ -11,12 +11,15 @@ namespace Glamourer.GameData;
/// </summary> /// </summary>
public class CustomizeSet public class CustomizeSet
{ {
internal CustomizeSet(SubRace clan, Gender gender) private NpcCustomizeSet _npcCustomizations;
internal CustomizeSet(NpcCustomizeSet npcCustomizations, SubRace clan, Gender gender)
{ {
Gender = gender; _npcCustomizations = npcCustomizations;
Clan = clan; Gender = gender;
Race = clan.ToRace(); Clan = clan;
SettingAvailable = 0; Race = clan.ToRace();
SettingAvailable = 0;
} }
public Gender Gender { get; } public Gender Gender { get; }
@ -85,6 +88,7 @@ public class CustomizeSet
{ {
if (IsAvailable(index)) if (IsAvailable(index))
return DataByValue(index, value, out custom, face) >= 0 return DataByValue(index, value, out custom, face) >= 0
|| _npcCustomizations.CheckColor(index, value)
|| NpcOptions.Any(t => t.Type == index && t.Value == value); || NpcOptions.Any(t => t.Type == index && t.Value == value);
custom = null; custom = null;

View file

@ -1,6 +1,5 @@
using Dalamud.Game; using Dalamud.Game;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using Dalamud.Utility;
using Lumina.Excel; using Lumina.Excel;
using Lumina.Excel.Sheets; using Lumina.Excel.Sheets;
using OtterGui.Classes; using OtterGui.Classes;
@ -29,7 +28,7 @@ internal class CustomizeSetFactory(
var row = _charaMakeSheet.GetRow(((uint)race - 1) * 2 - 1 + (uint)gender)!; var row = _charaMakeSheet.GetRow(((uint)race - 1) * 2 - 1 + (uint)gender)!;
var hrothgar = race.ToRace() == Race.Hrothgar; var hrothgar = race.ToRace() == Race.Hrothgar;
// Create the initial set with all the easily accessible parameters available for anyone. // Create the initial set with all the easily accessible parameters available for anyone.
var set = new CustomizeSet(race, gender) var set = new CustomizeSet(_npcCustomizeSet, race, gender)
{ {
Name = GetName(race, gender), Name = GetName(race, gender),
Voices = row.VoiceStruct, Voices = row.VoiceStruct,
@ -77,13 +76,7 @@ internal class CustomizeSetFactory(
CustomizeIndex.Hairstyle, CustomizeIndex.Hairstyle,
CustomizeIndex.LipColor, CustomizeIndex.LipColor,
CustomizeIndex.SkinColor, CustomizeIndex.SkinColor,
CustomizeIndex.FacePaintColor,
CustomizeIndex.HighlightsColor,
CustomizeIndex.HairColor,
CustomizeIndex.FacePaint, CustomizeIndex.FacePaint,
CustomizeIndex.TattooColor,
CustomizeIndex.EyeColorLeft,
CustomizeIndex.EyeColorRight,
CustomizeIndex.TailShape, CustomizeIndex.TailShape,
}; };

View file

@ -4,6 +4,7 @@ using FFXIVClientStructs.FFXIV.Client.Game.Object;
using Lumina.Excel.Sheets; using Lumina.Excel.Sheets;
using OtterGui.Services; using OtterGui.Services;
using Penumbra.GameData.DataContainers; using Penumbra.GameData.DataContainers;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
namespace Glamourer.GameData; namespace Glamourer.GameData;
@ -35,6 +36,23 @@ public class NpcCustomizeSet : IAsyncDataContainer, IReadOnlyList<NpcData>
/// <summary> The list of data. </summary> /// <summary> The list of data. </summary>
private readonly List<NpcData> _data = []; private readonly List<NpcData> _data = [];
private readonly BitArray _hairColors = new(256);
private readonly BitArray _eyeColors = new(256);
private readonly BitArray _facepaintColors = new(256);
private readonly BitArray _tattooColors = new(256);
public bool CheckColor(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,
};
/// <summary> Create the data when ready. </summary> /// <summary> Create the data when ready. </summary>
public NpcCustomizeSet(IDataManager data, DictENpc eNpcs, DictBNpc bNpcs, DictBNpcNames bNpcNames) public NpcCustomizeSet(IDataManager data, DictENpc eNpcs, DictBNpc bNpcs, DictBNpcNames bNpcNames)
{ {
@ -147,6 +165,12 @@ public class NpcCustomizeSet : IAsyncDataContainer, IReadOnlyList<NpcData>
for (var i = 0; i < duplicates.Count; ++i) for (var i = 0; i < duplicates.Count; ++i)
{ {
var current = duplicates[i]; var current = duplicates[i];
_hairColors[current.Customize[CustomizeIndex.HairColor].Value] = true;
_hairColors[current.Customize[CustomizeIndex.HighlightsColor].Value] = true;
_eyeColors[current.Customize[CustomizeIndex.EyeColorLeft].Value] = true;
_eyeColors[current.Customize[CustomizeIndex.EyeColorRight].Value] = true;
_facepaintColors[current.Customize[CustomizeIndex.FacePaintColor].Value] = true;
_tattooColors[current.Customize[CustomizeIndex.TattooColor].Value] = true;
for (var j = 0; j < i; ++j) for (var j = 0; j < i; ++j)
{ {
if (current.DataEquals(duplicates[j])) if (current.DataEquals(duplicates[j]))
@ -195,8 +219,8 @@ public class NpcCustomizeSet : IAsyncDataContainer, IReadOnlyList<NpcData>
data.Set(7, row.ModelWrists | (row.DyeWrists.RowId << 24) | ((ulong)row.Dye2Wrists.RowId << 32)); data.Set(7, row.ModelWrists | (row.DyeWrists.RowId << 24) | ((ulong)row.Dye2Wrists.RowId << 32));
data.Set(8, row.ModelRightRing | (row.DyeRightRing.RowId << 24) | ((ulong)row.Dye2RightRing.RowId << 32)); data.Set(8, row.ModelRightRing | (row.DyeRightRing.RowId << 24) | ((ulong)row.Dye2RightRing.RowId << 32));
data.Set(9, row.ModelLeftRing | (row.DyeLeftRing.RowId << 24) | ((ulong)row.Dye2LeftRing.RowId << 32)); data.Set(9, row.ModelLeftRing | (row.DyeLeftRing.RowId << 24) | ((ulong)row.Dye2LeftRing.RowId << 32));
data.Mainhand = new CharacterWeapon(row.ModelMainHand | ((ulong)row.DyeMainHand.RowId << 48) | ((ulong)row.Dye2MainHand.RowId << 56)); data.Mainhand = new CharacterWeapon(row.ModelMainHand | ((ulong)row.DyeMainHand.RowId << 48) | ((ulong)row.Dye2MainHand.RowId << 56));
data.Offhand = new CharacterWeapon(row.ModelOffHand | ((ulong)row.DyeOffHand.RowId << 48) | ((ulong)row.Dye2OffHand.RowId << 56)); data.Offhand = new CharacterWeapon(row.ModelOffHand | ((ulong)row.DyeOffHand.RowId << 48) | ((ulong)row.Dye2OffHand.RowId << 56));
data.VisorToggled = row.Visor; data.VisorToggled = row.Visor;
} }
@ -213,8 +237,8 @@ public class NpcCustomizeSet : IAsyncDataContainer, IReadOnlyList<NpcData>
data.Set(7, row.ModelWrists | (row.DyeWrists.RowId << 24) | ((ulong)row.Dye2Wrists.RowId << 32)); data.Set(7, row.ModelWrists | (row.DyeWrists.RowId << 24) | ((ulong)row.Dye2Wrists.RowId << 32));
data.Set(8, row.ModelRightRing | (row.DyeRightRing.RowId << 24) | ((ulong)row.Dye2RightRing.RowId << 32)); data.Set(8, row.ModelRightRing | (row.DyeRightRing.RowId << 24) | ((ulong)row.Dye2RightRing.RowId << 32));
data.Set(9, row.ModelLeftRing | (row.DyeLeftRing.RowId << 24) | ((ulong)row.Dye2LeftRing.RowId << 32)); data.Set(9, row.ModelLeftRing | (row.DyeLeftRing.RowId << 24) | ((ulong)row.Dye2LeftRing.RowId << 32));
data.Mainhand = new CharacterWeapon(row.ModelMainHand | ((ulong)row.DyeMainHand.RowId << 48) | ((ulong)row.Dye2MainHand.RowId << 56)); data.Mainhand = new CharacterWeapon(row.ModelMainHand | ((ulong)row.DyeMainHand.RowId << 48) | ((ulong)row.Dye2MainHand.RowId << 56));
data.Offhand = new CharacterWeapon(row.ModelOffHand | ((ulong)row.DyeOffHand.RowId << 48) | ((ulong)row.Dye2OffHand.RowId << 56)); data.Offhand = new CharacterWeapon(row.ModelOffHand | ((ulong)row.DyeOffHand.RowId << 48) | ((ulong)row.Dye2OffHand.RowId << 56));
data.VisorToggled = row.Visor; data.VisorToggled = row.Visor;
} }

View file

@ -1,10 +1,13 @@
using Glamourer.GameData; using Dalamud.Interface;
using Glamourer.GameData;
using Glamourer.Services; using Glamourer.Services;
using ImGuiNET; using ImGuiNET;
using OtterGui; using OtterGui;
using OtterGui.Raii; using OtterGui.Raii;
using OtterGui.Text;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Gui.Debug; using Penumbra.GameData.Gui.Debug;
using Penumbra.GameData.Structs;
namespace Glamourer.Gui.Tabs.DebugTab; namespace Glamourer.Gui.Tabs.DebugTab;
@ -24,6 +27,49 @@ public class CustomizationServicePanel(CustomizeService customize) : IGameDataDr
DrawCustomizationInfo(set); DrawCustomizationInfo(set);
DrawNpcCustomizationInfo(set); DrawNpcCustomizationInfo(set);
} }
DrawColorInfo();
}
private void DrawColorInfo()
{
using var tree = ImUtf8.TreeNode("NPC Colors"u8);
if (!tree)
return;
using var table = ImUtf8.Table("data"u8, 5, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg);
if (!table)
return;
ImGui.TableNextColumn();
ImUtf8.TableHeader("Id"u8);
ImGui.TableNextColumn();
ImUtf8.TableHeader("Hair"u8);
ImGui.TableNextColumn();
ImUtf8.TableHeader("Eyes"u8);
ImGui.TableNextColumn();
ImUtf8.TableHeader("Facepaint"u8);
ImGui.TableNextColumn();
ImUtf8.TableHeader("Tattoos"u8);
for (var i = 192; i < 256; ++i)
{
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)
? FontAwesomeIcon.Check.ToIconString()
: FontAwesomeIcon.Times.ToIconString());
ImUtf8.DrawTableColumn(customize.NpcCustomizeSet.CheckColor(CustomizeIndex.EyeColorLeft, index)
? FontAwesomeIcon.Check.ToIconString()
: FontAwesomeIcon.Times.ToIconString());
ImUtf8.DrawTableColumn(customize.NpcCustomizeSet.CheckColor(CustomizeIndex.FacePaintColor, index)
? FontAwesomeIcon.Check.ToIconString()
: FontAwesomeIcon.Times.ToIconString());
ImUtf8.DrawTableColumn(customize.NpcCustomizeSet.CheckColor(CustomizeIndex.TattooColor, index)
? FontAwesomeIcon.Check.ToIconString()
: FontAwesomeIcon.Times.ToIconString());
}
} }
private void DrawCustomizationInfo(CustomizeSet set) private void DrawCustomizationInfo(CustomizeSet set)