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.
This commit is contained in:
Kelsi 2026-04-03 18:18:53 -07:00
parent 8e1addf7a6
commit 8fd4dccf6b
2 changed files with 16 additions and 0 deletions

View file

@ -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", {});

View file

@ -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;