From 209f60031efcbf9a67ec751b110203aa500b8c06 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 18 Mar 2026 10:01:53 -0700 Subject: [PATCH] feat: respect loot roll voteMask for button visibility Store the voteMask from SMSG_LOOT_START_ROLL and use it to conditionally show Need/Greed/Disenchant/Pass buttons. Previously all four buttons were always shown regardless of the server's allowed roll types. --- include/game/game_handler.hpp | 1 + src/game/game_handler.cpp | 5 +++-- src/ui/game_screen.cpp | 32 +++++++++++++++++++++----------- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/include/game/game_handler.hpp b/include/game/game_handler.hpp index 02bd74cb..0a44957d 100644 --- a/include/game/game_handler.hpp +++ b/include/game/game_handler.hpp @@ -1458,6 +1458,7 @@ public: std::string itemName; uint8_t itemQuality = 0; uint32_t rollCountdownMs = 60000; // Duration of roll window in ms + uint8_t voteMask = 0xFF; // Bitmask: 0x01=pass, 0x02=need, 0x04=greed, 0x08=disenchant std::chrono::steady_clock::time_point rollStartedAt{}; struct PlayerRollResult { diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index a918db20..0bd365dc 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -2344,7 +2344,7 @@ void GameHandler::handlePacket(network::Packet& packet) { /*uint32_t randProp =*/ packet.readUInt32(); } uint32_t countdown = packet.readUInt32(); - /*uint8_t voteMask =*/ packet.readUInt8(); + uint8_t voteMask = packet.readUInt8(); // Trigger the roll popup for local player pendingLootRollActive_ = true; pendingLootRoll_.objectGuid = objectGuid; @@ -2358,9 +2358,10 @@ void GameHandler::handlePacket(network::Packet& packet) { pendingLootRoll_.itemName = info ? info->name : std::to_string(itemId); pendingLootRoll_.itemQuality = info ? static_cast(info->quality) : 0; pendingLootRoll_.rollCountdownMs = (countdown > 0 && countdown <= 120000) ? countdown : 60000; + pendingLootRoll_.voteMask = voteMask; pendingLootRoll_.rollStartedAt = std::chrono::steady_clock::now(); LOG_INFO("SMSG_LOOT_START_ROLL: item=", itemId, " (", pendingLootRoll_.itemName, - ") slot=", slot); + ") slot=", slot, " voteMask=0x", std::hex, (int)voteMask, std::dec); break; } diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index dd727550..9aacfa58 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -13198,20 +13198,30 @@ void GameScreen::renderLootRollPopup(game::GameHandler& gameHandler) { } ImGui::Spacing(); - if (ImGui::Button("Need", ImVec2(80, 30))) { - gameHandler.sendLootRoll(roll.objectGuid, roll.slot, 0); + // voteMask bits: 0x01=pass, 0x02=need, 0x04=greed, 0x08=disenchant + const uint8_t vm = roll.voteMask; + bool first = true; + if (vm & 0x02) { + if (ImGui::Button("Need", ImVec2(80, 30))) + gameHandler.sendLootRoll(roll.objectGuid, roll.slot, 0); + first = false; } - ImGui::SameLine(); - if (ImGui::Button("Greed", ImVec2(80, 30))) { - gameHandler.sendLootRoll(roll.objectGuid, roll.slot, 1); + if (vm & 0x04) { + if (!first) ImGui::SameLine(); + if (ImGui::Button("Greed", ImVec2(80, 30))) + gameHandler.sendLootRoll(roll.objectGuid, roll.slot, 1); + first = false; } - ImGui::SameLine(); - if (ImGui::Button("Disenchant", ImVec2(95, 30))) { - gameHandler.sendLootRoll(roll.objectGuid, roll.slot, 2); + if (vm & 0x08) { + if (!first) ImGui::SameLine(); + if (ImGui::Button("Disenchant", ImVec2(95, 30))) + gameHandler.sendLootRoll(roll.objectGuid, roll.slot, 2); + first = false; } - ImGui::SameLine(); - if (ImGui::Button("Pass", ImVec2(70, 30))) { - gameHandler.sendLootRoll(roll.objectGuid, roll.slot, 96); + if (vm & 0x01) { + if (!first) ImGui::SameLine(); + if (ImGui::Button("Pass", ImVec2(70, 30))) + gameHandler.sendLootRoll(roll.objectGuid, roll.slot, 96); } // Live roll results from group members