68 m_UpdateTimer(0), m_ArenaTesting(0), m_Testing(false)
80 battleground->RemoveFromBGFreeSlotQueueOnShutdown();
101 BattlegroundContainer::iterator itrDelete =
bgs.begin();
102 for (BattlegroundContainer::iterator itr = itrDelete; itr !=
bgs.end();)
111 if (!clients.empty())
117 bgs.erase(itrDelete);
127 pair.second.UpdateEvents(diff);
132 std::vector<ScheduledQueueUpdate> scheduled;
135 for (
auto& [arenaMMRating, bgQueueTypeId, bracket_id] : scheduled)
146 TC_LOG_TRACE(
"bg.arena",
"BattlegroundMgr: UPDATING ARENA QUEUES");
179 battlefieldStatus->
Ticket.
Id = ticketId;
188 battlefieldStatus->
Timeout = timeout;
189 battlefieldStatus->
Role = 0;
206 battlefieldStatus->
AsGroup = asGroup;
215 battlefieldStatus->
Ticket.
Id = ticketId;
219 battlefieldStatus->
Reason = result;
221 battlefieldStatus->
ClientID = *errorGuid;
229 BattlegroundDataContainer::const_iterator begin, end;
244 for (BattlegroundDataContainer::const_iterator it = begin; it != end; ++it)
247 BattlegroundContainer::const_iterator itr =
bgs.find(instanceId);
248 if (itr !=
bgs.end())
249 return itr->second.get();
263 TC_LOG_INFO(
"server.loading",
">> Loaded 0 battleground scripts. DB table `battleground_scripts` is empty!");
270 Field* fields = result->Fetch();
277 TC_LOG_ERROR(
"sql.sql",
"BattlegroundMgr::LoadBattlegroundScriptTemplate: bad mapid {}! Map doesn't exist or is not a battleground/arena!", mapID);
284 TC_LOG_ERROR(
"sql.sql",
"BattlegroundMgr::LoadBattlegroundScriptTemplate: bad battlemasterlist id {}! Battleground doesn't exist or is not supported in battleground_template!", bgTypeId);
289 scriptTemplate.
MapId = mapID;
290 scriptTemplate.
Id = bgTypeId;
294 }
while (result->NextRow());
302 return scriptTemplate;
312 packet.
Roles = roles;
331 for (BattlegroundClientIdsContainer::const_iterator itr = clientIds.begin(); itr != clientIds.end();)
333 if ((++lastId) != *itr)
338 clientIds.insert(++lastId);
352 TC_LOG_ERROR(
"bg.battleground",
"Battleground: CreateNewBattleground - bg template not found for {}", bgTypeId);
359 TC_LOG_ERROR(
"bg.battleground",
"Battleground: CreateNewBattleground: bg bracket entry not found for map {} bracket id {}", bg_template->
MapIDs.front(), bracketId);
365 bg =
new Arena(bg_template);
387 QueryResult result =
WorldDatabase.Query(
"SELECT ID, AllianceStartLoc, HordeStartLoc, StartMaxDist, Weight, ScriptName FROM battleground_template");
390 TC_LOG_INFO(
"server.loading",
">> Loaded 0 battlegrounds. DB table `battleground_template` is empty.");
394 std::unordered_map<BattlegroundTypeId, std::vector<int32>> mapsByBattleground;
397 mapsByBattleground[
BattlegroundTypeId(battlemasterListXMap->BattlemasterListID)].push_back(battlemasterListXMap->MapID);
403 Field* fields = result->Fetch();
414 TC_LOG_ERROR(
"bg.battleground",
"Battleground ID {} could not be found in BattlemasterList.dbc. The battleground was not created.", bgTypeId);
419 bgTemplate.
Id = bgTypeId;
425 bgTemplate.
MapIDs = std::move(mapsByBattleground[bgTypeId]);
433 TC_LOG_ERROR(
"sql.sql",
"Table `battleground_template` for id {} contains a non-existing WorldSafeLocs.dbc id {} in field `AllianceStartLoc`. Ignoring.", bgTemplate.
Id, startId);
436 TC_LOG_ERROR(
"sql.sql",
"Table `battleground_template` for id {} contains a non-existing WorldSafeLocs.dbc id {} in field `AllianceStartLoc`. BG not created.", bgTemplate.
Id, startId);
445 TC_LOG_ERROR(
"sql.sql",
"Table `battleground_template` for id {} contains a non-existing WorldSafeLocs.dbc id {} in field `HordeStartLoc`. Ignoring.", bgTemplate.
Id, startId);
448 TC_LOG_ERROR(
"sql.sql",
"Table `battleground_template` for id {} contains a non-existing WorldSafeLocs.dbc id {} in field `HordeStartLoc`. BG not created.", bgTemplate.
Id, startId);
454 if (bgTemplate.
MapIDs.size() == 1)
459 while (result->NextRow());
486 TC_LOG_ERROR(
"bg.battleground",
"BattlegroundMgr::SendToBattleground: Battleground not found while trying to teleport player {}", player->
GetName());
494 TC_LOG_DEBUG(
"bg.battleground",
"BattlegroundMgr::SendToBattleground: Sending {} to map {}, {} (bgType {})", player->
GetName(), mapid, pos->
Loc, battleground->
GetTypeID());
526 if (battlemasterListId != 0)
546 if (!battlemasterList)
560 if (!bgQueueTypeId.
Rated)
566 if (bgQueueTypeId.
Rated)
572 if (!bgQueueTypeId.
Rated)
622 TC_LOG_INFO(
"server.loading",
">> Loaded 0 battlemaster entries. DB table `battlemaster_entry` is empty!");
632 Field* fields = result->Fetch();
638 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) listed in `battlemaster_entry` is not a battlemaster.", entry);
642 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) listed in `battlemaster_entry` does not exist.", entry);
649 TC_LOG_ERROR(
"sql.sql",
"Table `battlemaster_entry` contains entry {} for a non-existing battleground type {}, ignored.", entry, bgTypeId);
655 while (result->NextRow());
665 for (
auto const& creatureTemplatePair : ctc)
669 TC_LOG_ERROR(
"sql.sql",
"Creature_Template Entry: {} has UNIT_NPC_FLAG_BATTLEMASTER, but no data in the `battlemaster_entry` table. Removing flag.", creatureTemplatePair.first);
719 std::vector<BattlegroundTemplate const*> ids;
720 ids.reserve(bgTemplate->MapIDs.size());
721 for (
int32 mapId : bgTemplate->MapIDs)
747 if (itr != freeSlotQueue->end())
748 freeSlotQueue->erase(itr);
@ BATTLEGROUND_OBJECTIVE_UPDATE_INTERVAL
std::set< uint32 > BattlegroundClientIdsContainer
std::map< uint32, Trinity::unique_trackable_ptr< Battleground > > BattlegroundContainer
std::list< Battleground * > BGFreeSlotQueueContainer
DB2Storage< BattlemasterListEntry > sBattlemasterListStore("BattlemasterList.db2", &BattlemasterListLoadInfo::Instance)
DB2Storage< MapEntry > sMapStore("Map.db2", &MapLoadInfo::Instance)
DB2Storage< BattlemasterListXMapEntry > sBattlemasterListXMapStore("BattlemasterListXMap.db2", &BattlemasterListXMapLoadInfo::Instance)
@ MAX_BATTLEGROUND_BRACKETS
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
@ DISABLE_TYPE_BATTLEGROUND
bool IsHolidayActive(HolidayIds id)
#define TC_LOG_DEBUG(filterType__, message__,...)
#define TC_LOG_ERROR(filterType__, message__,...)
#define TC_LOG_INFO(filterType__, message__,...)
#define TC_LOG_TRACE(filterType__, message__,...)
std::unordered_map< uint32, CreatureTemplate > CreatureTemplateContainer
@ CMSG_BATTLEMASTER_JOIN_ARENA
GroupJoinBattlegroundResult
@ ERR_BATTLEGROUND_JOIN_TIMED_OUT
@ ERR_BATTLEGROUND_NOT_IN_BATTLEGROUND
#define CURRENT_EXPANSION
constexpr uint32 GetMaxLevelForExpansion(uint32 expansion)
@ BATTLEGROUND_RANDOM_EPIC
@ HOLIDAY_CALL_TO_ARMS_AB
@ HOLIDAY_CALL_TO_ARMS_ES
@ HOLIDAY_CALL_TO_ARMS_SA
@ HOLIDAY_CALL_TO_ARMS_IC
@ HOLIDAY_CALL_TO_ARMS_BG
@ HOLIDAY_CALL_TO_ARMS_AV
@ HOLIDAY_CALL_TO_ARMS_WG
@ HOLIDAY_CALL_TO_ARMS_TP
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
@ UNIT_NPC_FLAG_BATTLEMASTER
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
ObjectGuid const & GetGUID() const
BattlegroundMapTemplateContainer _battlegroundMapTemplates
static void BuildBattlegroundStatusHeader(WorldPackets::Battleground::BattlefieldStatusHeader *header, Player const *player, uint32 ticketId, uint32 joinTime, BattlegroundQueueTypeId queueId)
static void BuildBattlegroundStatusNeedConfirmation(WorldPackets::Battleground::BattlefieldStatusNeedConfirmation *battlefieldStatus, Battleground const *bg, Player const *player, uint32 ticketId, uint32 joinTime, uint32 timeout, BattlegroundQueueTypeId queueId)
void LoadBattleMastersEntry()
std::map< BattlegroundQueueTypeId, BattlegroundQueue > m_BattlegroundQueues
BattlegroundTemplate const * GetBattlegroundTemplateByMapId(uint32 mapId)
static void BuildBattlegroundStatusActive(WorldPackets::Battleground::BattlefieldStatusActive *battlefieldStatus, Battleground const *bg, Player const *player, uint32 ticketId, uint32 joinTime, BattlegroundQueueTypeId queueId)
std::vector< ScheduledQueueUpdate > m_QueueUpdateScheduler
void DeleteAllBattlegrounds()
Battleground * GetBattleground(uint32 InstanceID, BattlegroundTypeId bgTypeId)
BattlegroundTemplateMap _battlegroundTemplates
static BattlegroundQueueTypeId BGQueueTypeId(uint16 battlemasterListId, BattlegroundQueueIdType type, bool rated, uint8 teamSize)
void LoadBattlegroundScriptTemplate()
uint32 GetMaxRatingDifference() const
static void QueuePlayerForArena(Player const *player, uint8 teamSize, uint8 roles)
static void SendToBattleground(Player *player, Battleground const *battleground)
static BattlegroundMgr * instance()
BGFreeSlotQueueContainer & GetBGFreeSlotQueueStore(uint32 mapId)
static bool IsValidQueueId(BattlegroundQueueTypeId bgQueueTypeId)
BattlegroundTypeId GetRandomBG(BattlegroundTypeId id)
static bool IsArenaType(BattlegroundTypeId bgTypeId)
static void BuildBattlegroundStatusNone(WorldPackets::Battleground::BattlefieldStatusNone *battlefieldStatus, Player const *player, uint32 ticketId, uint32 joinTime)
bool isArenaTesting() const
BattlegroundQueue & GetBattlegroundQueue(BattlegroundQueueTypeId bgQueueTypeId)
void AddBattleground(Battleground *bg)
void AddToBGFreeSlotQueue(Battleground *bg)
BattleMastersMap mBattleMastersMap
std::map< uint32, BGFreeSlotQueueContainer > m_BGFreeSlotQueue
static bool IsRandomBattleground(uint32 battlemasterListId)
void ScheduleQueueUpdate(uint32 arenaMatchmakerRating, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundBracketId bracket_id)
void SendBattlegroundList(Player *player, ObjectGuid const &guid, BattlegroundTypeId bgTypeId)
BattlegroundTemplate const * GetBattlegroundTemplateByTypeId(BattlegroundTypeId id)
Battleground * CreateNewBattleground(BattlegroundQueueTypeId queueId, BattlegroundBracketId bracketId)
void RemoveFromBGFreeSlotQueue(uint32 mapId, uint32 instanceId)
uint32 GetRatingDiscardTimer() const
bool ToggleArenaTesting(uint32 battlemasterListId)
static BattlegroundTypeId WeekendHolidayIdToBGType(HolidayIds holiday)
static HolidayIds BGTypeToWeekendHolidayId(BattlegroundTypeId bgTypeId)
static void BuildBattlegroundStatusQueued(WorldPackets::Battleground::BattlefieldStatusQueued *battlefieldStatus, Player const *player, uint32 ticketId, uint32 joinTime, BattlegroundQueueTypeId queueId, uint32 avgWaitTime, bool asGroup)
uint32 GetPrematureFinishTime() const
uint32 CreateClientVisibleInstanceId(BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id)
uint32 m_NextRatedArenaUpdate
BattlegroundScriptTemplate const * FindBattlegroundScriptTemplate(uint32 mapId, BattlegroundTypeId bgTypeId) const
std::map< std::pair< int32, uint32 >, BattlegroundScriptTemplate > _battlegroundScriptTemplates
static bool IsBGWeekend(BattlegroundTypeId bgTypeId)
static void BuildBattlegroundStatusFailed(WorldPackets::Battleground::BattlefieldStatusFailed *battlefieldStatus, BattlegroundQueueTypeId queueId, Player const *player, uint32 ticketId, GroupJoinBattlegroundResult result, ObjectGuid const *errorGuid=nullptr)
BattlegroundDataContainer bgDataStore
void CheckBattleMasters()
void LoadBattlegroundTemplates()
void BattlegroundQueueUpdate(uint32 diff, BattlegroundBracketId bracket_id, uint32 minRating=0)
void SetInstanceID(uint32 InstanceID)
WorldSafeLocsEntry const * GetTeamStartPosition(TeamId teamId) const
void SetRated(bool state)
uint32 GetRemainingTime() const
BattlegroundTypeId GetTypeID() const
uint32 GetInstanceID() const
uint32 GetClientInstanceID() const
void SetClientInstanceID(uint32 InstanceID)
static TeamId GetTeamIndexByTeamId(Team team)
void SetStatus(BattlegroundStatus Status)
void SetArenaType(uint8 type)
BattlegroundBracketId GetBracketId() const
uint32 GetElapsedTime() const
void SetBracket(PVPDifficultyEntry const *bracketEntry)
void SetWeakPtr(Trinity::unique_weak_ptr< Battleground > weakRef)
static PVPDifficultyEntry const * GetBattlegroundBracketById(uint32 mapid, BattlegroundBracketId id)
Class used to access individual fields of database query result.
float GetFloat() const noexcept
uint32 GetUInt32() const noexcept
uint8 GetUInt8() const noexcept
static ObjectGuid const Empty
void SendDirectMessage(WorldPacket const *data) const
uint32 GetBattlegroundQueueJoinTime(BattlegroundQueueTypeId bgQueueTypeId) const
WorldSession * GetSession() const
bool GetRandomWinner() const
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, TeleportToOptions options=TELE_TO_NONE, Optional< uint32 > instanceId={}, uint32 teleportSpellId=0)
std::unique_ptr< PlayerMenu > PlayerTalkClass
Specialized variant of std::shared_ptr that enforces unique ownership and/or std::unique_ptr with std...
std::string const & GetName() const
WorldPacket const * Write() override
ObjectGuid BattlemasterGuid
BattlefieldStatusHeader Hdr
WorldPackets::LFG::RideTicket Ticket
BattlefieldStatusHeader Hdr
WorldPackets::LFG::RideTicket Ticket
bool EligibleForMatchmaking
BattlefieldStatusHeader Hdr
void HandleBattlemasterJoinArena(WorldPackets::Battleground::BattlemasterJoinArena &packet)
@ CONFIG_ARENA_MAX_RATING_DIFFERENCE
@ CONFIG_ARENA_RATED_UPDATE_TIMER
@ CONFIG_ARENA_RATING_DISCARD_TIMER
@ CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER
bool IsDisabledFor(DisableType type, uint32 entry, WorldObject const *ref, uint8 flags)
auto SelectRandomWeightedContainerElement(C const &container, std::span< double > const &weights) -> decltype(std::ranges::begin(container))
auto MapGetValuePtr(M &map, typename M::key_type const &key)
constexpr uint64 GetPacked() const
uint16 BattlemasterListId
uint8 GetMinLevel() const
BattlemasterListEntry const * BattlemasterEntry
uint16 GetMaxPlayersPerTeam() const
std::vector< int32 > MapIDs
WorldSafeLocsEntry const * StartLocation[PVP_TEAMS_COUNT]
uint16 GetMinPlayersPerTeam() const
uint8 GetMaxLevel() const
BattlemasterType GetType() const
bool IsBattlegroundOrArena() const
BattlegroundBracketId GetBracketId() const
Optional< ObjectGuid::LowType > TransportSpawnId