Add equipment geosets for humanoid NPCs

Load equipment display IDs from CreatureDisplayInfoExtra.dbc and look up
geoset groups from ItemDisplayInfo.dbc. Apply appropriate geosets for
chest, pants, boots, gloves, tabard, and cape. Hide hair when NPC wears
a helmet.
This commit is contained in:
Kelsi 2026-02-05 22:57:32 -08:00
parent 09cec89f6c
commit 9083eec974
2 changed files with 102 additions and 10 deletions

View file

@ -139,6 +139,9 @@ private:
uint8_t hairColorId = 0; uint8_t hairColorId = 0;
uint8_t facialHairId = 0; uint8_t facialHairId = 0;
std::string bakeName; // Pre-baked texture path if available std::string bakeName; // Pre-baked texture path if available
// Equipment display IDs (from columns 8-18)
// 0=helm, 1=shoulder, 2=shirt, 3=chest, 4=belt, 5=legs, 6=feet, 7=wrist, 8=hands, 9=tabard, 10=cape
uint32_t equipDisplayId[11] = {0};
}; };
std::unordered_map<uint32_t, CreatureDisplayData> displayDataMap_; // displayId → display data std::unordered_map<uint32_t, CreatureDisplayData> displayDataMap_; // displayId → display data
std::unordered_map<uint32_t, HumanoidDisplayExtra> humanoidExtraMap_; // extraDisplayId → humanoid data std::unordered_map<uint32_t, HumanoidDisplayExtra> humanoidExtraMap_; // extraDisplayId → humanoid data

View file

