From cc2b413e22798f7f9ed46b0167008e5d41f2a241 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Fri, 13 Mar 2026 04:59:05 -0700 Subject: [PATCH] fix: guard gather-node CMSG_LOOT dispatch against instant casts and proc spells MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit handleSpellGo fired lootTarget(lastInteractedGoGuid_) on ANY player spell completion, including instant casts and proc/triggered spells that arrive while the gather cast is still in flight. Save the casting flag before clearing it and only dispatch CMSG_LOOT when wasInTimedCast is true — this ensures only the gather cast completion triggers the post-gather loot send, not unrelated instant spells that also produce SMSG_SPELL_GO. --- src/game/game_handler.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index e2baca55..8ee75b9c 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -16292,6 +16292,12 @@ void GameHandler::handleSpellGo(network::Packet& packet) { meleeSwingCallback_(); } + // Capture cast state before clearing: SMSG_SPELL_GO for instant casts and + // proc/triggered spells arrives while casting == false (they never go through + // handleSpellStart with castTime > 0). We must NOT send CMSG_LOOT for a + // gather node in those cases — only when a real timed gather cast completes. + const bool wasInTimedCast = casting; + casting = false; castIsChannel = false; currentCastSpellId = 0; @@ -16299,7 +16305,8 @@ void GameHandler::handleSpellGo(network::Packet& packet) { // If we were gathering a node (mining/herbalism), send CMSG_LOOT now that // the gather cast completed and the server has made the node lootable. - if (lastInteractedGoGuid_ != 0) { + // Guard with wasInTimedCast to avoid firing on instant casts / procs. + if (wasInTimedCast && lastInteractedGoGuid_ != 0) { lootTarget(lastInteractedGoGuid_); lastInteractedGoGuid_ = 0; }