From df0bfaea4fd3efccaf5f5d547a96192c5eef7ea1 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Tue, 17 Feb 2026 15:41:55 -0800 Subject: [PATCH] Fix action bar and buff bar spell tooltips showing 'Spell #xxx' The action bar's inline Spell.dbc loader had a broken field index lookup: operator[] on the layout map would silently insert 0 if 'Name' wasn't a key, causing all names to be read from field 0 (the spell ID). Also the once-only 'attempted' flag meant if assetMgr wasn't ready, it never retried. Replace the duplicated broken DBC loading in the action bar and buff bar with SpellbookScreen::lookupSpellName(), which reuses the spellbook's already-correct loading (expansion layout + WotLK fallback). Remove the now-unused actionSpellNames/actionSpellDbAttempted/actionSpellDbLoaded fields. --- include/ui/game_screen.hpp | 4 ---- include/ui/spellbook_screen.hpp | 3 +++ src/ui/game_screen.cpp | 41 ++++----------------------------- src/ui/spellbook_screen.cpp | 9 ++++++++ 4 files changed, 16 insertions(+), 41 deletions(-) diff --git a/include/ui/game_screen.hpp b/include/ui/game_screen.hpp index c5d8b600..d1833c63 100644 --- a/include/ui/game_screen.hpp +++ b/include/ui/game_screen.hpp @@ -203,10 +203,6 @@ private: TalentScreen talentScreen; rendering::WorldMap worldMap; - bool actionSpellDbAttempted = false; - bool actionSpellDbLoaded = false; - std::unordered_map actionSpellNames; - // Spell icon cache: spellId -> GL texture ID std::unordered_map spellIconCache_; // SpellIconID -> icon path (from SpellIcon.dbc) diff --git a/include/ui/spellbook_screen.hpp b/include/ui/spellbook_screen.hpp index 1ae5a1f6..ae3ec39e 100644 --- a/include/ui/spellbook_screen.hpp +++ b/include/ui/spellbook_screen.hpp @@ -35,6 +35,9 @@ public: void toggle() { open = !open; } void setOpen(bool o) { open = o; } + // Spell name lookup — triggers DBC load if needed, used by action bar tooltips + std::string lookupSpellName(uint32_t spellId, pipeline::AssetManager* assetManager); + // Drag-and-drop state for action bar assignment bool isDraggingSpell() const { return draggingSpell_; } uint32_t getDragSpellId() const { return dragSpellId_; } diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index 456914d9..09e33e9d 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -3084,36 +3084,8 @@ void GameScreen::renderActionBar(game::GameHandler& gameHandler) { bool onCooldown = !slot.isReady(); auto getSpellName = [&](uint32_t spellId) -> std::string { - if (!actionSpellDbAttempted) { - actionSpellDbAttempted = true; - if (assetMgr && assetMgr->isInitialized()) { - auto dbc = assetMgr->loadDBC("Spell.dbc"); - if (dbc && dbc->isLoaded()) { - const auto* actionSpellL = pipeline::getActiveDBCLayout() ? pipeline::getActiveDBCLayout()->getLayout("Spell") : nullptr; - uint32_t fieldCount = dbc->getFieldCount(); - uint32_t nameField = actionSpellL ? (*actionSpellL)["Name"] : 136; - if (fieldCount < 137) { - if (fieldCount > 10) { - nameField = fieldCount > 140 ? 136 : 1; - } else { - nameField = 1; - } - } - uint32_t count = dbc->getRecordCount(); - actionSpellNames.reserve(count); - for (uint32_t r = 0; r < count; ++r) { - uint32_t id = dbc->getUInt32(r, actionSpellL ? (*actionSpellL)["ID"] : 0); - std::string name = dbc->getString(r, nameField); - if (!name.empty() && id > 0) { - actionSpellNames[id] = name; - } - } - actionSpellDbLoaded = true; - } - } - } - auto it = actionSpellNames.find(spellId); - if (it != actionSpellNames.end()) return it->second; + std::string name = spellbookScreen.lookupSpellName(spellId, assetMgr); + if (!name.empty()) return name; return "Spell #" + std::to_string(spellId); }; @@ -4108,13 +4080,8 @@ void GameScreen::renderBuffBar(game::GameHandler& gameHandler) { // Tooltip with spell name and duration if (ImGui::IsItemHovered()) { - std::string name; - auto it = actionSpellNames.find(aura.spellId); - if (it != actionSpellNames.end()) { - name = it->second; - } else { - name = "Spell #" + std::to_string(aura.spellId); - } + std::string name = spellbookScreen.lookupSpellName(aura.spellId, assetMgr); + if (name.empty()) name = "Spell #" + std::to_string(aura.spellId); if (aura.durationMs > 0) { int seconds = aura.durationMs / 1000; if (seconds < 60) { diff --git a/src/ui/spellbook_screen.cpp b/src/ui/spellbook_screen.cpp index 41ccba86..0cccac44 100644 --- a/src/ui/spellbook_screen.cpp +++ b/src/ui/spellbook_screen.cpp @@ -71,6 +71,15 @@ void SpellbookScreen::loadSpellDBC(pipeline::AssetManager* assetManager) { dbcLoaded = !spellData.empty(); } +std::string SpellbookScreen::lookupSpellName(uint32_t spellId, pipeline::AssetManager* assetManager) { + if (!dbcLoadAttempted) { + loadSpellDBC(assetManager); + } + auto it = spellData.find(spellId); + if (it != spellData.end()) return it->second.name; + return {}; +} + void SpellbookScreen::loadSpellIconDBC(pipeline::AssetManager* assetManager) { if (iconDbLoaded) return; iconDbLoaded = true;