aboutsummaryrefslogtreecommitdiff
path: root/src/game/BattleGroundMgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/BattleGroundMgr.cpp')
-rw-r--r--src/game/BattleGroundMgr.cpp201
1 files changed, 201 insertions, 0 deletions
diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp
index 99339a835a6..f2143de5bdc 100644
--- a/src/game/BattleGroundMgr.cpp
+++ b/src/game/BattleGroundMgr.cpp
@@ -17,11 +17,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+
#include "Common.h"
#include "ObjectMgr.h"
#include "World.h"
#include "WorldPacket.h"
#include "Policies/SingletonImp.h"
+
#include "ArenaTeam.h"
#include "BattleGroundMgr.h"
#include "BattleGroundAV.h"
@@ -43,10 +45,13 @@
#include "GameEventMgr.h"
#include "ProgressBar.h"
#include "SharedDefines.h"
+
INSTANTIATE_SINGLETON_1( BattleGroundMgr );
+
/*********************************************************/
/*** BATTLEGROUND QUEUE SYSTEM ***/
/*********************************************************/
+
BattleGroundQueue::BattleGroundQueue()
{
for(uint32 i = 0; i < BG_TEAMS_COUNT; i++)
@@ -60,6 +65,7 @@ BattleGroundQueue::BattleGroundQueue()
}
}
}
+
BattleGroundQueue::~BattleGroundQueue()
{
m_QueuedPlayers.clear();
@@ -73,15 +79,18 @@ BattleGroundQueue::~BattleGroundQueue()
}
}
}
+
/*********************************************************/
/*** BATTLEGROUND QUEUE SELECTION POOLS ***/
/*********************************************************/
+
// selection pool initialization, used to clean up from prev selection
void BattleGroundQueue::SelectionPool::Init()
{
SelectedGroups.clear();
PlayerCount = 0;
}
+
// remove group info from selection pool
// returns true when we need to try to add new group to selection pool
// returns false when selection pool is ok or when we kicked smaller group than we need to kick
@@ -114,6 +123,7 @@ bool BattleGroundQueue::SelectionPool::KickGroup(uint32 size)
}
return true;
}
+
// add group to selection pool
// used when building selection pools
// returns true if we can invite more players, or when we added group to selection pool
@@ -132,13 +142,16 @@ bool BattleGroundQueue::SelectionPool::AddGroup(GroupQueueInfo *ginfo, uint32 de
return true;
return false;
}
+
/*********************************************************/
/*** BATTLEGROUND QUEUES ***/
/*********************************************************/
+
// add group to bg queue with the given leader and bg specifications
GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, BattleGroundTypeId BgTypeId, uint8 ArenaType, bool isRated, bool isPremade, uint32 arenaRating, uint32 arenateamid)
{
BGQueueIdBasedOnLevel queue_id = leader->GetBattleGroundQueueIdFromLevel(BgTypeId);
+
// create new ginfo
// cannot use the method like in addplayer, because that could modify an in-queue group's stats
// (e.g. leader leaving queue then joining as individual again)
@@ -153,7 +166,9 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, BattleGroundTypeId
ginfo->Team = leader->GetTeam();
ginfo->ArenaTeamRating = arenaRating;
ginfo->OpponentsTeamRating = 0;
+
ginfo->Players.clear();
+
//compute index (if group is premade or joined a rated match) to queues
uint32 index = 0;
if (!isRated && !isPremade)
@@ -161,10 +176,13 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, BattleGroundTypeId
if (ginfo->Team == HORDE)
index++;
sLog.outDebug("Adding Group to BattleGroundQueue bgTypeId : %u, queue_id : %u, index : %u", BgTypeId, queue_id, index);
+
m_QueuedGroups[queue_id][index].push_back(ginfo);
+
// return ginfo, because it is needed to add players to this group info
return ginfo;
}
+
//add player to playermap
void BattleGroundQueue::AddPlayer(Player *plr, GroupQueueInfo *ginfo)
{
@@ -172,9 +190,11 @@ void BattleGroundQueue::AddPlayer(Player *plr, GroupQueueInfo *ginfo)
PlayerQueueInfo& info = m_QueuedPlayers[plr->GetGUID()];
info.LastOnlineTime = getMSTime();
info.GroupInfo = ginfo;
+
// add the pinfo to ginfo's list
ginfo->Players[plr->GetGUID()] = &info;
}
+
void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id)
{
uint32 timeInQueue = getMSTimeDiff(ginfo->JoinTime, getMSTime());
@@ -189,6 +209,7 @@ void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* g
if (ginfo->IsRated)
team_index = BG_TEAM_HORDE; //for rated arenas use BG_TEAM_HORDE
}
+
//store pointer to arrayindex of player that was added first
uint32* lastPlayerAddedPointer = &(m_WaitTimeLastPlayer[team_index][queue_id]);
//remove his time from sum
@@ -201,6 +222,7 @@ void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* g
(*lastPlayerAddedPointer)++;
(*lastPlayerAddedPointer) %= COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME;
}
+
uint32 BattleGroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id)
{
uint8 team_index = BG_TEAM_ALLIANCE; //default set to BG_TEAM_ALLIANCE - or non rated arenas!
@@ -221,12 +243,15 @@ uint32 BattleGroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueue
//if there aren't enough values return 0 - not available
return 0;
}
+
//remove player from queue and from group info, if group info is empty then remove it too
void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCount)
{
//Player *plr = objmgr.GetPlayer(guid);
+
int32 queue_id = -1; // signed for proper for-loop finish
QueuedPlayersMap::iterator itr;
+
//remove player from map, if he's there
itr = m_QueuedPlayers.find(guid);
if (itr == m_QueuedPlayers.end())
@@ -234,12 +259,14 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
sLog.outError("BattleGroundQueue: couldn't find player to remove GUID: %u", GUID_LOPART(guid));
return;
}
+
GroupQueueInfo* group = itr->second.GroupInfo;
GroupsQueueType::iterator group_itr, group_itr_tmp;
// mostly people with the highest levels are in battlegrounds, thats why
// we count from MAX_BATTLEGROUND_QUEUES - 1 to 0
// variable index removes useless searching in other team's queue
uint32 index = (group->Team == HORDE) ? BG_TEAM_HORDE : BG_TEAM_ALLIANCE;
+
for (int32 queue_id_tmp = MAX_BATTLEGROUND_QUEUES - 1; queue_id_tmp >= 0 && queue_id == -1; --queue_id_tmp)
{
//we must check premade and normal team's queue - because when players from premade are joining bg,
@@ -266,14 +293,17 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
return;
}
sLog.outDebug("BattleGroundQueue: Removing player GUID %u, from queue_id %u", GUID_LOPART(guid), (uint32)queue_id);
+
// ALL variables are correctly set
// We can ignore leveling up in queue - it should not cause crash
// remove player from group
// if only one player there, remove group
+
// remove player queue info from group queue info
std::map<uint64, PlayerQueueInfo*>::iterator pitr = group->Players.find(guid);
if (pitr != group->Players.end())
group->Players.erase(pitr);
+
// if invited to bg, and should decrease invited count, then do it
if (decreaseInvitedCount && group->IsInvitedToBGInstanceGUID)
{
@@ -281,11 +311,14 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
if (bg)
bg->DecreaseInvitedCount(group->Team);
}
+
// remove player queue info
m_QueuedPlayers.erase(itr);
+
//if we left BG queue(not porting) OR if arena team left queue for rated match
if ((decreaseInvitedCount && !group->ArenaType) || (group->ArenaType && group->IsRated && group->Players.empty()))
AnnounceWorld(group, guid, false);
+
//if player leaves queue and he is invited to rated arena match, then he have to loose
if (group->IsInvitedToBGInstanceGUID && group->IsRated && decreaseInvitedCount)
{
@@ -301,6 +334,7 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
at->SaveToDB();
}
}
+
// remove group queue info if needed
if (group->Players.empty())
{
@@ -329,6 +363,7 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
RemovePlayer(group->Players.begin()->first, decreaseInvitedCount);
}
}
+
//Announce world message
void BattleGroundQueue::AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue)
{
@@ -339,6 +374,7 @@ void BattleGroundQueue::AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playe
BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(ginfo->BgTypeId);
if (!bg)
return;
+
char const* bgName = bg->GetName();
if (isAddedToQueue)
{
@@ -370,6 +406,7 @@ void BattleGroundQueue::AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playe
BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(ginfo->BgTypeId);
if (!bg || !plr)
return;
+
BGQueueIdBasedOnLevel queue_id = plr->GetBattleGroundQueueIdFromLevel(bg->GetTypeID());
char const* bgName = bg->GetName();
uint32 MinPlayers = bg->GetMinPlayersPerTeam();
@@ -384,6 +421,7 @@ void BattleGroundQueue::AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playe
for(itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].end(); ++itr)
if (!(*itr)->IsInvitedToBGInstanceGUID)
qHorde += (*itr)->Players.size();
+
// Show queue status to player only (when joining queue)
if (sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
{
@@ -399,11 +437,13 @@ void BattleGroundQueue::AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playe
}
}
}
+
bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side)
{
// set side if needed
if (side)
ginfo->Team = side;
+
if (!ginfo->IsInvitedToBGInstanceGUID)
{
// not yet invited
@@ -412,10 +452,13 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b
BattleGroundTypeId bgTypeId = bg->GetTypeID();
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, bg->GetArenaType());
BGQueueIdBasedOnLevel queue_id = bg->GetQueueId();
+
// set ArenaTeamId for rated matches
if (bg->isArena() && bg->isRated())
bg->SetArenaTeamIdForTeam(ginfo->Team, ginfo->ArenaTeamId);
+
ginfo->RemoveInviteTime = getMSTime() + INVITE_ACCEPT_WAIT_TIME;
+
// loop through the players
for(std::map<uint64,PlayerQueueInfo*>::iterator itr = ginfo->Players.begin(); itr != ginfo->Players.end(); ++itr)
{
@@ -424,29 +467,39 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b
// if offline, skip him, this should not happen - player is removed from queue when he logs out
if (!plr)
continue;
+
// invite the player
PlayerInvitedToBGUpdateAverageWaitTime(ginfo, queue_id);
//sBattleGroundMgr.InvitePlayer(plr, bg, ginfo->Team);
+
// set invited player counters
bg->IncreaseInvitedCount(ginfo->Team);
+
plr->SetInviteForBattleGroundQueueType(bgQueueTypeId, ginfo->IsInvitedToBGInstanceGUID);
+
// create remind invite events
BGQueueInviteEvent* inviteEvent = new BGQueueInviteEvent(plr->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, ginfo->RemoveInviteTime);
plr->m_Events.AddEvent(inviteEvent, plr->m_Events.CalculateTime(INVITATION_REMIND_TIME));
// create automatic remove events
BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(plr->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, bgQueueTypeId, ginfo->RemoveInviteTime);
plr->m_Events.AddEvent(removeEvent, plr->m_Events.CalculateTime(INVITE_ACCEPT_WAIT_TIME));
+
WorldPacket data;
+
uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId);
+
sLog.outDebug("Battleground: invited plr %s (%u) to BG instance %u queueindex %u bgtype %u, I can't help it if they don't press the enter battle button.",plr->GetName(),plr->GetGUIDLow(),bg->GetInstanceID(),queueSlot,bg->GetTypeID());
+
// send status packet
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0, ginfo->ArenaType);
plr->GetSession()->SendPacket(&data);
}
return true;
}
+
return false;
}
+
/*
This function is inviting players to already running battlegrounds
Invitation type is based on config file
@@ -456,6 +509,7 @@ void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel
{
int32 hordeFree = bg->GetFreeSlotsForTeam(HORDE);
int32 aliFree = bg->GetFreeSlotsForTeam(ALLIANCE);
+
//iterator for iterating through bg queue
GroupsQueueType::const_iterator Ali_itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].begin();
//count of groups in queue - used to stop cycles
@@ -470,9 +524,11 @@ void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel
uint32 hordeIndex = 0;
for (; hordeIndex < hordeCount && m_SelectionPools[BG_TEAM_HORDE].AddGroup((*Horde_itr), hordeFree); hordeIndex++)
++Horde_itr;
+
//if ofc like BG queue invitation is set in config, then we are happy
if (sWorld.getConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE) == 0)
return;
+
/*
if we reached this code, then we have to solve NP - complete problem called Subset sum problem
So one solution is to check all possible invitation subgroups, or we can use these conditions:
@@ -480,6 +536,7 @@ void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel
that we will invite now whole queue, because only 1 change has been made to queues from the last BattleGroundQueue::Update call
2. Other thing we should consider is group order in queue
*/
+
// At first we need to compare free space in bg and our selection pool
int32 diffAli = aliFree - int32(m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount());
int32 diffHorde = hordeFree - int32(m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount());
@@ -522,6 +579,7 @@ void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel
diffHorde = hordeFree - int32(m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount());
}
}
+
// this method checks if premade versus premade battleground is possible
// then after 30 mins (default) in queue it moves premade group to normal queue
// it tries to invite as much players as it can - to MaxPlayersPerTeam, because premade groups have more than MinPlayersPerTeam players
@@ -539,6 +597,7 @@ bool BattleGroundQueue::CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32
for( horde_group = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].begin(); horde_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].end(); ++horde_group)
if (!(*horde_group)->IsInvitedToBGInstanceGUID)
break;
+
if (ali_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].end() && horde_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].end())
{
m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*ali_group), MaxPlayersPerTeam);
@@ -580,6 +639,7 @@ bool BattleGroundQueue::CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32
//selection pools are not set
return false;
}
+
// this method tries to create battleground or arena with MinPlayersPerTeam against MinPlayersPerTeam
bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BGQueueIdBasedOnLevel queue_id, uint32 minPlayers, uint32 maxPlayers)
{
@@ -622,6 +682,7 @@ bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BGQueueIdBas
//return true if there are enough players in selection pools - enable to work .debug bg command correctly
return m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() >= minPlayers && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() >= minPlayers;
}
+
// this method will check if we can invite players to same faction skirmish match
bool BattleGroundQueue::CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_id, uint32 minPlayersPerTeam)
{
@@ -658,6 +719,7 @@ bool BattleGroundQueue::CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_
}
if (m_SelectionPools[otherTeam].GetPlayerCount() != minPlayersPerTeam)
return false;
+
//here we have correct 2 selections and we need to change one teams team and move selection pool teams to other team's queue
for(GroupsQueueType::iterator itr = m_SelectionPools[otherTeam].SelectedGroups.begin(); itr != m_SelectionPools[otherTeam].SelectedGroups.end(); ++itr)
{
@@ -679,6 +741,7 @@ bool BattleGroundQueue::CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_
}
return true;
}
+
/*
this method is called when group is inserted, or player / group is removed from BG Queue - there is only one player's status changed, so we don't use while(true) cycles to invite whole queue
it must be called after fully adding the members of a group to ensure group joining
@@ -692,6 +755,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].empty() &&
m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].empty() )
return;
+
//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 queue_id_based_on_level
BGFreeSlotQueueType::iterator itr, next;
@@ -705,16 +769,20 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
{
BattleGround* bg = *itr; //we have to store battleground pointer here, because when battleground is full, it is removed from free queue (not yet implemented!!)
// and iterator is invalid
+
// clear selection pools
m_SelectionPools[BG_TEAM_ALLIANCE].Init();
m_SelectionPools[BG_TEAM_HORDE].Init();
+
// call a function that does the job for us
FillPlayersToBG(bg, queue_id);
+
// now everything is set, invite players
for(GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.end(); ++citr)
InviteGroupToBG((*citr), bg, (*citr)->Team);
for(GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_HORDE].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_HORDE].SelectedGroups.end(); ++citr)
InviteGroupToBG((*citr), bg, (*citr)->Team);
+
if (!bg->HasFreeSlots())
{
// remove BG from BGFreeSlotQueue
@@ -722,7 +790,9 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
}
}
}
+
// finished iterating through the bgs with free slots, maybe we need to create a new bg
+
BattleGround * bg_template = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
if (!bg_template)
{
@@ -763,8 +833,10 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
}*/
}
}
+
m_SelectionPools[BG_TEAM_ALLIANCE].Init();
m_SelectionPools[BG_TEAM_HORDE].Init();
+
if (bg_template->isBattleGround())
{
//check if there is premade against premade match
@@ -788,6 +860,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
m_SelectionPools[BG_TEAM_HORDE].Init();
}
}
+
// now check if there are in queues enough players to start new game of (normal battleground, or non-rated arena)
if (!isRated)
{
@@ -802,6 +875,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
sLog.outError("BattleGroundQueue::Update - Cannot create battleground: %u", bgTypeId);
return;
}
+
// invite those selection pools
for(uint32 i = 0; i < BG_TEAMS_COUNT; i++)
for(GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.end(); ++citr)
@@ -837,6 +911,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
else if (!front1 && !front2)
return; //queues are empty
}
+
//set rating range
uint32 arenaMinRating = (arenaRating <= sBattleGroundMgr.GetMaxRatingDifference()) ? 0 : arenaRating - sBattleGroundMgr.GetMaxRatingDifference();
uint32 arenaMaxRating = arenaRating + sBattleGroundMgr.GetMaxRatingDifference();
@@ -845,9 +920,13 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
// the discard time is current_time - time_to_discard, teams that joined after that, will have their ratings taken into account
// else leave the discard time on 0, this way all ratings will be discarded
uint32 discardTime = getMSTime() - sBattleGroundMgr.GetRatingDiscardTimer();
+
// we need to find 2 teams which will play next game
+
GroupsQueueType::iterator itr_team[BG_TEAMS_COUNT];
+
//optimalization : --- we dont need to use selection_pools - each update we select max 2 groups
+
for(uint32 i = BG_QUEUE_PREMADE_ALLIANCE; i < BG_QUEUE_NORMAL_ALLIANCE; i++)
{
// take the group that joined first
@@ -900,6 +979,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
}
}
}
+
//if we have 2 teams, then start new arena and invite players!
if (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount())
{
@@ -909,6 +989,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
sLog.outError("BattlegroundQueue::Update couldn't create arena instance for rated arena match!");
return;
}
+
(*(itr_team[BG_TEAM_ALLIANCE]))->OpponentsTeamRating = (*(itr_team[BG_TEAM_HORDE]))->ArenaTeamRating;
sLog.outDebug("setting oposite teamrating for team %u to %u", (*(itr_team[BG_TEAM_ALLIANCE]))->ArenaTeamId, (*(itr_team[BG_TEAM_ALLIANCE]))->OpponentsTeamRating);
(*(itr_team[BG_TEAM_HORDE]))->OpponentsTeamRating = (*(itr_team[BG_TEAM_ALLIANCE]))->ArenaTeamRating;
@@ -928,26 +1009,33 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].erase(itr_team[BG_TEAM_HORDE]);
itr_team[BG_TEAM_HORDE] = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].begin();
}
+
InviteGroupToBG(*(itr_team[BG_TEAM_ALLIANCE]), arena, ALLIANCE);
InviteGroupToBG(*(itr_team[BG_TEAM_HORDE]), arena, HORDE);
+
sLog.outDebug("Starting rated arena match!");
+
arena->StartBattleGround();
}
}
}
+
/*********************************************************/
/*** BATTLEGROUND QUEUE EVENTS ***/
/*********************************************************/
+
bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
{
Player* plr = objmgr.GetPlayer( m_PlayerGuid );
// player logged off (we should do nothing, he is correctly removed from queue in another procedure)
if (!plr)
return true;
+
BattleGround* bg = sBattleGroundMgr.GetBattleGround(m_BgInstanceGUID, m_BgTypeId);
//if battleground ended and its instance deleted - do nothing
if (!bg)
return true;
+
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId);
if( queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES ) // player is in queue or in battleground
@@ -966,10 +1054,12 @@ bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
}
return true; //event will be deleted
}
+
void BGQueueInviteEvent::Abort(uint64 /*e_time*/)
{
//do nothing
}
+
/*
this event has many possibilities when it is executed:
1. player is in battleground ( he clicked enter on invitation window )
@@ -985,9 +1075,11 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
if (!plr)
// 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 can be deleted already when we are removing queue info
//bg pointer can be NULL! so use it carefully!
+
uint32 queueSlot = plr->GetBattleGroundQueueIndex(m_BgQueueTypeId);
if( queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES ) // player is in queue, or in Battleground
{
@@ -999,26 +1091,32 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
&& qMapItr->second.GroupInfo->RemoveInviteTime == m_RemoveTime )
{
sLog.outDebug("Battleground: removing player %u from bg queue for instance %u because of not pressing enter battle in time.",plr->GetGUIDLow(),m_BgInstanceGUID);
+
plr->RemoveBattleGroundQueueId(m_BgQueueTypeId);
sBattleGroundMgr.m_BattleGroundQueues[m_BgQueueTypeId].RemovePlayer(m_PlayerGuid, true);
//update queues if battleground isn't ended
if (bg)
sBattleGroundMgr.ScheduleQueueUpdate(m_BgQueueTypeId, m_BgTypeId, bg->GetQueueId());
+
WorldPacket data;
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0);
plr->GetSession()->SendPacket(&data);
}
}
+
//event will be deleted
return true;
}
+
void BGQueueRemoveEvent::Abort(uint64 /*e_time*/)
{
//do nothing
}
+
/*********************************************************/
/*** BATTLEGROUND MANAGER ***/
/*********************************************************/
+
BattleGroundMgr::BattleGroundMgr() : m_AutoDistributionTimeChecker(0), m_ArenaTesting(false)
{
for(uint32 i = BATTLEGROUND_TYPE_NONE; i < MAX_BATTLEGROUND_TYPE_ID; i++)
@@ -1026,10 +1124,12 @@ BattleGroundMgr::BattleGroundMgr() : m_AutoDistributionTimeChecker(0), m_ArenaTe
m_NextRatingDiscardUpdate = sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER);
m_Testing=false;
}
+
BattleGroundMgr::~BattleGroundMgr()
{
DeleteAllBattleGrounds();
}
+
void BattleGroundMgr::DeleteAllBattleGrounds()
{
for(uint32 i = BATTLEGROUND_TYPE_NONE; i < MAX_BATTLEGROUND_TYPE_ID; i++)
@@ -1043,6 +1143,7 @@ void BattleGroundMgr::DeleteAllBattleGrounds()
delete bg;
}
}
+
// destroy template battlegrounds that listed only in queues (other already terminated)
for(uint32 bgTypeId = 0; bgTypeId < MAX_BATTLEGROUND_TYPE_ID; ++bgTypeId)
{
@@ -1051,6 +1152,7 @@ void BattleGroundMgr::DeleteAllBattleGrounds()
delete BGFreeSlotQueue[bgTypeId].front();
}
}
+
// used to update running battlegrounds, and delete finished ones
void BattleGroundMgr::Update(uint32 diff)
{
@@ -1078,6 +1180,7 @@ void BattleGroundMgr::Update(uint32 diff)
}
}
}
+
// update scheduled queues
if (!m_QueueUpdateScheduler.empty())
{
@@ -1095,6 +1198,7 @@ void BattleGroundMgr::Update(uint32 diff)
m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, queue_id);
}
}
+
// if rating difference counts, maybe force-update queues
if (sWorld.getConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE) && sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER))
{
@@ -1130,9 +1234,11 @@ void BattleGroundMgr::Update(uint32 diff)
m_AutoDistributionTimeChecker -= diff;
}
}
+
void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint8 arenatype)
{
// we can be in 3 queues in same time...
+
if (StatusID == 0 || !bg)
{
data->Initialize(SMSG_BATTLEFIELD_STATUS, 4*3);
@@ -1140,6 +1246,7 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro
*data << uint64(0);
return;
}
+
data->Initialize(SMSG_BATTLEFIELD_STATUS, (4+1+1+4+2+4+1+4+4+4));
*data << uint32(QueueSlot); // queue id (0...2) - player can be in 3 queues in time
// uint64 in client
@@ -1188,12 +1295,15 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro
*data << uint8(0);
break;
}
+
if (bg->isArena() && (StatusID == STATUS_WAIT_QUEUE))
*data << uint32(BATTLEGROUND_AA); // all arenas I don't think so.
else
*data << uint32(bg->GetTypeID()); // BG id from DBC
+
*data << uint16(0x1F90); // unk value 8080
*data << uint32(bg->GetInstanceID()); // instance id
+
*data << uint8(bg->isArena()); // minimap-icon 0=faction 1=arena
*/
*data << uint32(StatusID); // status
@@ -1218,12 +1328,14 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro
break;
}
}
+
void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
{
uint8 type = (bg->isArena() ? 1 : 0);
// last check on 3.0.3
data->Initialize(MSG_PVP_LOG_DATA, (1+1+4+40*bg->GetPlayerScoresSize()));
*data << uint8(type); // type (battleground=0/arena=1)
+
if(type) // arena
{
// it seems this must be according to BG_WINNER_A/H and _NOT_ BG_TEAM_A/H
@@ -1244,6 +1356,7 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
*data << (uint8)0;
}
}
+
if (bg->GetStatus() != STATUS_WAIT_LEAVE)
{
*data << uint8(0); // bg not ended
@@ -1253,7 +1366,9 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
*data << uint8(1); // bg ended
*data << uint8(bg->GetWinner()); // who win
}
+
*data << (int32)(bg->GetPlayerScoresSize());
+
for(BattleGround::BattleGroundScoreMap::const_iterator itr = bg->GetPlayerScoresBegin(); itr != bg->GetPlayerScoresEnd(); ++itr)
{
*data << (uint64)itr->first;
@@ -1317,6 +1432,7 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
}
}
}
+
void BattleGroundMgr::BuildGroupJoinedBattlegroundPacket(WorldPacket *data, BattleGroundTypeId bgTypeId)
{
/*bgTypeId is:
@@ -1331,27 +1447,32 @@ void BattleGroundMgr::BuildGroupJoinedBattlegroundPacket(WorldPacket *data, Batt
data->Initialize(SMSG_GROUP_JOINED_BATTLEGROUND, 4);
*data << uint32(bgTypeId);
}
+
void BattleGroundMgr::BuildUpdateWorldStatePacket(WorldPacket *data, uint32 field, uint32 value)
{
data->Initialize(SMSG_UPDATE_WORLD_STATE, 4+4);
*data << uint32(field);
*data << uint32(value);
}
+
void BattleGroundMgr::BuildPlaySoundPacket(WorldPacket *data, uint32 soundid)
{
data->Initialize(SMSG_PLAY_SOUND, 4);
*data << uint32(soundid);
}
+
void BattleGroundMgr::BuildPlayerLeftBattleGroundPacket(WorldPacket *data, const uint64& guid)
{
data->Initialize(SMSG_BATTLEGROUND_PLAYER_LEFT, 8);
*data << uint64(guid);
}
+
void BattleGroundMgr::BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Player *plr)
{
data->Initialize(SMSG_BATTLEGROUND_PLAYER_JOINED, 8);
*data << uint64(plr->GetGUID());
}
+
BattleGround * BattleGroundMgr::GetBattleGroundThroughClientInstance(uint32 instanceId, BattleGroundTypeId bgTypeId)
{
//cause at HandleBattleGroundJoinOpcode the clients sends the instanceid he gets from
@@ -1359,8 +1480,10 @@ BattleGround * BattleGroundMgr::GetBattleGroundThroughClientInstance(uint32 inst
BattleGround* bg = GetBattleGroundTemplate(bgTypeId);
if (!bg)
return NULL;
+
if (bg->isArena())
return GetBattleGround(instanceId, bgTypeId);
+
for(BattleGroundSet::iterator itr = m_BattleGrounds[bgTypeId].begin(); itr != m_BattleGrounds[bgTypeId].end(); ++itr)
{
if (itr->second->GetClientInstanceID() == instanceId)
@@ -1368,6 +1491,7 @@ BattleGround * BattleGroundMgr::GetBattleGroundThroughClientInstance(uint32 inst
}
return NULL;
}
+
BattleGround * BattleGroundMgr::GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId)
{
if (!InstanceID)
@@ -1387,15 +1511,18 @@ BattleGround * BattleGroundMgr::GetBattleGround(uint32 InstanceID, BattleGroundT
itr = m_BattleGrounds[bgTypeId].find(InstanceID);
return ( (itr != m_BattleGrounds[bgTypeId].end()) ? itr->second : NULL );
}
+
BattleGround * BattleGroundMgr::GetBattleGroundTemplate(BattleGroundTypeId bgTypeId)
{
//map is sorted and we can be sure that lowest instance id has only BG template
return m_BattleGrounds[bgTypeId].empty() ? NULL : m_BattleGrounds[bgTypeId].begin()->second;
}
+
uint32 BattleGroundMgr::CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id)
{
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
@@ -1412,6 +1539,7 @@ uint32 BattleGroundMgr::CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeI
m_ClientBattleGroundIds[bgTypeId][queue_id].insert(lastId + 1);
return lastId + 1;
}
+
// create a new battleground that will really be used to play
BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated)
{
@@ -1422,6 +1550,7 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeI
sLog.outError("BattleGround: CreateNewBattleGround - bg template not found for %u", bgTypeId);
return NULL;
}
+
//for arenas there is random map used
if (bg_template->isArena())
{
@@ -1435,6 +1564,7 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeI
return NULL;
}
}
+
BattleGround *bg = NULL;
// create a copy of the BG template
switch(bgTypeId)
@@ -1476,18 +1606,23 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeI
//error, but it is handled few lines above
return 0;
}
+
// generate a new instance id
bg->SetInstanceID(MapManager::Instance().GenerateInstanceId()); // set instance id
bg->SetClientInstanceID(CreateClientVisibleInstanceId(bgTypeId, queue_id));
+
// reset the new bg (set status to status_wait_queue from status_none)
bg->Reset();
+
// start the joining of the bg
bg->SetStatus(STATUS_WAIT_JOIN);
bg->SetQueueId(queue_id);
bg->SetArenaType(arenaType);
bg->SetRated(isRated);
+
return bg;
}
+
// used to create the BG templates
uint32 BattleGroundMgr::CreateBattleGround(BattleGroundTypeId bgTypeId, bool IsArena, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO)
{
@@ -1508,6 +1643,7 @@ uint32 BattleGroundMgr::CreateBattleGround(BattleGroundTypeId bgTypeId, bool IsA
case BATTLEGROUND_RV: bg = new BattleGroundRV; break;
default:bg = new BattleGround; break; // placeholder for non implemented BG
}
+
bg->SetMapId(MapID);
bg->SetTypeID(bgTypeId);
bg->SetInstanceID(0);
@@ -1520,11 +1656,14 @@ uint32 BattleGroundMgr::CreateBattleGround(BattleGroundTypeId bgTypeId, bool IsA
bg->SetTeamStartLoc(ALLIANCE, Team1StartLocX, Team1StartLocY, Team1StartLocZ, Team1StartLocO);
bg->SetTeamStartLoc(HORDE, Team2StartLocX, Team2StartLocY, Team2StartLocZ, Team2StartLocO);
bg->SetLevelRange(LevelMin, LevelMax);
+
// add bg to update list
AddBattleGround(bg->GetInstanceID(), bg->GetTypeID(), bg);
+
// return some not-null value, bgTypeId is good enough for me
return bgTypeId;
}
+
void BattleGroundMgr::CreateInitialBattleGrounds()
{
float AStartLoc[4];
@@ -1533,23 +1672,32 @@ void BattleGroundMgr::CreateInitialBattleGrounds()
BattlemasterListEntry const *bl;
WorldSafeLocsEntry const *start;
bool IsArena;
+
uint32 count = 0;
+
// 0 1 2 3 4 5 6 7 8
QueryResult *result = WorldDatabase.Query("SELECT id, MinPlayersPerTeam,MaxPlayersPerTeam,MinLvl,MaxLvl,AllianceStartLoc,AllianceStartO,HordeStartLoc,HordeStartO FROM battleground_template");
+
if (!result)
{
barGoLink bar(1);
+
bar.step();
+
sLog.outString();
sLog.outErrorDb(">> Loaded 0 battlegrounds. DB table `battleground_template` is empty.");
return;
}
+
barGoLink bar(result->GetRowCount());
+
do
{
Field *fields = result->Fetch();
bar.step();
+
uint32 bgTypeID_ = fields[0].GetUInt32();
+
// can be overwrite by values from DB
bl = sBattlemasterListStore.LookupEntry(bgTypeID_);
if (!bl)
@@ -1557,7 +1705,9 @@ void BattleGroundMgr::CreateInitialBattleGrounds()
sLog.outError("Battleground ID %u not found in BattlemasterList.dbc. Battleground not created.", bgTypeID_);
continue;
}
+
BattleGroundTypeId bgTypeID = BattleGroundTypeId(bgTypeID_);
+
IsArena = (bl->type == TYPE_ARENA);
MinPlayersPerTeam = fields[1].GetUInt32();
MaxPlayersPerTeam = fields[2].GetUInt32();
@@ -1574,7 +1724,9 @@ void BattleGroundMgr::CreateInitialBattleGrounds()
MinLvl = bl->minlvl;
MaxLvl = bl->maxlvl;
}
+
start1 = fields[5].GetUInt32();
+
start = sWorldSafeLocsStore.LookupEntry(start1);
if (start)
{
@@ -1595,7 +1747,9 @@ void BattleGroundMgr::CreateInitialBattleGrounds()
sLog.outErrorDb("Table `battleground_template` for id %u have non-existed WorldSafeLocs.dbc id %u in field `AllianceStartLoc`. BG not created.", bgTypeID, start1);
continue;
}
+
start2 = fields[7].GetUInt32();
+
start = sWorldSafeLocsStore.LookupEntry(start2);
if (start)
{
@@ -1616,15 +1770,20 @@ void BattleGroundMgr::CreateInitialBattleGrounds()
sLog.outErrorDb("Table `battleground_template` for id %u have non-existed WorldSafeLocs.dbc id %u in field `HordeStartLoc`. BG not created.", bgTypeID, start2);
continue;
}
+
//sLog.outDetail("Creating battleground %s, %u-%u", bl->name[sWorld.GetDBClang()], MinLvl, MaxLvl);
if (!CreateBattleGround(bgTypeID, IsArena, MinPlayersPerTeam, MaxPlayersPerTeam, MinLvl, MaxLvl, bl->name[sWorld.GetDefaultDbcLocale()], bl->mapid[0], AStartLoc[0], AStartLoc[1], AStartLoc[2], AStartLoc[3], HStartLoc[0], HStartLoc[1], HStartLoc[2], HStartLoc[3]))
continue;
+
++count;
} while (result->NextRow());
+
delete result;
+
sLog.outString();
sLog.outString( ">> Loaded %u battlegrounds", count );
}
+
void BattleGroundMgr::InitAutomaticArenaPointDistribution()
{
if (sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS))
@@ -1645,17 +1804,22 @@ void BattleGroundMgr::InitAutomaticArenaPointDistribution()
sLog.outDebug("Automatic Arena Point Distribution initialized.");
}
}
+
void BattleGroundMgr::DistributeArenaPoints()
{
// used to distribute arena points based on last week's stats
sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_START);
+
sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_ONLINE_START);
+
//temporary structure for storing maximum points to add values for all players
std::map<uint32, uint32> PlayerPoints;
+
//at first update all points for all team members
for(ObjectMgr::ArenaTeamMap::iterator team_itr = objmgr.GetArenaTeamMapBegin(); team_itr != objmgr.GetArenaTeamMapEnd(); ++team_itr)
if (ArenaTeam * at = team_itr->second)
at->UpdateArenaPointsHelper(PlayerPoints);
+
//cycle that gives points to all players
for (std::map<uint32, uint32>::iterator plr_itr = PlayerPoints.begin(); plr_itr != PlayerPoints.end(); ++plr_itr)
{
@@ -1673,8 +1837,11 @@ void BattleGroundMgr::DistributeArenaPoints()
std::min(int32(plr_itr->second),int32(sWorld.getConfig(CONFIG_MAX_ARENA_POINTS))));
}
}
+
PlayerPoints.clear();
+
sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_ONLINE_END);
+
sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_TEAM_START);
for(ObjectMgr::ArenaTeamMap::iterator titr = objmgr.GetArenaTeamMapBegin(); titr != objmgr.GetArenaTeamMapEnd(); ++titr)
{
@@ -1685,15 +1852,20 @@ void BattleGroundMgr::DistributeArenaPoints()
at->NotifyStatsChanged(); // notify the players of the changes
}
}
+
sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_TEAM_END);
+
sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_END);
}
+
void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint64& guid, Player* plr, BattleGroundTypeId bgTypeId, uint8 fromWhere)
{
if (!plr)
return;
+
uint32 PlayerLevel = 10;
PlayerLevel = plr->getLevel();
+
data->Initialize(SMSG_BATTLEFIELD_LIST);
*data << uint64(guid); // battlemaster guid
*data << uint8(fromWhere); // from where you joined
@@ -1706,9 +1878,11 @@ void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint6
else // battleground
{
*data << uint8(0x00); // unk, different for each bg type
+
size_t count_pos = data->wpos();
uint32 count = 0;
*data << uint32(0x00); // number of bg instances
+
uint32 queue_id = plr->GetBattleGroundQueueIdFromLevel(bgTypeId);
for(std::set<uint32>::iterator itr = m_ClientBattleGroundIds[bgTypeId][queue_id].begin(); itr != m_ClientBattleGroundIds[bgTypeId][queue_id].end();++itr)
{
@@ -1718,6 +1892,7 @@ void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint6
data->put<uint32>( count_pos , count);
}
}
+
void BattleGroundMgr::SendToBattleGround(Player *pl, uint32 instanceId, BattleGroundTypeId bgTypeId)
{
BattleGround *bg = GetBattleGround(instanceId, bgTypeId);
@@ -1729,6 +1904,7 @@ void BattleGroundMgr::SendToBattleGround(Player *pl, uint32 instanceId, BattleGr
if (team==0)
team = pl->GetTeam();
bg->GetTeamStartLoc(team, x, y, z, O);
+
sLog.outDetail("BATTLEGROUND: Sending %s to map %u, X %f, Y %f, Z %f, O %f", pl->GetName(), mapid, x, y, z, O);
pl->TeleportTo(mapid, x, y, z, O);
}
@@ -1737,6 +1913,7 @@ void BattleGroundMgr::SendToBattleGround(Player *pl, uint32 instanceId, BattleGr
sLog.outError("player %u trying to port to non-existent bg instance %u",pl->GetGUIDLow(), instanceId);
}
}
+
void BattleGroundMgr::SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, const uint64& guid)
{
WorldPacket data(SMSG_AREA_SPIRIT_HEALER_TIME, 12);
@@ -1746,6 +1923,7 @@ void BattleGroundMgr::SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *
data << guid << time_;
pl->GetSession()->SendPacket(&data);
}
+
bool BattleGroundMgr::IsArenaType(BattleGroundTypeId bgTypeId)
{
return ( bgTypeId == BATTLEGROUND_AA ||
@@ -1753,6 +1931,7 @@ bool BattleGroundMgr::IsArenaType(BattleGroundTypeId bgTypeId)
bgTypeId == BATTLEGROUND_NA ||
bgTypeId == BATTLEGROUND_RL );
}
+
BattleGroundQueueTypeId BattleGroundMgr::BGQueueTypeId(BattleGroundTypeId bgTypeId, uint8 arenaType)
{
switch(bgTypeId)
@@ -1788,6 +1967,7 @@ BattleGroundQueueTypeId BattleGroundMgr::BGQueueTypeId(BattleGroundTypeId bgType
return BATTLEGROUND_QUEUE_NONE;
}
}
+
BattleGroundTypeId BattleGroundMgr::BGTemplateId(BattleGroundQueueTypeId bgQueueTypeId)
{
switch(bgQueueTypeId)
@@ -1810,6 +1990,7 @@ BattleGroundTypeId BattleGroundMgr::BGTemplateId(BattleGroundQueueTypeId bgQueue
return BattleGroundTypeId(0); // used for unknown template (it existed and do nothing)
}
}
+
uint8 BattleGroundMgr::BGArenaType(BattleGroundQueueTypeId bgQueueTypeId)
{
switch(bgQueueTypeId)
@@ -1824,6 +2005,7 @@ uint8 BattleGroundMgr::BGArenaType(BattleGroundQueueTypeId bgQueueTypeId)
return 0;
}
}
+
void BattleGroundMgr::ToggleTesting()
{
m_Testing = !m_Testing;
@@ -1832,6 +2014,7 @@ void BattleGroundMgr::ToggleTesting()
else
sWorld.SendWorldText(LANG_DEBUG_BG_OFF);
}
+
void BattleGroundMgr::ToggleArenaTesting()
{
m_ArenaTesting = !m_ArenaTesting;
@@ -1840,6 +2023,7 @@ void BattleGroundMgr::ToggleArenaTesting()
else
sWorld.SendWorldText(LANG_DEBUG_ARENA_OFF);
}
+
void BattleGroundMgr::SetHolidayWeekends(uint32 mask)
{
for(uint32 bgtype = 1; bgtype < MAX_BATTLEGROUND_TYPE_ID; ++bgtype)
@@ -1850,6 +2034,7 @@ void BattleGroundMgr::SetHolidayWeekends(uint32 mask)
}
}
}
+
void BattleGroundMgr::ScheduleQueueUpdate(BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id)
{
//This method must be atomic, TODO add mutex
@@ -1867,6 +2052,7 @@ void BattleGroundMgr::ScheduleQueueUpdate(BattleGroundQueueTypeId bgQueueTypeId,
if (!found)
m_QueueUpdateScheduler.push_back(schedule_id);
}
+
uint32 BattleGroundMgr::GetMaxRatingDifference() const
{
// this is for stupid people who can't use brain and set max rating difference to 0
@@ -1875,33 +2061,44 @@ uint32 BattleGroundMgr::GetMaxRatingDifference() const
diff = 5000;
return diff;
}
+
uint32 BattleGroundMgr::GetRatingDiscardTimer() const
{
return sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER);
}
+
uint32 BattleGroundMgr::GetPrematureFinishTime() const
{
return sWorld.getConfig(CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER);
}
+
void BattleGroundMgr::LoadBattleMastersEntry()
{
mBattleMastersMap.clear(); // need for reload case
+
QueryResult *result = WorldDatabase.Query( "SELECT entry,bg_template FROM battlemaster_entry" );
+
uint32 count = 0;
+
if (!result)
{
barGoLink bar( 1 );
bar.step();
+
sLog.outString();
sLog.outString( ">> Loaded 0 battlemaster entries - table is empty!" );
return;
}
+
barGoLink bar( result->GetRowCount() );
+
do
{
++count;
bar.step();
+
Field *fields = result->Fetch();
+
uint32 entry = fields[0].GetUInt32();
uint32 bgTypeId = fields[1].GetUInt32();
if (!sBattlemasterListStore.LookupEntry(bgTypeId))
@@ -1909,9 +2106,13 @@ void BattleGroundMgr::LoadBattleMastersEntry()
sLog.outErrorDb("Table `battlemaster_entry` contain entry %u for not existed battleground type %u, ignored.",entry,bgTypeId);
continue;
}
+
mBattleMastersMap[entry] = BattleGroundTypeId(bgTypeId);
+
} while( result->NextRow() );
+
delete result;
+
sLog.outString();
sLog.outString( ">> Loaded %u battlemaster entries", count );
}