From 60904e2e158b94111c2cb9e63ea94f26bae6dcb2 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Sat, 21 Mar 2026 02:29:48 -0700 Subject: [PATCH] fix: fire talent/spell events correctly when learning talents Fix bug where learning a talent caused an early return before firing LEARNED_SPELL_IN_TAB and SPELLS_CHANGED events, leaving talent addons unaware of changes. Now talent learning fires CHARACTER_POINTS_CHANGED, PLAYER_TALENT_UPDATE, LEARNED_SPELL_IN_TAB, and SPELLS_CHANGED. Also fire CHARACTER_POINTS_CHANGED, ACTIVE_TALENT_GROUP_CHANGED, and PLAYER_TALENT_UPDATE from handleTalentsInfo (SMSG_TALENTS_INFO), so talent addons update when the full talent state is received from the server (login, spec switch, respec). Also fire UNIT_HEALTH/UNIT_POWER events from SMSG_HEALTH_UPDATE and SMSG_POWER_UPDATE packets for real-time unit frame updates. --- src/game/game_handler.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index 3832eb39..74f027ef 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -19524,6 +19524,7 @@ void GameHandler::handleLearnedSpell(network::Packet& packet) { LOG_INFO("Learned spell: ", spellId, alreadyKnown ? " (already known, skipping chat)" : ""); // Check if this spell corresponds to a talent rank + bool isTalentSpell = false; for (const auto& [talentId, talent] : talentCache_) { for (int rank = 0; rank < 5; ++rank) { if (talent.rankSpells[rank] == spellId) { @@ -19532,9 +19533,15 @@ void GameHandler::handleLearnedSpell(network::Packet& packet) { learnedTalents_[activeTalentSpec_][talentId] = newRank; LOG_INFO("Talent learned: id=", talentId, " rank=", (int)newRank, " (spell ", spellId, ") in spec ", (int)activeTalentSpec_); - return; + isTalentSpell = true; + if (addonEventCallback_) { + addonEventCallback_("CHARACTER_POINTS_CHANGED", {}); + addonEventCallback_("PLAYER_TALENT_UPDATE", {}); + } + break; } } + if (isTalentSpell) break; } // Fire LEARNED_SPELL_IN_TAB / SPELLS_CHANGED for Lua addons @@ -19543,6 +19550,8 @@ void GameHandler::handleLearnedSpell(network::Packet& packet) { addonEventCallback_("SPELLS_CHANGED", {}); } + if (isTalentSpell) return; // talent spells don't show chat message + // Show chat message for non-talent spells, but only if not already announced by // SMSG_TRAINER_BUY_SUCCEEDED (which pre-inserts into knownSpells). if (!alreadyKnown) { @@ -19720,6 +19729,13 @@ void GameHandler::handleTalentsInfo(network::Packet& packet) { " groups=", (int)talentGroupCount, " active=", (int)activeTalentGroup, " learned=", learnedTalents_[activeTalentGroup].size()); + // Fire talent-related events for addons + if (addonEventCallback_) { + addonEventCallback_("CHARACTER_POINTS_CHANGED", {}); + addonEventCallback_("ACTIVE_TALENT_GROUP_CHANGED", {}); + addonEventCallback_("PLAYER_TALENT_UPDATE", {}); + } + if (!talentsInitialized_) { talentsInitialized_ = true; if (unspentTalents > 0) {