aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Battlegrounds/Battleground.cpp90
-rw-r--r--src/server/game/Battlegrounds/Battleground.h15
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.cpp223
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.h39
-rw-r--r--src/server/game/Battlegrounds/BattlegroundQueue.cpp45
-rw-r--r--src/server/game/Battlegrounds/BattlegroundQueue.h11
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp123
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundEY.h44
-rw-r--r--src/server/game/Entities/Player/Player.cpp4
-rw-r--r--src/server/game/Groups/Group.cpp8
-rw-r--r--src/server/game/Handlers/BattleGroundHandler.cpp90
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h64
-rw-r--r--src/server/game/Server/Packets/BattlegroundPackets.cpp53
-rw-r--r--src/server/game/Server/Packets/BattlegroundPackets.h53
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp4
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h6
-rw-r--r--src/server/game/Server/WorldSession.cpp3
17 files changed, 518 insertions, 357 deletions
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index 3296726efa8..46529667602 100644
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -467,16 +467,9 @@ inline void Battleground::_ProcessJoin(uint32 diff)
{
/// @todo add arena sound PlaySoundToAll(SOUND_ARENA_START);
for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
+ {
if (Player* player = ObjectAccessor::FindPlayer(itr->first))
{
- // BG Status packet
- BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
- uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId);
-
- WorldPackets::Battleground::BattlefieldStatusActive battlefieldStatus;
- sBattlegroundMgr->BuildBattlegroundStatusActive(&battlefieldStatus, this, player, queueSlot, player->GetBattlegroundQueueJoinTime(bgQueueTypeId), GetArenaType());
- player->SendDirectMessage(battlefieldStatus.Write());
-
// Correctly display EnemyUnitFrame
player->SetArenaFaction(player->GetBGTeam());
@@ -496,6 +489,7 @@ inline void Battleground::_ProcessJoin(uint32 diff)
});
}
}
+ }
CheckWinConditions();
}
@@ -504,11 +498,13 @@ inline void Battleground::_ProcessJoin(uint32 diff)
PlaySoundToAll(SOUND_BG_START);
for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
+ {
if (Player* player = ObjectAccessor::FindPlayer(itr->first))
{
player->RemoveAurasDueToSpell(SPELL_PREPARATION);
player->ResetAllPowers();
}
+ }
// Announce BG starting
if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE))
sWorld->SendWorldText(LANG_BG_STARTED_ANNOUNCE_WORLD, GetName(), GetMinLevel(), GetMaxLevel());
@@ -734,10 +730,14 @@ void Battleground::EndBattleground(uint32 winner)
//we must set it this way, because end time is sent in packet!
SetRemainingTime(TIME_AUTOCLOSE_BATTLEGROUND);
- WorldPackets::Battleground::PVPLogData pvpLogData;
- BuildPvPLogDataPacket(pvpLogData);
+ WorldPackets::Battleground::PVPMatchEnd pvpMatchEnd;
+ pvpMatchEnd.Winner = GetWinner();
+ pvpMatchEnd.Duration = std::max<int32>(0, (GetElapsedTime() - BG_START_DELAY_2M) / IN_MILLISECONDS);
+ pvpMatchEnd.LogData.emplace();
+ BuildPvPLogDataPacket(*pvpMatchEnd.LogData);
+ pvpMatchEnd.Write();
- BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
+ BattlegroundQueueTypeId bgQueueTypeId = GetQueueId();
for (BattlegroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
@@ -832,11 +832,7 @@ void Battleground::EndBattleground(uint32 winner)
BlockMovement(player);
- player->SendDirectMessage(pvpLogData.Write());
-
- WorldPackets::Battleground::BattlefieldStatusActive battlefieldStatus;
- sBattlegroundMgr->BuildBattlegroundStatusActive(&battlefieldStatus, this, player, player->GetBattlegroundQueueIndex(bgQueueTypeId), player->GetBattlegroundQueueJoinTime(bgQueueTypeId), GetArenaType());
- player->SendDirectMessage(battlefieldStatus.Write());
+ player->SendDirectMessage(pvpMatchEnd.GetRawPacket());
player->UpdateCriteria(CRITERIA_TYPE_COMPLETE_BATTLEGROUND, player->GetMapId());
}
@@ -907,7 +903,7 @@ void Battleground::RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool Sen
RemovePlayer(player, guid, team); // BG subclass specific code
BattlegroundTypeId bgTypeId = GetTypeID();
- BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
+ BattlegroundQueueTypeId bgQueueTypeId = GetQueueId();
if (participant) // if the player was a match participant, remove auras, calc rating, update queue
{
@@ -948,7 +944,7 @@ void Battleground::RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool Sen
{
// a player has left the battleground, so there are free slots -> add to queue
AddToBGFreeSlotQueue();
- sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, GetBracketId());
+ sBattlegroundMgr->ScheduleQueueUpdate(0, bgQueueTypeId, GetBracketId());
}
// Let others know
@@ -1050,12 +1046,39 @@ void Battleground::AddPlayer(Player* player)
SendPacketToTeam(team, playerJoined.Write(), player);
// BG Status packet
- BattlegroundQueueTypeId bgQueueTypeId = sBattlegroundMgr->BGQueueTypeId(GetTypeID(), GetArenaType());
+ BattlegroundQueueTypeId bgQueueTypeId = GetQueueId();
uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId);
- WorldPackets::Battleground::BattlefieldStatusActive battlefieldStatus;
- sBattlegroundMgr->BuildBattlegroundStatusActive(&battlefieldStatus, this, player, queueSlot, player->GetBattlegroundQueueJoinTime(bgQueueTypeId), GetArenaType());
- player->SendDirectMessage(battlefieldStatus.Write());
+ WorldPackets::Battleground::PVPMatchInit pvpMatchState;
+ pvpMatchState.MapID = GetMapId();
+ switch (GetStatus())
+ {
+ case STATUS_NONE:
+ case STATUS_WAIT_QUEUE:
+ pvpMatchState.State = WorldPackets::Battleground::PVPMatchInit::Inactive;
+ break;
+ case STATUS_WAIT_JOIN:
+ case STATUS_IN_PROGRESS:
+ pvpMatchState.State = WorldPackets::Battleground::PVPMatchInit::InProgress;
+ break;
+ case STATUS_WAIT_LEAVE:
+ pvpMatchState.State = WorldPackets::Battleground::PVPMatchInit::Complete;
+ break;
+ default:
+ break;
+ }
+
+ if (GetElapsedTime() >= BG_START_DELAY_2M)
+ {
+ pvpMatchState.Duration = (GetElapsedTime() - BG_START_DELAY_2M) / IN_MILLISECONDS;
+ pvpMatchState.StartTime = GameTime::GetGameTime() - pvpMatchState.Duration;
+ }
+ pvpMatchState.ArenaFaction = player->GetBGTeam() == HORDE ? BG_TEAM_HORDE : BG_TEAM_ALLIANCE;
+ pvpMatchState.BattlemasterListID = GetTypeID();
+ pvpMatchState.Registered = false;
+ pvpMatchState.AffectsRating = isRated();
+
+ player->SendDirectMessage(pvpMatchState.Write());
player->RemoveAurasByType(SPELL_AURA_MOUNTED);
@@ -1173,7 +1196,7 @@ void Battleground::AddToBGFreeSlotQueue()
{
if (!m_InBGFreeSlotQueue && isBattleground())
{
- sBattlegroundMgr->AddToBGFreeSlotQueue(GetTypeID(), this);
+ sBattlegroundMgr->AddToBGFreeSlotQueue(GetQueueId(), this);
m_InBGFreeSlotQueue = true;
}
}
@@ -1183,7 +1206,7 @@ void Battleground::RemoveFromBGFreeSlotQueue()
{
if (m_InBGFreeSlotQueue)
{
- sBattlegroundMgr->RemoveFromBGFreeSlotQueue(GetTypeID(), m_InstanceID);
+ sBattlegroundMgr->RemoveFromBGFreeSlotQueue(GetQueueId(), m_InstanceID);
m_InBGFreeSlotQueue = false;
}
}
@@ -1764,17 +1787,13 @@ void Battleground::PlayerAddedToBGCheckIfBGIsRunning(Player* player)
if (GetStatus() != STATUS_WAIT_LEAVE)
return;
- WorldPackets::Battleground::PVPLogData pvpLogData;
- BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
+ BattlegroundQueueTypeId bgQueueTypeId = GetQueueId();
BlockMovement(player);
- BuildPvPLogDataPacket(pvpLogData);
+ WorldPackets::Battleground::PVPLogDataMessage pvpLogData;
+ BuildPvPLogDataPacket(pvpLogData.Data);
player->SendDirectMessage(pvpLogData.Write());
-
- WorldPackets::Battleground::BattlefieldStatusActive battlefieldStatus;
- sBattlegroundMgr->BuildBattlegroundStatusActive(&battlefieldStatus, this, player, player->GetBattlegroundQueueIndex(bgQueueTypeId), player->GetBattlegroundQueueJoinTime(bgQueueTypeId), GetArenaType());
- player->SendDirectMessage(battlefieldStatus.Write());
}
uint32 Battleground::GetAlivePlayersCountByTeam(uint32 Team) const
@@ -1866,15 +1885,6 @@ char const* Battleground::GetName() const
return _battlegroundTemplate->BattlemasterEntry->Name->Str[sWorld->GetDefaultDbcLocale()];
}
-uint64 Battleground::GetQueueId() const
-{
- BattlegroundQueueIdType type = BattlegroundQueueIdType::Battleground;
- if (isArena())
- type = isRated() ? BattlegroundQueueIdType::Arena : BattlegroundQueueIdType::ArenaSkirmish;
-
- return uint64(_battlegroundTemplate->Id) | uint64(type) << 16 | UI64LIT(0x1F10000000000000);
-}
-
BattlegroundTypeId Battleground::GetTypeID(bool getRandom) const
{
return getRandom ? m_RandomTypeID : _battlegroundTemplate->Id;
diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
index e0c5083e429..ba92d3aa526 100644
--- a/src/server/game/Battlegrounds/Battleground.h
+++ b/src/server/game/Battlegrounds/Battleground.h
@@ -42,7 +42,7 @@ namespace WorldPackets
{
namespace Battleground
{
- class PVPLogData;
+ struct PVPLogData;
struct BattlegroundPlayerPosition;
}
@@ -239,6 +239,15 @@ enum class BattlegroundQueueIdType : uint8
ArenaSkirmish = 4
};
+enum class BattlegroundPointCaptureStatus
+{
+ AllianceControlled,
+ AllianceCapturing,
+ Neutral,
+ HordeCapturing,
+ HordeControlled
+};
+
/*
This class is used to:
1. Add player to battleground
@@ -273,7 +282,7 @@ class TC_GAME_API Battleground
/* Battleground */
// Get methods:
char const* GetName() const;
- uint64 GetQueueId() const;
+ BattlegroundQueueTypeId GetQueueId() const { return m_queueId; }
BattlegroundTypeId GetTypeID(bool getRandom = false) const;
BattlegroundBracketId GetBracketId() const;
uint32 GetInstanceID() const { return m_InstanceID; }
@@ -299,6 +308,7 @@ class TC_GAME_API Battleground
bool IsRandom() const { return m_IsRandom; }
// Set methods:
+ void SetQueueId(BattlegroundQueueTypeId queueId) { m_queueId = queueId; }
void SetRandomTypeID(BattlegroundTypeId TypeID) { m_RandomTypeID = TypeID; }
//here we can count minlevel and maxlevel for players
void SetBracket(PVPDifficultyEntry const* bracketEntry);
@@ -565,6 +575,7 @@ class TC_GAME_API Battleground
private:
// Battleground
+ BattlegroundQueueTypeId m_queueId;
BattlegroundTypeId m_RandomTypeID;
uint32 m_InstanceID; // Battleground Instance's GUID!
BattlegroundStatus m_Status;
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
index 2556ac012c3..311770bcdd1 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
@@ -94,13 +94,17 @@ void BattlegroundMgr::DeleteAllBattlegrounds()
while (!data.m_Battlegrounds.empty())
delete data.m_Battlegrounds.begin()->second;
- data.m_Battlegrounds.clear();
- while (!data.BGFreeSlotQueue.empty())
- delete data.BGFreeSlotQueue.front();
+ data.m_Battlegrounds.clear();
}
bgDataStore.clear();
+
+ for (auto itr = m_BGFreeSlotQueue.begin(); itr != m_BGFreeSlotQueue.end(); ++itr)
+ while (!itr->second.empty())
+ delete itr->second.front();
+
+ m_BGFreeSlotQueue.clear();
}
BattlegroundMgr* BattlegroundMgr::instance()
@@ -143,23 +147,21 @@ void BattlegroundMgr::Update(uint32 diff)
}
// update events timer
- for (int qtype = BATTLEGROUND_QUEUE_NONE; qtype < MAX_BATTLEGROUND_QUEUE_TYPES; ++qtype)
- m_BattlegroundQueues[qtype].UpdateEvents(diff);
+ for (std::pair<BattlegroundQueueTypeId const, BattlegroundQueue>& pair : m_BattlegroundQueues)
+ pair.second.UpdateEvents(diff);
// update scheduled queues
if (!m_QueueUpdateScheduler.empty())
{
- std::vector<uint64> scheduled;
+ std::vector<ScheduledQueueUpdate> scheduled;
std::swap(scheduled, m_QueueUpdateScheduler);
for (uint8 i = 0; i < scheduled.size(); i++)
{
- 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, bgTypeId, bracket_id, arenaType, arenaMMRating > 0, arenaMMRating);
+ uint32 arenaMMRating = scheduled[i].ArenaMatchmakerRating;
+ BattlegroundQueueTypeId bgQueueTypeId = scheduled[i].QueueId;
+ BattlegroundBracketId bracket_id = scheduled[i].BracketId;
+ GetBattlegroundQueue(bgQueueTypeId).BattlegroundQueueUpdate(diff, bracket_id, arenaMMRating);
}
}
@@ -171,11 +173,12 @@ void BattlegroundMgr::Update(uint32 diff)
{
// forced update for rated arenas (scan all, but skipped non rated)
TC_LOG_TRACE("bg.arena", "BattlegroundMgr: UPDATING ARENA QUEUES");
- for (int qtype = BATTLEGROUND_QUEUE_2v2; qtype <= BATTLEGROUND_QUEUE_5v5; ++qtype)
+ for (uint8 teamSize : { ARENA_TYPE_2v2, ARENA_TYPE_3v3, ARENA_TYPE_5v5 })
+ {
+ BattlegroundQueueTypeId ratedArenaQueueId = BGQueueTypeId(BATTLEGROUND_AA, BattlegroundQueueIdType::Arena, true, teamSize);
for (int bracket = BG_BRACKET_ID_FIRST; bracket < MAX_BATTLEGROUND_BRACKETS; ++bracket)
- m_BattlegroundQueues[qtype].BattlegroundQueueUpdate(diff,
- BATTLEGROUND_AA, BattlegroundBracketId(bracket),
- BattlegroundMgr::BGArenaType(BattlegroundQueueTypeId(qtype)), true, 0);
+ GetBattlegroundQueue(ratedArenaQueueId).BattlegroundQueueUpdate(diff, BattlegroundBracketId(bracket), 0);
+ }
m_NextRatedArenaUpdate = sWorld->getIntConfig(CONFIG_ARENA_RATED_UPDATE_TIMER);
}
@@ -184,13 +187,13 @@ void BattlegroundMgr::Update(uint32 diff)
}
}
-void BattlegroundMgr::BuildBattlegroundStatusHeader(WorldPackets::Battleground::BattlefieldStatusHeader* header, Battleground* bg, Player* player, uint32 ticketId, uint32 joinTime, uint32 arenaType)
+void BattlegroundMgr::BuildBattlegroundStatusHeader(WorldPackets::Battleground::BattlefieldStatusHeader* header, Battleground* bg, Player* player, uint32 ticketId, uint32 joinTime, BattlegroundQueueTypeId queueId, uint32 arenaType)
{
header->Ticket.RequesterGuid = player->GetGUID();
header->Ticket.Id = ticketId;
header->Ticket.Type = WorldPackets::LFG::RideType::Battlegrounds;
header->Ticket.Time = joinTime;
- header->QueueID.push_back(bg->GetQueueId());
+ header->QueueID.push_back(queueId.GetPacked());
header->RangeMin = bg->GetMinLevel();
header->RangeMax = bg->GetMaxLevel();
header->TeamSize = bg->isArena() ? arenaType : 0;
@@ -209,7 +212,7 @@ void BattlegroundMgr::BuildBattlegroundStatusNone(WorldPackets::Battleground::Ba
void BattlegroundMgr::BuildBattlegroundStatusNeedConfirmation(WorldPackets::Battleground::BattlefieldStatusNeedConfirmation* battlefieldStatus, Battleground* bg, Player* player, uint32 ticketId, uint32 joinTime, uint32 timeout, uint32 arenaType)
{
- BuildBattlegroundStatusHeader(&battlefieldStatus->Hdr, bg, player, ticketId, joinTime, arenaType);
+ BuildBattlegroundStatusHeader(&battlefieldStatus->Hdr, bg, player, ticketId, joinTime, bg->GetQueueId(), arenaType);
battlefieldStatus->Mapid = bg->GetMapId();
battlefieldStatus->Timeout = timeout;
battlefieldStatus->Role = 0;
@@ -217,7 +220,7 @@ void BattlegroundMgr::BuildBattlegroundStatusNeedConfirmation(WorldPackets::Batt
void BattlegroundMgr::BuildBattlegroundStatusActive(WorldPackets::Battleground::BattlefieldStatusActive* battlefieldStatus, Battleground* bg, Player* player, uint32 ticketId, uint32 joinTime, uint32 arenaType)
{
- BuildBattlegroundStatusHeader(&battlefieldStatus->Hdr, bg, player, ticketId, joinTime, arenaType);
+ BuildBattlegroundStatusHeader(&battlefieldStatus->Hdr, bg, player, ticketId, joinTime, bg->GetQueueId(), arenaType);
battlefieldStatus->ShutdownTimer = bg->GetRemainingTime();
battlefieldStatus->ArenaFaction = player->GetBGTeam() == HORDE ? BG_TEAM_HORDE : BG_TEAM_ALLIANCE;
battlefieldStatus->LeftEarly = false;
@@ -225,9 +228,9 @@ void BattlegroundMgr::BuildBattlegroundStatusActive(WorldPackets::Battleground::
battlefieldStatus->Mapid = bg->GetMapId();
}
-void BattlegroundMgr::BuildBattlegroundStatusQueued(WorldPackets::Battleground::BattlefieldStatusQueued* battlefieldStatus, Battleground* bg, Player* player, uint32 ticketId, uint32 joinTime, uint32 avgWaitTime, uint32 arenaType, bool asGroup)
+void BattlegroundMgr::BuildBattlegroundStatusQueued(WorldPackets::Battleground::BattlefieldStatusQueued* battlefieldStatus, Battleground* bg, Player* player, uint32 ticketId, uint32 joinTime, BattlegroundQueueTypeId queueId, uint32 avgWaitTime, uint32 arenaType, bool asGroup)
{
- BuildBattlegroundStatusHeader(&battlefieldStatus->Hdr, bg, player, ticketId, joinTime, arenaType);
+ BuildBattlegroundStatusHeader(&battlefieldStatus->Hdr, bg, player, ticketId, joinTime, queueId, arenaType);
battlefieldStatus->AverageWaitTime = avgWaitTime;
battlefieldStatus->AsGroup = asGroup;
battlefieldStatus->SuspendedQueue = false;
@@ -240,8 +243,8 @@ void BattlegroundMgr::BuildBattlegroundStatusFailed(WorldPackets::Battleground::
battlefieldStatus->Ticket.RequesterGuid = pPlayer->GetGUID();
battlefieldStatus->Ticket.Id = ticketId;
battlefieldStatus->Ticket.Type = WorldPackets::LFG::RideType::Battlegrounds;
- battlefieldStatus->Ticket.Time = pPlayer->GetBattlegroundQueueJoinTime(BGQueueTypeId(bg->GetTypeID(), arenaType));
- battlefieldStatus->QueueID = bg->GetQueueId();
+ battlefieldStatus->Ticket.Time = pPlayer->GetBattlegroundQueueJoinTime(bg->GetQueueId());
+ battlefieldStatus->QueueID = bg->GetQueueId().GetPacked();
battlefieldStatus->Reason = result;
if (errorGuid && (result == ERR_BATTLEGROUND_NOT_IN_BATTLEGROUND || result == ERR_BATTLEGROUND_JOIN_TIMED_OUT))
battlefieldStatus->ClientID = *errorGuid;
@@ -254,7 +257,7 @@ Battleground* BattlegroundMgr::GetBattleground(uint32 instanceId, BattlegroundTy
BattlegroundDataContainer::const_iterator begin, end;
- if (bgTypeId == BATTLEGROUND_TYPE_NONE)
+ if (bgTypeId == BATTLEGROUND_TYPE_NONE || bgTypeId == BATTLEGROUND_RB || bgTypeId == BATTLEGROUND_RANDOM_EPIC)
{
begin = bgDataStore.begin();
end = bgDataStore.end();
@@ -315,9 +318,9 @@ uint32 BattlegroundMgr::CreateClientVisibleInstanceId(BattlegroundTypeId bgTypeI
}
// create a new battleground that will really be used to play
-Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId originalBgTypeId, PVPDifficultyEntry const* bracketEntry, uint8 arenaType, bool isRated)
+Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundQueueTypeId queueId, PVPDifficultyEntry const* bracketEntry)
{
- BattlegroundTypeId bgTypeId = GetRandomBG(originalBgTypeId);
+ BattlegroundTypeId bgTypeId = GetRandomBG(BattlegroundTypeId(queueId.BattlemasterListId));
// get the template BG
Battleground* bg_template = GetBattlegroundTemplate(bgTypeId);
@@ -373,20 +376,22 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId original
break;
case BATTLEGROUND_RB:
case BATTLEGROUND_AA:
+ case BATTLEGROUND_RANDOM_EPIC:
default:
return NULL;
}
- bool isRandom = bgTypeId != originalBgTypeId && !bg->isArena();
+ bool isRandom = bgTypeId != BattlegroundTypeId(queueId.BattlemasterListId) && !bg->isArena();
+ bg->SetQueueId(queueId);
bg->SetBracket(bracketEntry);
bg->SetInstanceID(sMapMgr->GenerateInstanceId());
- bg->SetClientInstanceID(CreateClientVisibleInstanceId(originalBgTypeId, bracketEntry->GetBracketId()));
+ bg->SetClientInstanceID(CreateClientVisibleInstanceId(BattlegroundTypeId(queueId.BattlemasterListId), bracketEntry->GetBracketId()));
bg->Reset(); // reset the new bg (set status to status_wait_queue from status_none)
bg->SetStatus(STATUS_WAIT_JOIN); // start the joining of the bg
- bg->SetArenaType(arenaType);
+ bg->SetArenaType(queueId.TeamSize);
bg->SetRandomTypeID(bgTypeId);
- bg->SetRated(isRated);
+ bg->SetRated(queueId.Rated);
bg->SetRandom(isRandom);
return bg;
@@ -447,6 +452,10 @@ bool BattlegroundMgr::CreateBattleground(BattlegroundTemplate const* bgTemplate)
case BATTLEGROUND_BFG:
bg = new BattlegroundBFG(bgTemplate);
break;
+ case BATTLEGROUND_RANDOM_EPIC:
+ bg = new Battleground(bgTemplate);
+ bg->SetRandom(true);
+ break;
default:
return false;
}
@@ -455,10 +464,6 @@ bool BattlegroundMgr::CreateBattleground(BattlegroundTemplate const* bgTemplate)
AddBattleground(bg);
}
- bg->SetInstanceID(0);
-
- AddBattleground(bg);
-
return true;
}
@@ -501,7 +506,7 @@ void BattlegroundMgr::LoadBattlegroundTemplates()
bgTemplate.ScriptId = sObjectMgr->GetScriptId(fields[5].GetString());
bgTemplate.BattlemasterEntry = bl;
- if (bgTemplate.Id != BATTLEGROUND_AA && bgTemplate.Id != BATTLEGROUND_RB)
+ if (bgTemplate.Id != BATTLEGROUND_AA && bgTemplate.Id != BATTLEGROUND_RB && bgTemplate.Id != BATTLEGROUND_RANDOM_EPIC)
{
uint32 startId = fields[1].GetUInt32();
if (WorldSafeLocsEntry const* start = sObjectMgr->GetWorldSafeLoc(startId))
@@ -598,94 +603,9 @@ bool BattlegroundMgr::IsArenaType(BattlegroundTypeId bgTypeId)
|| bgTypeId == BATTLEGROUND_RL;
}
-BattlegroundQueueTypeId BattlegroundMgr::BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 arenaType)
-{
- switch (bgTypeId)
- {
- case BATTLEGROUND_AB:
- return BATTLEGROUND_QUEUE_AB;
- case BATTLEGROUND_AV:
- return BATTLEGROUND_QUEUE_AV;
- case BATTLEGROUND_EY:
- return BATTLEGROUND_QUEUE_EY;
- case BATTLEGROUND_IC:
- return BATTLEGROUND_QUEUE_IC;
- case BATTLEGROUND_TP:
- return BATTLEGROUND_QUEUE_TP;
- case BATTLEGROUND_BFG:
- return BATTLEGROUND_QUEUE_BFG;
- case BATTLEGROUND_RB:
- return BATTLEGROUND_QUEUE_RB;
- case BATTLEGROUND_SA:
- return BATTLEGROUND_QUEUE_SA;
- case BATTLEGROUND_WS:
- return BATTLEGROUND_QUEUE_WS;
- case BATTLEGROUND_AA:
- case BATTLEGROUND_BE:
- case BATTLEGROUND_DS:
- case BATTLEGROUND_NA:
- case BATTLEGROUND_RL:
- case BATTLEGROUND_RV:
- switch (arenaType)
- {
- case ARENA_TYPE_2v2:
- return BATTLEGROUND_QUEUE_2v2;
- case ARENA_TYPE_3v3:
- return BATTLEGROUND_QUEUE_3v3;
- case ARENA_TYPE_5v5:
- return BATTLEGROUND_QUEUE_5v5;
- default:
- return BATTLEGROUND_QUEUE_NONE;
- }
- default:
- return BATTLEGROUND_QUEUE_NONE;
- }
-}
-
-BattlegroundTypeId BattlegroundMgr::BGTemplateId(BattlegroundQueueTypeId bgQueueTypeId)
+BattlegroundQueueTypeId BattlegroundMgr::BGQueueTypeId(uint16 battlemasterListId, BattlegroundQueueIdType type, bool rated, uint8 teamSize)
{
- switch (bgQueueTypeId)
- {
- case BATTLEGROUND_QUEUE_WS:
- return BATTLEGROUND_WS;
- case BATTLEGROUND_QUEUE_AB:
- return BATTLEGROUND_AB;
- case BATTLEGROUND_QUEUE_AV:
- return BATTLEGROUND_AV;
- case BATTLEGROUND_QUEUE_EY:
- return BATTLEGROUND_EY;
- case BATTLEGROUND_QUEUE_SA:
- return BATTLEGROUND_SA;
- case BATTLEGROUND_QUEUE_IC:
- return BATTLEGROUND_IC;
- case BATTLEGROUND_QUEUE_TP:
- return BATTLEGROUND_TP;
- case BATTLEGROUND_QUEUE_BFG:
- return BATTLEGROUND_BFG;
- case BATTLEGROUND_QUEUE_RB:
- return BATTLEGROUND_RB;
- case BATTLEGROUND_QUEUE_2v2:
- case BATTLEGROUND_QUEUE_3v3:
- case BATTLEGROUND_QUEUE_5v5:
- return BATTLEGROUND_AA;
- default:
- return BattlegroundTypeId(0); // used for unknown template (it exists and does nothing)
- }
-}
-
-uint8 BattlegroundMgr::BGArenaType(BattlegroundQueueTypeId bgQueueTypeId)
-{
- switch (bgQueueTypeId)
- {
- case BATTLEGROUND_QUEUE_2v2:
- return ARENA_TYPE_2v2;
- case BATTLEGROUND_QUEUE_3v3:
- return ARENA_TYPE_3v3;
- case BATTLEGROUND_QUEUE_5v5:
- return ARENA_TYPE_5v5;
- default:
- return 0;
- }
+ return { battlemasterListId, AsUnderlyingType(type), rated, teamSize };
}
void BattlegroundMgr::ToggleTesting()
@@ -708,11 +628,52 @@ void BattlegroundMgr::SetHolidayWeekends(uint32 mask)
bg->SetHoliday((mask & (1 << bgtype)) != 0);
}
-void BattlegroundMgr::ScheduleQueueUpdate(uint32 arenaMatchmakerRating, uint8 arenaType, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id)
+bool BattlegroundMgr::IsValidQueueId(BattlegroundQueueTypeId bgQueueTypeId)
+{
+ BattlemasterListEntry const* battlemasterList = sBattlemasterListStore.LookupEntry(bgQueueTypeId.BattlemasterListId);
+ if (!battlemasterList)
+ return false;
+
+ switch (BattlegroundQueueIdType(bgQueueTypeId.Type))
+ {
+ case BattlegroundQueueIdType::Battleground:
+ if (battlemasterList->InstanceType != MAP_BATTLEGROUND)
+ return false;
+ if (bgQueueTypeId.TeamSize)
+ return false;
+ break;
+ case BattlegroundQueueIdType::Arena:
+ if (battlemasterList->InstanceType != MAP_ARENA)
+ return false;
+ if (!bgQueueTypeId.Rated)
+ return false;
+ if (!bgQueueTypeId.TeamSize)
+ return false;
+ break;
+ case BattlegroundQueueIdType::Wargame:
+ if (bgQueueTypeId.Rated)
+ return false;
+ break;
+ case BattlegroundQueueIdType::ArenaSkirmish:
+ if (battlemasterList->InstanceType != MAP_ARENA)
+ return false;
+ if (bgQueueTypeId.Rated)
+ return false;
+ if (bgQueueTypeId.TeamSize)
+ return false;
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+void BattlegroundMgr::ScheduleQueueUpdate(uint32 arenaMatchmakerRating, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundBracketId bracket_id)
{
//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;
+ ScheduledQueueUpdate scheduleId{ arenaMatchmakerRating, bgQueueTypeId, bracket_id };
if (std::find(m_QueueUpdateScheduler.begin(), m_QueueUpdateScheduler.end(), scheduleId) == m_QueueUpdateScheduler.end())
m_QueueUpdateScheduler.push_back(scheduleId);
}
@@ -862,19 +823,19 @@ BattlegroundTypeId BattlegroundMgr::GetRandomBG(BattlegroundTypeId bgTypeId)
return BATTLEGROUND_TYPE_NONE;
}
-BGFreeSlotQueueContainer& BattlegroundMgr::GetBGFreeSlotQueueStore(BattlegroundTypeId bgTypeId)
+BGFreeSlotQueueContainer& BattlegroundMgr::GetBGFreeSlotQueueStore(BattlegroundQueueTypeId bgTypeId)
{
- return bgDataStore[bgTypeId].BGFreeSlotQueue;
+ return m_BGFreeSlotQueue[bgTypeId];
}
-void BattlegroundMgr::AddToBGFreeSlotQueue(BattlegroundTypeId bgTypeId, Battleground* bg)
+void BattlegroundMgr::AddToBGFreeSlotQueue(BattlegroundQueueTypeId bgTypeId, Battleground* bg)
{
- bgDataStore[bgTypeId].BGFreeSlotQueue.push_front(bg);
+ m_BGFreeSlotQueue[bgTypeId].push_front(bg);
}
-void BattlegroundMgr::RemoveFromBGFreeSlotQueue(BattlegroundTypeId bgTypeId, uint32 instanceId)
+void BattlegroundMgr::RemoveFromBGFreeSlotQueue(BattlegroundQueueTypeId bgTypeId, uint32 instanceId)
{
- BGFreeSlotQueueContainer& queues = bgDataStore[bgTypeId].BGFreeSlotQueue;
+ BGFreeSlotQueueContainer& queues = m_BGFreeSlotQueue[bgTypeId];
for (BGFreeSlotQueueContainer::iterator itr = queues.begin(); itr != queues.end(); ++itr)
if ((*itr)->GetInstanceID() == instanceId)
{
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h
index 38cc163835c..d571cb00c98 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.h
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.h
@@ -41,7 +41,6 @@ struct BattlegroundData
{
BattlegroundContainer m_Battlegrounds;
BattlegroundClientIdsContainer m_ClientBattlegroundIds[MAX_BATTLEGROUND_BRACKETS];
- BGFreeSlotQueueContainer BGFreeSlotQueue;
};
struct BattlegroundTemplate
@@ -86,24 +85,24 @@ class TC_GAME_API BattlegroundMgr
/* Packet Building */
void SendBattlegroundList(Player* player, ObjectGuid const& guid, BattlegroundTypeId bgTypeId);
- void BuildBattlegroundStatusHeader(WorldPackets::Battleground::BattlefieldStatusHeader* battlefieldStatus, Battleground* bg, Player* player, uint32 ticketId, uint32 joinTime, uint32 arenaType);
+ void BuildBattlegroundStatusHeader(WorldPackets::Battleground::BattlefieldStatusHeader* battlefieldStatus, Battleground* bg, Player* player, uint32 ticketId, uint32 joinTime, BattlegroundQueueTypeId queueId, uint32 arenaType);
void BuildBattlegroundStatusNone(WorldPackets::Battleground::BattlefieldStatusNone* battlefieldStatus, Player* player, uint32 ticketId, uint32 joinTime);
void BuildBattlegroundStatusNeedConfirmation(WorldPackets::Battleground::BattlefieldStatusNeedConfirmation* battlefieldStatus, Battleground* bg, Player* player, uint32 ticketId, uint32 joinTime, uint32 timeout, uint32 arenaType);
void BuildBattlegroundStatusActive(WorldPackets::Battleground::BattlefieldStatusActive* battlefieldStatus, Battleground* bg, Player* player, uint32 ticketId, uint32 joinTime, uint32 arenaType);
- void BuildBattlegroundStatusQueued(WorldPackets::Battleground::BattlefieldStatusQueued* battlefieldStatus, Battleground* bg, Player* player, uint32 ticketId, uint32 joinTime, uint32 avgWaitTime, uint32 arenaType, bool asGroup);
+ void BuildBattlegroundStatusQueued(WorldPackets::Battleground::BattlefieldStatusQueued* battlefieldStatus, Battleground* bg, Player* player, uint32 ticketId, uint32 joinTime, BattlegroundQueueTypeId queueId, uint32 avgWaitTime, uint32 arenaType, bool asGroup);
void BuildBattlegroundStatusFailed(WorldPackets::Battleground::BattlefieldStatusFailed* battlefieldStatus, Battleground* bg, Player* pPlayer, uint32 ticketId, uint32 arenaType, GroupJoinBattlegroundResult result, ObjectGuid const* errorGuid = nullptr);
void SendAreaSpiritHealerQueryOpcode(Player* player, Battleground* bg, ObjectGuid const& guid);
/* Battlegrounds */
Battleground* GetBattleground(uint32 InstanceID, BattlegroundTypeId bgTypeId);
Battleground* GetBattlegroundTemplate(BattlegroundTypeId bgTypeId);
- Battleground* CreateNewBattleground(BattlegroundTypeId bgTypeId, PVPDifficultyEntry const* bracketEntry, uint8 arenaType, bool isRated);
+ Battleground* CreateNewBattleground(BattlegroundQueueTypeId queueId, PVPDifficultyEntry const* bracketEntry);
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 AddToBGFreeSlotQueue(BattlegroundQueueTypeId bgTypeId, Battleground* bg);
+ void RemoveFromBGFreeSlotQueue(BattlegroundQueueTypeId bgTypeId, uint32 instanceId);
+ BGFreeSlotQueueContainer& GetBGFreeSlotQueueStore(BattlegroundQueueTypeId bgTypeId);
void LoadBattlegroundTemplates();
void DeleteAllBattlegrounds();
@@ -111,8 +110,9 @@ class TC_GAME_API BattlegroundMgr
void SendToBattleground(Player* player, uint32 InstanceID, BattlegroundTypeId bgTypeId);
/* Battleground queues */
- BattlegroundQueue& GetBattlegroundQueue(BattlegroundQueueTypeId bgQueueTypeId) { return m_BattlegroundQueues[bgQueueTypeId]; }
- void ScheduleQueueUpdate(uint32 arenaMatchmakerRating, uint8 arenaType, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id);
+ static bool IsValidQueueId(BattlegroundQueueTypeId bgQueueTypeId);
+ BattlegroundQueue& GetBattlegroundQueue(BattlegroundQueueTypeId bgQueueTypeId) { return m_BattlegroundQueues.emplace(bgQueueTypeId, bgQueueTypeId).first->second; }
+ void ScheduleQueueUpdate(uint32 arenaMatchmakerRating, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundBracketId bracket_id);
uint32 GetPrematureFinishTime() const;
void ToggleArenaTesting();
@@ -123,9 +123,7 @@ class TC_GAME_API BattlegroundMgr
bool isArenaTesting() const { return m_ArenaTesting; }
bool isTesting() const { return m_Testing; }
- static BattlegroundQueueTypeId BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 arenaType);
- static BattlegroundTypeId BGTemplateId(BattlegroundQueueTypeId bgQueueTypeId);
- static uint8 BGArenaType(BattlegroundQueueTypeId bgQueueTypeId);
+ static BattlegroundQueueTypeId BGQueueTypeId(uint16 battlemasterListId, BattlegroundQueueIdType type, bool rated, uint8 teamSize);
static HolidayIds BGTypeToWeekendHolidayId(BattlegroundTypeId bgTypeId);
static BattlegroundTypeId WeekendHolidayIdToBGType(HolidayIds holiday);
@@ -152,9 +150,22 @@ class TC_GAME_API BattlegroundMgr
typedef std::map<BattlegroundTypeId, BattlegroundData> BattlegroundDataContainer;
BattlegroundDataContainer bgDataStore;
- BattlegroundQueue m_BattlegroundQueues[MAX_BATTLEGROUND_QUEUE_TYPES];
+ std::map<BattlegroundQueueTypeId, BattlegroundQueue> m_BattlegroundQueues;
+ std::map<BattlegroundQueueTypeId, BGFreeSlotQueueContainer> m_BGFreeSlotQueue;
- std::vector<uint64> m_QueueUpdateScheduler;
+ struct ScheduledQueueUpdate
+ {
+ uint32 ArenaMatchmakerRating;
+ BattlegroundQueueTypeId QueueId;
+ BattlegroundBracketId BracketId;
+
+ bool operator==(ScheduledQueueUpdate const& right) const
+ {
+ return ArenaMatchmakerRating == right.ArenaMatchmakerRating && QueueId == right.QueueId && BracketId == right.BracketId;
+ }
+ };
+
+ std::vector<ScheduledQueueUpdate> m_QueueUpdateScheduler;
uint32 m_NextRatedArenaUpdate;
uint32 m_UpdateTimer;
bool m_ArenaTesting;
diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
index 72dc24b11ba..15dbeb83f9b 100644
--- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
@@ -34,7 +34,7 @@
/*** BATTLEGROUND QUEUE SYSTEM ***/
/*********************************************************/
-BattlegroundQueue::BattlegroundQueue()
+BattlegroundQueue::BattlegroundQueue(BattlegroundQueueTypeId queueId) : m_queueId(queueId)
{
for (uint32 i = 0; i < BG_TEAMS_COUNT; ++i)
{
@@ -391,14 +391,13 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
// first send removal information
if (Player* plr2 = ObjectAccessor::FindConnectedPlayer(group->Players.begin()->first))
{
- BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(group->BgTypeId, group->ArenaType);
- uint32 queueSlot = plr2->GetBattlegroundQueueIndex(bgQueueTypeId);
+ uint32 queueSlot = plr2->GetBattlegroundQueueIndex(m_queueId);
- plr2->RemoveBattlegroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to
+ plr2->RemoveBattlegroundQueueId(m_queueId); // must be called this way, because if you move this call to
// queue->removeplayer, it causes bugs
WorldPackets::Battleground::BattlefieldStatusNone battlefieldStatus;
- sBattlegroundMgr->BuildBattlegroundStatusNone(&battlefieldStatus, plr2, queueSlot, plr2->GetBattlegroundQueueJoinTime(bgQueueTypeId));
+ sBattlegroundMgr->BuildBattlegroundStatusNone(&battlefieldStatus, plr2, queueSlot, plr2->GetBattlegroundQueueJoinTime(m_queueId));
plr2->SendDirectMessage(battlefieldStatus.Write());
}
// then actually delete, this may delete the group as well!
@@ -441,7 +440,7 @@ bool BattlegroundQueue::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg,
// set invitation
ginfo->IsInvitedToBGInstanceGUID = bg->GetInstanceID();
BattlegroundTypeId bgTypeId = bg->GetTypeID();
- BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, bg->GetArenaType());
+ BattlegroundQueueTypeId bgQueueTypeId = bg->GetQueueId();
BattlegroundBracketId bracket_id = bg->GetBracketId();
// set ArenaTeamId for rated matches
@@ -472,7 +471,7 @@ bool BattlegroundQueue::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg,
BGQueueInviteEvent* inviteEvent = new BGQueueInviteEvent(player->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, ginfo->ArenaType, ginfo->RemoveInviteTime);
m_events.AddEvent(inviteEvent, m_events.CalculateTime(INVITATION_REMIND_TIME));
// create automatic remove events
- BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(player->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, bgQueueTypeId, ginfo->RemoveInviteTime);
+ BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(player->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgQueueTypeId, ginfo->RemoveInviteTime);
m_events.AddEvent(removeEvent, m_events.CalculateTime(INVITE_ACCEPT_WAIT_TIME));
uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId);
@@ -769,7 +768,7 @@ this method is called when group is inserted, or player / group is removed from
it must be called after fully adding the members of a group to ensure group joining
should be called from Battleground::RemovePlayer function in some cases
*/
-void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id, uint8 arenaType, bool isRated, uint32 arenaRating)
+void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundBracketId bracket_id, uint32 arenaRating)
{
//if no players in queue - do nothing
if (m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty() &&
@@ -780,12 +779,12 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp
// battleground with free slot for player should be always in the beggining of the queue
// maybe it would be better to create bgfreeslotqueue for each bracket_id
- BGFreeSlotQueueContainer& bgQueues = sBattlegroundMgr->GetBGFreeSlotQueueStore(bgTypeId);
+ BGFreeSlotQueueContainer& bgQueues = sBattlegroundMgr->GetBGFreeSlotQueueStore(m_queueId);
for (BGFreeSlotQueueContainer::iterator itr = bgQueues.begin(); itr != bgQueues.end();)
{
Battleground* bg = *itr; ++itr;
// DO NOT allow queue manager to invite new player to rated games
- if (!bg->isRated() && bg->GetTypeID() == bgTypeId && bg->GetBracketId() == bracket_id &&
+ if (!bg->isRated() && bg->GetBracketId() == bracket_id &&
bg->GetStatus() > STATUS_WAIT_QUEUE && bg->GetStatus() < STATUS_WAIT_LEAVE)
{
// clear selection pools
@@ -809,10 +808,10 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp
// finished iterating through the bgs with free slots, maybe we need to create a new bg
- Battleground* bg_template = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
+ Battleground* bg_template = sBattlegroundMgr->GetBattlegroundTemplate(BattlegroundTypeId(m_queueId.BattlemasterListId));
if (!bg_template)
{
- TC_LOG_ERROR("bg.battleground", "Battleground: Update: bg template not found for %u", bgTypeId);
+ TC_LOG_ERROR("bg.battleground", "Battleground: Update: bg template not found for %hu", m_queueId.BattlemasterListId);
return;
}
@@ -829,8 +828,8 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp
if (bg_template->isArena())
{
- MaxPlayersPerTeam = arenaType;
- MinPlayersPerTeam = sBattlegroundMgr->isArenaTesting() ? 1 : arenaType;
+ MaxPlayersPerTeam = m_queueId.TeamSize;
+ MinPlayersPerTeam = sBattlegroundMgr->isArenaTesting() ? 1 : m_queueId.TeamSize;
}
else if (sBattlegroundMgr->isTesting())
MinPlayersPerTeam = 1;
@@ -843,10 +842,10 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp
if (CheckPremadeMatch(bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam))
{
// create new battleground
- Battleground* bg2 = sBattlegroundMgr->CreateNewBattleground(bgTypeId, bracketEntry, 0, false);
+ Battleground* bg2 = sBattlegroundMgr->CreateNewBattleground(m_queueId, bracketEntry);
if (!bg2)
{
- TC_LOG_ERROR("bg.battleground", "BattlegroundQueue::Update - Cannot create battleground: %u", bgTypeId);
+ TC_LOG_ERROR("bg.battleground", "BattlegroundQueue::Update - Cannot create battleground: %u", m_queueId.BattlemasterListId);
return;
}
// invite those selection pools
@@ -862,17 +861,17 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp
}
// now check if there are in queues enough players to start new game of (normal battleground, or non-rated arena)
- if (!isRated)
+ if (!m_queueId.Rated)
{
// if there are enough players in pools, start new battleground or non rated arena
if (CheckNormalMatch(bg_template, bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam)
|| (bg_template->isArena() && CheckSkirmishForSameFaction(bracket_id, MinPlayersPerTeam)))
{
// we successfully created a pool
- Battleground* bg2 = sBattlegroundMgr->CreateNewBattleground(bgTypeId, bracketEntry, arenaType, false);
+ Battleground* bg2 = sBattlegroundMgr->CreateNewBattleground(m_queueId, bracketEntry);
if (!bg2)
{
- TC_LOG_ERROR("bg.battleground", "BattlegroundQueue::Update - Cannot create battleground: %u", bgTypeId);
+ TC_LOG_ERROR("bg.battleground", "BattlegroundQueue::Update - Cannot create battleground: %hu", m_queueId.BattlemasterListId);
return;
}
@@ -968,7 +967,7 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp
{
GroupQueueInfo* aTeam = *itr_teams[TEAM_ALLIANCE];
GroupQueueInfo* hTeam = *itr_teams[TEAM_HORDE];
- Battleground* arena = sBattlegroundMgr->CreateNewBattleground(bgTypeId, bracketEntry, arenaType, true);
+ Battleground* arena = sBattlegroundMgr->CreateNewBattleground(m_queueId, bracketEntry);
if (!arena)
{
TC_LOG_ERROR("bg.battleground", "BattlegroundQueue::Update couldn't create arena instance for rated arena match!");
@@ -1021,7 +1020,7 @@ bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
if (!bg)
return true;
- BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
+ BattlegroundQueueTypeId bgQueueTypeId = bg->GetQueueId();
uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId);
if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue or in battleground
{
@@ -1058,7 +1057,7 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
// player logged off (we should do nothing, he is correctly removed from queue in another procedure)
return true;
- Battleground* bg = sBattlegroundMgr->GetBattleground(m_BgInstanceGUID, m_BgTypeId);
+ Battleground* bg = sBattlegroundMgr->GetBattleground(m_BgInstanceGUID, BattlegroundTypeId(m_BgQueueTypeId.BattlemasterListId));
//battleground can be deleted already when we are removing queue info
//bg pointer can be NULL! so use it carefully!
@@ -1075,7 +1074,7 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
bgQueue.RemovePlayer(m_PlayerGuid, true);
//update queues if battleground isn't ended
if (bg && bg->isBattleground() && bg->GetStatus() != STATUS_WAIT_LEAVE)
- sBattlegroundMgr->ScheduleQueueUpdate(0, 0, m_BgQueueTypeId, m_BgTypeId, bg->GetBracketId());
+ sBattlegroundMgr->ScheduleQueueUpdate(0, m_BgQueueTypeId, bg->GetBracketId());
WorldPackets::Battleground::BattlefieldStatusNone battlefieldStatus;
sBattlegroundMgr->BuildBattlegroundStatusNone(&battlefieldStatus, player, queueSlot, player->GetBattlegroundQueueJoinTime(m_BgQueueTypeId));
diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.h b/src/server/game/Battlegrounds/BattlegroundQueue.h
index 14ac03402b7..e6dba599f12 100644
--- a/src/server/game/Battlegrounds/BattlegroundQueue.h
+++ b/src/server/game/Battlegrounds/BattlegroundQueue.h
@@ -74,10 +74,10 @@ class Battleground;
class TC_GAME_API BattlegroundQueue
{
public:
- BattlegroundQueue();
+ BattlegroundQueue(BattlegroundQueueTypeId queueId);
~BattlegroundQueue();
- void BattlegroundQueueUpdate(uint32 diff, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id, uint8 arenaType = 0, bool isRated = false, uint32 minRating = 0);
+ void BattlegroundQueueUpdate(uint32 diff, BattlegroundBracketId bracket_id, uint32 minRating = 0);
void UpdateEvents(uint32 diff);
void FillPlayersToBG(Battleground* bg, BattlegroundBracketId bracket_id);
@@ -128,6 +128,8 @@ class TC_GAME_API BattlegroundQueue
uint32 GetPlayersInQueue(TeamId id);
private:
+ BattlegroundQueueTypeId m_queueId;
+
bool InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, uint32 side);
uint32 m_WaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME];
uint32 m_WaitTimeLastPlayer[BG_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS];
@@ -167,8 +169,8 @@ class TC_GAME_API BGQueueInviteEvent : public BasicEvent
class TC_GAME_API BGQueueRemoveEvent : public BasicEvent
{
public:
- 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(ObjectGuid pl_guid, uint32 bgInstanceGUID, BattlegroundQueueTypeId bgQueueTypeId, uint32 removeTime)
+ : m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_RemoveTime(removeTime), m_BgQueueTypeId(bgQueueTypeId)
{ }
virtual ~BGQueueRemoveEvent() { }
@@ -179,7 +181,6 @@ class TC_GAME_API BGQueueRemoveEvent : public BasicEvent
ObjectGuid m_PlayerGuid;
uint32 m_BgInstanceGUID;
uint32 m_RemoveTime;
- BattlegroundTypeId m_BgTypeId;
BattlegroundQueueTypeId m_BgQueueTypeId;
};
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
index 476daf5db21..c83e1ff48b1 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
@@ -65,6 +65,7 @@ BattlegroundEY::BattlegroundEY(BattlegroundTemplate const* battlegroundTemplate)
m_PointOwnedByTeam[i] = EY_POINT_NO_OWNER;
m_PointState[i] = EY_POINT_STATE_UNCONTROLLED;
m_PointBarStatus[i] = BG_EY_PROGRESS_BAR_STATE_MIDDLE;
+ m_LastPointCaptureStatus[i] = BattlegroundPointCaptureStatus::Neutral;
}
for (uint8 i = 0; i < 2 * EY_POINTS_MAX; ++i)
@@ -170,6 +171,22 @@ void BattlegroundEY::AddPoints(uint32 Team, uint32 Points)
UpdateTeamScore(team_index);
}
+BattlegroundPointCaptureStatus BattlegroundEY::GetPointCaptureStatus(uint32 point) const
+{
+ if (m_PointBarStatus[point] >= BG_EY_PROGRESS_BAR_ALI_CONTROLLED)
+ return BattlegroundPointCaptureStatus::AllianceControlled;
+
+ if (m_PointBarStatus[point] <= BG_EY_PROGRESS_BAR_HORDE_CONTROLLED)
+ return BattlegroundPointCaptureStatus::HordeControlled;
+
+ if (m_CurrentPointPlayersCount[2 * point] == m_CurrentPointPlayersCount[2 * point + 1])
+ return BattlegroundPointCaptureStatus::Neutral;
+
+ return m_CurrentPointPlayersCount[2 * point] > m_CurrentPointPlayersCount[2 * point + 1]
+ ? BattlegroundPointCaptureStatus::AllianceCapturing
+ : BattlegroundPointCaptureStatus::HordeCapturing;
+}
+
void BattlegroundEY::CheckSomeoneJoinedPoint()
{
GameObject* obj = NULL;
@@ -252,52 +269,63 @@ void BattlegroundEY::UpdatePointStatuses()
{
for (uint8 point = 0; point < EY_POINTS_MAX; ++point)
{
- if (m_PlayersNearPoint[point].empty())
- continue;
- //count new point bar status:
- m_PointBarStatus[point] += (m_CurrentPointPlayersCount[2 * point] - m_CurrentPointPlayersCount[2 * point + 1] < BG_EY_POINT_MAX_CAPTURERS_COUNT) ? m_CurrentPointPlayersCount[2 * point] - m_CurrentPointPlayersCount[2 * point + 1] : BG_EY_POINT_MAX_CAPTURERS_COUNT;
-
- if (m_PointBarStatus[point] > BG_EY_PROGRESS_BAR_ALI_CONTROLLED)
- //point is fully alliance's
- m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_ALI_CONTROLLED;
- if (m_PointBarStatus[point] < BG_EY_PROGRESS_BAR_HORDE_CONTROLLED)
- //point is fully horde's
- m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_HORDE_CONTROLLED;
-
- uint32 pointOwnerTeamId = 0;
- //find which team should own this point
- if (m_PointBarStatus[point] <= BG_EY_PROGRESS_BAR_NEUTRAL_LOW)
- pointOwnerTeamId = HORDE;
- else if (m_PointBarStatus[point] >= BG_EY_PROGRESS_BAR_NEUTRAL_HIGH)
- pointOwnerTeamId = ALLIANCE;
- else
- pointOwnerTeamId = EY_POINT_NO_OWNER;
-
- for (uint8 i = 0; i < m_PlayersNearPoint[point].size(); ++i)
+ if (!m_PlayersNearPoint[point].empty())
{
- Player* player = ObjectAccessor::FindPlayer(m_PlayersNearPoint[point][i]);
- if (player)
+ //count new point bar status:
+ int32 pointDelta = int32(m_CurrentPointPlayersCount[2 * point]) - int32(m_CurrentPointPlayersCount[2 * point + 1]);
+ RoundToInterval<int32>(pointDelta, -BG_EY_POINT_MAX_CAPTURERS_COUNT, BG_EY_POINT_MAX_CAPTURERS_COUNT);
+ m_PointBarStatus[point] += pointDelta;
+
+ if (m_PointBarStatus[point] > BG_EY_PROGRESS_BAR_ALI_CONTROLLED)
+ //point is fully alliance's
+ m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_ALI_CONTROLLED;
+ if (m_PointBarStatus[point] < BG_EY_PROGRESS_BAR_HORDE_CONTROLLED)
+ //point is fully horde's
+ m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_HORDE_CONTROLLED;
+
+ uint32 pointOwnerTeamId = 0;
+ //find which team should own this point
+ if (m_PointBarStatus[point] <= BG_EY_PROGRESS_BAR_NEUTRAL_LOW)
+ pointOwnerTeamId = HORDE;
+ else if (m_PointBarStatus[point] >= BG_EY_PROGRESS_BAR_NEUTRAL_HIGH)
+ pointOwnerTeamId = ALLIANCE;
+ else
+ pointOwnerTeamId = EY_POINT_NO_OWNER;
+
+ for (uint8 i = 0; i < m_PlayersNearPoint[point].size(); ++i)
{
- player->SendUpdateWorldState(PROGRESS_BAR_STATUS, m_PointBarStatus[point]);
- //if point owner changed we must evoke event!
- if (pointOwnerTeamId != m_PointOwnedByTeam[point])
+ Player* player = ObjectAccessor::FindPlayer(m_PlayersNearPoint[point][i]);
+ if (player)
{
- //point was uncontrolled and player is from team which captured point
- if (m_PointState[point] == EY_POINT_STATE_UNCONTROLLED && player->GetTeam() == pointOwnerTeamId)
- this->EventTeamCapturedPoint(player, point);
-
- //point was under control and player isn't from team which controlled it
- if (m_PointState[point] == EY_POINT_UNDER_CONTROL && player->GetTeam() != m_PointOwnedByTeam[point])
- this->EventTeamLostPoint(player, point);
+ player->SendUpdateWorldState(PROGRESS_BAR_STATUS, m_PointBarStatus[point]);
+ //if point owner changed we must evoke event!
+ if (pointOwnerTeamId != m_PointOwnedByTeam[point])
+ {
+ //point was uncontrolled and player is from team which captured point
+ if (m_PointState[point] == EY_POINT_STATE_UNCONTROLLED && player->GetTeam() == pointOwnerTeamId)
+ this->EventTeamCapturedPoint(player, point);
+
+ //point was under control and player isn't from team which controlled it
+ if (m_PointState[point] == EY_POINT_UNDER_CONTROL && player->GetTeam() != m_PointOwnedByTeam[point])
+ this->EventTeamLostPoint(player, point);
+ }
+
+ /// @workaround The original AreaTrigger is covered by a bigger one and not triggered on client side.
+ if (point == FEL_REAVER && m_PointOwnedByTeam[point] == player->GetTeam())
+ if (m_FlagState && GetFlagPickerGUID() == player->GetGUID())
+ if (player->GetDistance(2044.0f, 1729.729f, 1190.03f) < 3.0f)
+ EventPlayerCapturedFlag(player, BG_EY_OBJECT_FLAG_FEL_REAVER);
}
-
- /// @workaround The original AreaTrigger is covered by a bigger one and not triggered on client side.
- if (point == FEL_REAVER && m_PointOwnedByTeam[point] == player->GetTeam())
- if (m_FlagState && GetFlagPickerGUID() == player->GetGUID())
- if (player->GetDistance(2044.0f, 1729.729f, 1190.03f) < 3.0f)
- EventPlayerCapturedFlag(player, BG_EY_OBJECT_FLAG_FEL_REAVER);
}
}
+
+ BattlegroundPointCaptureStatus captureStatus = GetPointCaptureStatus(point);
+ if (m_LastPointCaptureStatus[point] != captureStatus)
+ {
+ UpdateWorldState(m_PointsIconStruct[point].WorldStateAllianceStatusBarIcon, captureStatus == BattlegroundPointCaptureStatus::AllianceControlled ? 2 : (captureStatus == BattlegroundPointCaptureStatus::AllianceCapturing ? 1 : 0));
+ UpdateWorldState(m_PointsIconStruct[point].WorldStateHordeStatusBarIcon, captureStatus == BattlegroundPointCaptureStatus::HordeControlled ? 2 : (captureStatus == BattlegroundPointCaptureStatus::HordeCapturing ? 1 : 0));
+ m_LastPointCaptureStatus[point] = captureStatus;
+ }
}
}
@@ -818,6 +846,9 @@ void BattlegroundEY::EventPlayerCapturedFlag(Player* player, uint32 BgObjectType
if (m_TeamPointsCount[team_id] > 0)
AddPoints(player->GetTeam(), BG_EY_FlagPoints[m_TeamPointsCount[team_id] - 1]);
+ UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_ON_BASE);
+ UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_ON_BASE);
+
UpdatePlayerScore(player, SCORE_FLAG_CAPTURES, 1);
}
@@ -867,14 +898,22 @@ void BattlegroundEY::FillInitialWorldStates(WorldPackets::WorldState::InitWorldS
packet.Worldstates.emplace_back(0xAD2, 0x1);
packet.Worldstates.emplace_back(0xAD1, 0x1);
- packet.Worldstates.emplace_back(0xABE, int32(GetTeamScore(TEAM_HORDE)));
- packet.Worldstates.emplace_back(0xABD, int32(GetTeamScore(TEAM_ALLIANCE)));
+ packet.Worldstates.emplace_back(int32(EY_HORDE_RESOURCES), int32(GetTeamScore(TEAM_HORDE)));
+ packet.Worldstates.emplace_back(int32(EY_ALLIANCE_RESOURCES), int32(GetTeamScore(TEAM_ALLIANCE)));
+ packet.Worldstates.emplace_back(int32(EY_MAX_RESOURCES), int32(BG_EY_MAX_TEAM_SCORE));
packet.Worldstates.emplace_back(0xA05, 0x8E);
packet.Worldstates.emplace_back(0xAA0, 0x0);
packet.Worldstates.emplace_back(0xA9F, 0x0);
packet.Worldstates.emplace_back(0xA9E, 0x0);
packet.Worldstates.emplace_back(0xC0D, 0x17B);
+
+ for (uint8 point = 0; point < EY_POINTS_MAX; ++point)
+ {
+ BattlegroundPointCaptureStatus captureStatus = GetPointCaptureStatus(point);
+ packet.Worldstates.emplace_back(m_PointsIconStruct[point].WorldStateAllianceStatusBarIcon, captureStatus == BattlegroundPointCaptureStatus::AllianceControlled ? 2 : (captureStatus == BattlegroundPointCaptureStatus::AllianceCapturing ? 1 : 0));
+ packet.Worldstates.emplace_back(m_PointsIconStruct[point].WorldStateHordeStatusBarIcon, captureStatus == BattlegroundPointCaptureStatus::HordeControlled ? 2 : (captureStatus == BattlegroundPointCaptureStatus::HordeCapturing ? 1 : 0));
+ }
}
WorldSafeLocsEntry const* BattlegroundEY::GetClosestGraveYard(Player* player)
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h
index e1028d491dd..37e3aed3837 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h
@@ -31,8 +31,9 @@ enum BG_EY_Misc
enum BG_EY_WorldStates
{
- EY_ALLIANCE_RESOURCES = 2749,
- EY_HORDE_RESOURCES = 2750,
+ EY_ALLIANCE_RESOURCES = 1776,
+ EY_HORDE_RESOURCES = 1777,
+ EY_MAX_RESOURCES = 1780,
EY_ALLIANCE_BASE = 2752,
EY_HORDE_BASE = 2753,
DRAENEI_RUINS_HORDE_CONTROL = 2733,
@@ -52,8 +53,17 @@ enum BG_EY_WorldStates
PROGRESS_BAR_SHOW = 2718, //1 init, 0 druhy send - bez messagu, 1 = controlled aliance
NETHERSTORM_FLAG = 2757,
//set to 2 when flag is picked up, and to 1 if it is dropped
- NETHERSTORM_FLAG_STATE_ALLIANCE = 2769,
- NETHERSTORM_FLAG_STATE_HORDE = 2770
+ NETHERSTORM_FLAG_STATE_ALLIANCE = 9808,
+ NETHERSTORM_FLAG_STATE_HORDE = 9809,
+
+ DRAENEI_RUINS_HORDE_CONTROL_STATE = 17362,
+ DRAENEI_RUINS_ALLIANCE_CONTROL_STATE = 17366,
+ MAGE_TOWER_HORDE_CONTROL_STATE = 17361,
+ MAGE_TOWER_ALLIANCE_CONTROL_STATE = 17368,
+ FEL_REAVER_HORDE_CONTROL_STATE = 17364,
+ FEL_REAVER_ALLIANCE_CONTROL_STATE = 17367,
+ BLOOD_ELF_HORDE_CONTROL_STATE = 17363,
+ BLOOD_ELF_ALLIANCE_CONTROL_STATE = 17365,
};
enum BG_EY_ProgressBarConsts
@@ -118,7 +128,7 @@ enum EYBattlegroundGaveyards
{
EY_GRAVEYARD_MAIN_ALLIANCE = 1103,
EY_GRAVEYARD_MAIN_HORDE = 1104,
- EY_GRAVEYARD_FEL_REAVER = 1105,
+ EY_GRAVEYARD_FEL_REAVER = 1105,
EY_GRAVEYARD_BLOOD_ELF = 1106,
EY_GRAVEYARD_DRAENEI_RUINS = 1107,
EY_GRAVEYARD_MAGE_TOWER = 1108
@@ -137,19 +147,19 @@ enum EYBattlegroundPoints
enum EYBattlegroundCreaturesTypes
{
- EY_SPIRIT_FEL_REAVER = 0,
+ EY_SPIRIT_FEL_REAVER = 0,
EY_SPIRIT_BLOOD_ELF = 1,
EY_SPIRIT_DRAENEI_RUINS = 2,
EY_SPIRIT_MAGE_TOWER = 3,
EY_SPIRIT_MAIN_ALLIANCE = 4,
EY_SPIRIT_MAIN_HORDE = 5,
- EY_TRIGGER_FEL_REAVER = 6,
+ EY_TRIGGER_FEL_REAVER = 6,
EY_TRIGGER_BLOOD_ELF = 7,
EY_TRIGGER_DRAENEI_RUINS = 8,
EY_TRIGGER_MAGE_TOWER = 9,
- BG_EY_CREATURES_MAX = 10
+ BG_EY_CREATURES_MAX = 10
};
enum EYBattlegroundObjectTypes
@@ -283,11 +293,15 @@ enum BG_EY_BroadcastTexts
struct BattlegroundEYPointIconsStruct
{
- BattlegroundEYPointIconsStruct(uint32 _WorldStateControlIndex, uint32 _WorldStateAllianceControlledIndex, uint32 _WorldStateHordeControlledIndex)
- : WorldStateControlIndex(_WorldStateControlIndex), WorldStateAllianceControlledIndex(_WorldStateAllianceControlledIndex), WorldStateHordeControlledIndex(_WorldStateHordeControlledIndex) { }
+ BattlegroundEYPointIconsStruct(uint32 _WorldStateControlIndex, uint32 _WorldStateAllianceControlledIndex, uint32 _WorldStateHordeControlledIndex,
+ uint32 worldStateAllianceStatusBarIcon, uint32 worldStateHordeStatusBarIcon)
+ : WorldStateControlIndex(_WorldStateControlIndex), WorldStateAllianceControlledIndex(_WorldStateAllianceControlledIndex), WorldStateHordeControlledIndex(_WorldStateHordeControlledIndex),
+ WorldStateAllianceStatusBarIcon(worldStateAllianceStatusBarIcon), WorldStateHordeStatusBarIcon(worldStateHordeStatusBarIcon) { }
uint32 WorldStateControlIndex;
uint32 WorldStateAllianceControlledIndex;
uint32 WorldStateHordeControlledIndex;
+ uint32 WorldStateAllianceStatusBarIcon;
+ uint32 WorldStateHordeStatusBarIcon;
};
Position const BG_EY_TriggerPositions[EY_POINTS_MAX] =
@@ -336,10 +350,10 @@ const uint32 BG_EY_FlagPoints[EY_POINTS_MAX] = {75, 85, 100, 500};
//constant arrays:
const BattlegroundEYPointIconsStruct m_PointsIconStruct[EY_POINTS_MAX] =
{
- BattlegroundEYPointIconsStruct(FEL_REAVER_UNCONTROL, FEL_REAVER_ALLIANCE_CONTROL, FEL_REAVER_HORDE_CONTROL),
- BattlegroundEYPointIconsStruct(BLOOD_ELF_UNCONTROL, BLOOD_ELF_ALLIANCE_CONTROL, BLOOD_ELF_HORDE_CONTROL),
- BattlegroundEYPointIconsStruct(DRAENEI_RUINS_UNCONTROL, DRAENEI_RUINS_ALLIANCE_CONTROL, DRAENEI_RUINS_HORDE_CONTROL),
- BattlegroundEYPointIconsStruct(MAGE_TOWER_UNCONTROL, MAGE_TOWER_ALLIANCE_CONTROL, MAGE_TOWER_HORDE_CONTROL)
+ BattlegroundEYPointIconsStruct(FEL_REAVER_UNCONTROL, FEL_REAVER_ALLIANCE_CONTROL, FEL_REAVER_HORDE_CONTROL, FEL_REAVER_ALLIANCE_CONTROL_STATE, FEL_REAVER_HORDE_CONTROL_STATE),
+ BattlegroundEYPointIconsStruct(BLOOD_ELF_UNCONTROL, BLOOD_ELF_ALLIANCE_CONTROL, BLOOD_ELF_HORDE_CONTROL, BLOOD_ELF_ALLIANCE_CONTROL_STATE, BLOOD_ELF_HORDE_CONTROL_STATE),
+ BattlegroundEYPointIconsStruct(DRAENEI_RUINS_UNCONTROL, DRAENEI_RUINS_ALLIANCE_CONTROL, DRAENEI_RUINS_HORDE_CONTROL, DRAENEI_RUINS_ALLIANCE_CONTROL_STATE, DRAENEI_RUINS_HORDE_CONTROL_STATE),
+ BattlegroundEYPointIconsStruct(MAGE_TOWER_UNCONTROL, MAGE_TOWER_ALLIANCE_CONTROL, MAGE_TOWER_HORDE_CONTROL, MAGE_TOWER_ALLIANCE_CONTROL_STATE, MAGE_TOWER_HORDE_CONTROL_STATE)
};
const BattlegroundEYLosingPointStruct m_LosingPointTypes[EY_POINTS_MAX] =
{
@@ -450,6 +464,7 @@ protected:
void RemovePoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] -= Points; }
void SetTeamPoint(uint32 TeamID, uint32 Points = 0) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] = Points; }
+ BattlegroundPointCaptureStatus GetPointCaptureStatus(uint32 point) const;
uint32 m_HonorScoreTics[2];
uint32 m_TeamPointsCount[2];
@@ -466,6 +481,7 @@ protected:
uint32 m_PointOwnedByTeam[EY_POINTS_MAX];
uint8 m_PointState[EY_POINTS_MAX];
int32 m_PointBarStatus[EY_POINTS_MAX];
+ BattlegroundPointCaptureStatus m_LastPointCaptureStatus[EY_POINTS_MAX];
GuidVector m_PlayersNearPoint[EY_POINTS_MAX + 1];
uint8 m_CurrentPointPlayersCount[2*EY_POINTS_MAX];
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index dbe5e69ed8a..40c19caf8f6 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -18164,7 +18164,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
{
map = currentBg->GetBgMap();
- BattlegroundQueueTypeId bgQueueTypeId = sBattlegroundMgr->BGQueueTypeId(currentBg->GetTypeID(), currentBg->GetArenaType());
+ BattlegroundQueueTypeId bgQueueTypeId = currentBg->GetQueueId();
AddBattlegroundQueueId(bgQueueTypeId);
m_bgData.bgTypeID = currentBg->GetTypeID();
@@ -24791,7 +24791,7 @@ uint32 Player::AddBattlegroundQueueId(BattlegroundQueueTypeId val)
{
m_bgBattlegroundQueueID[i].bgQueueTypeId = val;
m_bgBattlegroundQueueID[i].invitedToInstance = 0;
- m_bgBattlegroundQueueID[i].joinTime = getMSTime();
+ m_bgBattlegroundQueueID[i].joinTime = GameTime::GetGameTime();
return i;
}
}
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index caef3b52b27..0ce01460161 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -1826,8 +1826,6 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const*
uint32 arenaTeamId = reference->GetArenaTeamId(arenaSlot);
uint32 team = reference->GetTeam();
- BattlegroundQueueTypeId bgQueueTypeIdRandom = BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_RB, 0);
-
// check every member of the group to be able to join
memberscount = 0;
for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next(), ++memberscount)
@@ -1853,10 +1851,12 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const*
if (member->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId))
return ERR_BATTLEGROUND_JOIN_FAILED; // not blizz-like
// don't let join if someone from the group is in bg queue random
- if (member->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeIdRandom))
+ bool isInRandomBgQueue = member->InBattlegroundQueueForBattlegroundQueueType(BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_RB, BattlegroundQueueIdType::Battleground, false, 0))
+ || member->InBattlegroundQueueForBattlegroundQueueType(BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_RANDOM_EPIC, BattlegroundQueueIdType::Battleground, false, 0));
+ if (isInRandomBgQueue)
return ERR_IN_RANDOM_BG;
// don't let join to bg queue random if someone from the group is already in bg queue
- if (bgOrTemplate->GetTypeID() == BATTLEGROUND_RB && member->InBattlegroundQueue())
+ if ((bgOrTemplate->GetTypeID() == BATTLEGROUND_RB || bgOrTemplate->GetTypeID() == BATTLEGROUND_RANDOM_EPIC) && member->InBattlegroundQueue() && !isInRandomBgQueue)
return ERR_IN_NON_RANDOM_BG;
// check for deserter debuff in case not arena queue
if (bgOrTemplate->GetTypeID() != BATTLEGROUND_AA && !member->CanJoinToBattleground(bgOrTemplate))
diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp
index d8b5500a66a..7924cf01a18 100644
--- a/src/server/game/Handlers/BattleGroundHandler.cpp
+++ b/src/server/game/Handlers/BattleGroundHandler.cpp
@@ -69,25 +69,24 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPackets::Battleground::Batt
return;
}
- uint32 bgTypeId_ = battlemasterJoin.QueueIDs[0] & 0xFFFF;
- BattlemasterListEntry const* battlemasterListEntry = sBattlemasterListStore.LookupEntry(bgTypeId_);
- if (!battlemasterListEntry)
+ BattlegroundQueueTypeId bgQueueTypeId = BattlegroundQueueTypeId::FromPacked(battlemasterJoin.QueueIDs[0]);
+ if (!BattlegroundMgr::IsValidQueueId(bgQueueTypeId))
{
- TC_LOG_ERROR("network", "Battleground: invalid bgtype (%u) received. possible cheater? %s", bgTypeId_, _player->GetGUID().ToString().c_str());
+ TC_LOG_ERROR("network", "Battleground: invalid bg queue { BattlemasterListId: %hu, Type: %u, Rated: %s, TeamSize: %u } received. possible cheater? %s",
+ bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.Type), bgQueueTypeId.Rated ? "true" : "false", uint32(bgQueueTypeId.TeamSize),
+ _player->GetGUID().ToString().c_str());
return;
}
- if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId_, NULL) || (battlemasterListEntry->Flags & BATTLEMASTER_LIST_FLAG_DISABLED) != 0)
+ BattlemasterListEntry const* battlemasterListEntry = sBattlemasterListStore.AssertEntry(bgQueueTypeId.BattlemasterListId);
+
+ if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgQueueTypeId.BattlemasterListId, NULL) || (battlemasterListEntry->Flags & BATTLEMASTER_LIST_FLAG_DISABLED) != 0)
{
ChatHandler(this).PSendSysMessage(LANG_BG_DISABLED);
return;
}
- BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_);
-
- // can do this, since it's battleground, not arena
- BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, 0);
- BattlegroundQueueTypeId bgQueueTypeIdRandom = BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_RB, 0);
+ BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgQueueTypeId.BattlemasterListId);
// ignore if player is already in BG
if (_player->InBattleground())
@@ -127,7 +126,9 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPackets::Battleground::Batt
return;
}
- if (_player->GetBattlegroundQueueIndex(bgQueueTypeIdRandom) < PLAYER_MAX_BATTLEGROUND_QUEUES)
+ bool isInRandomBgQueue = _player->InBattlegroundQueueForBattlegroundQueueType(BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_RB, BattlegroundQueueIdType::Battleground, false, 0))
+ || _player->InBattlegroundQueueForBattlegroundQueueType(BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_RANDOM_EPIC, BattlegroundQueueIdType::Battleground, false, 0));
+ if (bgTypeId != BATTLEGROUND_RB && bgTypeId != BATTLEGROUND_RANDOM_EPIC && isInRandomBgQueue)
{
// player is already in random queue
WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus;
@@ -136,7 +137,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPackets::Battleground::Batt
return;
}
- if (_player->InBattlegroundQueue() && bgTypeId == BATTLEGROUND_RB)
+ if (_player->InBattlegroundQueue() && !isInRandomBgQueue && (bgTypeId == BATTLEGROUND_RB || bgTypeId == BATTLEGROUND_RANDOM_EPIC))
{
// player is already in queue, can't start random queue
WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus;
@@ -170,11 +171,12 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPackets::Battleground::Batt
uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId);
WorldPackets::Battleground::BattlefieldStatusQueued battlefieldStatus;
- sBattlegroundMgr->BuildBattlegroundStatusQueued(&battlefieldStatus, bg, _player, queueSlot, ginfo->JoinTime, avgTime, ginfo->ArenaType, false);
+ sBattlegroundMgr->BuildBattlegroundStatusQueued(&battlefieldStatus, bg, _player, queueSlot, ginfo->JoinTime, bgQueueTypeId, avgTime, ginfo->ArenaType, false);
SendPacket(battlefieldStatus.Write());
- TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue type %u bg type %u, %s, NAME %s",
- bgQueueTypeId, bgTypeId, _player->GetGUID().ToString().c_str(), _player->GetName().c_str());
+ TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue { BattlemasterListId: %hu, Type: %u, Rated: %s, TeamSize: %u }, %s, NAME %s",
+ bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.Type), bgQueueTypeId.Rated ? "true" : "false", uint32(bgQueueTypeId.TeamSize),
+ _player->GetGUID().ToString().c_str(), _player->GetName().c_str());
}
else
{
@@ -214,15 +216,16 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPackets::Battleground::Batt
uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId);
WorldPackets::Battleground::BattlefieldStatusQueued battlefieldStatus;
- sBattlegroundMgr->BuildBattlegroundStatusQueued(&battlefieldStatus, bg, member, queueSlot, ginfo->JoinTime, avgTime, ginfo->ArenaType, true);
+ sBattlegroundMgr->BuildBattlegroundStatusQueued(&battlefieldStatus, bg, member, queueSlot, ginfo->JoinTime, bgQueueTypeId, avgTime, ginfo->ArenaType, true);
member->SendDirectMessage(battlefieldStatus.Write());
- TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue type %u bg type %u, %s, NAME %s",
- bgQueueTypeId, bgTypeId, member->GetGUID().ToString().c_str(), member->GetName().c_str());
+ TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue { BattlemasterListId: %hu, Type: %u, Rated: %s, TeamSize: %u }, %s, NAME %s",
+ bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.Type), bgQueueTypeId.Rated ? "true" : "false", uint32(bgQueueTypeId.TeamSize),
+ member->GetGUID().ToString().c_str(), member->GetName().c_str());
}
TC_LOG_DEBUG("bg.battleground", "Battleground: group end");
}
- sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
+ sBattlegroundMgr->ScheduleQueueUpdate(0, bgQueueTypeId, bracketEntry->GetBracketId());
}
void WorldSession::HandlePVPLogDataOpcode(WorldPackets::Battleground::PVPLogDataRequest& /*pvpLogDataRequest*/)
@@ -235,8 +238,8 @@ void WorldSession::HandlePVPLogDataOpcode(WorldPackets::Battleground::PVPLogData
if (bg->isArena())
return;
- WorldPackets::Battleground::PVPLogData pvpLogData;
- bg->BuildPvPLogDataPacket(pvpLogData);
+ WorldPackets::Battleground::PVPLogDataMessage pvpLogData;
+ bg->BuildPvPLogDataPacket(pvpLogData.Data);
SendPacket(pvpLogData.Write());
}
@@ -287,7 +290,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPackets::Battleground::Battl
return;
}
- BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(bgQueueTypeId);
+ BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgQueueTypeId.BattlemasterListId);
// BGTemplateId returns BATTLEGROUND_AA when it is arena queue.
// Do instance id search as there is no AA bg instances.
Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId == BATTLEGROUND_AA ? BATTLEGROUND_TYPE_NONE : bgTypeId);
@@ -386,7 +389,9 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPackets::Battleground::Battl
sBattlegroundMgr->SendToBattleground(_player, ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
// add only in HandleMoveWorldPortAck()
// bg->AddPlayer(_player, team);
- TC_LOG_DEBUG("bg.battleground", "Battleground: player %s (%s) joined battle for bg %u, bgtype %u, queue type %u.", _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), bg->GetInstanceID(), bg->GetTypeID(), bgQueueTypeId);
+ TC_LOG_DEBUG("bg.battleground", "Battleground: player %s (%s) joined battle for bg %u, bgtype %u, queue { BattlemasterListId: %hu, Type: %u, Rated: %s, TeamSize: %u }.",
+ _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), bg->GetInstanceID(), bg->GetTypeID(),
+ bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.Type), bgQueueTypeId.Rated ? "true" : "false", uint32(bgQueueTypeId.TeamSize));
}
else // leave queue
{
@@ -410,9 +415,11 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPackets::Battleground::Battl
bgQueue.RemovePlayer(_player->GetGUID(), true);
// 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());
+ sBattlegroundMgr->ScheduleQueueUpdate(ginfo.ArenaMatchmakerRating, bgQueueTypeId, bracketEntry->GetBracketId());
- TC_LOG_DEBUG("bg.battleground", "Battleground: player %s (%s) left queue for bgtype %u, queue type %u.", _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), bg->GetTypeID(), bgQueueTypeId);
+ TC_LOG_DEBUG("bg.battleground", "Battleground: player %s (%s) left queue for bgtype %u, queue { BattlemasterListId: %hu, Type: %u, Rated: %s, TeamSize: %u }.",
+ _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), bg->GetTypeID(),
+ bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.Type), bgQueueTypeId.Rated ? "true" : "false", uint32(bgQueueTypeId.TeamSize));
}
}
@@ -434,22 +441,19 @@ void WorldSession::HandleRequestBattlefieldStatusOpcode(WorldPackets::Battlegrou
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
{
BattlegroundQueueTypeId bgQueueTypeId = _player->GetBattlegroundQueueTypeId(i);
- if (!bgQueueTypeId)
+ if (bgQueueTypeId == BATTLEGROUND_QUEUE_NONE)
continue;
- BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(bgQueueTypeId);
- uint8 arenaType = BattlegroundMgr::BGArenaType(bgQueueTypeId);
- if (bgTypeId == _player->GetBattlegroundTypeId())
+ BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgQueueTypeId.BattlemasterListId);
+ uint8 arenaType = bgQueueTypeId.TeamSize;
+ bg = _player->GetBattleground();
+ if (bg && bg->GetQueueId() == bgQueueTypeId)
{
- bg = _player->GetBattleground();
//i cannot check any variable from player class because player class doesn't know if player is in 2v2 / 3v3 or 5v5 arena
//so i must use bg pointer to get that information
- if (bg && bg->GetArenaType() == arenaType)
- {
- WorldPackets::Battleground::BattlefieldStatusActive battlefieldStatus;
- sBattlegroundMgr->BuildBattlegroundStatusActive(&battlefieldStatus, bg, _player, i, _player->GetBattlegroundQueueJoinTime(bgQueueTypeId), arenaType);
- SendPacket(battlefieldStatus.Write());
- continue;
- }
+ WorldPackets::Battleground::BattlefieldStatusActive battlefieldStatus;
+ sBattlegroundMgr->BuildBattlegroundStatusActive(&battlefieldStatus, bg, _player, i, _player->GetBattlegroundQueueJoinTime(bgQueueTypeId), arenaType);
+ SendPacket(battlefieldStatus.Write());
+ continue;
}
//we are sending update to player about queue - he can be invited there!
@@ -482,7 +486,7 @@ void WorldSession::HandleRequestBattlefieldStatusOpcode(WorldPackets::Battlegrou
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(&ginfo, bracketEntry->GetBracketId());
WorldPackets::Battleground::BattlefieldStatusQueued battlefieldStatus;
- sBattlegroundMgr->BuildBattlegroundStatusQueued(&battlefieldStatus, bg, _player, i, _player->GetBattlegroundQueueJoinTime(bgQueueTypeId), avgTime, arenaType, ginfo.Players.size() > 1);
+ sBattlegroundMgr->BuildBattlegroundStatusQueued(&battlefieldStatus, bg, _player, i, _player->GetBattlegroundQueueJoinTime(bgQueueTypeId), bgQueueTypeId, avgTime, arenaType, ginfo.Players.size() > 1);
SendPacket(battlefieldStatus.Write());
}
}
@@ -511,7 +515,7 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPackets::Battleground::Battl
}
BattlegroundTypeId bgTypeId = bg->GetTypeID();
- BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenatype);
+ BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, BattlegroundQueueIdType::Arena, true, arenatype);
PVPDifficultyEntry const* bracketEntry = DB2Manager::GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel());
if (!bracketEntry)
return;
@@ -570,13 +574,15 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPackets::Battleground::Battl
uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId);
WorldPackets::Battleground::BattlefieldStatusQueued battlefieldStatus;
- sBattlegroundMgr->BuildBattlegroundStatusQueued(&battlefieldStatus, bg, member, queueSlot, ginfo->JoinTime, avgTime, arenatype, true);
+ sBattlegroundMgr->BuildBattlegroundStatusQueued(&battlefieldStatus, bg, member, queueSlot, ginfo->JoinTime, bgQueueTypeId, avgTime, arenatype, true);
member->SendDirectMessage(battlefieldStatus.Write());
- TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena as group bg queue type %u bg type %u, %s, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUID().ToString().c_str(), member->GetName().c_str());
+ TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena as group bg queue { BattlemasterListId: %hu, Type: %u, Rated: %s, TeamSize: %u }, %s, NAME %s",
+ bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.Type), bgQueueTypeId.Rated ? "true" : "false", uint32(bgQueueTypeId.TeamSize),
+ member->GetGUID().ToString().c_str(), member->GetName().c_str());
}
- sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
+ sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, bgQueueTypeId, bracketEntry->GetBracketId());
}
void WorldSession::HandleReportPvPAFK(WorldPackets::Battleground::ReportPvPPlayerAFK& reportPvPPlayerAFK)
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index cbe5c32ff39..088cc262168 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -5091,6 +5091,7 @@ enum BattlegroundTypeId : uint32
// 809 = "New Nagrand Arena (Legion)"
BATTLEGROUND_AF = 816, // Ashamane's Fall
// 844 = "New Blade's Edge Arena (Legion)"
+ BATTLEGROUND_RANDOM_EPIC = 901
};
#define MAX_BATTLEGROUND_TYPE_ID 845
@@ -5239,25 +5240,54 @@ enum DuelCompleteType : uint8
DUEL_FLED = 2
};
-// handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time
-enum BattlegroundQueueTypeId
-{
- BATTLEGROUND_QUEUE_NONE = 0,
- BATTLEGROUND_QUEUE_AV = 1,
- BATTLEGROUND_QUEUE_WS = 2,
- BATTLEGROUND_QUEUE_AB = 3,
- BATTLEGROUND_QUEUE_EY = 4,
- BATTLEGROUND_QUEUE_SA = 5,
- BATTLEGROUND_QUEUE_IC = 6,
- BATTLEGROUND_QUEUE_TP = 7,
- BATTLEGROUND_QUEUE_BFG = 8,
- BATTLEGROUND_QUEUE_RB = 9,
- BATTLEGROUND_QUEUE_2v2 = 10,
- BATTLEGROUND_QUEUE_3v3 = 11,
- BATTLEGROUND_QUEUE_5v5 = 12,
- MAX_BATTLEGROUND_QUEUE_TYPES
+struct BattlegroundQueueTypeId
+{
+ uint16 BattlemasterListId;
+ uint8 Type;
+ bool Rated;
+ uint8 TeamSize;
+
+ static constexpr BattlegroundQueueTypeId FromPacked(uint64 packedQueueId)
+ {
+ return { packedQueueId & 0xFFFF, (packedQueueId >> 16) & 0xF, ((packedQueueId >> 20) & 1) != 0, (packedQueueId >> 24) & 0x3F };
+ }
+
+ constexpr uint64 GetPacked() const
+ {
+ return uint64(BattlemasterListId)
+ | (uint64(Type & 0xF) << 16)
+ | (uint64(Rated ? 1 : 0) << 20)
+ | (uint64(TeamSize & 0x3F) << 24)
+ | UI64LIT(0x1F10000000000000);
+ }
+
+ constexpr bool operator==(BattlegroundQueueTypeId right) const
+ {
+ return BattlemasterListId == right.BattlemasterListId
+ && Type == right.Type
+ && Rated == right.Rated
+ && TeamSize == right.TeamSize;
+ }
+
+ constexpr bool operator!=(BattlegroundQueueTypeId right) const
+ {
+ return !(*this == right);
+ }
+
+ constexpr bool operator<(BattlegroundQueueTypeId right) const
+ {
+ if (BattlemasterListId != right.BattlemasterListId)
+ return BattlemasterListId < right.BattlemasterListId;
+ if (Type != right.Type)
+ return Type < right.Type;
+ if (Rated != right.Rated)
+ return Rated < right.Rated;
+ return TeamSize < right.TeamSize;
+ }
};
+constexpr BattlegroundQueueTypeId BATTLEGROUND_QUEUE_NONE = { 0, 0, false, 0 };
+
enum GroupJoinBattlegroundResult
{
ERR_BATTLEGROUND_NONE = 0,
diff --git a/src/server/game/Server/Packets/BattlegroundPackets.cpp b/src/server/game/Server/Packets/BattlegroundPackets.cpp
index 1b974829633..0d0325644ba 100644
--- a/src/server/game/Server/Packets/BattlegroundPackets.cpp
+++ b/src/server/game/Server/Packets/BattlegroundPackets.cpp
@@ -114,19 +114,26 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Battleground::PVPLogData:
return data;
}
-WorldPacket const* WorldPackets::Battleground::PVPLogData::Write()
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Battleground::PVPLogData const& pvpLogData)
{
- _worldPacket.reserve(Statistics.size() * sizeof(PVPMatchPlayerStatistics) + sizeof(PVPLogData));
+ data.WriteBit(pvpLogData.Ratings.is_initialized());
+ data << uint32(pvpLogData.Statistics.size());
+ data.append(pvpLogData.PlayerCount.data(), pvpLogData.PlayerCount.size());
- _worldPacket.WriteBit(Ratings.is_initialized());
- _worldPacket << uint32(Statistics.size());
- _worldPacket.append(PlayerCount.data(), PlayerCount.size());
+ if (pvpLogData.Ratings.is_initialized())
+ data << *pvpLogData.Ratings;
- if (Ratings.is_initialized())
- _worldPacket << *Ratings;
+ for (WorldPackets::Battleground::PVPLogData::PVPMatchPlayerStatistics const& player : pvpLogData.Statistics)
+ data << player;
- for (PVPMatchPlayerStatistics const& player : Statistics)
- _worldPacket << player;
+ return data;
+}
+
+WorldPacket const* WorldPackets::Battleground::PVPLogDataMessage::Write()
+{
+ _worldPacket.reserve(Data.Statistics.size() * sizeof(PVPLogData::PVPMatchPlayerStatistics) + sizeof(PVPLogData));
+
+ _worldPacket << Data;
return &_worldPacket;
}
@@ -299,3 +306,31 @@ WorldPacket const* WorldPackets::Battleground::DestroyArenaUnit::Write()
_worldPacket << Guid;
return &_worldPacket;
}
+
+WorldPacket const* WorldPackets::Battleground::PVPMatchInit::Write()
+{
+ _worldPacket << uint32(MapID);
+ _worldPacket << uint8(State);
+ _worldPacket << int32(StartTime);
+ _worldPacket << int32(Duration);
+ _worldPacket << uint8(ArenaFaction);
+ _worldPacket << uint32(BattlemasterListID);
+ _worldPacket.WriteBit(Registered);
+ _worldPacket.WriteBit(AffectsRating);
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Battleground::PVPMatchEnd::Write()
+{
+ _worldPacket << uint8(Winner);
+ _worldPacket << int32(Duration);
+ _worldPacket.WriteBit(LogData.is_initialized());
+ _worldPacket.FlushBits();
+
+ if (LogData)
+ _worldPacket << *LogData;
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/BattlegroundPackets.h b/src/server/game/Server/Packets/BattlegroundPackets.h
index 6914dfef818..59c49dcc8b9 100644
--- a/src/server/game/Server/Packets/BattlegroundPackets.h
+++ b/src/server/game/Server/Packets/BattlegroundPackets.h
@@ -90,13 +90,8 @@ namespace WorldPackets
void Read() override { }
};
- class PVPLogData final : public ServerPacket
+ struct PVPLogData
{
- public:
- PVPLogData() : ServerPacket(SMSG_PVP_LOG_DATA, 0) { }
-
- WorldPacket const* Write() override;
-
struct RatingData
{
int32 Prematch[2] = { };
@@ -147,6 +142,16 @@ namespace WorldPackets
std::array<int8, 2> PlayerCount = { };
};
+ class PVPLogDataMessage final : public ServerPacket
+ {
+ public:
+ PVPLogDataMessage() : ServerPacket(SMSG_PVP_LOG_DATA, 0) { }
+
+ WorldPacket const* Write() override;
+
+ PVPLogData Data;
+ };
+
struct BattlefieldStatusHeader
{
WorldPackets::LFG::RideTicket Ticket;
@@ -418,6 +423,42 @@ namespace WorldPackets
void Read() override { }
};
+
+ class PVPMatchInit final : public ServerPacket
+ {
+ public:
+ PVPMatchInit() : ServerPacket(SMSG_PVP_MATCH_INIT, 4 + 1 + 4 + 4 + 1 + 4 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ enum MatchState : uint8
+ {
+ InProgress = 1,
+ Complete = 3,
+ Inactive = 4
+ };
+
+ uint32 MapID = 0;
+ MatchState State = Inactive;
+ time_t StartTime = time_t(0);
+ int32 Duration = 0;
+ uint8 ArenaFaction = 0;
+ uint32 BattlemasterListID = 0;
+ bool Registered = false;
+ bool AffectsRating = false;
+ };
+
+ class PVPMatchEnd final : public ServerPacket
+ {
+ public:
+ PVPMatchEnd() : ServerPacket(SMSG_PVP_MATCH_END) { }
+
+ WorldPacket const* Write() override;
+
+ uint8 Winner = 0;
+ int32 Duration = 0;
+ Optional<PVPLogData> LogData;
+ };
}
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index a8f0be7874e..521ba8a8407 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -925,8 +925,6 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_RE_PATH, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_RE_SHAPE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_CROWD_CONTROL_SPELLS, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_MATCH_END, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_MATCH_START, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_PREP_OPPONENT_SPECIALIZATIONS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARTIFACT_FORGE_OPENED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARTIFACT_RESPEC_CONFIRM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1637,6 +1635,8 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PUSH_SPELL_TO_ACTION_BAR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_CREDIT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_LOG_DATA, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_MATCH_END, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_MATCH_INIT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_MATCH_START, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_OPTIONS_ENABLED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_SEASON, STATUS_NEVER, CONNECTION_TYPE_REALM);
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index 2c90b66c0db..8b73a6fc26a 100644
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -825,8 +825,6 @@ enum OpcodeServer : uint16
SMSG_AREA_TRIGGER_RE_PATH = 0x263F,
SMSG_AREA_TRIGGER_RE_SHAPE = 0x2644,
SMSG_ARENA_CROWD_CONTROL_SPELLS = 0x2652,
- SMSG_ARENA_MATCH_END = 0x28A7,
- SMSG_ARENA_MATCH_START = 0x28A6,
SMSG_ARENA_PREP_OPPONENT_SPECIALIZATIONS = 0x2668,
SMSG_ARTIFACT_FORGE_OPENED = 0x27E8,
SMSG_ARTIFACT_RESPEC_CONFIRM = 0x27EB,
@@ -1543,7 +1541,9 @@ enum OpcodeServer : uint16
SMSG_PUSH_SPELL_TO_ACTION_BAR = 0x2C51,
SMSG_PVP_CREDIT = 0x271F,
SMSG_PVP_LOG_DATA = 0x25B4,
- SMSG_PVP_MATCH_START = 0x28AC,
+ SMSG_PVP_MATCH_END = 0x28A7,
+ SMSG_PVP_MATCH_INIT = 0x28AC,
+ SMSG_PVP_MATCH_START = 0x28A6,
SMSG_PVP_OPTIONS_ENABLED = 0x25B7,
SMSG_PVP_SEASON = 0x25D4,
SMSG_QUERY_BATTLE_PET_NAME_RESPONSE = 0x270E,
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 0b7c1583faf..1618267d420 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -541,7 +541,8 @@ void WorldSession::LogoutPlayer(bool save)
for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
{
- if (BattlegroundQueueTypeId bgQueueTypeId = _player->GetBattlegroundQueueTypeId(i))
+ BattlegroundQueueTypeId bgQueueTypeId = _player->GetBattlegroundQueueTypeId(i);
+ if (bgQueueTypeId != BATTLEGROUND_QUEUE_NONE)
{
_player->RemoveBattlegroundQueueId(bgQueueTypeId);
BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);