feat: battleground invitation popup with countdown timer

Replace the text-only "/join to enter" message with an interactive
popup that shows the BG name, a live countdown progress bar, and
Enter/Leave Queue buttons.

- Parse STATUS_WAIT_JOIN timeout from SMSG_BATTLEFIELD_STATUS
- Store inviteReceivedTime (steady_clock) on the queue slot
- BgQueueSlot moved to public section so UI can read invite details
- Add declineBattlefield() that sends CMSG_BATTLEFIELD_PORT(action=0)
- acceptBattlefield() optimistically sets statusId=3 to dismiss popup
- renderBgInvitePopup: colored countdown bar (green→yellow→red),
  named BG (Alterac Valley, Warsong Gulch, etc.), auto-dismisses on expiry
This commit is contained in:
Kelsi 2026-03-10 21:12:28 -07:00
parent 4986308581
commit a7a559cdcc
4 changed files with 184 additions and 8 deletions

View file

@ -340,9 +340,21 @@ public:
// Random roll
void randomRoll(uint32_t minRoll = 1, uint32_t maxRoll = 100);
// Battleground queue slot (public so UI can read invite details)
struct BgQueueSlot {
uint32_t queueSlot = 0;
uint32_t bgTypeId = 0;
uint8_t arenaType = 0;
uint32_t statusId = 0; // 0=none, 1=wait_queue, 2=wait_join, 3=in_progress
uint32_t inviteTimeout = 80;
std::chrono::steady_clock::time_point inviteReceivedTime{};
};
// Battleground
bool hasPendingBgInvite() const;
void acceptBattlefield(uint32_t queueSlot = 0xFFFFFFFF);
void declineBattlefield(uint32_t queueSlot = 0xFFFFFFFF);
const std::array<BgQueueSlot, 3>& getBgQueues() const { return bgQueues_; }
// Logout commands
void requestLogout();
@ -1970,12 +1982,6 @@ private:
std::unordered_set<uint32_t> petAutocastSpells_; // spells with autocast on
// ---- Battleground queue state ----
struct BgQueueSlot {
uint32_t queueSlot = 0;
uint32_t bgTypeId = 0;
uint8_t arenaType = 0;
uint32_t statusId = 0; // 0=none, 1=wait_queue, 2=wait_join, 3=in_progress
};
std::array<BgQueueSlot, 3> bgQueues_{};
// Instance difficulty

View file

@ -248,6 +248,7 @@ private:
void renderGuildRoster(game::GameHandler& gameHandler);
void renderGuildInvitePopup(game::GameHandler& gameHandler);
void renderReadyCheckPopup(game::GameHandler& gameHandler);
void renderBgInvitePopup(game::GameHandler& gameHandler);
void renderChatBubbles(game::GameHandler& gameHandler);
void renderMailWindow(game::GameHandler& gameHandler);
void renderMailComposeWindow(game::GameHandler& gameHandler);