From 05ab9922c4053b9554516e62fbf0d3a1a1658c1e Mon Sep 17 00:00:00 2001 From: Kelsi Date: Sat, 28 Mar 2026 11:04:29 -0700 Subject: [PATCH] =?UTF-8?q?fix:=20visible=20item=20stride=202=E2=86=924=20?= =?UTF-8?q?(confirmed=20from=20raw=20field=20dump)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RAW FIELDS dump shows equipment entries at indices 284, 288, 292, 296, 300 — stride 4, not 2. Each visible item slot occupies 4 fields (entry + enchant + 2 padding), not 2 as previously assumed. Field dump evidence: [284]=3817(Reinforced Buckler) [288]=3808(Double Mail Boots) [292]=3252 [296]=3823 [300]=3845 [312]=3825 [314]=3827 With stride 2, slots 0-18 read indices 284,286,288,290... which interleaves entries with enchant/padding values, producing mostly zeros for equipment. With stride 4, slots correctly map to entry-only fields. --- include/game/game_handler.hpp | 11 ++++++----- src/game/inventory_handler.cpp | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/include/game/game_handler.hpp b/include/game/game_handler.hpp index 2cdd8fa7..462c33b2 100644 --- a/include/game/game_handler.hpp +++ b/include/game/game_handler.hpp @@ -2568,11 +2568,12 @@ private: // Visible equipment for other players: detect the update-field layout (base + stride) // using the local player's own equipped items, then decode other players by index. - // WotLK 3.3.5a: PLAYER_VISIBLE_ITEM_1_ENTRYID = PLAYER_FIELD_INV_SLOT_HEAD(324) - 19*2 = 286. - // 19 visible item slots × 2 fields (entry + enchant) = 38 fields before inventory. - // The heuristic in maybeDetectVisibleItemLayout() can still override if needed. - int visibleItemEntryBase_ = 286; - int visibleItemStride_ = 2; + // WotLK 3.3.5a (AzerothCore/ChromieCraft): visible item entries appear at field + // indices 284, 288, 292, 296, ... with stride 4. Confirmed by RAW FIELDS dump: + // [284]=3817(Buckler) [288]=3808(Boots) [292]=3252 [296]=3823 [300]=3845 etc. + // Each visible item occupies 4 fields: entry(1) + enchant(1) + padding(2). + int visibleItemEntryBase_ = 284; + int visibleItemStride_ = 4; bool visibleItemLayoutVerified_ = false; // true once heuristic confirms/overrides default std::unordered_map> otherPlayerVisibleItemEntries_; std::unordered_set otherPlayerVisibleDirty_; diff --git a/src/game/inventory_handler.cpp b/src/game/inventory_handler.cpp index 4a73fb76..1c83417d 100644 --- a/src/game/inventory_handler.cpp +++ b/src/game/inventory_handler.cpp @@ -3105,6 +3105,22 @@ void InventoryHandler::updateOtherPlayerVisibleItems(uint64_t guid, const std::m int nonZero = 0; for (uint32_t e : newEntries) { if (e != 0) nonZero++; } + + // Dump raw fields around visible item range to find the correct offset + static bool dumpedOnce = false; + if (!dumpedOnce && fields.size() > 50) { + dumpedOnce = true; + std::string dump; + for (const auto& [idx, val] : fields) { + if (idx >= 270 && idx <= 340 && val != 0) { + char buf[32]; + snprintf(buf, sizeof(buf), " [%u]=%u", idx, val); + dump += buf; + } + } + LOG_WARNING("RAW FIELDS 270-340:", dump); + } + if (nonZero > 0) { LOG_WARNING("updateOtherPlayerVisibleItems: guid=0x", std::hex, guid, std::dec, " nonZero=", nonZero, " base=", base, " stride=", stride,