diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index 287f0456..eab06871 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -6551,17 +6551,23 @@ VkDescriptorSet GameScreen::getSpellIcon(uint32_t spellId, pipeline::AssetManage } }; - // Always use expansion-aware layout if available - // Field indices vary by expansion: Classic=117, TBC=124, WotLK=133 + // Use expansion-aware layout if available AND the DBC field count + // matches the expansion's expected format. Classic=173, TBC=216, + // WotLK=234 fields. When Classic is active but the base WotLK DBC + // is loaded (234 fields), field 117 is NOT IconID — we must use + // the WotLK field 133 instead. + uint32_t iconField = 133; // WotLK default + uint32_t idField = 0; if (spellL) { - tryLoadIcons((*spellL)["ID"], (*spellL)["IconID"]); - } - - // Fallback if expansion layout missing or yielded nothing - // Only use WotLK field 133 as last resort if we have no layout - if (spellIconIds_.empty() && !spellL && fieldCount > 133) { - tryLoadIcons(0, 133); + uint32_t layoutIcon = (*spellL)["IconID"]; + // Only trust the expansion layout if the DBC has a compatible + // field count (within ~20 of the layout's icon field). + if (layoutIcon < fieldCount && fieldCount <= layoutIcon + 20) { + iconField = layoutIcon; + idField = (*spellL)["ID"]; + } } + tryLoadIcons(idField, iconField); } } diff --git a/src/ui/talent_screen.cpp b/src/ui/talent_screen.cpp index bed817ab..c2b92eff 100644 --- a/src/ui/talent_screen.cpp +++ b/src/ui/talent_screen.cpp @@ -593,15 +593,27 @@ void TalentScreen::loadSpellDBC(pipeline::AssetManager* assetManager) { if (!dbc || !dbc->isLoaded()) return; const auto* spellL = pipeline::getActiveDBCLayout() ? pipeline::getActiveDBCLayout()->getLayout("Spell") : nullptr; + uint32_t fieldCount = dbc->getFieldCount(); + // Detect DBC/layout mismatch: Classic layout expects ~173 fields but we may + // load the WotLK base DBC (234 fields). Use WotLK field indices in that case. + uint32_t idField = 0, iconField = 133, tooltipField = 139; + if (spellL) { + uint32_t layoutIcon = (*spellL)["IconID"]; + if (layoutIcon < fieldCount && fieldCount <= layoutIcon + 20) { + idField = (*spellL)["ID"]; + iconField = layoutIcon; + try { tooltipField = (*spellL)["Tooltip"]; } catch (...) {} + } + } uint32_t count = dbc->getRecordCount(); for (uint32_t i = 0; i < count; ++i) { - uint32_t spellId = dbc->getUInt32(i, spellL ? (*spellL)["ID"] : 0); + uint32_t spellId = dbc->getUInt32(i, idField); if (spellId == 0) continue; - uint32_t iconId = dbc->getUInt32(i, spellL ? (*spellL)["IconID"] : 133); + uint32_t iconId = dbc->getUInt32(i, iconField); spellIconIds[spellId] = iconId; - std::string tooltip = dbc->getString(i, spellL ? (*spellL)["Tooltip"] : 139); + std::string tooltip = dbc->getString(i, tooltipField); if (!tooltip.empty()) { spellTooltips[spellId] = tooltip; }