namespace AcDream.Core.CharGen; /// /// Pure projection of a PalSet dat object (0x0F......, retail /// PalSet::Unpack / Chorizite DatReaderWriter.DBObjs.PalSet): /// the ordered list of Palette dat ids (0x04......) a shade fraction picks /// from via . Every appearance /// color slot that resolves "by shade" — skin (ChargenGenderOptions.SkinPalSetId), /// hair (ChargenGenderOptions.HairColors[i]), and every clothing /// dye choice (ChargenClothingSubPaletteChoice.PalSetId) — reads one /// of these. Eye color is the one exception: retail uses the raw entry /// from ChargenGenderOptions.EyeColors directly as a Palette id, no /// PalSet/shade indirection (gmCG3DView::Update pseudo-C ~0x004EF12F; /// cross-checked against /// references/ACE/Source/ACE.Server/Factories/PlayerFactory.cs:100, /// which sets EyesPalette straight from sex.EyeColorList[eyeColor] /// with no GetPaletteID call, unlike the Skin/Hair lines immediately /// above it). /// public sealed record ChargenPalSet(IReadOnlyList PaletteIds) { public static ChargenPalSet Empty { get; } = new(Array.Empty()); }