From 63c6039dbb35e7d81859d44ff54cc4b198694d00 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Mon, 9 Mar 2026 13:40:19 -0700 Subject: [PATCH] Handle SMSG_CLEAR_COOLDOWN and SMSG_MODIFY_COOLDOWN SMSG_CLEAR_COOLDOWN: remove spell cooldown from cache and clear action bar slot's remaining cooldown immediately (e.g. after item use, trinket proc). SMSG_MODIFY_COOLDOWN: adjust an existing cooldown duration by a signed delta in milliseconds (used by glyphs, Borrowed Time, etc.). --- src/game/game_handler.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index 383af10c..2acbb324 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -1791,6 +1791,40 @@ void GameHandler::handlePacket(network::Packet& packet) { case Opcode::SMSG_COOLDOWN_EVENT: handleCooldownEvent(packet); break; + case Opcode::SMSG_CLEAR_COOLDOWN: { + // spellId(u32) + guid(u64): clear cooldown for the given spell/guid + if (packet.getSize() - packet.getReadPos() >= 4) { + uint32_t spellId = packet.readUInt32(); + // guid is present but we only track per-spell for the local player + spellCooldowns.erase(spellId); + for (auto& slot : actionBar) { + if (slot.type == ActionBarSlot::SPELL && slot.id == spellId) { + slot.cooldownRemaining = 0.0f; + } + } + LOG_DEBUG("SMSG_CLEAR_COOLDOWN: spellId=", spellId); + } + break; + } + case Opcode::SMSG_MODIFY_COOLDOWN: { + // spellId(u32) + diffMs(i32): adjust cooldown remaining by diffMs + if (packet.getSize() - packet.getReadPos() >= 8) { + uint32_t spellId = packet.readUInt32(); + int32_t diffMs = static_cast(packet.readUInt32()); + float diffSec = diffMs / 1000.0f; + auto it = spellCooldowns.find(spellId); + if (it != spellCooldowns.end()) { + it->second = std::max(0.0f, it->second + diffSec); + for (auto& slot : actionBar) { + if (slot.type == ActionBarSlot::SPELL && slot.id == spellId) { + slot.cooldownRemaining = std::max(0.0f, slot.cooldownRemaining + diffSec); + } + } + } + LOG_DEBUG("SMSG_MODIFY_COOLDOWN: spellId=", spellId, " diff=", diffMs, "ms"); + } + break; + } case Opcode::SMSG_CANCEL_AUTO_REPEAT: break; // Server signals to stop a repeating spell (wand/shoot); no client action needed case Opcode::SMSG_AURA_UPDATE: