68 m_UpdateTimer(0), m_ArenaTesting(0), m_Testing(false)
97 BattlegroundContainer::iterator itrDelete =
bgs.begin();
98 for (BattlegroundContainer::iterator itr = itrDelete; itr !=
bgs.end();)
107 if (!clients.empty())
113 bgs.erase(itrDelete);
123 pair.second.UpdateEvents(diff);
128 std::vector<ScheduledQueueUpdate> scheduled;
131 for (
auto& [arenaMMRating, bgQueueTypeId, bracket_id] : scheduled)
142 TC_LOG_TRACE(
"bg.arena",
"BattlegroundMgr: UPDATING ARENA QUEUES");
175 battlefieldStatus->
Ticket.
Id = ticketId;
184 battlefieldStatus->
Timeout = timeout;
185 battlefieldStatus->
Role = 0;
202 battlefieldStatus->
AsGroup = asGroup;
211 battlefieldStatus->
Ticket.
Id = ticketId;
215 battlefieldStatus->
Reason = result;
217 battlefieldStatus->
ClientID = *errorGuid;
225 BattlegroundDataContainer::const_iterator begin, end;
240 for (BattlegroundDataContainer::const_iterator it = begin; it != end; ++it)
243 BattlegroundContainer::const_iterator itr =
bgs.find(instanceId);
244 if (itr !=
bgs.end())
245 return itr->second.get();
259 TC_LOG_INFO(
"server.loading",
">> Loaded 0 battleground scripts. DB table `battleground_scripts` is empty!");
266 Field* fields = result->Fetch();
273 TC_LOG_ERROR(
"sql.sql",
"BattlegroundMgr::LoadBattlegroundScriptTemplate: bad mapid {}! Map doesn't exist or is not a battleground/arena!", mapID);
280 TC_LOG_ERROR(
"sql.sql",
"BattlegroundMgr::LoadBattlegroundScriptTemplate: bad battlemasterlist id {}! Battleground doesn't exist or is not supported in battleground_template!", bgTypeId);
285 scriptTemplate.
MapId = mapID;
286 scriptTemplate.
Id = bgTypeId;
290 }
while (result->NextRow());
298 return scriptTemplate;
308 packet.
Roles = roles;
327 for (BattlegroundClientIdsContainer::const_iterator itr = clientIds.begin(); itr != clientIds.end();)
329 if ((++lastId) != *itr)
334 clientIds.insert(++lastId);
348 TC_LOG_ERROR(
"bg.battleground",
"Battleground: CreateNewBattleground - bg template not found for {}", bgTypeId);
355 TC_LOG_ERROR(
"bg.battleground",
"Battleground: CreateNewBattleground: bg bracket entry not found for map {} bracket id {}", bg_template->
MapIDs.front(), bracketId);
361 bg =
new Arena(bg_template);
383 QueryResult result =
WorldDatabase.Query(
"SELECT ID, AllianceStartLoc, HordeStartLoc, StartMaxDist, Weight, ScriptName FROM battleground_template");
386 TC_LOG_INFO(
"server.loading",
">> Loaded 0 battlegrounds. DB table `battleground_template` is empty.");
390 std::unordered_map<BattlegroundTypeId, std::vector<int32>> mapsByBattleground;
393 mapsByBattleground[
BattlegroundTypeId(battlemasterListXMap->BattlemasterListID)].push_back(battlemasterListXMap->MapID);
399 Field* fields = result->Fetch();
410 TC_LOG_ERROR(
"bg.battleground",
"Battleground ID {} could not be found in BattlemasterList.dbc. The battleground was not created.", bgTypeId);
415 bgTemplate.
Id = bgTypeId;
421 bgTemplate.
MapIDs = std::move(mapsByBattleground[bgTypeId]);
429 TC_LOG_ERROR(
"sql.sql",
"Table `battleground_template` for id {} contains a non-existing WorldSafeLocs.dbc id {} in field `AllianceStartLoc`. Ignoring.", bgTemplate.
Id, startId);
432 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);
441 TC_LOG_ERROR(
"sql.sql",
"Table `battleground_template` for id {} contains a non-existing WorldSafeLocs.dbc id {} in field `HordeStartLoc`. Ignoring.", bgTemplate.
Id, startId);
444 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);
450 if (bgTemplate.
MapIDs.size() == 1)
455 while (result->NextRow());
482 TC_LOG_ERROR(
"bg.battleground",
"BattlegroundMgr::SendToBattleground: Battleground not found while trying to teleport player {}", player->
GetName());
490 TC_LOG_DEBUG(
"bg.battleground",
"BattlegroundMgr::SendToBattleground: Sending {} to map {}, {} (bgType {})", player->
GetName(), mapid, pos->
Loc, battleground->
GetTypeID());
522 if (battlemasterListId != 0)
542 if (!battlemasterList)
556 if (!bgQueueTypeId.
Rated)
562 if (bgQueueTypeId.
Rated)
568 if (!bgQueueTypeId.
Rated)
618 TC_LOG_INFO(
"server.loading",
">> Loaded 0 battlemaster entries. DB table `battlemaster_entry` is empty!");
628 Field* fields = result->Fetch();
634 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) listed in `battlemaster_entry` is not a battlemaster.", entry);
638 TC_LOG_ERROR(
"sql.sql",
"Creature (Entry: {}) listed in `battlemaster_entry` does not exist.", entry);
645 TC_LOG_ERROR(
"sql.sql",
"Table `battlemaster_entry` contains entry {} for a non-existing battleground type {}, ignored.", entry, bgTypeId);
651 while (result->NextRow());
661 for (
auto const& creatureTemplatePair : ctc)
665 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);
715 std::vector<BattlegroundTemplate const*> ids;
716 ids.reserve(bgTemplate->MapIDs.size());
717 for (
int32 mapId : bgTemplate->MapIDs)
741 for (BGFreeSlotQueueContainer::iterator itr = queues.begin(); itr != queues.end(); ++itr)
742 if ((*itr)->GetInstanceID() == instanceId)
@ 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