feat: handle SMSG_BATTLEFIELD_MGR_* and SMSG_CALENDAR_* opcodes

Implements WotLK Outdoor Battlefield Manager (Wintergrasp/Tol Barad):
- Parse SMSG_BATTLEFIELD_MGR_ENTRY_INVITE, ENTERED, QUEUE_INVITE,
  QUEUE_REQUEST_RESPONSE, EJECT_PENDING, EJECTED, STATE_CHANGE
- Store bfMgrInvitePending_/bfMgrActive_/bfMgrZoneId_ state
- Send CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE via acceptBfMgrInvite() /
  declineBfMgrInvite() accessors
- Add renderBfMgrInvitePopup() UI dialog with Enter/Decline buttons;
  recognises Wintergrasp (zone 4197) and Tol Barad (zone 5095) by name

Implements WotLK Calendar notifications:
- SMSG_CALENDAR_SEND_NUM_PENDING: track pending invite count
- SMSG_CALENDAR_COMMAND_RESULT: map 15 error codes to friendly messages
- SMSG_CALENDAR_EVENT_INVITE_ALERT: notify player of new event invite with title
- SMSG_CALENDAR_EVENT_STATUS: show per-event RSVP status changes (9 statuses)
- SMSG_CALENDAR_RAID_LOCKOUT_ADDED/REMOVED: log raid lockout calendar entries
- Remaining SMSG_CALENDAR_* packets safely consumed
- requestCalendar() sends CMSG_CALENDAR_GET_CALENDAR + GET_NUM_PENDING
This commit is contained in:
Kelsi 2026-03-12 22:25:46 -07:00
parent dd38026b23
commit c5a6979d69
4 changed files with 415 additions and 0 deletions

View file

@ -501,6 +501,17 @@ public:
const std::string& getGmTicketText() const { return gmTicketText_; }
bool isGmSupportAvailable() const { return gmSupportAvailable_; }
float getGmTicketWaitHours() const { return gmTicketWaitHours_; }
// Battlefield Manager (Wintergrasp)
bool hasBfMgrInvite() const { return bfMgrInvitePending_; }
bool isInBfMgrZone() const { return bfMgrActive_; }
uint32_t getBfMgrZoneId() const { return bfMgrZoneId_; }
void acceptBfMgrInvite();
void declineBfMgrInvite();
// WotLK Calendar
uint32_t getCalendarPendingInvites() const { return calendarPendingInvites_; }
void requestCalendar(); ///< Send CMSG_CALENDAR_GET_CALENDAR to the server
void queryGuildInfo(uint32_t guildId);
void createGuild(const std::string& guildName);
void addGuildRank(const std::string& rankName);
@ -3034,6 +3045,14 @@ private:
std::string gmTicketText_; ///< Text of the open ticket (from SMSG_GMTICKET_GETTICKET)
float gmTicketWaitHours_ = 0.0f; ///< Server-estimated wait time in hours
bool gmSupportAvailable_ = true; ///< GM support system online (SMSG_GMTICKET_SYSTEMSTATUS)
// ---- Battlefield Manager state (WotLK Wintergrasp / outdoor battlefields) ----
bool bfMgrInvitePending_ = false; ///< True when an entry/queue invite is pending acceptance
bool bfMgrActive_ = false; ///< True while the player is inside an outdoor battlefield
uint32_t bfMgrZoneId_ = 0; ///< Zone ID of the pending/active battlefield
// ---- WotLK Calendar: pending invite counter ----
uint32_t calendarPendingInvites_ = 0; ///< Unacknowledged calendar invites (SMSG_CALENDAR_SEND_NUM_PENDING)
};
} // namespace game

View file

@ -361,6 +361,7 @@ private:
void renderGuildInvitePopup(game::GameHandler& gameHandler);
void renderReadyCheckPopup(game::GameHandler& gameHandler);
void renderBgInvitePopup(game::GameHandler& gameHandler);
void renderBfMgrInvitePopup(game::GameHandler& gameHandler);
void renderLfgProposalPopup(game::GameHandler& gameHandler);
void renderChatBubbles(game::GameHandler& gameHandler);
void renderMailWindow(game::GameHandler& gameHandler);