From c89c35ecff77038afc36e87bdbfb4c479a28f610 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Thu, 19 Feb 2026 18:10:25 -0800 Subject: [PATCH] Fix item tooltip armor: default to 5 damage entries (correct for all WoW versions) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All WoW versions use exactly 5 damage entries in SMSG_ITEM_QUERY_SINGLE_RESPONSE. The previous heuristic defaulted to parsed2 (2 entries) and only switched to parsed5 for armor items based on a non-zero armor check — but that check was circular: it needed parsed5.armor>0 to switch to parsed5, which only happens if parsed5 is already the selected result. Flipping the default to parsed5 and falling back to parsed2 only when parsed2 clearly identifies a weapon item (damage+delay present, parsed5 doesn't match) fixes armor for armor items without breaking weapon stat parsing. --- src/game/world_packets.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/game/world_packets.cpp b/src/game/world_packets.cpp index c05f694a..fc0af398 100644 --- a/src/game/world_packets.cpp +++ b/src/game/world_packets.cpp @@ -2179,24 +2179,23 @@ bool ItemQueryResponseParser::parse(network::Packet& packet, ItemQueryResponseDa return r; }; - // Most WotLK/TBC cores use 2 damage entries, but some custom cores still - // serialize a 5-entry damage block. Try both and select the plausible one. + // All WoW versions (Classic, TBC, WotLK) use exactly 5 damage entries in + // SMSG_ITEM_QUERY_SINGLE_RESPONSE. Default to 5. Fall back to 2 only if + // the 5-entry parse fails or yields clearly implausible results for weapons. DamageParseResult parsed2 = parseDamageBlock(2); DamageParseResult parsed5 = parseDamageBlock(5); - auto looksArmorItem = [&](const DamageParseResult& r) { - return (data.itemClass == 4) && (data.inventoryType != 0) && (r.armor > 0); - }; auto looksWeaponItem = [&](const DamageParseResult& r) { return (data.itemClass == 2) && (r.damageMax > 0.0f) && (r.delayMs > 0); }; - const DamageParseResult* chosen = &parsed2; - if (parsed5.ok && !parsed2.ok) { - chosen = &parsed5; - } else if (parsed2.ok && parsed5.ok) { - if (looksArmorItem(parsed5) && !looksArmorItem(parsed2)) chosen = &parsed5; - else if (looksWeaponItem(parsed5) && !looksWeaponItem(parsed2)) chosen = &parsed5; + const DamageParseResult* chosen = &parsed5; + if (parsed5.ok && parsed2.ok) { + // Only prefer parsed2 if it identifies as a weapon and parsed5 doesn't. + // This handles non-standard 2-entry servers for weapon items. + if (looksWeaponItem(parsed2) && !looksWeaponItem(parsed5)) chosen = &parsed2; + } else if (!parsed5.ok && parsed2.ok) { + chosen = &parsed2; } int chosenDamageEntries = (chosen == &parsed5) ? 5 : 2;