From 8fd4dccf6b77a711e4471798376438cd4792ee01 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Fri, 3 Apr 2026 18:18:53 -0700 Subject: [PATCH] fix(vendor): preserve repair flag across ListInventory parse ListInventoryParser::parse() was resetting the entire ListInventoryData struct, wiping the canRepair flag set by the gossip handler before the server response arrived. Preserve it across the parse. Also detect repair capability from UNIT_NPC_FLAG_REPAIR (0x1000) on the vendor NPC entity, so direct vendors without gossip menus also show the repair button. --- src/game/inventory_handler.cpp | 11 +++++++++++ src/game/world_packets.cpp | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/src/game/inventory_handler.cpp b/src/game/inventory_handler.cpp index 1a4c1ab4..74903f86 100644 --- a/src/game/inventory_handler.cpp +++ b/src/game/inventory_handler.cpp @@ -1285,6 +1285,17 @@ void InventoryHandler::useItemById(uint32_t itemId) { void InventoryHandler::handleListInventory(network::Packet& packet) { if (!ListInventoryParser::parse(packet, currentVendorItems_)) return; + + // Detect repair capability from NPC flags (covers direct vendors without gossip). + // UNIT_NPC_FLAG_REPAIR = 0x1000. + if (!currentVendorItems_.canRepair && currentVendorItems_.vendorGuid != 0) { + if (auto* unit = owner_.getUnitByGuid(currentVendorItems_.vendorGuid)) { + if (unit->getNpcFlags() & 0x1000) { + currentVendorItems_.canRepair = true; + } + } + } + vendorWindowOpen_ = true; owner_.closeGossip(); if (owner_.addonEventCallback_) owner_.addonEventCallback_("MERCHANT_SHOW", {}); diff --git a/src/game/world_packets.cpp b/src/game/world_packets.cpp index cc23e18b..e5753b70 100644 --- a/src/game/world_packets.cpp +++ b/src/game/world_packets.cpp @@ -4964,7 +4964,12 @@ network::Packet BuybackItemPacket::build(uint64_t vendorGuid, uint32_t slot) { } bool ListInventoryParser::parse(network::Packet& packet, ListInventoryData& data) { + // Preserve canRepair — it was set by the gossip handler before this packet + // arrived and is not part of the wire format. + const bool savedCanRepair = data.canRepair; data = ListInventoryData{}; + data.canRepair = savedCanRepair; + if (!packet.hasRemaining(9)) { LOG_WARNING("ListInventoryParser: packet too short"); return false;