fix: restore correct CharSections.dbc field indices for character textures

PR #19 (572bb4ef) swapped CharSections.dbc field indices, placing
Texture1-3 at fields 4-6 and VariationIndex/ColorIndex at 8-9. Binary
analysis of the actual DBC files (Classic, TBC, Turtle — all identical
layout, no WotLK-specific override) confirms the correct order is:

  Field 4 = VariationIndex
  Field 5 = ColorIndex
  Field 6 = Texture1 (string)
  Field 7 = Texture2 (string)
  Field 8 = Texture3 (string)
  Field 9 = Flags

With the wrong indices, VariationIndex/ColorIndex reads returned string
offsets (garbage values that never matched), so all CharSections lookups
failed silently — producing white untextured character models at the
login screen and in-world.

Fixes all 4 expansion JSON layouts, hardcoded fallbacks in
character_preview.cpp, application.cpp, and character_create_screen.cpp.
Also handles the single-layer edge case (body skin only, no face/underwear)
by loading the texture directly instead of skipping compositing.
This commit is contained in:
Kelsi 2026-03-22 15:22:25 -07:00
parent 329a1f4b12
commit e9ce062112
7 changed files with 49 additions and 38 deletions

View file

@ -257,8 +257,8 @@ void CharacterCreateScreen::updateAppearanceRanges() {
if (raceId != targetRaceId || sexId != targetSexId) continue;
uint32_t baseSection = dbc->getUInt32(r, csL ? (*csL)["BaseSection"] : 3);
uint32_t variationIndex = dbc->getUInt32(r, csL ? (*csL)["VariationIndex"] : 8);
uint32_t colorIndex = dbc->getUInt32(r, csL ? (*csL)["ColorIndex"] : 9);
uint32_t variationIndex = dbc->getUInt32(r, csL ? (*csL)["VariationIndex"] : 4);
uint32_t colorIndex = dbc->getUInt32(r, csL ? (*csL)["ColorIndex"] : 5);
if (baseSection == 0 && variationIndex == 0) {
skinMax = std::max(skinMax, static_cast<int>(colorIndex));
@ -284,8 +284,8 @@ void CharacterCreateScreen::updateAppearanceRanges() {
if (raceId != targetRaceId || sexId != targetSexId) continue;
uint32_t baseSection = dbc->getUInt32(r, csL ? (*csL)["BaseSection"] : 3);
uint32_t variationIndex = dbc->getUInt32(r, csL ? (*csL)["VariationIndex"] : 8);
uint32_t colorIndex = dbc->getUInt32(r, csL ? (*csL)["ColorIndex"] : 9);
uint32_t variationIndex = dbc->getUInt32(r, csL ? (*csL)["VariationIndex"] : 4);
uint32_t colorIndex = dbc->getUInt32(r, csL ? (*csL)["ColorIndex"] : 5);
if (baseSection == 1 && colorIndex == static_cast<uint32_t>(skin)) {
faceMax = std::max(faceMax, static_cast<int>(variationIndex));