From d6e398d814fa2c1d69aa848ce42f4ca6baaaa2c1 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 11 Mar 2026 03:53:18 -0700 Subject: [PATCH] fix: add Classic parseCastResult override with result enum +1 shift Classic 1.12 SMSG_CAST_RESULT uses an enum starting at 0=AFFECTING_COMBAT (no SUCCESS entry), while WotLK starts at 0=SUCCESS, 1=AFFECTING_COMBAT. Without this override, Classic result codes were handled by TBC's parseCastResult which passed them unshifted, causing result 0 (AFFECTING_COMBAT) to be silently treated as success with no error shown. This applies the same +1 shift used in parseCastFailed so all Classic spell failure codes map correctly to getSpellCastResultString. --- include/game/packet_parsers.hpp | 1 + src/game/packet_parsers_classic.cpp | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/include/game/packet_parsers.hpp b/include/game/packet_parsers.hpp index 2cb17fdb..9fb0f166 100644 --- a/include/game/packet_parsers.hpp +++ b/include/game/packet_parsers.hpp @@ -389,6 +389,7 @@ public: network::Packet buildCastSpell(uint32_t spellId, uint64_t targetGuid, uint8_t castCount) override; network::Packet buildUseItem(uint8_t bagIndex, uint8_t slotIndex, uint64_t itemGuid, uint32_t spellId = 0) override; bool parseCastFailed(network::Packet& packet, CastFailedData& data) override; + bool parseCastResult(network::Packet& packet, uint32_t& spellId, uint8_t& result) override; bool parseMessageChat(network::Packet& packet, MessageChatData& data) override; bool parseGameObjectQueryResponse(network::Packet& packet, GameObjectQueryResponseData& data) override; // Classic 1.12 SMSG_CREATURE_QUERY_RESPONSE lacks the iconName string that TBC/WotLK include diff --git a/src/game/packet_parsers_classic.cpp b/src/game/packet_parsers_classic.cpp index 35dc54f4..7277a184 100644 --- a/src/game/packet_parsers_classic.cpp +++ b/src/game/packet_parsers_classic.cpp @@ -633,6 +633,22 @@ bool ClassicPacketParsers::parseCastFailed(network::Packet& packet, CastFailedDa return true; } +// ============================================================================ +// Classic SMSG_CAST_RESULT: same layout as parseCastFailed (spellId + result), +// but the result enum starts at 0=AFFECTING_COMBAT (no SUCCESS entry). +// Apply the same +1 shift used in parseCastFailed so the result codes +// align with WotLK's getSpellCastResultString table. +// ============================================================================ +bool ClassicPacketParsers::parseCastResult(network::Packet& packet, uint32_t& spellId, uint8_t& result) { + if (packet.getSize() - packet.getReadPos() < 5) return false; + spellId = packet.readUInt32(); + uint8_t vanillaResult = packet.readUInt8(); + // Shift +1: Vanilla result 0=AFFECTING_COMBAT maps to WotLK result 1=AFFECTING_COMBAT + result = vanillaResult + 1; + LOG_DEBUG("[Classic] Cast result: spell=", spellId, " vanillaResult=", (int)vanillaResult); + return true; +} + // ============================================================================ // Classic 1.12.1 parseCharEnum // Differences from TBC: