mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-02-03 11:03:47 +00:00
feat(Core/Battleground): rework bg queue system (#10817)
This commit is contained in:
@@ -137,7 +137,7 @@ bool ArenaSpectator::HandleSpectatorSpectateCommand(ChatHandler* handler, std::s
|
||||
|
||||
if (uint32 inviteInstanceId = player->GetPendingSpectatorInviteInstanceId())
|
||||
{
|
||||
if (Battleground* tbg = sBattlegroundMgr->GetBattleground(inviteInstanceId))
|
||||
if (Battleground* tbg = sBattlegroundMgr->GetBattleground(inviteInstanceId, BATTLEGROUND_TYPE_NONE))
|
||||
tbg->RemoveToBeTeleported(player->GetGUID());
|
||||
player->SetPendingSpectatorInviteInstanceId(0);
|
||||
}
|
||||
|
||||
@@ -312,6 +312,10 @@ void Arena::EndBattleground(TeamId winnerTeamId)
|
||||
}
|
||||
}
|
||||
|
||||
// update previous opponents for arena queue
|
||||
winnerArenaTeam->SetPreviousOpponents(loserArenaTeam->GetId());
|
||||
loserArenaTeam->SetPreviousOpponents(winnerArenaTeam->GetId());
|
||||
|
||||
// save the stat changes
|
||||
if (bValidArena)
|
||||
{
|
||||
|
||||
@@ -61,7 +61,7 @@ protected:
|
||||
{
|
||||
RatingChange = ratingChange;
|
||||
MatchmakerRating = matchMakerRating;
|
||||
TeamName = teamName;
|
||||
TeamName = std::string(teamName);
|
||||
}
|
||||
|
||||
void BuildRatingInfoBlock(WorldPacket& data);
|
||||
|
||||
@@ -345,7 +345,7 @@ void ArenaTeam::DelMember(ObjectGuid guid, bool cleanDb)
|
||||
WorldPacket data;
|
||||
playerMember->RemoveBattlegroundQueueId(bgQueue);
|
||||
sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, nullptr, playerMember->GetBattlegroundQueueIndex(bgQueue), STATUS_NONE, 0, 0, 0, TEAM_NEUTRAL);
|
||||
queue.RemovePlayer(playerMember->GetGUID(), true, 0);
|
||||
queue.RemovePlayer(playerMember->GetGUID(), true);
|
||||
playerMember->GetSession()->SendPacket(&data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,6 +209,9 @@ public:
|
||||
void FinishWeek();
|
||||
void FinishGame(int32 mod, const Map* bgMap);
|
||||
|
||||
void SetPreviousOpponents(uint32 arenaTeamId) { PreviousOpponents = arenaTeamId; }
|
||||
uint32 GetPreviousOpponents() { return PreviousOpponents; }
|
||||
|
||||
void CreateTempArenaTeam(std::vector<Player*> playerList, uint8 type, std::string const& teamName);
|
||||
|
||||
// Containers
|
||||
@@ -229,5 +232,7 @@ protected:
|
||||
|
||||
MemberList Members;
|
||||
ArenaTeamStats Stats;
|
||||
|
||||
uint32 PreviousOpponents = 0;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -232,6 +232,9 @@ Battleground::~Battleground()
|
||||
m_Map = nullptr;
|
||||
}
|
||||
|
||||
// remove from bg free slot queue
|
||||
RemoveFromBGFreeSlotQueue();
|
||||
|
||||
for (auto const& itr : PlayerScores)
|
||||
delete itr.second;
|
||||
}
|
||||
@@ -251,8 +254,21 @@ void Battleground::Update(uint32 diff)
|
||||
|
||||
if (!GetPlayersSize())
|
||||
{
|
||||
//BG is empty
|
||||
// if there are no players invited, delete BG
|
||||
// this will delete arena or bg object, where any player entered
|
||||
// [[ but if you use battleground object again (more battles possible to be played on 1 instance)
|
||||
// then this condition should be removed and code:
|
||||
// if (!GetInvitedCount(TEAM_HORDE) && !GetInvitedCount(TEAM_ALLIANCE))
|
||||
// AddToFreeBGObjectsQueue(); // not yet implemented
|
||||
// should be used instead of current
|
||||
// ]]
|
||||
// Battleground Template instance cannot be updated, because it would be deleted
|
||||
if (!GetInvitedCount(TEAM_HORDE) && !GetInvitedCount(TEAM_ALLIANCE))
|
||||
{
|
||||
m_SetDeleteThis = true;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -768,6 +784,7 @@ void Battleground::EndBattleground(PvPTeamId winnerTeamId)
|
||||
if (GetStatus() == STATUS_WAIT_LEAVE)
|
||||
return;
|
||||
|
||||
RemoveFromBGFreeSlotQueue();
|
||||
SetStatus(STATUS_WAIT_LEAVE);
|
||||
SetWinner(winnerTeamId);
|
||||
|
||||
@@ -956,13 +973,17 @@ void Battleground::RemovePlayerAtLeave(Player* player)
|
||||
// if the player was a match participant
|
||||
if (participant)
|
||||
{
|
||||
WorldPacket data;
|
||||
|
||||
player->ClearAfkReports();
|
||||
|
||||
WorldPacket data;
|
||||
sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetCurrentBattlegroundQueueSlot(), STATUS_NONE, 0, 0, 0, TEAM_NEUTRAL);
|
||||
player->GetSession()->SendPacket(&data);
|
||||
|
||||
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetBgTypeID(), GetArenaType());
|
||||
|
||||
// this call is important, because player, when joins to battleground, this method is not called, so it must be called when leaving bg
|
||||
player->RemoveBattlegroundQueueId(bgQueueTypeId);
|
||||
|
||||
// remove from raid group if player is member
|
||||
if (Group* group = GetBgRaid(teamId))
|
||||
if (group->IsMember(player->GetGUID()))
|
||||
@@ -977,6 +998,19 @@ void Battleground::RemovePlayerAtLeave(Player* player)
|
||||
if (isBattleground() && !player->IsGameMaster() && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_CAST_DESERTER))
|
||||
if (status == STATUS_IN_PROGRESS || status == STATUS_WAIT_JOIN)
|
||||
player->ScheduleDelayedOperation(DELAYED_SPELL_CAST_DESERTER);
|
||||
|
||||
DecreaseInvitedCount(teamId);
|
||||
|
||||
//we should update battleground queue, but only if bg isn't ending
|
||||
if (isBattleground() && GetStatus() < STATUS_WAIT_LEAVE)
|
||||
{
|
||||
BattlegroundTypeId bgTypeId = GetBgTypeID();
|
||||
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetBgTypeID(), GetArenaType());
|
||||
|
||||
// a player has left the battleground, so there are free slots -> add to queue
|
||||
AddToBGFreeSlotQueue();
|
||||
sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, GetBracketId());
|
||||
}
|
||||
}
|
||||
|
||||
// Remove shapeshift auras
|
||||
@@ -1009,6 +1043,7 @@ void Battleground::Init()
|
||||
|
||||
m_BgInvitedPlayers[TEAM_ALLIANCE] = 0;
|
||||
m_BgInvitedPlayers[TEAM_HORDE] = 0;
|
||||
_InBGFreeSlotQueue = false;
|
||||
|
||||
m_Players.clear();
|
||||
|
||||
@@ -1028,9 +1063,15 @@ void Battleground::StartBattleground()
|
||||
SetStartTime(0);
|
||||
SetLastResurrectTime(0);
|
||||
|
||||
// add BG to free slot queue
|
||||
AddToBGFreeSlotQueue();
|
||||
|
||||
// add bg to update list
|
||||
// this must be done here, because we need to have already invited some players when first Battleground::Update() method is executed
|
||||
sBattlegroundMgr->AddBattleground(this);
|
||||
|
||||
if (m_IsRated)
|
||||
LOG_DEBUG("bg.arena", "Arena match type: {} for Team1Id: {} - Team2Id: {} started.", m_ArenaType, m_ArenaTeamIds[TEAM_ALLIANCE], m_ArenaTeamIds[TEAM_HORDE]);
|
||||
}
|
||||
|
||||
void Battleground::AddPlayer(Player* player)
|
||||
@@ -1129,6 +1170,26 @@ void Battleground::AddOrSetPlayerToCorrectBgGroup(Player* player, TeamId teamId)
|
||||
}
|
||||
}
|
||||
|
||||
// This method should be called only once ... it adds pointer to queue
|
||||
void Battleground::AddToBGFreeSlotQueue()
|
||||
{
|
||||
if (!_InBGFreeSlotQueue && isBattleground())
|
||||
{
|
||||
sBattlegroundMgr->AddToBGFreeSlotQueue(m_RealTypeID, this);
|
||||
_InBGFreeSlotQueue = true;
|
||||
}
|
||||
}
|
||||
|
||||
// This method removes this battleground from free queue - it must be called when deleting battleground
|
||||
void Battleground::RemoveFromBGFreeSlotQueue()
|
||||
{
|
||||
if (_InBGFreeSlotQueue)
|
||||
{
|
||||
sBattlegroundMgr->RemoveFromBGFreeSlotQueue(m_RealTypeID, m_InstanceID);
|
||||
_InBGFreeSlotQueue = false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Battleground::GetFreeSlotsForTeam(TeamId teamId) const
|
||||
{
|
||||
if (!(GetStatus() == STATUS_IN_PROGRESS || GetStatus() == STATUS_WAIT_JOIN))
|
||||
@@ -1611,6 +1672,7 @@ void Battleground::SendMessage2ToAll(uint32 entry, ChatMsg type, Player const* s
|
||||
|
||||
void Battleground::EndNow()
|
||||
{
|
||||
RemoveFromBGFreeSlotQueue();
|
||||
SetStatus(STATUS_WAIT_LEAVE);
|
||||
SetEndTime(0);
|
||||
}
|
||||
@@ -1777,6 +1839,12 @@ GraveyardStruct const* Battleground::GetClosestGraveyard(Player* player)
|
||||
return sGraveyard->GetClosestGraveyard(player, player->GetBgTeamId());
|
||||
}
|
||||
|
||||
void Battleground::SetBracket(PvPDifficultyEntry const* bracketEntry)
|
||||
{
|
||||
m_BracketId = bracketEntry->GetBracketId();
|
||||
SetLevelRange(bracketEntry->minLevel, bracketEntry->maxLevel);
|
||||
}
|
||||
|
||||
void Battleground::StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry)
|
||||
{
|
||||
for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
|
||||
@@ -316,6 +316,7 @@ public:
|
||||
// Get methods:
|
||||
[[nodiscard]] std::string GetName() const { return m_Name; }
|
||||
[[nodiscard]] BattlegroundTypeId GetBgTypeID(bool GetRandom = false) const { return GetRandom ? m_RandomTypeID : m_RealTypeID; }
|
||||
[[nodiscard]] BattlegroundBracketId GetBracketId() const { return m_BracketId; }
|
||||
[[nodiscard]] uint32 GetInstanceID() const { return m_InstanceID; }
|
||||
[[nodiscard]] BattlegroundStatus GetStatus() const { return m_Status; }
|
||||
[[nodiscard]] uint32 GetClientInstanceID() const { return m_ClientInstanceID; }
|
||||
@@ -341,6 +342,7 @@ public:
|
||||
void SetName(std::string_view name) { m_Name = std::string(name); }
|
||||
void SetBgTypeID(BattlegroundTypeId TypeID) { m_RealTypeID = TypeID; }
|
||||
void SetRandomTypeID(BattlegroundTypeId TypeID) { m_RandomTypeID = TypeID; }
|
||||
void SetBracket(PvPDifficultyEntry const* bracketEntry);
|
||||
void SetInstanceID(uint32 InstanceID) { m_InstanceID = InstanceID; }
|
||||
void SetStatus(BattlegroundStatus Status) { m_Status = Status; }
|
||||
void SetClientInstanceID(uint32 InstanceID) { m_ClientInstanceID = InstanceID; }
|
||||
@@ -361,6 +363,9 @@ public:
|
||||
void SetMaxPlayersPerTeam(uint32 MaxPlayers) { m_MaxPlayersPerTeam = MaxPlayers; }
|
||||
void SetMinPlayersPerTeam(uint32 MinPlayers) { m_MinPlayersPerTeam = MinPlayers; }
|
||||
|
||||
void AddToBGFreeSlotQueue(); // this queue will be useful when more battlegrounds instances will be available
|
||||
void RemoveFromBGFreeSlotQueue(); // this method could delete whole BG instance, if another free is available
|
||||
|
||||
void DecreaseInvitedCount(TeamId teamId) { if (m_BgInvitedPlayers[teamId]) --m_BgInvitedPlayers[teamId]; }
|
||||
void IncreaseInvitedCount(TeamId teamId) { ++m_BgInvitedPlayers[teamId]; }
|
||||
[[nodiscard]] uint32 GetInvitedCount(TeamId teamId) const { return m_BgInvitedPlayers[teamId]; }
|
||||
@@ -642,7 +647,9 @@ private:
|
||||
uint32 m_ValidStartPositionTimer;
|
||||
int32 m_EndTime; // it is set to 120000 when bg is ending and it decreases itself
|
||||
uint32 m_LastResurrectTime;
|
||||
BattlegroundBracketId m_BracketId{ BG_BRACKET_ID_FIRST };
|
||||
uint8 m_ArenaType; // 2=2v2, 3=3v3, 5=5v5
|
||||
bool _InBGFreeSlotQueue{ false }; // used to make sure that BG is only once inserted into the BattlegroundMgr.BGFreeSlotQueue[bgTypeId] deque
|
||||
bool m_SetDeleteThis; // used for safe deletion of the bg after end / all players leave
|
||||
bool m_IsArena;
|
||||
PvPTeamId m_WinnerId;
|
||||
|
||||
@@ -48,15 +48,22 @@
|
||||
#include "WorldPacket.h"
|
||||
#include <unordered_map>
|
||||
|
||||
bool BattlegroundTemplate::IsArena() const
|
||||
{
|
||||
return BattlemasterEntry->type == MAP_ARENA;
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
/*** BATTLEGROUND MANAGER ***/
|
||||
/*********************************************************/
|
||||
|
||||
BattlegroundMgr::BattlegroundMgr() : m_ArenaTesting(false), m_Testing(false),
|
||||
m_lastClientVisibleInstanceId(0), m_NextAutoDistributionTime(0), m_AutoDistributionTimeChecker(0), m_NextPeriodicQueueUpdateTime(5 * IN_MILLISECONDS)
|
||||
BattlegroundMgr::BattlegroundMgr() :
|
||||
m_ArenaTesting(false),
|
||||
m_Testing(false),
|
||||
m_NextAutoDistributionTime(0),
|
||||
m_AutoDistributionTimeChecker(0),
|
||||
m_NextPeriodicQueueUpdateTime(5 * IN_MILLISECONDS)
|
||||
{
|
||||
for (uint32 qtype = BATTLEGROUND_QUEUE_NONE; qtype < MAX_BATTLEGROUND_QUEUE_TYPES; ++qtype)
|
||||
m_BattlegroundQueues[qtype].SetBgTypeIdAndArenaType(BGTemplateId(BattlegroundQueueTypeId(qtype)), BGArenaType(BattlegroundQueueTypeId(qtype)));
|
||||
}
|
||||
|
||||
BattlegroundMgr::~BattlegroundMgr()
|
||||
@@ -72,47 +79,68 @@ BattlegroundMgr* BattlegroundMgr::instance()
|
||||
|
||||
void BattlegroundMgr::DeleteAllBattlegrounds()
|
||||
{
|
||||
while (!m_Battlegrounds.empty())
|
||||
delete m_Battlegrounds.begin()->second;
|
||||
m_Battlegrounds.clear();
|
||||
for (auto& [_, data] : bgDataStore)
|
||||
{
|
||||
while (!data._Battlegrounds.empty())
|
||||
delete data._Battlegrounds.begin()->second;
|
||||
|
||||
while (!m_BattlegroundTemplates.empty())
|
||||
delete m_BattlegroundTemplates.begin()->second;
|
||||
m_BattlegroundTemplates.clear();
|
||||
data._Battlegrounds.clear();
|
||||
|
||||
while (!data.BGFreeSlotQueue.empty())
|
||||
delete data.BGFreeSlotQueue.front();
|
||||
}
|
||||
|
||||
bgDataStore.clear();
|
||||
}
|
||||
|
||||
// used to update running battlegrounds, and delete finished ones
|
||||
void BattlegroundMgr::Update(uint32 diff)
|
||||
{
|
||||
// update all battlegrounds and delete if needed
|
||||
for (BattlegroundContainer::iterator itr = m_Battlegrounds.begin(), itrDelete; itr != m_Battlegrounds.end(); )
|
||||
for (auto& [_, bgData] : bgDataStore)
|
||||
{
|
||||
itrDelete = itr++;
|
||||
Battleground* bg = itrDelete->second;
|
||||
bg->Update(diff);
|
||||
if (bg->ToBeDeleted())
|
||||
auto& bgList = bgData._Battlegrounds;
|
||||
auto itrDelete = bgList.begin();
|
||||
|
||||
// first one is template and should not be deleted
|
||||
for (BattlegroundContainer::iterator itr = ++itrDelete; itr != bgList.end();)
|
||||
{
|
||||
itrDelete->second = nullptr;
|
||||
m_Battlegrounds.erase(itrDelete);
|
||||
delete bg;
|
||||
itrDelete = itr++;
|
||||
Battleground* bg = itrDelete->second;
|
||||
|
||||
bg->Update(diff);
|
||||
if (bg->ToBeDeleted())
|
||||
{
|
||||
itrDelete->second = nullptr;
|
||||
bgList.erase(itrDelete);
|
||||
|
||||
BattlegroundClientIdsContainer& clients = bgData._ClientBattlegroundIds[bg->GetBracketId()];
|
||||
if (!clients.empty())
|
||||
clients.erase(bg->GetClientInstanceID());
|
||||
|
||||
delete bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update events
|
||||
for (int qtype = BATTLEGROUND_QUEUE_NONE; qtype < MAX_BATTLEGROUND_QUEUE_TYPES; ++qtype)
|
||||
for (uint8 qtype = BATTLEGROUND_QUEUE_NONE; qtype < MAX_BATTLEGROUND_QUEUE_TYPES; ++qtype)
|
||||
m_BattlegroundQueues[qtype].UpdateEvents(diff);
|
||||
|
||||
// update using scheduled tasks (used only for rated arenas, initial opponent search works differently than periodic queue update)
|
||||
if (!m_ArenaQueueUpdateScheduler.empty())
|
||||
if (!m_QueueUpdateScheduler.empty())
|
||||
{
|
||||
std::vector<uint64> scheduled;
|
||||
std::swap(scheduled, m_ArenaQueueUpdateScheduler);
|
||||
std::swap(scheduled, m_QueueUpdateScheduler);
|
||||
|
||||
for (uint8 i = 0; i < scheduled.size(); i++)
|
||||
{
|
||||
uint32 arenaRatedTeamId = scheduled[i] >> 32;
|
||||
uint32 arenaMMRating = scheduled[i] >> 32;
|
||||
uint8 arenaType = scheduled[i] >> 24 & 255;
|
||||
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundQueueTypeId(scheduled[i] >> 16 & 255);
|
||||
BattlegroundTypeId bgTypeId = BattlegroundTypeId((scheduled[i] >> 8) & 255);
|
||||
BattlegroundBracketId bracket_id = BattlegroundBracketId(scheduled[i] & 255);
|
||||
m_BattlegroundQueues[bgQueueTypeId].BattlegroundQueueUpdate(diff, bracket_id, true, arenaRatedTeamId); // pussywizard: looking for opponents only for this team
|
||||
m_BattlegroundQueues[bgQueueTypeId].BattlegroundQueueUpdate(diff, bgTypeId, bracket_id, arenaType, arenaMMRating > 0, arenaMMRating);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,16 +149,16 @@ void BattlegroundMgr::Update(uint32 diff)
|
||||
{
|
||||
m_NextPeriodicQueueUpdateTime = 5 * IN_MILLISECONDS;
|
||||
|
||||
LOG_TRACE("bg.arena", "BattlegroundMgr: UPDATING ARENA QUEUES");
|
||||
|
||||
// for rated arenas
|
||||
for (uint32 qtype = BATTLEGROUND_QUEUE_2v2; qtype < MAX_BATTLEGROUND_QUEUE_TYPES; ++qtype)
|
||||
{
|
||||
for (uint32 bracket = BG_BRACKET_ID_FIRST; bracket < MAX_BATTLEGROUND_BRACKETS; ++bracket)
|
||||
m_BattlegroundQueues[qtype].BattlegroundQueueUpdate(m_NextPeriodicQueueUpdateTime, BattlegroundBracketId(bracket), true, 0); // pussywizard: 0 for rated means looking for opponents for every team
|
||||
|
||||
// for battlegrounds and not rated arenas
|
||||
// in first loop try to fill already running battlegrounds, then in a second loop try to create new battlegrounds
|
||||
for (uint32 qtype = BATTLEGROUND_QUEUE_AV; qtype < MAX_BATTLEGROUND_QUEUE_TYPES; ++qtype)
|
||||
for (uint32 bracket = BG_BRACKET_ID_FIRST; bracket < MAX_BATTLEGROUND_BRACKETS; ++bracket)
|
||||
m_BattlegroundQueues[qtype].BattlegroundQueueUpdate(m_NextPeriodicQueueUpdateTime, BattlegroundBracketId(bracket), false, 0);
|
||||
{
|
||||
m_BattlegroundQueues[qtype].BattlegroundQueueUpdate(diff, BATTLEGROUND_AA, BattlegroundBracketId(bracket), BattlegroundMgr::BGArenaType(BattlegroundQueueTypeId(qtype)), true, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
m_NextPeriodicQueueUpdateTime -= diff;
|
||||
@@ -225,36 +253,108 @@ void BattlegroundMgr::BuildPlayerJoinedBattlegroundPacket(WorldPacket* data, Pla
|
||||
*data << player->GetGUID();
|
||||
}
|
||||
|
||||
Battleground* BattlegroundMgr::GetBattleground(uint32 instanceId)
|
||||
Battleground* BattlegroundMgr::GetBattlegroundThroughClientInstance(uint32 instanceId, BattlegroundTypeId bgTypeId)
|
||||
{
|
||||
//cause at HandleBattlegroundJoinOpcode the clients sends the instanceid he gets from
|
||||
//SMSG_BATTLEFIELD_LIST we need to find the battleground with this clientinstance-id
|
||||
Battleground* bg = GetBattlegroundTemplate(bgTypeId);
|
||||
if (!bg)
|
||||
return nullptr;
|
||||
|
||||
if (bg->isArena())
|
||||
return GetBattleground(instanceId, bgTypeId);
|
||||
|
||||
auto const& it = bgDataStore.find(bgTypeId);
|
||||
if (it == bgDataStore.end())
|
||||
return nullptr;
|
||||
|
||||
for (auto const& itr : it->second._Battlegrounds)
|
||||
{
|
||||
if (itr.second->GetClientInstanceID() == instanceId)
|
||||
return itr.second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Battleground* BattlegroundMgr::GetBattleground(uint32 instanceId, BattlegroundTypeId bgTypeId)
|
||||
{
|
||||
if (!instanceId)
|
||||
return nullptr;
|
||||
|
||||
BattlegroundContainer::const_iterator itr = m_Battlegrounds.find(instanceId);
|
||||
if (itr != m_Battlegrounds.end())
|
||||
return itr->second;
|
||||
auto GetBgWithInstanceID = [instanceId](BattlegroundData const* bgData) -> Battleground*
|
||||
{
|
||||
auto const& itr = bgData->_Battlegrounds.find(instanceId);
|
||||
if (itr != bgData->_Battlegrounds.end())
|
||||
return itr->second;
|
||||
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
if (bgTypeId == BATTLEGROUND_TYPE_NONE)
|
||||
{
|
||||
for (auto const& [bgType, bgData] : bgDataStore)
|
||||
{
|
||||
if (auto bg = GetBgWithInstanceID(&bgData))
|
||||
return bg;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const& itr = bgDataStore.find(bgTypeId);
|
||||
if (itr == bgDataStore.end())
|
||||
return nullptr;
|
||||
|
||||
if (auto bg = GetBgWithInstanceID(&itr->second))
|
||||
return bg;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Battleground* BattlegroundMgr::GetBattlegroundTemplate(BattlegroundTypeId bgTypeId)
|
||||
{
|
||||
BattlegroundTemplateContainer::const_iterator itr = m_BattlegroundTemplates.find(bgTypeId);
|
||||
if (itr != m_BattlegroundTemplates.end())
|
||||
return itr->second;
|
||||
BattlegroundDataContainer::const_iterator itr = bgDataStore.find(bgTypeId);
|
||||
if (itr == bgDataStore.end())
|
||||
return nullptr;
|
||||
|
||||
return nullptr;
|
||||
BattlegroundContainer const& bgs = itr->second._Battlegrounds;
|
||||
|
||||
// map is sorted and we can be sure that lowest instance id has only BG template
|
||||
return bgs.empty() ? nullptr : bgs.begin()->second;
|
||||
}
|
||||
|
||||
uint32 BattlegroundMgr::GetNextClientVisibleInstanceId()
|
||||
uint32 BattlegroundMgr::CreateClientVisibleInstanceId(BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id)
|
||||
{
|
||||
return ++m_lastClientVisibleInstanceId;
|
||||
if (IsArenaType(bgTypeId))
|
||||
return 0; // arenas don't have client-instanceids
|
||||
|
||||
// we create here an instanceid, which is just for
|
||||
// displaying this to the client and without any other use..
|
||||
// the client-instanceIds are unique for each battleground-type
|
||||
// the instance-id just needs to be as low as possible, beginning with 1
|
||||
// the following works, because std::set is default ordered with "<"
|
||||
// the optimalization would be to use as bitmask std::vector<uint32> - but that would only make code unreadable
|
||||
|
||||
BattlegroundClientIdsContainer& clientIds = bgDataStore[bgTypeId]._ClientBattlegroundIds[bracket_id];
|
||||
uint32 lastId = 0;
|
||||
|
||||
for (BattlegroundClientIdsContainer::const_iterator itr = clientIds.begin(); itr != clientIds.end();)
|
||||
{
|
||||
if ((++lastId) != *itr) // if there is a gap between the ids, we will break..
|
||||
break;
|
||||
|
||||
lastId = *itr;
|
||||
}
|
||||
|
||||
clientIds.emplace(++lastId);
|
||||
return lastId;
|
||||
}
|
||||
|
||||
// create a new battleground that will really be used to play
|
||||
Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId originalBgTypeId, uint32 minLevel, uint32 maxLevel, uint8 arenaType, bool isRated)
|
||||
Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId originalBgTypeId, PvPDifficultyEntry const* bracketEntry, uint8 arenaType, bool isRated)
|
||||
{
|
||||
BattlegroundTypeId bgTypeId = GetRandomBG(originalBgTypeId, minLevel);
|
||||
BattlegroundTypeId bgTypeId = GetRandomBG(originalBgTypeId, bracketEntry->minLevel);
|
||||
|
||||
if (originalBgTypeId == BATTLEGROUND_AA)
|
||||
originalBgTypeId = bgTypeId;
|
||||
@@ -262,9 +362,13 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId original
|
||||
// get the template BG
|
||||
Battleground* bg_template = GetBattlegroundTemplate(bgTypeId);
|
||||
if (!bg_template)
|
||||
{
|
||||
LOG_ERROR("bg.battleground", "Battleground: CreateNewBattleground - bg template not found for {}", bgTypeId);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Battleground* bg = nullptr;
|
||||
|
||||
// create a copy of the BG template
|
||||
if (BattlegroundMgr::bgTypeToTemplate.find(bgTypeId) == BattlegroundMgr::bgTypeToTemplate.end())
|
||||
{
|
||||
@@ -275,9 +379,9 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId original
|
||||
|
||||
bool isRandom = bgTypeId != originalBgTypeId && !bg->isArena();
|
||||
|
||||
bg->SetLevelRange(minLevel, maxLevel);
|
||||
bg->SetBracket(bracketEntry);
|
||||
bg->SetInstanceID(sMapMgr->GenerateInstanceId());
|
||||
bg->SetClientInstanceID(IsArenaType(originalBgTypeId) ? 0 : GetNextClientVisibleInstanceId());
|
||||
bg->SetClientInstanceID(CreateClientVisibleInstanceId(originalBgTypeId, bracketEntry->GetBracketId()));
|
||||
bg->Init();
|
||||
bg->SetStatus(STATUS_WAIT_JOIN); // start the joining of the bg
|
||||
bg->SetArenaType(arenaType);
|
||||
@@ -298,37 +402,40 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId original
|
||||
}
|
||||
|
||||
// used to create the BG templates
|
||||
bool BattlegroundMgr::CreateBattleground(CreateBattlegroundData& data)
|
||||
bool BattlegroundMgr::CreateBattleground(BattlegroundTemplate const* bgTemplate)
|
||||
{
|
||||
// Create the BG
|
||||
Battleground* bg = nullptr;
|
||||
bg = BattlegroundMgr::bgtypeToBattleground[data.bgTypeId];
|
||||
Battleground* bg = GetBattlegroundTemplate(bgTemplate->Id);
|
||||
|
||||
if (bg == nullptr)
|
||||
return false;
|
||||
if (!bg)
|
||||
{
|
||||
bg = BattlegroundMgr::bgtypeToBattleground[bgTemplate->Id];
|
||||
|
||||
if (data.bgTypeId == BATTLEGROUND_RB)
|
||||
bg->SetRandom(true);
|
||||
ASSERT(bg);
|
||||
|
||||
bg->SetMapId(data.MapID);
|
||||
bg->SetBgTypeID(data.bgTypeId);
|
||||
bg->SetInstanceID(0);
|
||||
bg->SetArenaorBGType(data.IsArena);
|
||||
bg->SetMinPlayersPerTeam(data.MinPlayersPerTeam);
|
||||
bg->SetMaxPlayersPerTeam(data.MaxPlayersPerTeam);
|
||||
bg->SetName(data.BattlegroundName);
|
||||
bg->SetTeamStartPosition(TEAM_ALLIANCE, data.StartLocation[TEAM_ALLIANCE]);
|
||||
bg->SetTeamStartPosition(TEAM_HORDE, data.StartLocation[TEAM_HORDE]);
|
||||
bg->SetStartMaxDist(data.StartMaxDist);
|
||||
bg->SetLevelRange(data.LevelMin, data.LevelMax);
|
||||
bg->SetScriptId(data.scriptId);
|
||||
if (bgTemplate->Id == BATTLEGROUND_RB)
|
||||
bg->SetRandom(true);
|
||||
|
||||
AddBattleground(bg);
|
||||
bg->SetBgTypeID(bgTemplate->Id);
|
||||
bg->SetInstanceID(0);
|
||||
AddBattleground(bg);
|
||||
}
|
||||
|
||||
bg->SetMapId(bgTemplate->BattlemasterEntry->mapid[0]);
|
||||
bg->SetName(bgTemplate->BattlemasterEntry->name[sWorld->GetDefaultDbcLocale()]);
|
||||
bg->SetArenaorBGType(bgTemplate->IsArena());
|
||||
bg->SetMinPlayersPerTeam(bgTemplate->MinPlayersPerTeam);
|
||||
bg->SetMaxPlayersPerTeam(bgTemplate->MaxPlayersPerTeam);
|
||||
bg->SetTeamStartPosition(TEAM_ALLIANCE, bgTemplate->StartLocation[TEAM_ALLIANCE]);
|
||||
bg->SetTeamStartPosition(TEAM_HORDE, bgTemplate->StartLocation[TEAM_HORDE]);
|
||||
bg->SetStartMaxDist(bgTemplate->MaxStartDistSq);
|
||||
bg->SetLevelRange(bgTemplate->MinLevel, bgTemplate->MaxLevel);
|
||||
bg->SetScriptId(bgTemplate->ScriptId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattlegroundMgr::CreateInitialBattlegrounds()
|
||||
void BattlegroundMgr::LoadBattlegroundTemplates()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
@@ -344,13 +451,11 @@ void BattlegroundMgr::CreateInitialBattlegrounds()
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
uint32 bgTypeId = fields[0].Get<uint32>();
|
||||
BattlegroundTypeId bgTypeId = static_cast<BattlegroundTypeId>(fields[0].Get<uint32>());
|
||||
|
||||
if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId, nullptr))
|
||||
continue;
|
||||
@@ -363,72 +468,69 @@ void BattlegroundMgr::CreateInitialBattlegrounds()
|
||||
continue;
|
||||
}
|
||||
|
||||
CreateBattlegroundData data;
|
||||
data.bgTypeId = BattlegroundTypeId(bgTypeId);
|
||||
data.IsArena = (bl->type == TYPE_ARENA);
|
||||
data.MinPlayersPerTeam = fields[1].Get<uint16>();
|
||||
data.MaxPlayersPerTeam = fields[2].Get<uint16>();
|
||||
data.LevelMin = fields[3].Get<uint8>();
|
||||
data.LevelMax = fields[4].Get<uint8>();
|
||||
BattlegroundTemplate bgTemplate;
|
||||
bgTemplate.Id = bgTypeId;
|
||||
bgTemplate.MinPlayersPerTeam = fields[1].Get<uint16>();
|
||||
bgTemplate.MaxPlayersPerTeam = fields[2].Get<uint16>();
|
||||
bgTemplate.MinLevel = fields[3].Get<uint8>();
|
||||
bgTemplate.MaxLevel = fields[4].Get<uint8>();
|
||||
float dist = fields[9].Get<float>();
|
||||
data.StartMaxDist = dist * dist;
|
||||
data.Weight = fields[10].Get<uint8>();
|
||||
bgTemplate.MaxStartDistSq = dist * dist;
|
||||
bgTemplate.Weight = fields[10].Get<uint8>();
|
||||
bgTemplate.ScriptId = sObjectMgr->GetScriptId(fields[11].Get<std::string>());
|
||||
bgTemplate.BattlemasterEntry = bl;
|
||||
|
||||
data.scriptId = sObjectMgr->GetScriptId(fields[11].Get<std::string>());
|
||||
data.BattlegroundName = bl->name[sWorld->GetDefaultDbcLocale()];
|
||||
data.MapID = bl->mapid[0];
|
||||
|
||||
if (data.MaxPlayersPerTeam == 0 || data.MinPlayersPerTeam > data.MaxPlayersPerTeam)
|
||||
if (bgTemplate.MaxPlayersPerTeam == 0 || bgTemplate.MinPlayersPerTeam > bgTemplate.MaxPlayersPerTeam)
|
||||
{
|
||||
LOG_ERROR("bg.battleground", "Table `battleground_template` for id {} has bad values for MinPlayersPerTeam ({}) and MaxPlayersPerTeam({})",
|
||||
data.bgTypeId, data.MinPlayersPerTeam, data.MaxPlayersPerTeam);
|
||||
LOG_ERROR("sql.sql", "Table `battleground_template` for id {} contains bad values for MinPlayersPerTeam ({}) and MaxPlayersPerTeam({}).",
|
||||
bgTemplate.Id, bgTemplate.MinPlayersPerTeam, bgTemplate.MaxPlayersPerTeam);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (data.LevelMin == 0 || data.LevelMax == 0 || data.LevelMin > data.LevelMax)
|
||||
if (bgTemplate.MinLevel == 0 || bgTemplate.MaxLevel == 0 || bgTemplate.MinLevel > bgTemplate.MaxLevel)
|
||||
{
|
||||
LOG_ERROR("bg.battleground", "Table `battleground_template` for id {} has bad values for LevelMin ({}) and LevelMax({})",
|
||||
data.bgTypeId, data.LevelMin, data.LevelMax);
|
||||
LOG_ERROR("sql.sql", "Table `battleground_template` for id {} has bad values for LevelMin ({}) and LevelMax({})",
|
||||
bgTemplate.Id, bgTemplate.MinLevel, bgTemplate.MaxLevel);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (data.bgTypeId != BATTLEGROUND_AA && data.bgTypeId != BATTLEGROUND_RB)
|
||||
if (bgTemplate.Id != BATTLEGROUND_AA && bgTemplate.Id != BATTLEGROUND_RB)
|
||||
{
|
||||
uint32 startId = fields[5].Get<uint32>();
|
||||
if (GraveyardStruct const* start = sGraveyard->GetGraveyard(startId))
|
||||
{
|
||||
data.StartLocation[TEAM_ALLIANCE].Relocate(start->x, start->y, start->z, fields[6].Get<float>());
|
||||
bgTemplate.StartLocation[TEAM_ALLIANCE].Relocate(start->x, start->y, start->z, fields[6].Get<float>());
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("sql.sql", "Table `battleground_template` for id %u contains a non-existing WorldSafeLocs.dbc id %u in field `AllianceStartLoc`. BG not created.", data.bgTypeId, startId);
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
|
||||
startId = fields[7].Get<uint32>();
|
||||
if (GraveyardStruct const* start = sGraveyard->GetGraveyard(startId))
|
||||
{
|
||||
data.StartLocation[TEAM_HORDE].Relocate(start->x, start->y, start->z, fields[8].Get<float>());
|
||||
bgTemplate.StartLocation[TEAM_HORDE].Relocate(start->x, start->y, start->z, fields[8].Get<float>());
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("sql.sql", "Table `battleground_template` for id %u contains a non-existing WorldSafeLocs.dbc id %u in field `HordeStartLoc`. BG not created.", data.bgTypeId, startId);
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!CreateBattleground(data))
|
||||
if (!CreateBattleground(&bgTemplate))
|
||||
continue;
|
||||
|
||||
_battlegroundTemplates[BattlegroundTypeId(bgTypeId)] = data;
|
||||
_battlegroundTemplates[bgTypeId] = bgTemplate;
|
||||
|
||||
if (bl->mapid[1] == -1) // in this case we have only one mapId
|
||||
_battlegroundMapTemplates[bl->mapid[0]] = &_battlegroundTemplates[BattlegroundTypeId(bgTypeId)];
|
||||
if (bgTemplate.BattlemasterEntry->mapid[1] == -1) // in this case we have only one mapId
|
||||
_battlegroundMapTemplates[bgTemplate.BattlemasterEntry->mapid[0]] = &_battlegroundTemplates[bgTypeId];
|
||||
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
|
||||
LOG_INFO("server.loading", ">> Loaded {} battlegrounds in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
LOG_INFO("server.loading", ">> Loaded {} battlegrounds in {} ms", _battlegroundTemplates.size(), GetMSTimeDiffToNow(oldMSTime));
|
||||
LOG_INFO("server.loading", " ");
|
||||
}
|
||||
|
||||
@@ -499,23 +601,31 @@ void BattlegroundMgr::BuildBattlegroundListPacket(WorldPacket* data, ObjectGuid
|
||||
size_t count_pos = data->wpos();
|
||||
*data << uint32(0); // number of bg instances
|
||||
|
||||
if (Battleground* bgt = GetBattlegroundTemplate(bgTypeId))
|
||||
if (GetBattlegroundBracketByLevel(bgt->GetMapId(), player->getLevel()))
|
||||
auto const& it = bgDataStore.find(bgTypeId);
|
||||
if (it != bgDataStore.end())
|
||||
{
|
||||
// expected bracket entry
|
||||
if (PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(it->second._Battlegrounds.begin()->second->GetMapId(), player->getLevel()))
|
||||
{
|
||||
uint32 count = 0;
|
||||
/*for (BattlegroundClientIdsContainer::const_iterator itr = clientIds.begin(); itr != clientIds.end(); ++itr)
|
||||
BattlegroundBracketId bracketId = bracketEntry->GetBracketId();
|
||||
BattlegroundClientIdsContainer& clientIds = it->second._ClientBattlegroundIds[bracketId];
|
||||
|
||||
for (auto const& itr : clientIds)
|
||||
{
|
||||
*data << uint32(*itr);
|
||||
*data << uint32(itr);
|
||||
++count;
|
||||
}*/
|
||||
}
|
||||
|
||||
data->put<uint32>(count_pos, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundMgr::SendToBattleground(Player* player, uint32 instanceId, BattlegroundTypeId bgTypeId)
|
||||
{
|
||||
if (Battleground* bg = GetBattleground(instanceId))
|
||||
if (Battleground* bg = GetBattleground(instanceId, bgTypeId))
|
||||
{
|
||||
uint32 mapid = bg->GetMapId();
|
||||
Position const* pos = bg->GetTeamStartPosition(player->GetBgTeamId());
|
||||
@@ -636,11 +746,25 @@ void BattlegroundMgr::SetHolidayWeekends(uint32 mask)
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundMgr::ScheduleArenaQueueUpdate(uint32 arenaRatedTeamId, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundBracketId bracket_id)
|
||||
void BattlegroundMgr::ScheduleQueueUpdate(uint32 arenaMatchmakerRating, uint8 arenaType, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id)
|
||||
{
|
||||
uint64 const scheduleId = ((uint64)arenaRatedTeamId << 32) | (bgQueueTypeId << 16) | bracket_id;
|
||||
if (std::find(m_ArenaQueueUpdateScheduler.begin(), m_ArenaQueueUpdateScheduler.end(), scheduleId) == m_ArenaQueueUpdateScheduler.end())
|
||||
m_ArenaQueueUpdateScheduler.push_back(scheduleId);
|
||||
//This method must be atomic, @todo add mutex
|
||||
//we will use only 1 number created of bgTypeId and bracket_id
|
||||
uint64 const scheduleId = ((uint64)arenaMatchmakerRating << 32) | ((uint64)arenaType << 24) | ((uint64)bgQueueTypeId << 16) | ((uint64)bgTypeId << 8) | (uint64)bracket_id;
|
||||
if (std::find(m_QueueUpdateScheduler.begin(), m_QueueUpdateScheduler.end(), scheduleId) == m_QueueUpdateScheduler.end())
|
||||
m_QueueUpdateScheduler.emplace_back(scheduleId);
|
||||
}
|
||||
|
||||
uint32 BattlegroundMgr::GetMaxRatingDifference() const
|
||||
{
|
||||
uint32 diff = sWorld->getIntConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE);
|
||||
|
||||
if (diff == 0)
|
||||
{
|
||||
diff = 5000;
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
uint32 BattlegroundMgr::GetRatingDiscardTimer() const
|
||||
@@ -766,24 +890,23 @@ bool BattlegroundMgr::IsBGWeekend(BattlegroundTypeId bgTypeId)
|
||||
|
||||
BattlegroundTypeId BattlegroundMgr::GetRandomBG(BattlegroundTypeId bgTypeId, uint32 minLevel)
|
||||
{
|
||||
if (GetBattlegroundTemplateByTypeId(bgTypeId))
|
||||
if (BattlegroundTemplate const* bgTemplate = GetBattlegroundTemplateByTypeId(bgTypeId))
|
||||
{
|
||||
std::vector<BattlegroundTypeId> ids;
|
||||
ids.reserve(16);
|
||||
std::vector<double> weights;
|
||||
weights.reserve(16);
|
||||
BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId);
|
||||
|
||||
for (int32 mapId : bl->mapid)
|
||||
for (int32 mapId : bgTemplate->BattlemasterEntry->mapid)
|
||||
{
|
||||
if (mapId == -1)
|
||||
break;
|
||||
|
||||
if (CreateBattlegroundData const* bg = GetBattlegroundTemplateByMapId(mapId))
|
||||
if (BattlegroundTemplate const* bg = GetBattlegroundTemplateByMapId(mapId))
|
||||
{
|
||||
if (bg->LevelMin <= minLevel)
|
||||
if (bg->MinLevel <= minLevel)
|
||||
{
|
||||
ids.push_back(bg->bgTypeId);
|
||||
ids.push_back(bg->Id);
|
||||
weights.push_back(bg->Weight);
|
||||
}
|
||||
}
|
||||
@@ -795,30 +918,38 @@ BattlegroundTypeId BattlegroundMgr::GetRandomBG(BattlegroundTypeId bgTypeId, uin
|
||||
return BATTLEGROUND_TYPE_NONE;
|
||||
}
|
||||
|
||||
BGFreeSlotQueueContainer& BattlegroundMgr::GetBGFreeSlotQueueStore(BattlegroundTypeId bgTypeId)
|
||||
{
|
||||
return bgDataStore[bgTypeId].BGFreeSlotQueue;
|
||||
}
|
||||
|
||||
void BattlegroundMgr::AddToBGFreeSlotQueue(BattlegroundTypeId bgTypeId, Battleground* bg)
|
||||
{
|
||||
bgDataStore[bgTypeId].BGFreeSlotQueue.push_front(bg);
|
||||
}
|
||||
|
||||
void BattlegroundMgr::RemoveFromBGFreeSlotQueue(BattlegroundTypeId bgTypeId, uint32 instanceId)
|
||||
{
|
||||
BGFreeSlotQueueContainer& queues = bgDataStore[bgTypeId].BGFreeSlotQueue;
|
||||
for (BGFreeSlotQueueContainer::iterator itr = queues.begin(); itr != queues.end(); ++itr)
|
||||
if ((*itr)->GetInstanceID() == instanceId)
|
||||
{
|
||||
queues.erase(itr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundMgr::AddBattleground(Battleground* bg)
|
||||
{
|
||||
if (bg->GetInstanceID() == 0)
|
||||
m_BattlegroundTemplates[bg->GetBgTypeID()] = bg;
|
||||
else
|
||||
m_Battlegrounds[bg->GetInstanceID()] = bg;
|
||||
if (bg)
|
||||
bgDataStore[bg->GetBgTypeID()]._Battlegrounds[bg->GetInstanceID()] = bg;
|
||||
|
||||
sScriptMgr->OnBattlegroundCreate(bg);
|
||||
}
|
||||
|
||||
void BattlegroundMgr::RemoveBattleground(BattlegroundTypeId bgTypeId, uint32 instanceId)
|
||||
{
|
||||
if (instanceId == 0)
|
||||
m_BattlegroundTemplates.erase(bgTypeId);
|
||||
else
|
||||
m_Battlegrounds.erase(instanceId);
|
||||
}
|
||||
|
||||
void BattlegroundMgr::DoForAllBattlegrounds(std::function<void(Battleground*)> const& worker)
|
||||
{
|
||||
for (auto const& [_, bg] : m_Battlegrounds)
|
||||
{
|
||||
worker(bg);
|
||||
}
|
||||
bgDataStore[bgTypeId]._Battlegrounds.erase(instanceId);
|
||||
}
|
||||
|
||||
// init/update unordered_map
|
||||
|
||||
@@ -27,29 +27,38 @@
|
||||
#include <functional>
|
||||
|
||||
typedef std::map<uint32, Battleground*> BattlegroundContainer;
|
||||
typedef std::set<uint32> BattlegroundClientIdsContainer;
|
||||
typedef std::unordered_map<uint32, BattlegroundTypeId> BattleMastersMap;
|
||||
typedef Battleground* (*bgRef)(Battleground*);
|
||||
|
||||
typedef void(*bgMapRef)(WorldPacket*, Battleground::BattlegroundScoreMap::const_iterator);
|
||||
typedef void(*bgTypeRef)(WorldPacket*, Battleground::BattlegroundScoreMap::const_iterator, Battleground*);
|
||||
|
||||
struct CreateBattlegroundData
|
||||
// this container can't be deque, because deque doesn't like removing the last element - if you remove it, it invalidates next iterator and crash appears
|
||||
using BGFreeSlotQueueContainer = std::list<Battleground*>;
|
||||
|
||||
struct BattlegroundData
|
||||
{
|
||||
BattlegroundTypeId bgTypeId;
|
||||
bool IsArena;
|
||||
uint32 MinPlayersPerTeam;
|
||||
uint32 MaxPlayersPerTeam;
|
||||
uint32 LevelMin;
|
||||
uint32 LevelMax;
|
||||
char const* BattlegroundName;
|
||||
uint32 MapID;
|
||||
float StartMaxDist;
|
||||
std::array<Position, PVP_TEAMS_COUNT> StartLocation;
|
||||
uint32 scriptId;
|
||||
uint8 Weight;
|
||||
BattlegroundContainer _Battlegrounds;
|
||||
std::array<BattlegroundClientIdsContainer, MAX_BATTLEGROUND_BRACKETS> _ClientBattlegroundIds;
|
||||
BGFreeSlotQueueContainer BGFreeSlotQueue;
|
||||
};
|
||||
|
||||
struct GroupQueueInfo;
|
||||
struct BattlegroundTemplate
|
||||
{
|
||||
BattlegroundTypeId Id;
|
||||
uint16 MinPlayersPerTeam;
|
||||
uint16 MaxPlayersPerTeam;
|
||||
uint8 MinLevel;
|
||||
uint8 MaxLevel;
|
||||
std::array<Position, PVP_TEAMS_COUNT> StartLocation;
|
||||
float MaxStartDistSq;
|
||||
uint8 Weight;
|
||||
uint32 ScriptId;
|
||||
BattlemasterListEntry const* BattlemasterEntry;
|
||||
|
||||
bool IsArena() const;
|
||||
};
|
||||
|
||||
class BattlegroundMgr
|
||||
{
|
||||
@@ -71,21 +80,25 @@ public:
|
||||
void SendAreaSpiritHealerQueryOpcode(Player* player, Battleground* bg, ObjectGuid guid);
|
||||
|
||||
/* Battlegrounds */
|
||||
Battleground* GetBattleground(uint32 InstanceID);
|
||||
Battleground* GetBattlegroundThroughClientInstance(uint32 instanceId, BattlegroundTypeId bgTypeId);
|
||||
Battleground* GetBattleground(uint32 instanceID, BattlegroundTypeId bgTypeId);
|
||||
Battleground* GetBattlegroundTemplate(BattlegroundTypeId bgTypeId);
|
||||
Battleground* CreateNewBattleground(BattlegroundTypeId bgTypeId, uint32 minLevel, uint32 maxLevel, uint8 arenaType, bool isRated);
|
||||
Battleground* CreateNewBattleground(BattlegroundTypeId bgTypeId, PvPDifficultyEntry const* bracketEntry, uint8 arenaType, bool isRated);
|
||||
|
||||
void AddBattleground(Battleground* bg);
|
||||
void RemoveBattleground(BattlegroundTypeId bgTypeId, uint32 instanceId);
|
||||
void AddToBGFreeSlotQueue(BattlegroundTypeId bgTypeId, Battleground* bg);
|
||||
void RemoveFromBGFreeSlotQueue(BattlegroundTypeId bgTypeId, uint32 instanceId);
|
||||
BGFreeSlotQueueContainer& GetBGFreeSlotQueueStore(BattlegroundTypeId bgTypeId);
|
||||
|
||||
void CreateInitialBattlegrounds();
|
||||
void LoadBattlegroundTemplates();
|
||||
void DeleteAllBattlegrounds();
|
||||
|
||||
void SendToBattleground(Player* player, uint32 InstanceID, BattlegroundTypeId bgTypeId);
|
||||
|
||||
/* Battleground queues */
|
||||
BattlegroundQueue& GetBattlegroundQueue(BattlegroundQueueTypeId bgQueueTypeId) { return m_BattlegroundQueues[bgQueueTypeId]; }
|
||||
void ScheduleArenaQueueUpdate(uint32 arenaRatedTeamId, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundBracketId bracket_id);
|
||||
void ScheduleQueueUpdate(uint32 arenaMatchmakerRating, uint8 arenaType, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id);
|
||||
uint32 GetPrematureFinishTime() const;
|
||||
|
||||
void ToggleArenaTesting();
|
||||
@@ -105,10 +118,12 @@ public:
|
||||
static BattlegroundTypeId WeekendHolidayIdToBGType(HolidayIds holiday);
|
||||
static bool IsBGWeekend(BattlegroundTypeId bgTypeId);
|
||||
|
||||
uint32 GetRatingDiscardTimer() const;
|
||||
uint32 GetMaxRatingDifference() const;
|
||||
uint32 GetRatingDiscardTimer() const;
|
||||
void InitAutomaticArenaPointDistribution();
|
||||
void LoadBattleMastersEntry();
|
||||
void CheckBattleMasters();
|
||||
|
||||
BattlegroundTypeId GetBattleMasterBG(uint32 entry) const
|
||||
{
|
||||
BattleMastersMap::const_iterator itr = mBattleMastersMap.find(entry);
|
||||
@@ -117,8 +132,6 @@ public:
|
||||
return BATTLEGROUND_TYPE_NONE;
|
||||
}
|
||||
|
||||
const BattlegroundContainer& GetBattlegroundList() { return m_Battlegrounds; } // pussywizard
|
||||
|
||||
static std::unordered_map<int, BattlegroundQueueTypeId> bgToQueue; // BattlegroundTypeId -> BattlegroundQueueTypeId
|
||||
static std::unordered_map<int, BattlegroundTypeId> queueToBg; // BattlegroundQueueTypeId -> BattlegroundTypeId
|
||||
static std::unordered_map<int, Battleground*> bgtypeToBattleground; // BattlegroundTypeId -> Battleground*
|
||||
@@ -128,48 +141,46 @@ public:
|
||||
static std::unordered_map<uint32, BattlegroundQueueTypeId> ArenaTypeToQueue; // ArenaType -> BattlegroundQueueTypeId
|
||||
static std::unordered_map<uint32, ArenaType> QueueToArenaType; // BattlegroundQueueTypeId -> ArenaType
|
||||
|
||||
void DoForAllBattlegrounds(std::function<void(Battleground*)> const& worker);
|
||||
|
||||
private:
|
||||
bool CreateBattleground(CreateBattlegroundData& data);
|
||||
uint32 GetNextClientVisibleInstanceId();
|
||||
bool CreateBattleground(BattlegroundTemplate const* bgTemplate);
|
||||
uint32 CreateClientVisibleInstanceId(BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id);
|
||||
BattlegroundTypeId GetRandomBG(BattlegroundTypeId id, uint32 minLevel);
|
||||
|
||||
typedef std::map<BattlegroundTypeId, Battleground*> BattlegroundTemplateContainer;
|
||||
BattlegroundTemplateContainer m_BattlegroundTemplates;
|
||||
BattlegroundContainer m_Battlegrounds;
|
||||
typedef std::map<BattlegroundTypeId, BattlegroundData> BattlegroundDataContainer;
|
||||
BattlegroundDataContainer bgDataStore;
|
||||
|
||||
BattlegroundQueue m_BattlegroundQueues[MAX_BATTLEGROUND_QUEUE_TYPES];
|
||||
|
||||
std::vector<uint64> m_ArenaQueueUpdateScheduler;
|
||||
std::vector<uint64> m_QueueUpdateScheduler;
|
||||
bool m_ArenaTesting;
|
||||
bool m_Testing;
|
||||
uint32 m_lastClientVisibleInstanceId;
|
||||
Seconds m_NextAutoDistributionTime;
|
||||
uint32 m_AutoDistributionTimeChecker;
|
||||
uint32 m_NextPeriodicQueueUpdateTime;
|
||||
BattleMastersMap mBattleMastersMap;
|
||||
|
||||
CreateBattlegroundData const* GetBattlegroundTemplateByTypeId(BattlegroundTypeId id)
|
||||
BattlegroundTemplate const* GetBattlegroundTemplateByTypeId(BattlegroundTypeId id)
|
||||
{
|
||||
BattlegroundTemplateMap::const_iterator itr = _battlegroundTemplates.find(id);
|
||||
auto const& itr = _battlegroundTemplates.find(id);
|
||||
if (itr != _battlegroundTemplates.end())
|
||||
return &itr->second;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CreateBattlegroundData const* GetBattlegroundTemplateByMapId(uint32 mapId)
|
||||
BattlegroundTemplate const* GetBattlegroundTemplateByMapId(uint32 mapId)
|
||||
{
|
||||
BattlegroundMapTemplateContainer::const_iterator itr = _battlegroundMapTemplates.find(mapId);
|
||||
auto const& itr = _battlegroundMapTemplates.find(mapId);
|
||||
if (itr != _battlegroundMapTemplates.end())
|
||||
return itr->second;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
typedef std::map<BattlegroundTypeId, uint8 /*weight*/> BattlegroundSelectionWeightMap;
|
||||
|
||||
typedef std::map<BattlegroundTypeId, CreateBattlegroundData> BattlegroundTemplateMap;
|
||||
typedef std::map<uint32 /*mapId*/, CreateBattlegroundData*> BattlegroundMapTemplateContainer;
|
||||
typedef std::map<BattlegroundTypeId, BattlegroundTemplate> BattlegroundTemplateMap;
|
||||
typedef std::map<uint32 /*mapId*/, BattlegroundTemplate*> BattlegroundMapTemplateContainer;
|
||||
BattlegroundTemplateMap _battlegroundTemplates;
|
||||
BattlegroundMapTemplateContainer _battlegroundMapTemplates;
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,7 +25,7 @@
|
||||
#include <array>
|
||||
#include <deque>
|
||||
|
||||
#define COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME 10
|
||||
constexpr auto COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME = 10;
|
||||
|
||||
struct GroupQueueInfo // stores information about the group in queue (also used when joined as solo!)
|
||||
{
|
||||
@@ -43,10 +43,9 @@ struct GroupQueueInfo // stores informatio
|
||||
uint32 ArenaMatchmakerRating; // if rated match, inited to the rating of the team
|
||||
uint32 OpponentsTeamRating; // for rated arena matches
|
||||
uint32 OpponentsMatchmakerRating; // for rated arena matches
|
||||
|
||||
// pussywizard: for internal use
|
||||
uint8 _bracketId;
|
||||
uint8 _groupType;
|
||||
uint32 PreviousOpponentsTeamId; // excluded from the current queue until the timer is met
|
||||
uint8 BracketId; // BattlegroundBracketId
|
||||
uint8 GroupType; // BattlegroundQueueGroupTypes
|
||||
};
|
||||
|
||||
enum BattlegroundQueueGroupTypes
|
||||
@@ -61,22 +60,21 @@ enum BattlegroundQueueGroupTypes
|
||||
BG_QUEUE_MAX = 10
|
||||
};
|
||||
|
||||
class Battleground;
|
||||
class BattlegroundQueue
|
||||
{
|
||||
public:
|
||||
BattlegroundQueue();
|
||||
~BattlegroundQueue();
|
||||
|
||||
void BattlegroundQueueUpdate(uint32 diff, BattlegroundBracketId bracket_id, bool isRated, uint32 arenaRatedTeamId);
|
||||
void BattlegroundQueueUpdate(uint32 diff, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id, uint8 arenaType, bool isRated, uint32 arenaRating);
|
||||
void UpdateEvents(uint32 diff);
|
||||
|
||||
void FillPlayersToBG(Battleground* bg, int32 aliFree, int32 hordeFree, BattlegroundBracketId bracket_id);
|
||||
void FillPlayersToBG(Battleground* bg, BattlegroundBracketId bracket_id);
|
||||
bool CheckPremadeMatch(BattlegroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam);
|
||||
bool CheckNormalMatch(Battleground* bgTemplate, BattlegroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers);
|
||||
bool CheckSkirmishForSameFaction(BattlegroundBracketId bracket_id, uint32 minPlayersPerTeam);
|
||||
GroupQueueInfo* AddGroup(Player* leader, Group* group, PvPDifficultyEntry const* bracketEntry, bool isRated, bool isPremade, uint32 ArenaRating, uint32 MatchmakerRating, uint32 ArenaTeamId);
|
||||
void RemovePlayer(ObjectGuid guid, bool sentToBg, uint32 playerQueueSlot);
|
||||
GroupQueueInfo* AddGroup(Player* leader, Group* group, BattlegroundTypeId bgTypeId, PvPDifficultyEntry const* bracketEntry, uint8 arenaType, bool isRated, bool isPremade, uint32 arenaRating, uint32 matchmakerRating, uint32 arenaTeamId = 0, uint32 opponentsArenaTeamId = 0);
|
||||
void RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount);
|
||||
bool IsPlayerInvitedToRatedArena(ObjectGuid pl_guid);
|
||||
bool IsPlayerInvited(ObjectGuid pl_guid, uint32 bgInstanceGuid, uint32 removeTime);
|
||||
bool GetPlayerGroupInfoData(ObjectGuid guid, GroupQueueInfo* ginfo);
|
||||
@@ -89,7 +87,6 @@ public:
|
||||
void SendJoinMessageArenaQueue(Player* leader, GroupQueueInfo* ginfo, PvPDifficultyEntry const* bracketEntry, bool isRated);
|
||||
void SendExitMessageArenaQueue(GroupQueueInfo* ginfo);
|
||||
|
||||
void SetBgTypeIdAndArenaType(BattlegroundTypeId b, uint8 a) { m_bgTypeId = b; m_arenaType = ArenaType(a); } // pussywizard
|
||||
void AddEvent(BasicEvent* Event, uint64 e_time);
|
||||
|
||||
typedef std::map<ObjectGuid, GroupQueueInfo*> QueuedPlayersMap;
|
||||
@@ -127,15 +124,10 @@ public:
|
||||
//one selection pool for horde, other one for alliance
|
||||
SelectionPool m_SelectionPools[PVP_TEAMS_COUNT];
|
||||
|
||||
ArenaType GetArenaType() { return m_arenaType; }
|
||||
BattlegroundTypeId GetBGTypeID() { return m_bgTypeId; }
|
||||
|
||||
void SetQueueAnnouncementTimer(uint32 bracketId, int32 timer, bool isCrossFactionBG = true);
|
||||
[[nodiscard]] int32 GetQueueAnnouncementTimer(uint32 bracketId) const;
|
||||
|
||||
private:
|
||||
BattlegroundTypeId m_bgTypeId;
|
||||
ArenaType m_arenaType;
|
||||
uint32 m_WaitTimes[PVP_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME];
|
||||
uint32 m_WaitTimeLastIndex[PVP_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS];
|
||||
|
||||
@@ -176,9 +168,8 @@ private:
|
||||
class BGQueueRemoveEvent : public BasicEvent
|
||||
{
|
||||
public:
|
||||
BGQueueRemoveEvent(ObjectGuid pl_guid, uint32 bgInstanceGUID, BattlegroundQueueTypeId bgQueueTypeId, uint32 removeTime)
|
||||
: m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_RemoveTime(removeTime), m_BgQueueTypeId(bgQueueTypeId)
|
||||
{}
|
||||
BGQueueRemoveEvent(ObjectGuid pl_guid, uint32 bgInstanceGUID, BattlegroundTypeId BgTypeId, BattlegroundQueueTypeId bgQueueTypeId, uint32 removeTime) :
|
||||
m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_RemoveTime(removeTime), m_BgTypeId(BgTypeId), m_BgQueueTypeId(bgQueueTypeId) { }
|
||||
|
||||
~BGQueueRemoveEvent() override = default;
|
||||
|
||||
@@ -188,6 +179,7 @@ private:
|
||||
ObjectGuid m_PlayerGuid;
|
||||
uint32 m_BgInstanceGUID;
|
||||
uint32 m_RemoveTime;
|
||||
BattlegroundTypeId m_BgTypeId;
|
||||
BattlegroundQueueTypeId m_BgQueueTypeId;
|
||||
};
|
||||
|
||||
|
||||
@@ -1708,7 +1708,7 @@ namespace lfg
|
||||
if (bgQueueTypeId != BATTLEGROUND_QUEUE_NONE)
|
||||
{
|
||||
plr->RemoveBattlegroundQueueId(bgQueueTypeId);
|
||||
sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId).RemovePlayer(plr->GetGUID(), false, i);
|
||||
sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId).RemovePlayer(plr->GetGUID(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,7 +248,10 @@ Player::Player(WorldSession* session): Unit(true), m_mover(this)
|
||||
m_swingErrorMsg = 0;
|
||||
|
||||
for (uint8 j = 0; j < PLAYER_MAX_BATTLEGROUND_QUEUES; ++j)
|
||||
m_bgBattlegroundQueueID[j] = BATTLEGROUND_QUEUE_NONE;
|
||||
{
|
||||
_BgBattlegroundQueueID[j].bgQueueTypeId = BATTLEGROUND_QUEUE_NONE;
|
||||
_BgBattlegroundQueueID[j].invitedToInstance = 0;
|
||||
}
|
||||
|
||||
m_logintime = GameTime::GetGameTime().count();
|
||||
m_Last_tick = m_logintime;
|
||||
@@ -11025,6 +11028,8 @@ void Player::LeaveBattleground(Battleground* bg)
|
||||
sScriptMgr->OnBattlegroundDesertion(this, BG_DESERTION_TYPE_LEAVE_BG);
|
||||
}
|
||||
|
||||
bg->RemovePlayerAtLeave(this);
|
||||
|
||||
// xinef: reset corpse reclaim time
|
||||
m_deathExpireTime = GameTime::GetGameTime().count();
|
||||
|
||||
@@ -11853,10 +11858,102 @@ Battleground* Player::GetBattleground(bool create) const
|
||||
if (GetBattlegroundId() == 0)
|
||||
return nullptr;
|
||||
|
||||
Battleground* bg = sBattlegroundMgr->GetBattleground(GetBattlegroundId());
|
||||
Battleground* bg = sBattlegroundMgr->GetBattleground(GetBattlegroundId(), GetBattlegroundTypeId());
|
||||
return (create || (bg && bg->FindBgMap()) ? bg : nullptr);
|
||||
}
|
||||
|
||||
bool Player::InBattlegroundQueue(bool ignoreArena) const
|
||||
{
|
||||
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
if (_BgBattlegroundQueueID[i].bgQueueTypeId != BATTLEGROUND_QUEUE_NONE &&
|
||||
(!ignoreArena || (_BgBattlegroundQueueID[i].bgQueueTypeId != BATTLEGROUND_QUEUE_2v2 &&
|
||||
_BgBattlegroundQueueID[i].bgQueueTypeId != BATTLEGROUND_QUEUE_3v3 &&
|
||||
_BgBattlegroundQueueID[i].bgQueueTypeId != BATTLEGROUND_QUEUE_5v5)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
BattlegroundQueueTypeId Player::GetBattlegroundQueueTypeId(uint32 index) const
|
||||
{
|
||||
return _BgBattlegroundQueueID[index].bgQueueTypeId;
|
||||
}
|
||||
|
||||
uint32 Player::GetBattlegroundQueueIndex(BattlegroundQueueTypeId bgQueueTypeId) const
|
||||
{
|
||||
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
if (_BgBattlegroundQueueID[i].bgQueueTypeId == bgQueueTypeId)
|
||||
return i;
|
||||
|
||||
return PLAYER_MAX_BATTLEGROUND_QUEUES;
|
||||
}
|
||||
|
||||
bool Player::IsInvitedForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
|
||||
{
|
||||
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
if (_BgBattlegroundQueueID[i].bgQueueTypeId == bgQueueTypeId)
|
||||
return _BgBattlegroundQueueID[i].invitedToInstance != 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Player::InBattlegroundQueueForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
|
||||
{
|
||||
return GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES;
|
||||
}
|
||||
|
||||
uint32 Player::AddBattlegroundQueueId(BattlegroundQueueTypeId val)
|
||||
{
|
||||
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
{
|
||||
if (_BgBattlegroundQueueID[i].bgQueueTypeId == BATTLEGROUND_QUEUE_NONE || _BgBattlegroundQueueID[i].bgQueueTypeId == val)
|
||||
{
|
||||
_BgBattlegroundQueueID[i].bgQueueTypeId = val;
|
||||
_BgBattlegroundQueueID[i].invitedToInstance = 0;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return PLAYER_MAX_BATTLEGROUND_QUEUES;
|
||||
}
|
||||
|
||||
bool Player::HasFreeBattlegroundQueueId() const
|
||||
{
|
||||
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
if (_BgBattlegroundQueueID[i].bgQueueTypeId == BATTLEGROUND_QUEUE_NONE)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Player::RemoveBattlegroundQueueId(BattlegroundQueueTypeId val)
|
||||
{
|
||||
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
{
|
||||
if (_BgBattlegroundQueueID[i].bgQueueTypeId == val)
|
||||
{
|
||||
_BgBattlegroundQueueID[i].bgQueueTypeId = BATTLEGROUND_QUEUE_NONE;
|
||||
_BgBattlegroundQueueID[i].invitedToInstance = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Player::SetInviteForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId, uint32 instanceId)
|
||||
{
|
||||
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
if (_BgBattlegroundQueueID[i].bgQueueTypeId == bgQueueTypeId)
|
||||
_BgBattlegroundQueueID[i].invitedToInstance = instanceId;
|
||||
}
|
||||
|
||||
bool Player::IsInvitedForBattlegroundInstance(uint32 instanceId) const
|
||||
{
|
||||
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
if (_BgBattlegroundQueueID[i].invitedToInstance == instanceId)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Player::InArena() const
|
||||
{
|
||||
Battleground* bg = GetBattleground();
|
||||
@@ -11868,16 +11965,6 @@ bool Player::InArena() const
|
||||
|
||||
void Player::SetBattlegroundId(uint32 id, BattlegroundTypeId bgTypeId, uint32 queueSlot, bool invited, bool isRandom, TeamId teamId)
|
||||
{
|
||||
// if leaving current bg (and was invited) - decrease invited count for current one
|
||||
if (m_bgData.bgInstanceID && m_bgData.isInvited)
|
||||
if (Battleground* bg = sBattlegroundMgr->GetBattleground(m_bgData.bgInstanceID))
|
||||
bg->DecreaseInvitedCount(m_bgData.bgTeamId);
|
||||
|
||||
// if entering new bg (and is invited) - increase invited count for new one
|
||||
if (id && invited)
|
||||
if (Battleground* bg = sBattlegroundMgr->GetBattleground(id))
|
||||
bg->IncreaseInvitedCount(teamId);
|
||||
|
||||
m_bgData.bgInstanceID = id;
|
||||
m_bgData.bgTypeID = bgTypeId;
|
||||
m_bgData.bgQueueSlot = queueSlot;
|
||||
|
||||
@@ -177,7 +177,7 @@ enum TalentTree // talent tabs
|
||||
// Spell modifier (used for modify other spells)
|
||||
struct SpellModifier
|
||||
{
|
||||
SpellModifier(Aura* _ownerAura = nullptr) : op(SPELLMOD_DAMAGE), type(SPELLMOD_FLAT), charges(0), mask(), ownerAura(_ownerAura) {}
|
||||
SpellModifier(Aura* _ownerAura = nullptr) : op(SPELLMOD_DAMAGE), type(SPELLMOD_FLAT), charges(0), mask(), ownerAura(_ownerAura) {}
|
||||
SpellModOp op : 8;
|
||||
SpellModType type : 8;
|
||||
int16 charges : 16;
|
||||
@@ -2188,59 +2188,20 @@ public:
|
||||
void SetBGData(BGData& bgdata) { m_bgData = bgdata; }
|
||||
[[nodiscard]] Battleground* GetBattleground(bool create = false) const;
|
||||
|
||||
[[nodiscard]] bool InBattlegroundQueue() const
|
||||
{
|
||||
for (auto i : m_bgBattlegroundQueueID)
|
||||
if (i != BATTLEGROUND_QUEUE_NONE)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
[[nodiscard]] bool InBattlegroundQueue(bool ignoreArena = false) const;
|
||||
[[nodiscard]] bool IsDeserter() const { return HasAura(26013); }
|
||||
|
||||
[[nodiscard]] BattlegroundQueueTypeId GetBattlegroundQueueTypeId(uint32 index) const { return m_bgBattlegroundQueueID[index]; }
|
||||
|
||||
[[nodiscard]] uint32 GetBattlegroundQueueIndex(BattlegroundQueueTypeId bgQueueTypeId) const
|
||||
{
|
||||
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
if (m_bgBattlegroundQueueID[i] == bgQueueTypeId)
|
||||
return i;
|
||||
return PLAYER_MAX_BATTLEGROUND_QUEUES;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool InBattlegroundQueueForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
|
||||
{
|
||||
return GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES;
|
||||
}
|
||||
[[nodiscard]] BattlegroundQueueTypeId GetBattlegroundQueueTypeId(uint32 index) const;
|
||||
[[nodiscard]] uint32 GetBattlegroundQueueIndex(BattlegroundQueueTypeId bgQueueTypeId) const;
|
||||
[[nodiscard]] bool IsInvitedForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const;
|
||||
[[nodiscard]] bool InBattlegroundQueueForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const;
|
||||
|
||||
void SetBattlegroundId(uint32 id, BattlegroundTypeId bgTypeId, uint32 queueSlot, bool invited, bool isRandom, TeamId teamId);
|
||||
|
||||
uint32 AddBattlegroundQueueId(BattlegroundQueueTypeId val)
|
||||
{
|
||||
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
if (m_bgBattlegroundQueueID[i] == BATTLEGROUND_QUEUE_NONE || m_bgBattlegroundQueueID[i] == val)
|
||||
{
|
||||
m_bgBattlegroundQueueID[i] = val;
|
||||
return i;
|
||||
}
|
||||
return PLAYER_MAX_BATTLEGROUND_QUEUES;
|
||||
}
|
||||
|
||||
bool HasFreeBattlegroundQueueId()
|
||||
{
|
||||
for (auto & i : m_bgBattlegroundQueueID)
|
||||
if (i == BATTLEGROUND_QUEUE_NONE)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void RemoveBattlegroundQueueId(BattlegroundQueueTypeId val)
|
||||
{
|
||||
for (auto & i : m_bgBattlegroundQueueID)
|
||||
if (i == val)
|
||||
{
|
||||
i = BATTLEGROUND_QUEUE_NONE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
uint32 AddBattlegroundQueueId(BattlegroundQueueTypeId val);
|
||||
bool HasFreeBattlegroundQueueId() const;
|
||||
void RemoveBattlegroundQueueId(BattlegroundQueueTypeId val);
|
||||
void SetInviteForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId, uint32 instanceId);
|
||||
bool IsInvitedForBattlegroundInstance(uint32 instanceId) const;
|
||||
|
||||
[[nodiscard]] TeamId GetBgTeamId() const { return m_bgData.bgTeamId != TEAM_NEUTRAL ? m_bgData.bgTeamId : GetTeamId(); }
|
||||
|
||||
@@ -2601,7 +2562,13 @@ public:
|
||||
/*** BATTLEGROUND SYSTEM ***/
|
||||
/*********************************************************/
|
||||
|
||||
BattlegroundQueueTypeId m_bgBattlegroundQueueID[PLAYER_MAX_BATTLEGROUND_QUEUES];
|
||||
struct BgBattlegroundQueueID_Rec
|
||||
{
|
||||
BattlegroundQueueTypeId bgQueueTypeId;
|
||||
uint32 invitedToInstance;
|
||||
};
|
||||
|
||||
std::array<BgBattlegroundQueueID_Rec, PLAYER_MAX_BATTLEGROUND_QUEUES> _BgBattlegroundQueueID;
|
||||
BGData m_bgData;
|
||||
bool m_IsBGRandomWinner;
|
||||
|
||||
|
||||
@@ -2189,6 +2189,11 @@ ObjectGuid Group::GetLeaderGUID() const
|
||||
return m_leaderGuid;
|
||||
}
|
||||
|
||||
Player* Group::GetLeader()
|
||||
{
|
||||
return ObjectAccessor::FindConnectedPlayer(m_leaderGuid);
|
||||
}
|
||||
|
||||
ObjectGuid Group::GetGUID() const
|
||||
{
|
||||
return m_guid;
|
||||
@@ -2425,3 +2430,15 @@ void Group::SetDifficultyChangePrevention(DifficultyPreventionChangeType type)
|
||||
_difficultyChangePreventionTime = GameTime::GetGameTime().count() + MINUTE;
|
||||
_difficultyChangePreventionType = type;
|
||||
}
|
||||
|
||||
void Group::DoForAllMembers(std::function<void(Player*)> const& worker)
|
||||
{
|
||||
for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
|
||||
{
|
||||
Player* member = itr->GetSource();
|
||||
if (!member)
|
||||
continue;
|
||||
|
||||
worker(member);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "LootMgr.h"
|
||||
#include "QueryResult.h"
|
||||
#include "SharedDefines.h"
|
||||
#include <functional>
|
||||
|
||||
class Battlefield;
|
||||
class Battleground;
|
||||
@@ -214,6 +215,7 @@ public:
|
||||
bool isBGGroup() const;
|
||||
bool IsCreated() const;
|
||||
ObjectGuid GetLeaderGUID() const;
|
||||
Player* GetLeader();
|
||||
ObjectGuid GetGUID() const;
|
||||
const char* GetLeaderName() const;
|
||||
LootMethod GetLootMethod() const;
|
||||
@@ -313,6 +315,8 @@ public:
|
||||
DifficultyPreventionChangeType GetDifficultyChangePreventionReason() const { return _difficultyChangePreventionType; }
|
||||
void SetDifficultyChangePrevention(DifficultyPreventionChangeType type);
|
||||
|
||||
void DoForAllMembers(std::function<void(Player*)> const& worker);
|
||||
|
||||
protected:
|
||||
void _homebindIfInstance(Player* player);
|
||||
void _cancelHomebindIfInstance(Player* player);
|
||||
|
||||
@@ -72,8 +72,9 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
|
||||
{
|
||||
ObjectGuid guid;
|
||||
uint32 bgTypeId_;
|
||||
uint32 instanceId; // sent to queue for particular bg from battlemaster's list, currently not used
|
||||
uint32 instanceId;
|
||||
uint8 joinAsGroup;
|
||||
bool isPremade = false;
|
||||
|
||||
recvData >> guid; // battlemaster guid
|
||||
recvData >> bgTypeId_; // battleground type id (DBC id)
|
||||
@@ -82,7 +83,10 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
|
||||
|
||||
// entry not found
|
||||
if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
|
||||
{
|
||||
LOG_ERROR("network", "Battleground: invalid bgtype ({}) received. possible cheater? player {}", bgTypeId_, _player->GetGUID().ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
// chosen battleground type is disabled
|
||||
if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId_, nullptr))
|
||||
@@ -91,6 +95,8 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from {}", guid.ToString());
|
||||
|
||||
// get queue typeid and random typeid to check if already queued for them
|
||||
BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_);
|
||||
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, 0);
|
||||
@@ -100,35 +106,26 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
|
||||
if (bgQueueTypeId == BATTLEGROUND_QUEUE_NONE)
|
||||
return;
|
||||
|
||||
// get bg template
|
||||
Battleground* bgt = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
|
||||
if (!bgt)
|
||||
// ignore if player is already in BG
|
||||
if (_player->InBattleground())
|
||||
return;
|
||||
|
||||
// get bg instance or bg template if instance not found
|
||||
Battleground* bg = nullptr;
|
||||
if (instanceId)
|
||||
bg = sBattlegroundMgr->GetBattlegroundThroughClientInstance(instanceId, bgTypeId);
|
||||
|
||||
if (!bg)
|
||||
bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
|
||||
|
||||
if (!bg)
|
||||
return;
|
||||
|
||||
// expected bracket entry
|
||||
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bgt->GetMapId(), _player->getLevel());
|
||||
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel());
|
||||
if (!bracketEntry)
|
||||
return;
|
||||
|
||||
// pussywizard: if trying to queue for already queued
|
||||
// just remove from queue and it will requeue!
|
||||
uint32 qSlot = _player->GetBattlegroundQueueIndex(bgQueueTypeId);
|
||||
if (qSlot < PLAYER_MAX_BATTLEGROUND_QUEUES)
|
||||
{
|
||||
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
|
||||
|
||||
if (bgQueue.IsPlayerInvitedToRatedArena(_player->GetGUID()))
|
||||
{
|
||||
WorldPacket data;
|
||||
sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_JOIN_FAILED);
|
||||
SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
|
||||
bgQueue.RemovePlayer(_player->GetGUID(), false, qSlot);
|
||||
_player->RemoveBattlegroundQueueId(bgQueueTypeId);
|
||||
}
|
||||
|
||||
// must have free queue slot
|
||||
if (!_player->HasFreeBattlegroundQueueId())
|
||||
{
|
||||
@@ -139,7 +136,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
|
||||
}
|
||||
|
||||
// queue result (default ok)
|
||||
GroupJoinBattlegroundResult err = GroupJoinBattlegroundResult(bgt->GetBgTypeID());
|
||||
GroupJoinBattlegroundResult err = GroupJoinBattlegroundResult(bg->GetBgTypeID());
|
||||
|
||||
if (!sScriptMgr->CanJoinInBattlegroundQueue(_player, guid, bgTypeId, joinAsGroup, err) && err <= 0)
|
||||
{
|
||||
@@ -149,6 +146,8 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
|
||||
return;
|
||||
}
|
||||
|
||||
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
|
||||
|
||||
// check if player can queue:
|
||||
if (!joinAsGroup)
|
||||
{
|
||||
@@ -169,6 +168,10 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
|
||||
{
|
||||
err = ERR_IN_RANDOM_BG;
|
||||
}
|
||||
else if (_player->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId)) // queued for this bg
|
||||
{
|
||||
err = ERR_BATTLEGROUND_NONE;
|
||||
}
|
||||
else if (_player->InBattlegroundQueue() && bgTypeId == BATTLEGROUND_RB) // already in queue, so can't queue for random
|
||||
{
|
||||
err = ERR_IN_NON_RANDOM_BG;
|
||||
@@ -193,15 +196,13 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
|
||||
return;
|
||||
}
|
||||
|
||||
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
|
||||
GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bracketEntry, false, false, 0, 0, 0);
|
||||
GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0);
|
||||
uint32 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
|
||||
|
||||
uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId);
|
||||
|
||||
// send status packet
|
||||
WorldPacket data;
|
||||
sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, 0, TEAM_NEUTRAL);
|
||||
sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, 0, TEAM_NEUTRAL);
|
||||
SendPacket(&data);
|
||||
|
||||
sScriptMgr->OnPlayerJoinBG(_player);
|
||||
@@ -214,30 +215,6 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
|
||||
if (!grp || grp->GetLeaderGUID() != _player->GetGUID())
|
||||
return;
|
||||
|
||||
// pussywizard: for party members - remove queues for which leader is not queued to!
|
||||
std::set<uint32> leaderQueueTypeIds;
|
||||
for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
leaderQueueTypeIds.insert((uint32)_player->GetBattlegroundQueueTypeId(i));
|
||||
for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next())
|
||||
if (Player* member = itr->GetSource())
|
||||
for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
if (BattlegroundQueueTypeId mqtid = member->GetBattlegroundQueueTypeId(i))
|
||||
if (leaderQueueTypeIds.count((uint32)mqtid) == 0)
|
||||
{
|
||||
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(mqtid);
|
||||
|
||||
if (bgQueue.IsPlayerInvitedToRatedArena(member->GetGUID()))
|
||||
{
|
||||
WorldPacket data;
|
||||
sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_JOIN_FAILED);
|
||||
SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
|
||||
bgQueue.RemovePlayer(member->GetGUID(), false, i);
|
||||
member->RemoveBattlegroundQueueId(mqtid);
|
||||
}
|
||||
|
||||
if (_player->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeIdRandom)) // queued for random bg, so can't queue for anything else
|
||||
err = ERR_IN_RANDOM_BG;
|
||||
else if (_player->InBattlegroundQueue() && bgTypeId == BATTLEGROUND_RB) // already in queue, so can't queue for random
|
||||
@@ -248,44 +225,42 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
|
||||
err = ERR_BATTLEGROUND_QUEUED_FOR_RATED;
|
||||
|
||||
if (err > 0)
|
||||
err = grp->CanJoinBattlegroundQueue(bgt, bgQueueTypeId, 0, bgt->GetMaxPlayersPerTeam(), false, 0);
|
||||
err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0);
|
||||
|
||||
bool isPremade = (grp->GetMembersCount() >= bgt->GetMinPlayersPerTeam() && bgTypeId != BATTLEGROUND_RB);
|
||||
isPremade = (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam() && bgTypeId != BATTLEGROUND_RB);
|
||||
uint32 avgWaitTime = 0;
|
||||
|
||||
if (err > 0)
|
||||
{
|
||||
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
|
||||
GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bracketEntry, false, isPremade, 0, 0, 0);
|
||||
GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0);
|
||||
avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
|
||||
}
|
||||
|
||||
WorldPacket data;
|
||||
for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next())
|
||||
grp->DoForAllMembers([bg, err, bgQueueTypeId, avgWaitTime](Player* member)
|
||||
{
|
||||
Player* member = itr->GetSource();
|
||||
if (!member)
|
||||
continue;
|
||||
WorldPacket data;
|
||||
|
||||
if (err <= 0)
|
||||
{
|
||||
sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
|
||||
member->GetSession()->SendPacket(&data);
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId);
|
||||
|
||||
// send status packet
|
||||
sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, 0, TEAM_NEUTRAL);
|
||||
sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, 0, TEAM_NEUTRAL);
|
||||
member->GetSession()->SendPacket(&data);
|
||||
|
||||
sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
|
||||
member->GetSession()->SendPacket(&data);
|
||||
|
||||
sScriptMgr->OnPlayerJoinBG(member);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
|
||||
}
|
||||
|
||||
void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket& /*recvData*/)
|
||||
@@ -373,7 +348,10 @@ void WorldSession::HandleBattlefieldListOpcode(WorldPacket& recvData)
|
||||
|
||||
BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId);
|
||||
if (!bl)
|
||||
{
|
||||
LOG_DEBUG("bg.battleground", "BattlegroundHandler: invalid bgtype ({}) with player (Name: {}, {}) received.", bgTypeId, _player->GetName(), _player->GetGUID().ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
WorldPacket data;
|
||||
sBattlegroundMgr->BuildBattlegroundListPacket(&data, ObjectGuid::Empty, _player, BattlegroundTypeId(bgTypeId), fromWhere);
|
||||
@@ -382,21 +360,27 @@ void WorldSession::HandleBattlefieldListOpcode(WorldPacket& recvData)
|
||||
|
||||
void WorldSession::HandleBattleFieldPortOpcode(WorldPacket& recvData)
|
||||
{
|
||||
uint8 arenaType; // arenatype if arena
|
||||
uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1
|
||||
uint32 bgTypeId_; // type id from dbc
|
||||
uint16 unk; // 0x1F90 constant?
|
||||
uint8 action; // enter battle 0x1, leave queue 0x0
|
||||
uint8 arenaType; // arenatype if arena
|
||||
uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1
|
||||
uint32 bgTypeId_; // type id from dbc
|
||||
uint16 unk; // 0x1F90 constant?
|
||||
uint8 action; // enter battle 0x1, leave queue 0x0
|
||||
|
||||
recvData >> arenaType >> unk2 >> bgTypeId_ >> unk >> action;
|
||||
|
||||
// bgTypeId not valid
|
||||
if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
|
||||
{
|
||||
LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Invalid BgType!", GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
|
||||
return;
|
||||
}
|
||||
|
||||
// player not in any queue, so can't really answer
|
||||
if (!_player->InBattlegroundQueue())
|
||||
{
|
||||
LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Player not in queue!", GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
|
||||
return;
|
||||
}
|
||||
|
||||
// get BattlegroundQueue for received
|
||||
BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_);
|
||||
@@ -409,20 +393,40 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket& recvData)
|
||||
// get group info from queue
|
||||
GroupQueueInfo ginfo;
|
||||
if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
|
||||
{
|
||||
LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Player not in queue (No player Group Info)!",
|
||||
GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
|
||||
return;
|
||||
}
|
||||
|
||||
// to accept, player must be invited to particular battleground id
|
||||
if (!ginfo.IsInvitedToBGInstanceGUID && action == 1)
|
||||
{
|
||||
LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Player is not invited to any bg!",
|
||||
GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
|
||||
return;
|
||||
}
|
||||
|
||||
Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID);
|
||||
|
||||
// use template if leaving queue (instance might not be created yet)
|
||||
if (!bg && action == 0)
|
||||
bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
|
||||
|
||||
Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
|
||||
if (!bg)
|
||||
return;
|
||||
{
|
||||
if (action)
|
||||
{
|
||||
LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Cant find BG with id {}!",
|
||||
GetPlayerInfo(), arenaType, unk2, bgTypeId_, action, ginfo.IsInvitedToBGInstanceGUID);
|
||||
return;
|
||||
}
|
||||
|
||||
bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
|
||||
if (!bg)
|
||||
{
|
||||
LOG_ERROR("network", "BattlegroundHandler: bg_template not found for type id {}.", bgTypeId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}.",
|
||||
GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
|
||||
|
||||
// expected bracket entry
|
||||
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel());
|
||||
@@ -439,74 +443,90 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket& recvData)
|
||||
sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS);
|
||||
SendPacket(&data);
|
||||
action = 0;
|
||||
LOG_DEBUG("bg.battleground", "Player {} {} has a deserter debuff, do not port him to battleground!", _player->GetName(), _player->GetGUID().ToString());
|
||||
}
|
||||
|
||||
if (_player->getLevel() > bg->GetMaxLevel())
|
||||
{
|
||||
LOG_ERROR("network", "Player {} {} has level ({}) higher than maxlevel ({}) of battleground ({})! Do not port him to battleground!",
|
||||
_player->GetName(), _player->GetGUID().ToString(), _player->getLevel(), bg->GetMaxLevel(), bg->GetBgTypeID());
|
||||
action = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// get player queue slot index for this bg (can be in up to 2 queues at the same time)
|
||||
uint32 queueSlot = _player->GetBattlegroundQueueIndex(bgQueueTypeId);
|
||||
|
||||
WorldPacket data;
|
||||
switch (action)
|
||||
|
||||
if (action) // accept
|
||||
{
|
||||
case 1: // accept
|
||||
// check Freeze debuff
|
||||
if (_player->HasAura(9454))
|
||||
return;
|
||||
|
||||
if (!_player->IsInvitedForBattlegroundQueueType(bgQueueTypeId))
|
||||
return; // cheating?
|
||||
|
||||
// set entry point if not in battleground
|
||||
if (!_player->InBattleground())
|
||||
_player->SetEntryPoint();
|
||||
|
||||
// resurrect the player
|
||||
if (!_player->IsAlive())
|
||||
{
|
||||
_player->ResurrectPlayer(1.0f);
|
||||
_player->SpawnCorpseBones();
|
||||
}
|
||||
|
||||
TeamId teamId = ginfo.teamId;
|
||||
|
||||
// send status packet
|
||||
sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType(), teamId);
|
||||
SendPacket(&data);
|
||||
|
||||
// remove battleground queue status from BGmgr
|
||||
bgQueue.RemovePlayer(_player->GetGUID(), false);
|
||||
|
||||
// this is still needed here if battleground "jumping" shouldn't add deserter debuff
|
||||
// also this is required to prevent stuck at old battleground after SetBattlegroundId set to new
|
||||
if (Battleground* currentBg = _player->GetBattleground())
|
||||
currentBg->RemovePlayerAtLeave(_player);
|
||||
|
||||
// Remove from LFG queues
|
||||
sLFGMgr->LeaveAllLfgQueues(_player->GetGUID(), false);
|
||||
|
||||
_player->SetBattlegroundId(bg->GetInstanceID(), bg->GetBgTypeID(), queueSlot, true, bgTypeId == BATTLEGROUND_RB, teamId);
|
||||
sBattlegroundMgr->SendToBattleground(_player, ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
|
||||
|
||||
LOG_DEBUG("bg.battleground", "Battleground: player {} {} joined battle for bg {}, bgtype {}, queue type {}.", _player->GetName(), _player->GetGUID().ToString(), bg->GetInstanceID(), bg->GetBgTypeID(), bgQueueTypeId);
|
||||
}
|
||||
else // leave queue
|
||||
{
|
||||
bgQueue.RemovePlayer(_player->GetGUID(), true);
|
||||
_player->RemoveBattlegroundQueueId(bgQueueTypeId);
|
||||
|
||||
sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0, TEAM_NEUTRAL);
|
||||
SendPacket(&data);
|
||||
|
||||
LOG_DEBUG("bg.battleground", "Battleground: player {} {} left queue for bgtype {}, queue type {}.", _player->GetName(), _player->GetGUID().ToString(), bg->GetBgTypeID(), bgQueueTypeId);
|
||||
|
||||
// player left queue, we should update it - do not update Arena Queue
|
||||
if (!ginfo.ArenaType)
|
||||
sBattlegroundMgr->ScheduleQueueUpdate(ginfo.ArenaMatchmakerRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
|
||||
|
||||
// track if player refuses to join the BG after being invited
|
||||
if (bg->isBattleground() && (bg->GetStatus() == STATUS_IN_PROGRESS || bg->GetStatus() == STATUS_WAIT_JOIN))
|
||||
{
|
||||
if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_TRACK_DESERTERS))
|
||||
{
|
||||
// set entry point if not in battleground
|
||||
if (!_player->InBattleground())
|
||||
_player->SetEntryPoint();
|
||||
|
||||
// resurrect the player
|
||||
if (!_player->IsAlive())
|
||||
{
|
||||
_player->ResurrectPlayer(1.0f);
|
||||
_player->SpawnCorpseBones();
|
||||
}
|
||||
|
||||
TeamId teamId = ginfo.teamId;
|
||||
|
||||
// remove player from all bg queues
|
||||
for (uint32 qslot = 0; qslot < PLAYER_MAX_BATTLEGROUND_QUEUES; ++qslot)
|
||||
if (BattlegroundQueueTypeId q = _player->GetBattlegroundQueueTypeId(qslot))
|
||||
{
|
||||
BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(q);
|
||||
queue.RemovePlayer(_player->GetGUID(), (bgQueueTypeId == q), qslot);
|
||||
_player->RemoveBattlegroundQueueId(q);
|
||||
}
|
||||
|
||||
// send status packet
|
||||
sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType(), teamId);
|
||||
SendPacket(&data);
|
||||
|
||||
// Remove from LFG queues
|
||||
sLFGMgr->LeaveAllLfgQueues(_player->GetGUID(), false);
|
||||
|
||||
_player->SetBattlegroundId(bg->GetInstanceID(), bg->GetBgTypeID(), queueSlot, true, bgTypeId == BATTLEGROUND_RB, teamId);
|
||||
sBattlegroundMgr->SendToBattleground(_player, ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_DESERTER_TRACK);
|
||||
stmt->SetData(0, _player->GetGUID().GetCounter());
|
||||
stmt->SetData(1, BG_DESERTION_TYPE_LEAVE_QUEUE);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
break;
|
||||
case 0: // leave queue
|
||||
{
|
||||
bgQueue.RemovePlayer(_player->GetGUID(), false, queueSlot);
|
||||
_player->RemoveBattlegroundQueueId(bgQueueTypeId);
|
||||
// track if player refuses to join the BG after being invited
|
||||
if (bg->isBattleground() && (bg->GetStatus() == STATUS_IN_PROGRESS || bg->GetStatus() == STATUS_WAIT_JOIN))
|
||||
{
|
||||
if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_TRACK_DESERTERS))
|
||||
{
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_DESERTER_TRACK);
|
||||
stmt->SetData(0, _player->GetGUID().GetCounter());
|
||||
stmt->SetData(1, BG_DESERTION_TYPE_LEAVE_QUEUE);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
sScriptMgr->OnBattlegroundDesertion(_player, BG_DESERTION_TYPE_LEAVE_QUEUE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
sScriptMgr->OnBattlegroundDesertion(_player, BG_DESERTION_TYPE_LEAVE_QUEUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,7 +582,7 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket& /*recvData*/)
|
||||
// if invited - send STATUS_WAIT_JOIN
|
||||
if (ginfo.IsInvitedToBGInstanceGUID)
|
||||
{
|
||||
Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID);
|
||||
Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
|
||||
if (!bg)
|
||||
continue;
|
||||
|
||||
@@ -591,10 +611,12 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket& /*recvData*/)
|
||||
|
||||
void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
|
||||
{
|
||||
ObjectGuid guid; // arena Battlemaster guid
|
||||
uint8 arenaslot; // 2v2, 3v3 or 5v5
|
||||
uint8 asGroup; // asGroup
|
||||
uint8 isRated; // isRated
|
||||
LOG_DEBUG("network", "WORLD: CMSG_BATTLEMASTER_JOIN_ARENA");
|
||||
|
||||
ObjectGuid guid; // arena Battlemaster guid
|
||||
uint8 arenaslot; // 2v2, 3v3 or 5v5
|
||||
uint8 asGroup; // asGroup
|
||||
uint8 isRated; // isRated
|
||||
|
||||
recvData >> guid >> arenaslot >> asGroup >> isRated;
|
||||
|
||||
@@ -602,6 +624,10 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
|
||||
if (isRated && !asGroup)
|
||||
return;
|
||||
|
||||
// ignore if we already in BG or BG queue
|
||||
if (_player->InBattleground())
|
||||
return;
|
||||
|
||||
// find creature by guid
|
||||
Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
|
||||
if (!unit || !unit->IsBattleMaster())
|
||||
@@ -609,6 +635,11 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
|
||||
|
||||
// get arena type
|
||||
uint8 arenatype = 0;
|
||||
uint32 ateamId = 0;
|
||||
uint32 arenaRating = 0;
|
||||
uint32 matchmakerRating = 0;
|
||||
uint32 previousOpponents = 0;
|
||||
|
||||
switch (arenaslot)
|
||||
{
|
||||
case 0:
|
||||
@@ -621,13 +652,17 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
|
||||
arenatype = ARENA_TYPE_5v5;
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("network", "Unknown arena slot {} at HandleBattlemasterJoinArena()", arenaslot);
|
||||
return;
|
||||
}
|
||||
|
||||
// get template for all arenas
|
||||
Battleground* bgt = sBattlegroundMgr->GetBattlegroundTemplate(BATTLEGROUND_AA);
|
||||
if (!bgt)
|
||||
{
|
||||
LOG_ERROR("network", "Battleground: template bg (all arenas) not found");
|
||||
return;
|
||||
}
|
||||
|
||||
// arenas disabled
|
||||
if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, BATTLEGROUND_AA, nullptr))
|
||||
@@ -637,32 +672,12 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
|
||||
}
|
||||
|
||||
BattlegroundTypeId bgTypeId = bgt->GetBgTypeID();
|
||||
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenatype);
|
||||
|
||||
// expected bracket entry
|
||||
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bgt->GetMapId(), _player->getLevel());
|
||||
if (!bracketEntry)
|
||||
return;
|
||||
|
||||
// pussywizard: if trying to queue for already queued
|
||||
// just remove from queue and it will requeue!
|
||||
uint32 qSlot = _player->GetBattlegroundQueueIndex(bgQueueTypeId);
|
||||
if (qSlot < PLAYER_MAX_BATTLEGROUND_QUEUES)
|
||||
{
|
||||
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
|
||||
|
||||
if (bgQueue.IsPlayerInvitedToRatedArena(_player->GetGUID()))
|
||||
{
|
||||
WorldPacket data;
|
||||
sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_JOIN_FAILED);
|
||||
SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
|
||||
bgQueue.RemovePlayer(_player->GetGUID(), false, qSlot);
|
||||
_player->RemoveBattlegroundQueueId(bgQueueTypeId);
|
||||
}
|
||||
|
||||
// must have free queue slot
|
||||
// pussywizard: allow being queued only in one arena queue, and it even cannot be together with bg queues
|
||||
if (_player->InBattlegroundQueue())
|
||||
@@ -684,6 +699,9 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
|
||||
return;
|
||||
}
|
||||
|
||||
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenatype);
|
||||
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
|
||||
|
||||
// check if player can queue:
|
||||
if (!asGroup)
|
||||
{
|
||||
@@ -705,16 +723,25 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
|
||||
return;
|
||||
}
|
||||
|
||||
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
|
||||
GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bracketEntry, false, false, 0, 0, 0);
|
||||
uint32 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
|
||||
// check if already in queue
|
||||
if (_player->GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES)
|
||||
//player is already in this queue
|
||||
return;
|
||||
|
||||
// check if has free queue slots
|
||||
if (!_player->HasFreeBattlegroundQueueId())
|
||||
return;
|
||||
|
||||
GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bgTypeId, bracketEntry, arenatype, isRated != 0, false, arenaRating, matchmakerRating, ateamId, previousOpponents);
|
||||
uint32 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
|
||||
uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId);
|
||||
|
||||
WorldPacket data;
|
||||
sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, arenatype, TEAM_NEUTRAL);
|
||||
SendPacket(&data);
|
||||
|
||||
LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena, skirmish, bg queue type {} bg type {}: {}, NAME {}", bgQueueTypeId, bgTypeId, _player->GetGUID().ToString(), _player->GetName());
|
||||
|
||||
sScriptMgr->OnPlayerJoinArena(_player);
|
||||
}
|
||||
// check if group can queue:
|
||||
@@ -725,34 +752,6 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
|
||||
if (!grp || grp->GetLeaderGUID() != _player->GetGUID())
|
||||
return;
|
||||
|
||||
// pussywizard: for party members - remove queues for which leader is not queued to!
|
||||
std::set<uint32> leaderQueueTypeIds;
|
||||
for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
leaderQueueTypeIds.insert((uint32)_player->GetBattlegroundQueueTypeId(i));
|
||||
for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next())
|
||||
if (Player* member = itr->GetSource())
|
||||
for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
if (BattlegroundQueueTypeId mqtid = member->GetBattlegroundQueueTypeId(i))
|
||||
if (leaderQueueTypeIds.count((uint32)mqtid) == 0)
|
||||
{
|
||||
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(mqtid);
|
||||
|
||||
if (bgQueue.IsPlayerInvitedToRatedArena(member->GetGUID()))
|
||||
{
|
||||
WorldPacket data;
|
||||
sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_JOIN_FAILED);
|
||||
SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
|
||||
bgQueue.RemovePlayer(member->GetGUID(), false, i);
|
||||
member->RemoveBattlegroundQueueId(mqtid);
|
||||
}
|
||||
|
||||
uint32 ateamId = 0;
|
||||
uint32 arenaRating = 0;
|
||||
uint32 matchmakerRating = 0;
|
||||
|
||||
// additional checks for rated arenas
|
||||
if (isRated)
|
||||
{
|
||||
@@ -775,15 +774,40 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
|
||||
matchmakerRating = at->GetAverageMMR(grp);
|
||||
if (arenaRating <= 0)
|
||||
arenaRating = 1;
|
||||
|
||||
previousOpponents = at->GetPreviousOpponents();
|
||||
}
|
||||
|
||||
err = grp->CanJoinBattlegroundQueue(bgt, bgQueueTypeId, arenatype, arenatype, (bool)isRated, arenaslot);
|
||||
|
||||
// Check queue group members
|
||||
if (err)
|
||||
{
|
||||
grp->DoForAllMembers([&bgQueue, &err](Player* member)
|
||||
{
|
||||
if (bgQueue.IsPlayerInvitedToRatedArena(member->GetGUID()))
|
||||
{
|
||||
err = ERR_BATTLEGROUND_JOIN_FAILED;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
uint32 avgWaitTime = 0;
|
||||
if (err > 0)
|
||||
{
|
||||
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
|
||||
GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bracketEntry, isRated, false, arenaRating, matchmakerRating, ateamId);
|
||||
LOG_DEBUG("bg.battleground", "Battleground: arena join as group start");
|
||||
|
||||
if (isRated)
|
||||
{
|
||||
LOG_DEBUG("bg.battleground", "Battleground: arena team id {}, leader {} queued with matchmaker rating {} for type {}", _player->GetArenaTeamId(arenaslot), _player->GetName(), matchmakerRating, arenatype);
|
||||
bgt->SetRated(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
bgt->SetRated(false);
|
||||
}
|
||||
|
||||
GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, isRated != 0, false, arenaRating, matchmakerRating, ateamId, previousOpponents);
|
||||
avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
|
||||
}
|
||||
|
||||
@@ -810,13 +834,13 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
|
||||
sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
|
||||
member->GetSession()->SendPacket(&data);
|
||||
|
||||
LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena as group bg queue type {} bg type {}: {}, NAME {}", bgQueueTypeId, bgTypeId, member->GetGUID().ToString(), member->GetName());
|
||||
|
||||
sScriptMgr->OnPlayerJoinArena(member);
|
||||
}
|
||||
|
||||
// pussywizard: schedule update for rated arena
|
||||
if (ateamId)
|
||||
sBattlegroundMgr->ScheduleArenaQueueUpdate(ateamId, bgQueueTypeId, bracketEntry->GetBracketId());
|
||||
}
|
||||
|
||||
sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
|
||||
}
|
||||
|
||||
void WorldSession::HandleReportPvPAFK(WorldPacket& recvData)
|
||||
|
||||
@@ -170,7 +170,7 @@ void WorldSession::HandleMoveWorldportAck()
|
||||
|
||||
if (uint32 inviteInstanceId = _player->GetPendingSpectatorInviteInstanceId())
|
||||
{
|
||||
if (Battleground* tbg = sBattlegroundMgr->GetBattleground(inviteInstanceId))
|
||||
if (Battleground* tbg = sBattlegroundMgr->GetBattleground(inviteInstanceId, BATTLEGROUND_TYPE_NONE))
|
||||
tbg->RemoveToBeTeleported(_player->GetGUID());
|
||||
_player->SetPendingSpectatorInviteInstanceId(0);
|
||||
}
|
||||
@@ -904,14 +904,14 @@ void WorldSession::ComputeNewClockDelta()
|
||||
std::vector<uint32> latencies;
|
||||
std::vector<int64> clockDeltasAfterFiltering;
|
||||
|
||||
for (auto pair : _timeSyncClockDeltaQueue.content())
|
||||
for (auto& pair : _timeSyncClockDeltaQueue.content())
|
||||
latencies.push_back(pair.second);
|
||||
|
||||
uint32 latencyMedian = median(latencies);
|
||||
uint32 latencyStandardDeviation = standard_deviation(latencies);
|
||||
|
||||
uint32 sampleSizeAfterFiltering = 0;
|
||||
for (auto pair : _timeSyncClockDeltaQueue.content())
|
||||
for (auto& pair : _timeSyncClockDeltaQueue.content())
|
||||
{
|
||||
if (pair.second <= latencyMedian + latencyStandardDeviation) {
|
||||
clockDeltasAfterFiltering.push_back(pair.first);
|
||||
|
||||
@@ -66,58 +66,41 @@ void ScriptMgr::OnBattlegroundRemovePlayerAtLeave(Battleground* bg, Player* play
|
||||
});
|
||||
}
|
||||
|
||||
void ScriptMgr::OnAddGroup(BattlegroundQueue* queue, GroupQueueInfo* ginfo, uint32& index, Player* leader, Group* grp, PvPDifficultyEntry const* bracketEntry, bool isPremade)
|
||||
void ScriptMgr::OnAddGroup(BattlegroundQueue* queue, GroupQueueInfo* ginfo, uint32& index, Player* leader, Group* group, BattlegroundTypeId bgTypeId, PvPDifficultyEntry const* bracketEntry,
|
||||
uint8 arenaType, bool isRated, bool isPremade, uint32 arenaRating, uint32 matchmakerRating, uint32 arenaTeamId, uint32 opponentsArenaTeamId)
|
||||
{
|
||||
ExecuteScript<BGScript>([&](BGScript* script)
|
||||
{
|
||||
script->OnAddGroup(queue, ginfo, index, leader, grp, bracketEntry, isPremade);
|
||||
script->OnAddGroup(queue, ginfo, index, leader, group, bgTypeId, bracketEntry,
|
||||
arenaType, isRated, isPremade, arenaRating, matchmakerRating, arenaTeamId, opponentsArenaTeamId);
|
||||
});
|
||||
}
|
||||
|
||||
bool ScriptMgr::CanFillPlayersToBG(BattlegroundQueue* queue, Battleground* bg, const int32 aliFree, const int32 hordeFree, BattlegroundBracketId bracket_id)
|
||||
bool ScriptMgr::CanFillPlayersToBG(BattlegroundQueue* queue, Battleground* bg, BattlegroundBracketId bracket_id)
|
||||
{
|
||||
auto ret = IsValidBoolScript<BGScript>([&](BGScript* script)
|
||||
{
|
||||
return !script->CanFillPlayersToBG(queue, bg, aliFree, hordeFree, bracket_id);
|
||||
return !script->CanFillPlayersToBG(queue, bg, bracket_id);
|
||||
});
|
||||
|
||||
if (ret && *ret)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return ReturnValidBool(ret);
|
||||
}
|
||||
|
||||
bool ScriptMgr::CanFillPlayersToBGWithSpecific(BattlegroundQueue* queue, Battleground* bg, const int32 aliFree, const int32 hordeFree,
|
||||
BattlegroundBracketId thisBracketId, BattlegroundQueue* specificQueue, BattlegroundBracketId specificBracketId)
|
||||
bool ScriptMgr::IsCheckNormalMatch(BattlegroundQueue* queue, Battleground* bgTemplate, BattlegroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers)
|
||||
{
|
||||
auto ret = IsValidBoolScript<BGScript>([&](BGScript* script)
|
||||
{
|
||||
return !script->CanFillPlayersToBGWithSpecific(queue, bg, aliFree, hordeFree, thisBracketId, specificQueue, specificBracketId);
|
||||
return script->IsCheckNormalMatch(queue, bgTemplate, bracket_id, minPlayers, maxPlayers);
|
||||
});
|
||||
|
||||
if (ret && *ret)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return ReturnValidBool(ret, true);
|
||||
}
|
||||
|
||||
void ScriptMgr::OnCheckNormalMatch(BattlegroundQueue* queue, uint32& Coef, Battleground* bgTemplate, BattlegroundBracketId bracket_id, uint32& minPlayers, uint32& maxPlayers)
|
||||
void ScriptMgr::OnQueueUpdate(BattlegroundQueue* queue, uint32 diff, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id, uint8 arenaType, bool isRated, uint32 arenaRating)
|
||||
{
|
||||
ExecuteScript<BGScript>([&](BGScript* script)
|
||||
{
|
||||
script->OnCheckNormalMatch(queue, Coef, bgTemplate, bracket_id, minPlayers, maxPlayers);
|
||||
});
|
||||
}
|
||||
|
||||
void ScriptMgr::OnQueueUpdate(BattlegroundQueue* queue, BattlegroundBracketId bracket_id, bool isRated, uint32 arenaRatedTeamId)
|
||||
{
|
||||
ExecuteScript<BGScript>([&](BGScript* script)
|
||||
{
|
||||
script->OnQueueUpdate(queue, bracket_id, isRated, arenaRatedTeamId);
|
||||
script->OnQueueUpdate(queue, diff, bgTypeId, bracket_id, arenaType, isRated, arenaRating);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -128,12 +111,7 @@ bool ScriptMgr::CanSendMessageBGQueue(BattlegroundQueue* queue, Player* leader,
|
||||
return !script->CanSendMessageBGQueue(queue, leader, bg, bracketEntry);
|
||||
});
|
||||
|
||||
if (ret && *ret)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return ReturnValidBool(ret);
|
||||
}
|
||||
|
||||
bool ScriptMgr::OnBeforeSendJoinMessageArenaQueue(BattlegroundQueue* queue, Player* leader, GroupQueueInfo* ginfo, PvPDifficultyEntry const* bracketEntry, bool isRated)
|
||||
@@ -143,12 +121,7 @@ bool ScriptMgr::OnBeforeSendJoinMessageArenaQueue(BattlegroundQueue* queue, Play
|
||||
return !script->OnBeforeSendJoinMessageArenaQueue(queue, leader, ginfo, bracketEntry, isRated);
|
||||
});
|
||||
|
||||
if (ret && *ret)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return ReturnValidBool(ret);
|
||||
}
|
||||
|
||||
bool ScriptMgr::OnBeforeSendExitMessageArenaQueue(BattlegroundQueue* queue, GroupQueueInfo* ginfo)
|
||||
@@ -158,12 +131,7 @@ bool ScriptMgr::OnBeforeSendExitMessageArenaQueue(BattlegroundQueue* queue, Grou
|
||||
return !script->OnBeforeSendExitMessageArenaQueue(queue, ginfo);
|
||||
});
|
||||
|
||||
if (ret && *ret)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return ReturnValidBool(ret);
|
||||
}
|
||||
|
||||
void ScriptMgr::OnBattlegroundEnd(Battleground* bg, TeamId winnerTeam)
|
||||
|
||||
@@ -1566,16 +1566,14 @@ public:
|
||||
// Remove player at leave BG
|
||||
virtual void OnBattlegroundRemovePlayerAtLeave(Battleground* /*bg*/, Player* /*player*/) { }
|
||||
|
||||
virtual void OnQueueUpdate(BattlegroundQueue* /*queue*/, BattlegroundBracketId /*bracket_id*/, bool /*isRated*/, uint32 /*arenaRatedTeamId*/) { }
|
||||
virtual void OnQueueUpdate(BattlegroundQueue* /*queue*/, uint32 /* diff */, BattlegroundTypeId /* bgTypeId */, BattlegroundBracketId /* bracket_id */, uint8 /* arenaType */, bool /* isRated */, uint32 /* arenaRating */) { }
|
||||
|
||||
virtual void OnAddGroup(BattlegroundQueue* /*queue*/, GroupQueueInfo* /*ginfo*/, uint32& /*index*/, Player* /*leader*/, Group* /*grp*/, PvPDifficultyEntry const* /*bracketEntry*/, bool /*isPremade*/) { }
|
||||
virtual void OnAddGroup(BattlegroundQueue* /*queue*/, GroupQueueInfo* /*ginfo*/, uint32& /*index*/, Player* /*leader*/, Group* /*group*/, BattlegroundTypeId /* bgTypeId */, PvPDifficultyEntry const* /* bracketEntry */,
|
||||
uint8 /* arenaType */, bool /* isRated */, bool /* isPremade */, uint32 /* arenaRating */, uint32 /* matchmakerRating */, uint32 /* arenaTeamId */, uint32 /* opponentsArenaTeamId */) { }
|
||||
|
||||
[[nodiscard]] virtual bool CanFillPlayersToBG(BattlegroundQueue* /*queue*/, Battleground* /*bg*/, const int32 /*aliFree*/, const int32 /*hordeFree*/, BattlegroundBracketId /*bracket_id*/) { return true; }
|
||||
[[nodiscard]] virtual bool CanFillPlayersToBG(BattlegroundQueue* /*queue*/, Battleground* /*bg*/, BattlegroundBracketId /*bracket_id*/) { return true; }
|
||||
|
||||
[[nodiscard]] virtual bool CanFillPlayersToBGWithSpecific(BattlegroundQueue* /*queue*/, Battleground* /*bg*/, const int32 /*aliFree*/, const int32 /*hordeFree*/,
|
||||
BattlegroundBracketId /*thisBracketId*/, BattlegroundQueue* /*specificQueue*/, BattlegroundBracketId /*specificBracketId*/) { return true; }
|
||||
|
||||
virtual void OnCheckNormalMatch(BattlegroundQueue* /*queue*/, uint32& /*Coef*/, Battleground* /*bgTemplate*/, BattlegroundBracketId /*bracket_id*/, uint32& /*minPlayers*/, uint32& /*maxPlayers*/) { }
|
||||
[[nodiscard]] virtual bool IsCheckNormalMatch(BattlegroundQueue* /*queue*/, Battleground* /*bgTemplate*/, BattlegroundBracketId /*bracket_id*/, uint32 /*minPlayers*/, uint32 /*maxPlayers*/) { return false; };
|
||||
|
||||
[[nodiscard]] virtual bool CanSendMessageBGQueue(BattlegroundQueue* /*queue*/, Player* /*leader*/, Battleground* /*bg*/, PvPDifficultyEntry const* /*bracketEntry*/) { return true; }
|
||||
|
||||
@@ -2402,12 +2400,11 @@ public: /* BGScript */
|
||||
void OnBattlegroundAddPlayer(Battleground* bg, Player* player);
|
||||
void OnBattlegroundBeforeAddPlayer(Battleground* bg, Player* player);
|
||||
void OnBattlegroundRemovePlayerAtLeave(Battleground* bg, Player* player);
|
||||
void OnQueueUpdate(BattlegroundQueue* queue, BattlegroundBracketId bracket_id, bool isRated, uint32 arenaRatedTeamId);
|
||||
void OnAddGroup(BattlegroundQueue* queue, GroupQueueInfo* ginfo, uint32& index, Player* leader, Group* grp, PvPDifficultyEntry const* bracketEntry, bool isPremade);
|
||||
bool CanFillPlayersToBG(BattlegroundQueue* queue, Battleground* bg, const int32 aliFree, const int32 hordeFree, BattlegroundBracketId bracket_id);
|
||||
bool CanFillPlayersToBGWithSpecific(BattlegroundQueue* queue, Battleground* bg, const int32 aliFree, const int32 hordeFree,
|
||||
BattlegroundBracketId thisBracketId, BattlegroundQueue* specificQueue, BattlegroundBracketId specificBracketId);
|
||||
void OnCheckNormalMatch(BattlegroundQueue* queue, uint32& Coef, Battleground* bgTemplate, BattlegroundBracketId bracket_id, uint32& minPlayers, uint32& maxPlayers);
|
||||
void OnQueueUpdate(BattlegroundQueue* queue, uint32 diff, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id, uint8 arenaType, bool isRated, uint32 arenaRating);
|
||||
void OnAddGroup(BattlegroundQueue* queue, GroupQueueInfo* ginfo, uint32& index, Player* leader, Group* group, BattlegroundTypeId bgTypeId, PvPDifficultyEntry const* bracketEntry,
|
||||
uint8 arenaType, bool isRated, bool isPremade, uint32 arenaRating, uint32 matchmakerRating, uint32 arenaTeamId, uint32 opponentsArenaTeamId);
|
||||
bool CanFillPlayersToBG(BattlegroundQueue* queue, Battleground* bg, BattlegroundBracketId bracket_id);
|
||||
bool IsCheckNormalMatch(BattlegroundQueue* queue, Battleground* bgTemplate, BattlegroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers);
|
||||
bool CanSendMessageBGQueue(BattlegroundQueue* queue, Player* leader, Battleground* bg, PvPDifficultyEntry const* bracketEntry);
|
||||
bool OnBeforeSendJoinMessageArenaQueue(BattlegroundQueue* queue, Player* leader, GroupQueueInfo* ginfo, PvPDifficultyEntry const* bracketEntry, bool isRated);
|
||||
bool OnBeforeSendExitMessageArenaQueue(BattlegroundQueue* queue, GroupQueueInfo* ginfo);
|
||||
|
||||
@@ -64,4 +64,9 @@ inline void ExecuteScript(std::function<void(ScriptName*)> executeHook)
|
||||
}
|
||||
}
|
||||
|
||||
inline bool ReturnValidBool(Optional<bool> ret, bool need = false)
|
||||
{
|
||||
return ret && *ret ? need : !need;
|
||||
}
|
||||
|
||||
#endif // _SCRIPT_MGR_MACRO_H_
|
||||
|
||||
@@ -587,8 +587,6 @@ void WorldSession::LogoutPlayer(bool save)
|
||||
for (int i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
if (BattlegroundQueueTypeId bgQueueTypeId = _player->GetBattlegroundQueueTypeId(i))
|
||||
{
|
||||
_player->RemoveBattlegroundQueueId(bgQueueTypeId);
|
||||
sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId).RemovePlayer(_player->GetGUID(), false, i);
|
||||
// track if player logs out after invited to join BG
|
||||
if (_player->IsInvitedForBattlegroundInstance())
|
||||
{
|
||||
@@ -599,8 +597,12 @@ void WorldSession::LogoutPlayer(bool save)
|
||||
stmt->SetData(1, BG_DESERTION_TYPE_INVITE_LOGOUT);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
sScriptMgr->OnBattlegroundDesertion(_player, BG_DESERTION_TYPE_INVITE_LOGOUT);
|
||||
}
|
||||
|
||||
_player->RemoveBattlegroundQueueId(bgQueueTypeId);
|
||||
sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId).RemovePlayer(_player->GetGUID(), true);
|
||||
}
|
||||
|
||||
///- If the player is in a guild, update the guild roster and broadcast a logout message to other guild members
|
||||
|
||||
@@ -307,6 +307,7 @@ enum WorldIntConfigs
|
||||
CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_LIMIT_MIN_PLAYERS,
|
||||
CONFIG_ARENA_MAX_RATING_DIFFERENCE,
|
||||
CONFIG_ARENA_RATING_DISCARD_TIMER,
|
||||
CONFIG_ARENA_PREV_OPPONENTS_DISCARD_TIMER,
|
||||
CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS,
|
||||
CONFIG_ARENA_GAMES_REQUIRED,
|
||||
CONFIG_ARENA_SEASON_ID,
|
||||
|
||||
@@ -1163,25 +1163,26 @@ void World::LoadConfigSettings(bool reload)
|
||||
m_int_configs[CONFIG_BATTLEGROUND_SPEED_BUFF_RESPAWN] = 150;
|
||||
}
|
||||
|
||||
m_int_configs[CONFIG_ARENA_MAX_RATING_DIFFERENCE] = sConfigMgr->GetOption<int32> ("Arena.MaxRatingDifference", 150);
|
||||
m_int_configs[CONFIG_ARENA_RATING_DISCARD_TIMER] = sConfigMgr->GetOption<int32> ("Arena.RatingDiscardTimer", 10 * MINUTE * IN_MILLISECONDS);
|
||||
m_int_configs[CONFIG_ARENA_MAX_RATING_DIFFERENCE] = sConfigMgr->GetOption<uint32>("Arena.MaxRatingDifference", 150);
|
||||
m_int_configs[CONFIG_ARENA_RATING_DISCARD_TIMER] = sConfigMgr->GetOption<uint32>("Arena.RatingDiscardTimer", 10 * MINUTE * IN_MILLISECONDS);
|
||||
m_int_configs[CONFIG_ARENA_PREV_OPPONENTS_DISCARD_TIMER] = sConfigMgr->GetOption<uint32>("Arena.PreviousOpponentsDiscardTimer", 2 * MINUTE * IN_MILLISECONDS);
|
||||
m_bool_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS] = sConfigMgr->GetOption<bool>("Arena.AutoDistributePoints", false);
|
||||
m_int_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS] = sConfigMgr->GetOption<int32> ("Arena.AutoDistributeInterval", 7); // pussywizard: spoiled by implementing constant day and hour, always 7 now
|
||||
m_int_configs[CONFIG_ARENA_GAMES_REQUIRED] = sConfigMgr->GetOption<int32> ("Arena.GamesRequired", 10);
|
||||
m_int_configs[CONFIG_ARENA_SEASON_ID] = sConfigMgr->GetOption<int32> ("Arena.ArenaSeason.ID", 1);
|
||||
m_int_configs[CONFIG_ARENA_START_RATING] = sConfigMgr->GetOption<int32> ("Arena.ArenaStartRating", 0);
|
||||
m_int_configs[CONFIG_ARENA_START_PERSONAL_RATING] = sConfigMgr->GetOption<int32> ("Arena.ArenaStartPersonalRating", 1000);
|
||||
m_int_configs[CONFIG_ARENA_START_MATCHMAKER_RATING] = sConfigMgr->GetOption<int32> ("Arena.ArenaStartMatchmakerRating", 1500);
|
||||
m_int_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS] = sConfigMgr->GetOption<uint32>("Arena.AutoDistributeInterval", 7); // pussywizard: spoiled by implementing constant day and hour, always 7 now
|
||||
m_int_configs[CONFIG_ARENA_GAMES_REQUIRED] = sConfigMgr->GetOption<uint32>("Arena.GamesRequired", 10);
|
||||
m_int_configs[CONFIG_ARENA_SEASON_ID] = sConfigMgr->GetOption<uint32>("Arena.ArenaSeason.ID", 1);
|
||||
m_int_configs[CONFIG_ARENA_START_RATING] = sConfigMgr->GetOption<uint32>("Arena.ArenaStartRating", 0);
|
||||
m_int_configs[CONFIG_ARENA_START_PERSONAL_RATING] = sConfigMgr->GetOption<uint32>("Arena.ArenaStartPersonalRating", 1000);
|
||||
m_int_configs[CONFIG_ARENA_START_MATCHMAKER_RATING] = sConfigMgr->GetOption<uint32>("Arena.ArenaStartMatchmakerRating", 1500);
|
||||
m_bool_configs[CONFIG_ARENA_SEASON_IN_PROGRESS] = sConfigMgr->GetOption<bool>("Arena.ArenaSeason.InProgress", true);
|
||||
m_float_configs[CONFIG_ARENA_WIN_RATING_MODIFIER_1] = sConfigMgr->GetOption<float>("Arena.ArenaWinRatingModifier1", 48.0f);
|
||||
m_float_configs[CONFIG_ARENA_WIN_RATING_MODIFIER_2] = sConfigMgr->GetOption<float>("Arena.ArenaWinRatingModifier2", 24.0f);
|
||||
m_float_configs[CONFIG_ARENA_LOSE_RATING_MODIFIER] = sConfigMgr->GetOption<float>("Arena.ArenaLoseRatingModifier", 24.0f);
|
||||
m_float_configs[CONFIG_ARENA_MATCHMAKER_RATING_MODIFIER] = sConfigMgr->GetOption<float>("Arena.ArenaMatchmakerRatingModifier", 24.0f);
|
||||
m_bool_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE] = sConfigMgr->GetOption<bool> ("Arena.QueueAnnouncer.Enable", false);
|
||||
m_bool_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_PLAYERONLY] = sConfigMgr->GetOption<bool> ("Arena.QueueAnnouncer.PlayerOnly", false);
|
||||
m_bool_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE] = sConfigMgr->GetOption<bool>("Arena.QueueAnnouncer.Enable", false);
|
||||
m_bool_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_PLAYERONLY] = sConfigMgr->GetOption<bool>("Arena.QueueAnnouncer.PlayerOnly", false);
|
||||
|
||||
m_bool_configs[CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN] = sConfigMgr->GetOption<bool>("OffhandCheckAtSpellUnlearn", true);
|
||||
m_int_configs[CONFIG_CREATURE_STOP_FOR_PLAYER] = sConfigMgr->GetOption<int32>("Creature.MovingStopTimeForPlayer", 3 * MINUTE * IN_MILLISECONDS);
|
||||
m_int_configs[CONFIG_CREATURE_STOP_FOR_PLAYER] = sConfigMgr->GetOption<uint32>("Creature.MovingStopTimeForPlayer", 3 * MINUTE * IN_MILLISECONDS);
|
||||
|
||||
if (int32 clientCacheId = sConfigMgr->GetOption<int32>("ClientCacheVersion", 0))
|
||||
{
|
||||
@@ -2046,7 +2047,7 @@ void World::SetInitialWorldSettings()
|
||||
|
||||
///- Initialize Battlegrounds
|
||||
LOG_INFO("server.loading", "Starting Battleground System");
|
||||
sBattlegroundMgr->CreateInitialBattlegrounds();
|
||||
sBattlegroundMgr->LoadBattlegroundTemplates();
|
||||
sBattlegroundMgr->InitAutomaticArenaPointDistribution();
|
||||
|
||||
///- Initialize outdoor pvp
|
||||
|
||||
@@ -412,7 +412,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
Battleground* bg = sBattlegroundMgr->CreateNewBattleground(randomizedArenaBgTypeId, 80, 80, ArenaType(hcnt >= 2 ? hcnt : 2), false);
|
||||
Battleground* bg = sBattlegroundMgr->CreateNewBattleground(randomizedArenaBgTypeId, GetBattlegroundBracketById(bgt->GetMapId(), bgt->GetBracketId()), ArenaType(hcnt >= 2 ? hcnt : 2), false);
|
||||
if (!bg)
|
||||
{
|
||||
handler->PSendSysMessage("Couldn't create arena map!");
|
||||
|
||||
@@ -215,7 +215,7 @@ public:
|
||||
static bool HandleReloadBattlegroundTemplate(ChatHandler* handler)
|
||||
{
|
||||
LOG_INFO("server.loading", "Re-Loading Battleground Templates...");
|
||||
sBattlegroundMgr->CreateInitialBattlegrounds();
|
||||
sBattlegroundMgr->LoadBattlegroundTemplates();
|
||||
handler->SendGlobalGMSysMessage("DB table `battleground_template` reloaded.");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2923,6 +2923,14 @@ Arena.MaxRatingDifference = 150
|
||||
|
||||
Arena.RatingDiscardTimer = 600000
|
||||
|
||||
#
|
||||
# Arena.PreviousOpponentsDiscardTimer
|
||||
# Description: Time (in milliseconds) after which the previous opponents will be ignored.
|
||||
# Default: 120000 - (Enabled, 2 minutes - Blizzlike)
|
||||
# 0 - (Disabled)
|
||||
|
||||
Arena.PreviousOpponentsDiscardTimer = 120000
|
||||
|
||||
#
|
||||
# Arena.AutoDistributePoints
|
||||
# Description: Automatically distribute arena points.
|
||||
|
||||
Reference in New Issue
Block a user