diff --git a/include/game/spell_defines.hpp b/include/game/spell_defines.hpp index e8ceee38..cec57a52 100644 --- a/include/game/spell_defines.hpp +++ b/include/game/spell_defines.hpp @@ -69,9 +69,10 @@ struct SpellCooldownEntry { * Get human-readable spell cast failure reason (WoW 3.3.5a SpellCastResult) */ inline const char* getSpellCastResultString(uint8_t result) { + // AzerothCore 3.3.5a SpellCastResult enum (SharedDefines.h) switch (result) { - case 0: return "Spell failed"; - case 1: return "Affects dead target"; + case 0: return nullptr; // SUCCESS — not a failure + case 1: return "Affecting combat"; case 2: return "Already at full health"; case 3: return "Already at full mana"; case 4: return "Already at full power"; @@ -80,7 +81,7 @@ inline const char* getSpellCastResultString(uint8_t result) { case 7: return "Already have summon"; case 8: return "Already open"; case 9: return "Aura bounced"; - case 10: return "Autopilot in use"; + case 10: return "Autotrack interrupted"; case 11: return "Bad implicit targets"; case 12: return "Bad targets"; case 13: return "Can't be charmed"; @@ -97,31 +98,31 @@ inline const char* getSpellCastResultString(uint8_t result) { case 24: return "Charmed"; case 25: return "Chest in use"; case 26: return "Confused"; - case 27: return "Don't report"; - case 28: return "Equipped item"; - case 29: return "Equipped item (class)"; - case 30: return "Equipped item (class2)"; - case 31: return "Equipped item (level)"; + case 27: return nullptr; // DONT_REPORT — suppress message + case 28: return "Equipped item required"; + case 29: return "Equipped item class (mainhand)"; + case 30: return "Equipped item class (mainhand)"; + case 31: return "Equipped item class (offhand)"; case 32: return "Error"; case 33: return "Fizzle"; case 34: return "Fleeing"; case 35: return "Food too low level"; - case 36: return "Highlighted rune needed"; - case 37: return "Immune"; - case 38: return "Interrupted"; - case 39: return "Interrupted (combat)"; - case 40: return "Invalid item"; - case 41: return "Item already enchanted"; - case 42: return "Item gone"; - case 43: return "Item not found"; - case 44: return "Item not ready"; - case 45: return "Level requirement"; - case 46: return "Line of sight"; - case 47: return "Lowlevel"; - case 48: return "Low castlevel"; - case 49: return "Mainhand empty"; - case 50: return "Moving"; - case 51: return "Must be behind target"; + case 36: return "Target too high level"; + case 37: return "Hunger satiated"; + case 38: return "Immune"; + case 39: return "Incorrect area"; + case 40: return "Interrupted"; + case 41: return "Interrupted (combat)"; + case 42: return "Item already enchanted"; + case 43: return "Item gone"; + case 44: return "Item not found"; + case 45: return "Item not ready"; + case 46: return "Level requirement"; + case 47: return "Line of sight"; + case 48: return "Target too low level"; + case 49: return "Low cast level"; + case 50: return "Mainhand empty"; + case 51: return "Moving"; case 52: return "Need ammo"; case 53: return "Need ammo pouch"; case 54: return "Need exotic ammo"; @@ -131,104 +132,134 @@ inline const char* getSpellCastResultString(uint8_t result) { case 58: return "Not fishable"; case 59: return "Not flying"; case 60: return "Not here"; - case 61: return "Not infront"; + case 61: return "Not in front"; case 62: return "Not in control"; case 63: return "Not known"; case 64: return "Not mounted"; case 65: return "Not on taxi"; case 66: return "Not on transport"; case 67: return "Not ready"; - case 68: return "Not shapeshift"; + case 68: return "Not in shapeshift form"; case 69: return "Not standing"; case 70: return "Not tradeable"; - case 71: return "Not trading"; + case 71: return "Not while trading"; case 72: return "Not unsheathed"; case 73: return "Not while ghost"; case 74: return "Not while looting"; - case 75: return "No charges remain"; - case 76: return "No champion"; - case 77: return "No combo points"; - case 78: return "No dueling"; - case 79: return "No endurance"; - case 80: return "No fish"; - case 81: return "No items while shapeshifted"; - case 82: return "No mounts allowed here"; - case 83: return "No pet"; - case 84: return "No power"; - case 85: return "Nothing to dispel"; - case 86: return "Nothing to steal"; - case 87: return "Only above water"; - case 88: return "Only daytime"; - case 89: return "Only indoors"; - case 90: return "Only mounted"; - case 91: return "Only nighttime"; - case 92: return "Only outdoors"; - case 93: return "Only shapeshift"; - case 94: return "Only stealthed"; - case 95: return "Only underwater"; - case 96: return "Out of range"; - case 97: return "Pacified"; - case 98: return "Possessed"; - case 99: return "Reagents"; - case 100: return "Requires area"; - case 101: return "Requires spell focus"; - case 102: return "Rooted"; - case 103: return "Silenced"; - case 104: return "Spell in progress"; - case 105: return "Spell learned"; - case 106: return "Spell unavailable"; - case 107: return "Stunned"; - case 108: return "Targets dead"; - case 109: return "Target not dead"; - case 110: return "Target not in party"; - case 111: return "Target not in raid"; - case 112: return "Target friendly"; - case 113: return "Target is player"; - case 114: return "Target is player controlled"; - case 115: return "Target not dead"; - case 116: return "Target not in party"; - case 117: return "Target not player"; - case 118: return "Target no pockets"; - case 119: return "Target no weapons"; - case 120: return "Target out of range"; - case 121: return "Target unskinnable"; - case 122: return "Thirst satiated"; - case 123: return "Too close"; - case 124: return "Too many of item"; - case 125: return "Totem category"; - case 126: return "Totems"; - case 127: return "Training points"; - case 128: return "Try again"; - case 129: return "Unit not behind"; - case 130: return "Unit not infront"; - case 131: return "Wrong pet food"; - case 132: return "Not while fatigued"; - case 133: return "Target not in instance"; - case 134: return "Not while trading"; - case 135: return "Target not in raid"; - case 136: return "Target feign dead"; - case 137: return "Disabled by power scaling"; - case 138: return "Quest players only"; - case 139: return "Not idle"; - case 140: return "Not inactive"; - case 141: return "Partial playtime"; - case 142: return "No playtime"; - case 143: return "Not in battleground"; - case 144: return "Not in raid instance"; - case 145: return "Only in arena"; - case 146: return "Target locked to raid instance"; - case 147: return "On use enchant"; - case 148: return "Not on ground"; - case 149: return "Custom error"; - case 150: return "Can't open lock"; - case 151: return "Wrong artifact equipped"; - case 173: return "Not enough mana"; - case 174: return "Not enough health"; - case 175: return "Not enough holy power"; - case 176: return "Not enough rage"; - case 177: return "Not enough energy"; - case 178: return "Not enough runes"; - case 179: return "Not enough runic power"; + case 75: return "No ammo"; + case 76: return "No charges remain"; + case 77: return "No champion"; + case 78: return "No combo points"; + case 79: return "No dueling"; + case 80: return "No endurance"; + case 81: return "No fish"; + case 82: return "No items while shapeshifted"; + case 83: return "No mounts allowed here"; + case 84: return "No pet"; + case 85: return "Not enough mana"; + case 86: return "Nothing to dispel"; + case 87: return "Nothing to steal"; + case 88: return "Only above water"; + case 89: return "Only daytime"; + case 90: return "Only indoors"; + case 91: return "Only mounted"; + case 92: return "Only nighttime"; + case 93: return "Only outdoors"; + case 94: return "Only shapeshift"; + case 95: return "Only stealthed"; + case 96: return "Only underwater"; + case 97: return "Out of range"; + case 98: return "Pacified"; + case 99: return "Possessed"; + case 100: return "Reagents required"; + case 101: return "Requires area"; + case 102: return "Requires spell focus"; + case 103: return "Rooted"; + case 104: return "Silenced"; + case 105: return "Spell in progress"; + case 106: return "Spell learned"; + case 107: return "Spell unavailable"; + case 108: return "Stunned"; + case 109: return "Targets dead"; + case 110: return "Target affecting combat"; + case 111: return "Target aurastate"; + case 112: return "Target dueling"; + case 113: return "Target is enemy"; + case 114: return "Target enraged"; + case 115: return "Target friendly"; + case 116: return "Target in combat"; + case 117: return "Target is player"; + case 118: return "Target is player controlled"; + case 119: return "Target not dead"; + case 120: return "Target not in party"; + case 121: return "Target not looted"; + case 122: return "Target not player"; + case 123: return "Target no pockets"; + case 124: return "Target no weapons"; + case 125: return "Target no ranged weapons"; + case 126: return "Target unskinnable"; + case 127: return "Thirst satiated"; + case 128: return "Too close"; + case 129: return "Too many of item"; + case 130: return "Totem category"; + case 131: return "Totems"; + case 132: return "Try again"; + case 133: return "Unit not behind"; + case 134: return "Unit not in front"; + case 135: return "Wrong pet food"; + case 136: return "Not while fatigued"; + case 137: return "Target not in instance"; + case 138: return "Not while trading"; + case 139: return "Target not in raid"; + case 140: return "Target free for all"; + case 141: return "No edible corpses"; + case 142: return "Only battlegrounds"; + case 143: return "Target not ghost"; + case 144: return "Transform unusable"; + case 145: return "Wrong weather"; + case 146: return "Damage immune"; + case 147: return "Prevented by mechanic"; + case 148: return "Play time restriction"; + case 149: return "Reputation required"; + case 150: return "Min skill required"; + case 151: return "Not in arena"; + case 152: return "Not on shapeshift"; + case 153: return "Not on stealthed"; + case 154: return "Not on damage immune"; + case 155: return "Not on mounted"; + case 156: return "Too shallow"; + case 157: return "Target not in sanctuary"; + case 158: return "Target is trivial"; + case 159: return "BM or invis god"; + case 160: return "Expert riding required"; + case 161: return "Artisan riding required"; + case 162: return "Not idle"; + case 163: return "Not inactive"; + case 164: return "Partial playtime"; + case 165: return "No playtime"; + case 166: return "Not in battleground"; + case 167: return "Not in raid instance"; + case 168: return "Only in arena"; + case 169: return "Target locked to raid instance"; + case 170: return "On use enchant"; + case 171: return "Not on ground"; + case 172: return "Custom error"; + case 173: return "Can't do that right now"; + case 174: return "Too many sockets"; + case 175: return "Invalid glyph"; + case 176: return "Unique glyph"; + case 177: return "Glyph socket locked"; + case 178: return "No valid targets"; + case 179: return "Item at max charges"; + case 180: return "Not in barbershop"; + case 181: return "Fishing too low"; + case 182: return "Item enchant trade window"; + case 183: return "Summon pending"; + case 184: return "Max sockets"; + case 185: return "Pet can rename"; + case 186: return "Target cannot be resurrected"; + case 187: return "Unknown error"; + case 255: return nullptr; // SPELL_CAST_OK default: return nullptr; } } diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index 105873c9..9d4707c9 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -806,6 +806,8 @@ void GameHandler::disconnect() { socket.reset(); } activeCharacterGuid_ = 0; + playerNameCache.clear(); + pendingNameQueries.clear(); setState(WorldState::DISCONNECTED); LOG_INFO("Disconnected from world server"); } diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index 8667385a..bbb1e1ff 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -720,8 +720,14 @@ void GameScreen::renderPlayerFrame(game::GameHandler& gameHandler) { uint32_t playerMaxHp = 100; const auto& characters = gameHandler.getCharacters(); - if (!characters.empty()) { - const auto& ch = characters[0]; + uint64_t activeGuid = gameHandler.getActiveCharacterGuid(); + const game::Character* activeChar = nullptr; + for (const auto& c : characters) { + if (c.guid == activeGuid) { activeChar = &c; break; } + } + if (!activeChar && !characters.empty()) activeChar = &characters[0]; + if (activeChar) { + const auto& ch = *activeChar; playerName = ch.name; // Use live server level if available, otherwise character struct playerLevel = gameHandler.getPlayerLevel(); @@ -1510,7 +1516,7 @@ void GameScreen::renderActionBar(game::GameHandler& gameHandler) { } bool rightClicked = ImGui::IsItemClicked(ImGuiMouseButton_Right); - bool hoveredOnRelease = ImGui::IsItemHovered() && + bool hoveredOnRelease = ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) && ImGui::IsMouseReleased(ImGuiMouseButton_Left); // Drop dragged spell from spellbook onto this slot