@ -1655,6 +1655,10 @@ void Application::buildCreatureDisplayLookups() {
extra.hairStyleId = static_cast<uint8_t>(cdie->getUInt32(i, 5)); extra.hairStyleId = static_cast<uint8_t>(cdie->getUInt32(i, 5));
extra.hairColorId = static_cast<uint8_t>(cdie->getUInt32(i, 6)); extra.hairColorId = static_cast<uint8_t>(cdie->getUInt32(i, 6));
extra.facialHairId = static_cast<uint8_t>(cdie->getUInt32(i, 7)); extra.facialHairId = static_cast<uint8_t>(cdie->getUInt32(i, 7));
// Equipment display IDs (columns 8-18)
for (int eq = 0; eq < 11; eq++) {
extra.equipDisplayId[eq] = cdie->getUInt32(i, 8 + eq);
}
extra.bakeName = cdie->getString(i, 20); extra.bakeName = cdie->getString(i, 20);
if (!extra.bakeName.empty()) withBakeName++; if (!extra.bakeName.empty()) withBakeName++;
humanoidExtraMap_[cdie->getUInt32(i, 0)] = extra; humanoidExtraMap_[cdie->getUInt32(i, 0)] = extra;
@ -1891,18 +1895,103 @@ void Application::spawnOnlineCreature(uint64_t guid, uint32_t displayId, float x
// Facial hair geoset: 200 + facialHairId + 1 (201 = none/style 0, 202 = style 1, etc.) // Facial hair geoset: 200 + facialHairId + 1 (201 = none/style 0, 202 = style 1, etc.)
activeGeosets.insert(static_cast<uint16_t>(201 + extra.facialHairId)); activeGeosets.insert(static_cast<uint16_t>(201 + extra.facialHairId));
// Equipment groups: bare (no armor) // Default equipment geosets (bare/no armor)
activeGeosets.insert(301); // Gloves: bare hands uint16_t geosetGloves = 301; // Bare hands
activeGeosets.insert(401); // Boots: bare feet uint16_t geosetBoots = 401; // Bare feet
activeGeosets.insert(501); // Chest: bare uint16_t geosetChest = 501; // Bare chest
activeGeosets.insert(701); // Ears: default uint16_t geosetPants = 1301; // Bare legs
activeGeosets.insert(1301); // Trousers: bare legs uint16_t geosetCape = 1501; // No cape
activeGeosets.insert(1501); // Back body (cloak=none) uint16_t geosetTabard = 1201; // No tabard
// Note: Do NOT add 1703 (DK eye glow) for normal NPCs bool hideHair = false;
// Load equipment geosets from ItemDisplayInfo.dbc
auto itemDisplayDbc = assetManager->loadDBC("ItemDisplayInfo.dbc");
if (itemDisplayDbc) {
// Equipment slots: 0=helm, 1=shoulder, 2=shirt, 3=chest, 4=belt, 5=legs, 6=feet, 7=wrist, 8=hands, 9=tabard, 10=cape
// ItemDisplayInfo geoset columns: 5=GeosetGroup[0], 6=GeosetGroup[1], 7=GeosetGroup[2]
// Helm (slot 0) - may hide hair
if (extra.equipDisplayId[0] != 0) {
int32_t idx = itemDisplayDbc->findRecordById(extra.equipDisplayId[0]);
if (idx >= 0) {
// Check helmet vis flags (col 12-13) or just hide hair if helm exists
hideHair = true;
}
}
// Chest (slot 3) - geoset group 5xx/8xx
if (extra.equipDisplayId[3] != 0) {
int32_t idx = itemDisplayDbc->findRecordById(extra.equipDisplayId[3]);
if (idx >= 0) {
uint32_t geoGroup = itemDisplayDbc->getUInt32(static_cast<uint32_t>(idx), 5);
if (geoGroup > 0) geosetChest = static_cast<uint16_t>(500 + geoGroup);
}
}
// Legs (slot 5) - geoset group 13xx
if (extra.equipDisplayId[5] != 0) {
int32_t idx = itemDisplayDbc->findRecordById(extra.equipDisplayId[5]);
if (idx >= 0) {
uint32_t geoGroup = itemDisplayDbc->getUInt32(static_cast<uint32_t>(idx), 5);
if (geoGroup > 0) geosetPants = static_cast<uint16_t>(1300 + geoGroup);
}
}
// Feet (slot 6) - geoset group 4xx
if (extra.equipDisplayId[6] != 0) {
int32_t idx = itemDisplayDbc->findRecordById(extra.equipDisplayId[6]);
if (idx >= 0) {
uint32_t geoGroup = itemDisplayDbc->getUInt32(static_cast<uint32_t>(idx), 5);
if (geoGroup > 0) geosetBoots = static_cast<uint16_t>(400 + geoGroup);
}
}
// Hands (slot 8) - geoset group 3xx
if (extra.equipDisplayId[8] != 0) {
int32_t idx = itemDisplayDbc->findRecordById(extra.equipDisplayId[8]);
if (idx >= 0) {
uint32_t geoGroup = itemDisplayDbc->getUInt32(static_cast<uint32_t>(idx), 5);
if (geoGroup > 0) geosetGloves = static_cast<uint16_t>(300 + geoGroup);
}
}
// Tabard (slot 9) - geoset group 12xx
if (extra.equipDisplayId[9] != 0) {
int32_t idx = itemDisplayDbc->findRecordById(extra.equipDisplayId[9]);
if (idx >= 0) {
geosetTabard = 1202; // Show tabard mesh
}
}
// Cape (slot 10) - geoset group 15xx
if (extra.equipDisplayId[10] != 0) {
int32_t idx = itemDisplayDbc->findRecordById(extra.equipDisplayId[10]);
if (idx >= 0) {
uint32_t geoGroup = itemDisplayDbc->getUInt32(static_cast<uint32_t>(idx), 5);
if (geoGroup > 0) geosetCape = static_cast<uint16_t>(1500 + geoGroup);
}
}
}
// Apply equipment geosets
activeGeosets.insert(geosetGloves);
activeGeosets.insert(geosetBoots);
activeGeosets.insert(geosetChest);
activeGeosets.insert(geosetPants);
activeGeosets.insert(geosetCape);
activeGeosets.insert(geosetTabard);
activeGeosets.insert(701); // Ears: default
// Hide hair if wearing helm
if (hideHair) {
activeGeosets.erase(static_cast<uint16_t>(101 + extra.hairStyleId));
}
charRenderer->setActiveGeosets(instanceId, activeGeosets); charRenderer->setActiveGeosets(instanceId, activeGeosets);
LOG_DEBUG("Set humanoid geosets: hair=", 101 + extra.hairStyleId, LOG_DEBUG("Set humanoid geosets: hair=", hideHair ? 0 : (101 + extra.hairStyleId),
" facial=", 201 + extra.facialHairId); " facial=", 201 + extra.facialHairId,
" chest=", geosetChest, " pants=", geosetPants,
" boots=", geosetBoots, " gloves=", geosetGloves);
} }
} }