2008-10-02 16:23:55 -05:00
/*
2009-02-04 12:42:26 +01:00
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
2008-10-14 11:57:03 -05:00
*
2010-01-16 20:19:18 +03:00
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
2008-10-02 16:23:55 -05:00
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
2008-12-19 16:05:13 -06:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2008-10-02 16:23:55 -05:00
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
2008-12-19 16:05:13 -06:00
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2008-10-02 16:23:55 -05:00
*/
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
#include "Common.h"
2009-06-04 21:41:07 +02:00
#include "ObjectMgr.h"
#include "World.h"
#include "WorldPacket.h"
#include "Policies/SingletonImp.h"
2009-10-17 15:51:44 -07:00
2009-06-04 21:41:07 +02:00
#include "ArenaTeam.h"
2008-10-02 16:23:55 -05:00
#include "BattleGroundMgr.h"
#include "BattleGroundAV.h"
#include "BattleGroundAB.h"
#include "BattleGroundEY.h"
#include "BattleGroundWS.h"
#include "BattleGroundNA.h"
#include "BattleGroundBE.h"
#include "BattleGroundAA.h"
#include "BattleGroundRL.h"
2009-01-04 23:25:27 -06:00
#include "BattleGroundSA.h"
#include "BattleGroundDS.h"
#include "BattleGroundRV.h"
2009-12-17 10:43:12 +01:00
#include "BattleGroundIC.h"
#include "BattleGroundABG.h"
2009-06-04 21:41:07 +02:00
#include "Chat.h"
2008-10-05 08:48:32 -05:00
#include "Map.h"
#include "MapInstanced.h"
2009-06-04 21:41:07 +02:00
#include "MapManager.h"
#include "Player.h"
2009-10-09 20:48:55 -07:00
#include "GameEventMgr.h"
2009-02-09 22:08:06 -06:00
#include "ProgressBar.h"
2009-06-04 21:41:07 +02:00
#include "SharedDefines.h"
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
INSTANTIATE_SINGLETON_1 ( BattleGroundMgr );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
/*********************************************************/
/*** BATTLEGROUND QUEUE SYSTEM ***/
/*********************************************************/
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
BattleGroundQueue :: BattleGroundQueue ()
{
2010-02-15 15:31:27 +01:00
for ( uint32 i = 0 ; i < BG_TEAMS_COUNT ; ++ i )
2009-03-10 15:29:50 -06:00
{
2010-02-15 15:31:27 +01:00
for ( uint32 j = 0 ; j < MAX_BATTLEGROUND_BRACKETS ; ++ j )
2009-03-10 15:29:50 -06:00
{
m_SumOfWaitTimes [ i ][ j ] = 0 ;
m_WaitTimeLastPlayer [ i ][ j ] = 0 ;
2010-02-15 15:31:27 +01:00
for ( uint32 k = 0 ; k < COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME ; ++ k )
2009-03-10 15:29:50 -06:00
m_WaitTimes [ i ][ j ][ k ] = 0 ;
}
}
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
BattleGroundQueue ::~ BattleGroundQueue ()
{
2009-02-27 12:13:59 -06:00
m_QueuedPlayers . clear ();
2010-02-15 15:31:27 +01:00
for ( int i = 0 ; i < MAX_BATTLEGROUND_BRACKETS ; ++ i )
2008-10-02 16:23:55 -05:00
{
2010-02-15 15:31:27 +01:00
for ( uint32 j = 0 ; j < BG_QUEUE_GROUP_TYPES_COUNT ; ++ j )
2008-10-05 08:48:32 -05:00
{
2009-10-17 16:20:24 -07:00
for ( GroupsQueueType :: iterator itr = m_QueuedGroups [ i ][ j ]. begin (); itr != m_QueuedGroups [ i ][ j ]. end (); ++ itr )
2009-02-27 12:13:59 -06:00
delete ( * itr );
m_QueuedGroups [ i ][ j ]. clear ();
2008-10-05 08:48:32 -05:00
}
2008-10-02 16:23:55 -05:00
}
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
/*********************************************************/
/*** BATTLEGROUND QUEUE SELECTION POOLS ***/
/*********************************************************/
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
// selection pool initialization, used to clean up from prev selection
2009-02-27 12:13:59 -06:00
void BattleGroundQueue :: SelectionPool :: Init ()
2008-10-05 08:48:32 -05:00
{
SelectedGroups . clear ();
PlayerCount = 0 ;
}
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
// remove group info from selection pool
2009-02-27 12:13:59 -06:00
// returns true when we need to try to add new group to selection pool
2009-03-07 12:05:30 -06:00
// returns false when selection pool is ok or when we kicked smaller group than we need to kick
2009-02-27 12:13:59 -06:00
// sometimes it can be called on empty selection pool
bool BattleGroundQueue :: SelectionPool :: KickGroup ( uint32 size )
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
//find maxgroup or LAST group with size == size and kick it
bool found = false ;
GroupsQueueType :: iterator groupToKick = SelectedGroups . begin ();
for ( GroupsQueueType :: iterator itr = groupToKick ; itr != SelectedGroups . end (); ++ itr )
2008-10-02 16:23:55 -05:00
{
2009-04-08 16:33:46 -05:00
if ( abs (( int32 )(( * itr ) -> Players . size () - size )) <= 1 )
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
groupToKick = itr ;
found = true ;
2008-10-05 08:48:32 -05:00
}
2009-02-27 12:13:59 -06:00
else if ( ! found && ( * itr ) -> Players . size () >= ( * groupToKick ) -> Players . size ())
groupToKick = itr ;
}
//if pool is empty, do nothing
2009-04-08 16:33:46 -05:00
if ( GetPlayerCount ())
2009-02-27 12:13:59 -06:00
{
//update player count
GroupQueueInfo * ginfo = ( * groupToKick );
SelectedGroups . erase ( groupToKick );
PlayerCount -= ginfo -> Players . size ();
2009-03-07 12:05:30 -06:00
//return false if we kicked smaller group or there are enough players in selection pool
if ( ginfo -> Players . size () <= size + 1 )
2009-02-27 12:13:59 -06:00
return false ;
2008-10-05 08:48:32 -05:00
}
2009-02-27 12:13:59 -06:00
return true ;
2008-10-05 08:48:32 -05:00
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
// add group to selection pool
2008-10-05 08:48:32 -05:00
// used when building selection pools
2009-03-07 12:05:30 -06:00
// returns true if we can invite more players, or when we added group to selection pool
// returns false when selection pool is full
2009-02-27 12:13:59 -06:00
bool BattleGroundQueue :: SelectionPool :: AddGroup ( GroupQueueInfo * ginfo , uint32 desiredCount )
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
//if group is larger than desired count - don't allow to add it to pool
2009-04-08 16:33:46 -05:00
if ( ! ginfo -> IsInvitedToBGInstanceGUID && desiredCount >= PlayerCount + ginfo -> Players . size ())
2009-02-27 12:13:59 -06:00
{
SelectedGroups . push_back ( ginfo );
// increase selected players count
PlayerCount += ginfo -> Players . size ();
2009-03-07 12:05:30 -06:00
return true ;
2009-02-27 12:13:59 -06:00
}
2009-04-08 16:33:46 -05:00
if ( PlayerCount < desiredCount )
2009-02-27 12:13:59 -06:00
return true ;
return false ;
2008-10-05 08:48:32 -05:00
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
/*********************************************************/
/*** BATTLEGROUND QUEUES ***/
/*********************************************************/
2009-10-17 15:51:44 -07:00
2010-02-15 15:31:27 +01:00
// add group or player (grp == NULL) to bg queue with the given leader and bg specifications
GroupQueueInfo * BattleGroundQueue :: AddGroup ( Player * leader , Group * grp , BattleGroundTypeId BgTypeId , PvPDifficultyEntry const * backetEntry , uint8 ArenaType , bool isRated , bool isPremade , uint32 arenaRating , uint32 arenateamid )
2008-10-05 08:48:32 -05:00
{
2010-02-15 15:31:27 +01:00
BattleGroundBracketId bracketId = backetEntry -> GetBracketId ();
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
// create new ginfo
2009-12-17 10:43:12 +01:00
GroupQueueInfo * ginfo = new GroupQueueInfo ;
2008-10-05 08:48:32 -05:00
ginfo -> BgTypeId = BgTypeId ;
ginfo -> ArenaType = ArenaType ;
ginfo -> ArenaTeamId = arenateamid ;
ginfo -> IsRated = isRated ;
2009-02-27 12:13:59 -06:00
ginfo -> IsInvitedToBGInstanceGUID = 0 ;
2009-03-13 18:06:36 -06:00
ginfo -> JoinTime = getMSTime ();
ginfo -> RemoveInviteTime = 0 ;
2008-10-05 08:48:32 -05:00
ginfo -> Team = leader -> GetTeam ();
2008-12-19 16:05:13 -06:00
ginfo -> ArenaTeamRating = arenaRating ;
2009-02-27 12:13:59 -06:00
ginfo -> OpponentsTeamRating = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
ginfo -> Players . clear ();
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
//compute index (if group is premade or joined a rated match) to queues
uint32 index = 0 ;
2009-04-08 16:33:46 -05:00
if ( ! isRated && ! isPremade )
2009-02-27 12:13:59 -06:00
index += BG_TEAMS_COUNT ;
2009-04-08 16:33:46 -05:00
if ( ginfo -> Team == HORDE )
2009-02-27 12:13:59 -06:00
index ++ ;
2010-02-15 15:31:27 +01:00
sLog . outDebug ( "Adding Group to BattleGroundQueue bgTypeId : %u, bracket_id : %u, index : %u" , BgTypeId , bracketId , index );
2009-10-17 15:51:44 -07:00
2010-02-15 15:31:27 +01:00
uint32 lastOnlineTime = getMSTime ();
2009-10-17 15:51:44 -07:00
2010-02-15 15:31:27 +01:00
//announce world (this don't need mutex)
if ( isRated && sWorld . getConfig ( CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE ))
{
sWorld . SendWorldText ( LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN , ginfo -> ArenaType , ginfo -> ArenaType , ginfo -> ArenaTeamRating );
}
2009-10-17 15:51:44 -07:00
2010-02-15 15:31:27 +01:00
//add players from group to ginfo
{
//ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_Lock);
if ( grp )
{
for ( GroupReference * itr = grp -> GetFirstMember (); itr != NULL ; itr = itr -> next ())
{
Player * member = itr -> getSource ();
if ( ! member )
continue ; // this should never happen
PlayerQueueInfo & pl_info = m_QueuedPlayers [ member -> GetGUID ()];
pl_info . LastOnlineTime = lastOnlineTime ;
pl_info . GroupInfo = ginfo ;
// add the pinfo to ginfo's list
ginfo -> Players [ member -> GetGUID ()] = & pl_info ;
}
}
else
{
PlayerQueueInfo & pl_info = m_QueuedPlayers [ leader -> GetGUID ()];
pl_info . LastOnlineTime = lastOnlineTime ;
pl_info . GroupInfo = ginfo ;
ginfo -> Players [ leader -> GetGUID ()] = & pl_info ;
}
//add GroupInfo to m_QueuedGroups
m_QueuedGroups [ bracketId ][ index ]. push_back ( ginfo );
2009-10-17 15:51:44 -07:00
2010-02-15 15:31:27 +01:00
//announce to world, this code needs mutex
if ( ! isRated && ! isPremade && sWorld . getConfig ( CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE ))
{
if ( BattleGround * bg = sBattleGroundMgr . GetBattleGroundTemplate ( ginfo -> BgTypeId ))
{
char const * bgName = bg -> GetName ();
uint32 MinPlayers = bg -> GetMinPlayersPerTeam ();
uint32 qHorde = 0 ;
uint32 qAlliance = 0 ;
uint32 q_min_level = backetEntry -> minLevel ;
uint32 q_max_level = backetEntry -> maxLevel ;
GroupsQueueType :: const_iterator itr ;
for ( itr = m_QueuedGroups [ bracketId ][ BG_QUEUE_NORMAL_ALLIANCE ]. begin (); itr != m_QueuedGroups [ bracketId ][ BG_QUEUE_NORMAL_ALLIANCE ]. end (); ++ itr )
if ( ! ( * itr ) -> IsInvitedToBGInstanceGUID )
qAlliance += ( * itr ) -> Players . size ();
for ( itr = m_QueuedGroups [ bracketId ][ BG_QUEUE_NORMAL_HORDE ]. begin (); itr != m_QueuedGroups [ bracketId ][ 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 ))
{
ChatHandler ( leader ). PSendSysMessage ( LANG_BG_QUEUE_ANNOUNCE_SELF , bgName , q_min_level , q_max_level ,
qAlliance , ( MinPlayers > qAlliance ) ? MinPlayers - qAlliance : ( uint32 ) 0 , qHorde , ( MinPlayers > qHorde ) ? MinPlayers - qHorde : ( uint32 ) 0 );
}
// System message
else
{
sWorld . SendWorldText ( LANG_BG_QUEUE_ANNOUNCE_WORLD , bgName , q_min_level , q_max_level ,
qAlliance , ( MinPlayers > qAlliance ) ? MinPlayers - qAlliance : ( uint32 ) 0 , qHorde , ( MinPlayers > qHorde ) ? MinPlayers - qHorde : ( uint32 ) 0 );
}
}
}
//release mutex
}
return ginfo ;
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2010-02-15 15:31:27 +01:00
void BattleGroundQueue :: PlayerInvitedToBGUpdateAverageWaitTime ( GroupQueueInfo * ginfo , BattleGroundBracketId bracket_id )
2009-03-10 15:29:50 -06:00
{
2009-03-13 18:06:36 -06:00
uint32 timeInQueue = getMSTimeDiff ( ginfo -> JoinTime , getMSTime ());
2009-03-10 15:29:50 -06:00
uint8 team_index = BG_TEAM_ALLIANCE ; //default set to BG_TEAM_ALLIANCE - or non rated arenas!
2009-04-08 16:33:46 -05:00
if ( ! ginfo -> ArenaType )
2009-03-10 15:29:50 -06:00
{
2009-04-08 16:33:46 -05:00
if ( ginfo -> Team == HORDE )
2009-03-10 15:29:50 -06:00
team_index = BG_TEAM_HORDE ;
}
else
{
2009-04-08 16:33:46 -05:00
if ( ginfo -> IsRated )
2009-03-10 15:29:50 -06:00
team_index = BG_TEAM_HORDE ; //for rated arenas use BG_TEAM_HORDE
}
2009-10-17 15:51:44 -07:00
2009-03-10 15:29:50 -06:00
//store pointer to arrayindex of player that was added first
2010-02-15 15:31:27 +01:00
uint32 * lastPlayerAddedPointer = & ( m_WaitTimeLastPlayer [ team_index ][ bracket_id ]);
2009-03-10 15:29:50 -06:00
//remove his time from sum
2010-02-15 15:31:27 +01:00
m_SumOfWaitTimes [ team_index ][ bracket_id ] -= m_WaitTimes [ team_index ][ bracket_id ][( * lastPlayerAddedPointer )];
2009-03-10 15:29:50 -06:00
//set average time to new
2010-02-15 15:31:27 +01:00
m_WaitTimes [ team_index ][ bracket_id ][( * lastPlayerAddedPointer )] = timeInQueue ;
2009-03-10 15:29:50 -06:00
//add new time to sum
2010-02-15 15:31:27 +01:00
m_SumOfWaitTimes [ team_index ][ bracket_id ] += timeInQueue ;
2009-03-10 15:29:50 -06:00
//set index of last player added to next one
( * lastPlayerAddedPointer ) ++ ;
( * lastPlayerAddedPointer ) %= COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME ;
}
2009-10-17 15:51:44 -07:00
2010-02-15 15:31:27 +01:00
uint32 BattleGroundQueue :: GetAverageQueueWaitTime ( GroupQueueInfo * ginfo , BattleGroundBracketId bracket_id )
2009-03-10 15:29:50 -06:00
{
uint8 team_index = BG_TEAM_ALLIANCE ; //default set to BG_TEAM_ALLIANCE - or non rated arenas!
2009-04-08 16:33:46 -05:00
if ( ! ginfo -> ArenaType )
2009-03-10 15:29:50 -06:00
{
2009-04-08 16:33:46 -05:00
if ( ginfo -> Team == HORDE )
2009-03-10 15:29:50 -06:00
team_index = BG_TEAM_HORDE ;
}
else
{
2009-04-08 16:33:46 -05:00
if ( ginfo -> IsRated )
2009-03-10 15:29:50 -06:00
team_index = BG_TEAM_HORDE ; //for rated arenas use BG_TEAM_HORDE
}
//check if there is enought values(we always add values > 0)
2010-02-15 15:31:27 +01:00
if ( m_WaitTimes [ team_index ][ bracket_id ][ COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME - 1 ] )
return ( m_SumOfWaitTimes [ team_index ][ bracket_id ] / COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME );
2009-03-10 15:29:50 -06:00
else
//if there aren't enough values return 0 - not available
return 0 ;
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
//remove player from queue and from group info, if group info is empty then remove it too
2009-01-18 19:01:41 -06:00
void BattleGroundQueue :: RemovePlayer ( const uint64 & guid , bool decreaseInvitedCount )
2008-10-02 16:23:55 -05:00
{
2009-02-27 12:13:59 -06:00
//Player *plr = objmgr.GetPlayer(guid);
2009-10-17 15:51:44 -07:00
2010-02-15 15:31:27 +01:00
int32 bracket_id = - 1 ; // signed for proper for-loop finish
2008-10-02 16:23:55 -05:00
QueuedPlayersMap :: iterator itr ;
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
//remove player from map, if he's there
itr = m_QueuedPlayers . find ( guid );
2009-04-08 16:33:46 -05:00
if ( itr == m_QueuedPlayers . end ())
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
sLog . outError ( "BattleGroundQueue: couldn't find player to remove GUID: %u" , GUID_LOPART ( guid ));
2008-10-05 08:48:32 -05:00
return ;
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2009-02-16 20:09:22 -06:00
GroupQueueInfo * group = itr -> second . GroupInfo ;
2009-02-27 12:13:59 -06:00
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 ;
2009-10-17 15:51:44 -07:00
2010-02-15 15:31:27 +01:00
for ( int32 bracket_id_tmp = MAX_BATTLEGROUND_BRACKETS - 1 ; bracket_id_tmp >= 0 && bracket_id == - 1 ; -- bracket_id_tmp )
2008-10-02 16:23:55 -05:00
{
2009-02-27 12:13:59 -06:00
//we must check premade and normal team's queue - because when players from premade are joining bg,
//they leave groupinfo so we can't use its players size to find out index
2009-02-27 12:56:00 -06:00
for ( uint32 j = index ; j < BG_QUEUE_GROUP_TYPES_COUNT ; j += BG_QUEUE_NORMAL_ALLIANCE )
2009-02-27 12:13:59 -06:00
{
2010-02-15 15:31:27 +01:00
for ( group_itr_tmp = m_QueuedGroups [ bracket_id_tmp ][ j ]. begin (); group_itr_tmp != m_QueuedGroups [ bracket_id_tmp ][ j ]. end (); ++ group_itr_tmp )
2009-02-27 12:13:59 -06:00
{
2009-04-08 16:33:46 -05:00
if (( * group_itr_tmp ) == group )
2009-02-27 12:13:59 -06:00
{
2010-02-15 15:31:27 +01:00
bracket_id = bracket_id_tmp ;
2009-02-27 12:13:59 -06:00
group_itr = group_itr_tmp ;
//we must store index to be able to erase iterator
index = j ;
break ;
}
}
}
2008-10-05 08:48:32 -05:00
}
2009-02-27 12:13:59 -06:00
//player can't be in queue without group, but just in case
2010-02-15 15:31:27 +01:00
if ( bracket_id == - 1 )
2009-02-27 12:13:59 -06:00
{
sLog . outError ( "BattleGroundQueue: ERROR Cannot find groupinfo for player GUID: %u" , GUID_LOPART ( guid ));
return ;
}
2010-02-15 15:31:27 +01:00
sLog . outDebug ( "BattleGroundQueue: Removing player GUID %u, from bracket_id %u" , GUID_LOPART ( guid ), ( uint32 ) bracket_id );
2009-10-17 15:51:44 -07:00
2009-03-09 17:07:40 -06:00
// ALL variables are correctly set
2009-02-27 12:13:59 -06:00
// We can ignore leveling up in queue - it should not cause crash
2008-10-05 08:48:32 -05:00
// remove player from group
2009-02-27 12:13:59 -06:00
// if only one player there, remove group
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
// remove player queue info from group queue info
std :: map < uint64 , PlayerQueueInfo *>:: iterator pitr = group -> Players . find ( guid );
2009-04-08 16:33:46 -05:00
if ( pitr != group -> Players . end ())
2008-10-05 08:48:32 -05:00
group -> Players . erase ( pitr );
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
// if invited to bg, and should decrease invited count, then do it
2009-04-08 16:33:46 -05:00
if ( decreaseInvitedCount && group -> IsInvitedToBGInstanceGUID )
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:57:33 -06:00
BattleGround * bg = sBattleGroundMgr . GetBattleGround ( group -> IsInvitedToBGInstanceGUID , group -> BgTypeId );
2009-04-08 16:33:46 -05:00
if ( bg )
2009-02-27 12:13:59 -06:00
bg -> DecreaseInvitedCount ( group -> Team );
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
// remove player queue info
m_QueuedPlayers . erase ( itr );
2009-10-17 15:51:44 -07:00
2010-02-15 15:31:27 +01:00
// announce to world if arena team left queue for rated match, show only once
if ( group -> ArenaType && group -> IsRated && group -> Players . empty () && sWorld . getConfig ( CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE ))
sWorld . SendWorldText ( LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT , group -> ArenaType , group -> ArenaType , group -> ArenaTeamRating );
2009-10-17 15:51:44 -07:00
2009-03-09 17:07:40 -06:00
//if player leaves queue and he is invited to rated arena match, then he have to loose
2009-04-08 16:33:46 -05:00
if ( group -> IsInvitedToBGInstanceGUID && group -> IsRated && decreaseInvitedCount )
2009-03-09 17:07:40 -06:00
{
ArenaTeam * at = objmgr . GetArenaTeamById ( group -> ArenaTeamId );
2009-04-08 16:33:46 -05:00
if ( at )
2009-03-09 17:07:40 -06:00
{
sLog . outDebug ( "UPDATING memberLost's personal arena rating for %u by opponents rating: %u" , GUID_LOPART ( guid ), group -> OpponentsTeamRating );
Player * plr = objmgr . GetPlayer ( guid );
2009-04-08 16:33:46 -05:00
if ( plr )
2009-03-09 17:07:40 -06:00
at -> MemberLost ( plr , group -> OpponentsTeamRating );
else
at -> OfflineMemberLost ( guid , group -> OpponentsTeamRating );
at -> SaveToDB ();
}
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
// remove group queue info if needed
2009-04-08 16:33:46 -05:00
if ( group -> Players . empty ())
2009-02-27 12:13:59 -06:00
{
2010-02-15 15:31:27 +01:00
m_QueuedGroups [ bracket_id ][ index ]. erase ( group_itr );
2009-02-27 12:13:59 -06:00
delete group ;
}
// if group wasn't empty, so it wasn't deleted, and player have left a rated
// queue -> everyone from the group should leave too
// don't remove recursively if already invited to bg!
2009-04-08 16:33:46 -05:00
else if ( ! group -> IsInvitedToBGInstanceGUID && group -> IsRated )
2009-02-27 12:13:59 -06:00
{
// remove next player, this is recursive
// first send removal information
2009-04-08 16:33:46 -05:00
if ( Player * plr2 = objmgr . GetPlayer ( group -> Players . begin () -> first ))
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
BattleGround * bg = sBattleGroundMgr . GetBattleGroundTemplate ( group -> BgTypeId );
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr :: BGQueueTypeId ( group -> BgTypeId , group -> ArenaType );
uint32 queueSlot = plr2 -> GetBattleGroundQueueIndex ( bgQueueTypeId );
plr2 -> RemoveBattleGroundQueueId ( bgQueueTypeId ); // must be called this way, because if you move this call to
// queue->removeplayer, it causes bugs
WorldPacket data ;
2009-03-13 18:06:36 -06:00
sBattleGroundMgr . BuildBattleGroundStatusPacket ( & data , bg , queueSlot , STATUS_NONE , 0 , 0 , 0 );
2009-02-27 12:13:59 -06:00
plr2 -> GetSession () -> SendPacket ( & data );
2008-10-05 08:48:32 -05:00
}
2009-02-27 12:13:59 -06:00
// then actually delete, this may delete the group as well!
RemovePlayer ( group -> Players . begin () -> first , decreaseInvitedCount );
2008-10-05 08:48:32 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-02-15 15:31:27 +01:00
//returns true when player pl_guid is in queue and is invited to bgInstanceGuid
bool BattleGroundQueue :: IsPlayerInvited ( const uint64 & pl_guid , const uint32 bgInstanceGuid , const uint32 removeTime )
2008-12-26 17:08:59 -06:00
{
2010-02-15 15:31:27 +01:00
QueuedPlayersMap :: const_iterator qItr = m_QueuedPlayers . find ( pl_guid );
return ( qItr != m_QueuedPlayers . end ()
&& qItr -> second . GroupInfo -> IsInvitedToBGInstanceGUID == bgInstanceGuid
&& qItr -> second . GroupInfo -> RemoveInviteTime == removeTime );
}
2009-10-17 15:51:44 -07:00
2010-02-15 15:31:27 +01:00
bool BattleGroundQueue :: GetPlayerGroupInfoData ( const uint64 & guid , GroupQueueInfo * ginfo )
{
QueuedPlayersMap :: const_iterator qItr = m_QueuedPlayers . find ( guid );
if ( qItr == m_QueuedPlayers . end ())
return false ;
* ginfo = * ( qItr -> second . GroupInfo );
return true ;
2008-12-26 17:08:59 -06:00
}
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
bool BattleGroundQueue :: InviteGroupToBG ( GroupQueueInfo * ginfo , BattleGround * bg , uint32 side )
{
// set side if needed
2009-04-08 16:33:46 -05:00
if ( side )
2008-10-05 08:48:32 -05:00
ginfo -> Team = side ;
2009-10-17 15:51:44 -07:00
2009-04-08 16:33:46 -05:00
if ( ! ginfo -> IsInvitedToBGInstanceGUID )
2008-10-05 08:48:32 -05:00
{
// not yet invited
// set invitation
ginfo -> IsInvitedToBGInstanceGUID = bg -> GetInstanceID ();
2009-04-08 16:29:28 -05:00
BattleGroundTypeId bgTypeId = bg -> GetTypeID ();
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr :: BGQueueTypeId ( bgTypeId , bg -> GetArenaType ());
2010-02-15 15:31:27 +01:00
BattleGroundBracketId bracket_id = bg -> GetBracketId ();
2009-10-17 15:51:44 -07:00
2009-04-08 16:29:28 -05:00
// set ArenaTeamId for rated matches
2009-04-08 16:33:46 -05:00
if ( bg -> isArena () && bg -> isRated ())
2009-04-08 16:29:28 -05:00
bg -> SetArenaTeamIdForTeam ( ginfo -> Team , ginfo -> ArenaTeamId );
2009-10-17 15:51:44 -07:00
2009-04-08 16:29:28 -05:00
ginfo -> RemoveInviteTime = getMSTime () + INVITE_ACCEPT_WAIT_TIME ;
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
// loop through the players
2009-10-17 16:20:24 -07:00
for ( std :: map < uint64 , PlayerQueueInfo *>:: iterator itr = ginfo -> Players . begin (); itr != ginfo -> Players . end (); ++ itr )
2008-10-05 08:48:32 -05:00
{
// get the player
Player * plr = objmgr . GetPlayer ( itr -> first );
2009-02-27 12:13:59 -06:00
// if offline, skip him, this should not happen - player is removed from queue when he logs out
2009-04-08 16:33:46 -05:00
if ( ! plr )
2008-10-05 08:48:32 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
// invite the player
2010-02-15 15:31:27 +01:00
PlayerInvitedToBGUpdateAverageWaitTime ( ginfo , bracket_id );
2009-04-08 16:29:28 -05:00
//sBattleGroundMgr.InvitePlayer(plr, bg, ginfo->Team);
2009-10-17 15:51:44 -07:00
2009-04-08 16:29:28 -05:00
// set invited player counters
bg -> IncreaseInvitedCount ( ginfo -> Team );
2009-10-17 15:51:44 -07:00
2009-04-08 16:29:28 -05:00
plr -> SetInviteForBattleGroundQueueType ( bgQueueTypeId , ginfo -> IsInvitedToBGInstanceGUID );
2009-10-17 15:51:44 -07:00
2009-04-08 16:29:28 -05:00
// create remind invite events
2010-02-15 15:31:27 +01:00
BGQueueInviteEvent * inviteEvent = new BGQueueInviteEvent ( plr -> GetGUID (), ginfo -> IsInvitedToBGInstanceGUID , bgTypeId , ginfo -> ArenaType , ginfo -> RemoveInviteTime );
2009-04-08 16:29:28 -05:00
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 ));
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
WorldPacket data ;
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
uint32 queueSlot = plr -> GetBattleGroundQueueIndex ( bgQueueTypeId );
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
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 ());
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
// send status packet
2009-03-13 18:06:36 -06:00
sBattleGroundMgr . BuildBattleGroundStatusPacket ( & data , bg , queueSlot , STATUS_WAIT_JOIN , INVITE_ACCEPT_WAIT_TIME , 0 , ginfo -> ArenaType );
2008-10-05 08:48:32 -05:00
plr -> GetSession () -> SendPacket ( & data );
}
return true ;
}
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
return false ;
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
/*
This function is inviting players to already running battlegrounds
Invitation type is based on config file
large groups are disadvantageous, because they will be kicked first if invitation type = 1
*/
2010-02-15 15:31:27 +01:00
void BattleGroundQueue :: FillPlayersToBG ( BattleGround * bg , BattleGroundBracketId bracket_id )
2008-10-05 08:48:32 -05:00
{
2009-04-29 00:31:03 -05:00
int32 hordeFree = bg -> GetFreeSlotsForTeam ( HORDE );
int32 aliFree = bg -> GetFreeSlotsForTeam ( ALLIANCE );
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
//iterator for iterating through bg queue
2010-02-15 15:31:27 +01:00
GroupsQueueType :: const_iterator Ali_itr = m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_ALLIANCE ]. begin ();
2009-02-27 12:13:59 -06:00
//count of groups in queue - used to stop cycles
2010-02-15 15:31:27 +01:00
uint32 aliCount = m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_ALLIANCE ]. size ();
2009-02-27 12:13:59 -06:00
//index to queue which group is current
uint32 aliIndex = 0 ;
for (; aliIndex < aliCount && m_SelectionPools [ BG_TEAM_ALLIANCE ]. AddGroup (( * Ali_itr ), aliFree ); aliIndex ++ )
++ Ali_itr ;
//the same thing for horde
2010-02-15 15:31:27 +01:00
GroupsQueueType :: const_iterator Horde_itr = m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_HORDE ]. begin ();
uint32 hordeCount = m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_HORDE ]. size ();
2009-02-27 12:13:59 -06:00
uint32 hordeIndex = 0 ;
for (; hordeIndex < hordeCount && m_SelectionPools [ BG_TEAM_HORDE ]. AddGroup (( * Horde_itr ), hordeFree ); hordeIndex ++ )
++ Horde_itr ;
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
//if ofc like BG queue invitation is set in config, then we are happy
if ( sWorld . getConfig ( CONFIG_BATTLEGROUND_INVITATION_TYPE ) == 0 )
return ;
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
/*
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:
1. Last time when BattleGroundQueue::Update was executed we invited all possible players - so there is only small possibility
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
*/
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
// At first we need to compare free space in bg and our selection pool
2009-04-29 00:31:03 -05:00
int32 diffAli = aliFree - int32 ( m_SelectionPools [ BG_TEAM_ALLIANCE ]. GetPlayerCount ());
int32 diffHorde = hordeFree - int32 ( m_SelectionPools [ BG_TEAM_HORDE ]. GetPlayerCount ());
2009-02-27 12:13:59 -06:00
while ( abs ( diffAli - diffHorde ) > 1 && ( m_SelectionPools [ BG_TEAM_HORDE ]. GetPlayerCount () > 0 || m_SelectionPools [ BG_TEAM_ALLIANCE ]. GetPlayerCount () > 0 ) )
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
//each cycle execution we need to kick at least 1 group
2009-04-08 16:33:46 -05:00
if ( diffAli < diffHorde )
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
//kick alliance group, add to pool new group if needed
2009-04-08 16:33:46 -05:00
if ( m_SelectionPools [ BG_TEAM_ALLIANCE ]. KickGroup ( diffHorde - diffAli ))
2009-02-27 12:13:59 -06:00
{
for (; aliIndex < aliCount && m_SelectionPools [ BG_TEAM_ALLIANCE ]. AddGroup (( * Ali_itr ), ( aliFree >= diffHorde ) ? aliFree - diffHorde : 0 ); aliIndex ++ )
++ Ali_itr ;
}
//if ali selection is already empty, then kick horde group, but if there are less horde than ali in bg - break;
2009-04-08 16:33:46 -05:00
if ( ! m_SelectionPools [ BG_TEAM_ALLIANCE ]. GetPlayerCount ())
2009-02-27 12:56:48 -06:00
{
2009-04-08 16:33:46 -05:00
if ( aliFree <= diffHorde + 1 )
2009-02-27 12:13:59 -06:00
break ;
m_SelectionPools [ BG_TEAM_HORDE ]. KickGroup ( diffHorde - diffAli );
2009-02-27 12:56:48 -06:00
}
2008-10-05 08:48:32 -05:00
}
2009-02-27 12:13:59 -06:00
else
{
//kick horde group, add to pool new group if needed
2009-04-08 16:33:46 -05:00
if ( m_SelectionPools [ BG_TEAM_HORDE ]. KickGroup ( diffAli - diffHorde ))
2009-02-27 12:13:59 -06:00
{
for (; hordeIndex < hordeCount && m_SelectionPools [ BG_TEAM_HORDE ]. AddGroup (( * Horde_itr ), ( hordeFree >= diffAli ) ? hordeFree - diffAli : 0 ); hordeIndex ++ )
++ Horde_itr ;
}
2009-04-08 16:33:46 -05:00
if ( ! m_SelectionPools [ BG_TEAM_HORDE ]. GetPlayerCount ())
2009-02-27 12:56:48 -06:00
{
2009-04-08 16:33:46 -05:00
if ( hordeFree <= diffAli + 1 )
2009-02-27 12:13:59 -06:00
break ;
m_SelectionPools [ BG_TEAM_ALLIANCE ]. KickGroup ( diffAli - diffHorde );
2009-02-27 12:56:48 -06:00
}
2009-02-27 12:13:59 -06:00
}
//count diffs after small update
2009-04-29 00:31:03 -05:00
diffAli = aliFree - int32 ( m_SelectionPools [ BG_TEAM_ALLIANCE ]. GetPlayerCount ());
diffHorde = hordeFree - int32 ( m_SelectionPools [ BG_TEAM_HORDE ]. GetPlayerCount ());
2008-10-05 08:48:32 -05:00
}
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
// 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
2010-02-15 15:31:27 +01:00
bool BattleGroundQueue :: CheckPremadeMatch ( BattleGroundBracketId bracket_id , uint32 MinPlayersPerTeam , uint32 MaxPlayersPerTeam )
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
//check match
2010-02-15 15:31:27 +01:00
if ( ! m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_ALLIANCE ]. empty () && ! m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_HORDE ]. empty ())
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
//start premade match
//if groups aren't invited
GroupsQueueType :: const_iterator ali_group , horde_group ;
2010-02-15 15:31:27 +01:00
for ( ali_group = m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_ALLIANCE ]. begin (); ali_group != m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_ALLIANCE ]. end (); ++ ali_group )
2009-04-08 16:33:46 -05:00
if ( ! ( * ali_group ) -> IsInvitedToBGInstanceGUID )
2009-02-27 12:13:59 -06:00
break ;
2010-02-15 15:31:27 +01:00
for ( horde_group = m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_HORDE ]. begin (); horde_group != m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_HORDE ]. end (); ++ horde_group )
2009-04-08 16:33:46 -05:00
if ( ! ( * horde_group ) -> IsInvitedToBGInstanceGUID )
2009-02-27 12:13:59 -06:00
break ;
2009-10-17 15:51:44 -07:00
2010-02-15 15:31:27 +01:00
if ( ali_group != m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_ALLIANCE ]. end () && horde_group != m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_HORDE ]. end ())
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
m_SelectionPools [ BG_TEAM_ALLIANCE ]. AddGroup (( * ali_group ), MaxPlayersPerTeam );
m_SelectionPools [ BG_TEAM_HORDE ]. AddGroup (( * horde_group ), MaxPlayersPerTeam );
//add groups/players from normal queue to size of bigger group
2009-06-19 12:41:16 -05:00
uint32 maxPlayers = std :: min ( m_SelectionPools [ BG_TEAM_ALLIANCE ]. GetPlayerCount (), m_SelectionPools [ BG_TEAM_HORDE ]. GetPlayerCount ());
2009-02-27 12:13:59 -06:00
GroupsQueueType :: const_iterator itr ;
2009-10-17 16:20:24 -07:00
for ( uint32 i = 0 ; i < BG_TEAMS_COUNT ; i ++ )
2008-10-05 08:48:32 -05:00
{
2010-02-15 15:31:27 +01:00
for ( itr = m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_ALLIANCE + i ]. begin (); itr != m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_ALLIANCE + i ]. end (); ++ itr )
2008-10-05 08:48:32 -05:00
{
2009-03-05 19:02:08 -06:00
//if itr can join BG and player count is less that maxPlayers, then add group to selectionpool
2009-04-08 16:33:46 -05:00
if ( ! ( * itr ) -> IsInvitedToBGInstanceGUID && ! m_SelectionPools [ i ]. AddGroup (( * itr ), maxPlayers ))
2009-02-27 12:13:59 -06:00
break ;
2008-10-05 08:48:32 -05:00
}
2009-02-27 12:13:59 -06:00
}
//premade selection pools are set
return true ;
}
}
// now check if we can move group from Premade queue to normal queue (timer has expired) or group size lowered!!
// this could be 2 cycles but i'm checking only first team in queue - it can cause problem -
// if first is invited to BG and seconds timer expired, but we can ignore it, because players have only 80 seconds to click to enter bg
// and when they click or after 80 seconds the queue info is removed from queue
uint32 time_before = getMSTime () - sWorld . getConfig ( CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH );
2009-10-17 16:20:24 -07:00
for ( uint32 i = 0 ; i < BG_TEAMS_COUNT ; i ++ )
2009-02-27 12:13:59 -06:00
{
2010-02-15 15:31:27 +01:00
if ( ! m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_ALLIANCE + i ]. empty ())
2009-02-27 12:13:59 -06:00
{
2010-02-15 15:31:27 +01:00
GroupsQueueType :: iterator itr = m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_ALLIANCE + i ]. begin ();
2009-04-08 16:33:46 -05:00
if ( ! ( * itr ) -> IsInvitedToBGInstanceGUID && (( * itr ) -> JoinTime < time_before || ( * itr ) -> Players . size () < MinPlayersPerTeam ))
2009-02-27 12:13:59 -06:00
{
//we must insert group to normal queue and erase pointer from premade queue
2010-02-15 15:31:27 +01:00
m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_ALLIANCE + i ]. push_front (( * itr ));
m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_ALLIANCE + i ]. erase ( itr );
2009-02-27 12:13:59 -06:00
}
}
}
//selection pools are not set
return false ;
}
2009-10-17 15:51:44 -07:00
2009-03-02 17:02:27 -06:00
// this method tries to create battleground or arena with MinPlayersPerTeam against MinPlayersPerTeam
2010-02-15 15:31:27 +01:00
bool BattleGroundQueue :: CheckNormalMatch ( BattleGround * bg_template , BattleGroundBracketId bracket_id , uint32 minPlayers , uint32 maxPlayers )
2009-02-27 12:13:59 -06:00
{
GroupsQueueType :: const_iterator itr_team [ BG_TEAMS_COUNT ];
2009-10-17 16:20:24 -07:00
for ( uint32 i = 0 ; i < BG_TEAMS_COUNT ; i ++ )
2009-02-27 12:13:59 -06:00
{
2010-02-15 15:31:27 +01:00
itr_team [ i ] = m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_ALLIANCE + i ]. begin ();
for (; itr_team [ i ] != m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_ALLIANCE + i ]. end (); ++ ( itr_team [ i ]))
2009-02-27 12:13:59 -06:00
{
2009-04-08 16:33:46 -05:00
if ( ! ( * ( itr_team [ i ])) -> IsInvitedToBGInstanceGUID )
2009-02-27 12:13:59 -06:00
{
m_SelectionPools [ i ]. AddGroup ( * ( itr_team [ i ]), maxPlayers );
2009-04-08 16:33:46 -05:00
if ( m_SelectionPools [ i ]. GetPlayerCount () >= minPlayers )
2009-02-27 12:13:59 -06:00
break ;
2008-10-05 08:48:32 -05:00
}
}
2008-10-02 16:23:55 -05:00
}
2009-02-27 12:13:59 -06:00
//try to invite same number of players - this cycle may cause longer wait time even if there are enough players in queue, but we want ballanced bg
uint32 j = BG_TEAM_ALLIANCE ;
2009-04-08 16:33:46 -05:00
if ( m_SelectionPools [ BG_TEAM_HORDE ]. GetPlayerCount () < m_SelectionPools [ BG_TEAM_ALLIANCE ]. GetPlayerCount ())
2009-02-27 12:13:59 -06:00
j = BG_TEAM_HORDE ;
if ( sWorld . getConfig ( CONFIG_BATTLEGROUND_INVITATION_TYPE ) != 0
&& m_SelectionPools [ BG_TEAM_HORDE ]. GetPlayerCount () >= minPlayers && m_SelectionPools [ BG_TEAM_ALLIANCE ]. GetPlayerCount () >= minPlayers )
{
//we will try to invite more groups to team with less players indexed by j
++ ( itr_team [ j ]); //this will not cause a crash, because for cycle above reached break;
2010-02-15 15:31:27 +01:00
for (; itr_team [ j ] != m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_ALLIANCE + j ]. end (); ++ ( itr_team [ j ]))
2009-02-27 12:13:59 -06:00
{
2009-04-08 16:33:46 -05:00
if ( ! ( * ( itr_team [ j ])) -> IsInvitedToBGInstanceGUID )
if ( ! m_SelectionPools [ j ]. AddGroup ( * ( itr_team [ j ]), m_SelectionPools [( j + 1 ) % BG_TEAMS_COUNT ]. GetPlayerCount ()))
2009-02-27 12:13:59 -06:00
break ;
}
// do not allow to start bg with more than 2 players more on 1 faction
2009-04-08 16:33:46 -05:00
if ( abs (( int32 )( m_SelectionPools [ BG_TEAM_HORDE ]. GetPlayerCount () - m_SelectionPools [ BG_TEAM_ALLIANCE ]. GetPlayerCount ())) > 2 )
2009-02-27 12:13:59 -06:00
return false ;
}
2009-02-27 12:58:02 -06:00
//allow 1v0 if debug bg
2009-04-08 16:33:46 -05:00
if ( sBattleGroundMgr . isTesting () && bg_template -> isBattleGround () && ( m_SelectionPools [ BG_TEAM_ALLIANCE ]. GetPlayerCount () || m_SelectionPools [ BG_TEAM_HORDE ]. GetPlayerCount ()))
2009-02-27 12:58:02 -06:00
return true ;
2009-02-27 12:13:59 -06:00
//return true if there are enough players in selection pools - enable to work .debug bg command correctly
2009-02-27 12:58:02 -06:00
return m_SelectionPools [ BG_TEAM_ALLIANCE ]. GetPlayerCount () >= minPlayers && m_SelectionPools [ BG_TEAM_HORDE ]. GetPlayerCount () >= minPlayers ;
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2009-03-02 17:02:27 -06:00
// this method will check if we can invite players to same faction skirmish match
2010-02-15 15:31:27 +01:00
bool BattleGroundQueue :: CheckSkirmishForSameFaction ( BattleGroundBracketId bracket_id , uint32 minPlayersPerTeam )
2009-03-02 17:02:27 -06:00
{
2009-04-08 16:33:46 -05:00
if ( m_SelectionPools [ BG_TEAM_ALLIANCE ]. GetPlayerCount () < minPlayersPerTeam && m_SelectionPools [ BG_TEAM_HORDE ]. GetPlayerCount () < minPlayersPerTeam )
2009-03-02 17:02:27 -06:00
return false ;
uint32 teamIndex = BG_TEAM_ALLIANCE ;
uint32 otherTeam = BG_TEAM_HORDE ;
uint32 otherTeamId = HORDE ;
2009-04-08 16:33:46 -05:00
if ( m_SelectionPools [ BG_TEAM_HORDE ]. GetPlayerCount () == minPlayersPerTeam )
2009-03-02 17:02:27 -06:00
{
teamIndex = BG_TEAM_HORDE ;
otherTeam = BG_TEAM_ALLIANCE ;
otherTeamId = ALLIANCE ;
}
//clear other team's selection
m_SelectionPools [ otherTeam ]. Init ();
//store last ginfo pointer
GroupQueueInfo * ginfo = m_SelectionPools [ teamIndex ]. SelectedGroups . back ();
//set itr_team to group that was added to selection pool latest
2010-02-15 15:31:27 +01:00
GroupsQueueType :: iterator itr_team = m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_ALLIANCE + teamIndex ]. begin ();
for (; itr_team != m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_ALLIANCE + teamIndex ]. end (); ++ itr_team )
2009-04-08 16:33:46 -05:00
if ( ginfo == * itr_team )
2009-03-02 17:02:27 -06:00
break ;
2010-02-15 15:31:27 +01:00
if ( itr_team == m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_ALLIANCE + teamIndex ]. end ())
2009-03-02 17:02:27 -06:00
return false ;
2009-03-02 17:07:18 -06:00
GroupsQueueType :: iterator itr_team2 = itr_team ;
++ itr_team2 ;
2009-03-02 17:02:27 -06:00
//invite players to other selection pool
2010-02-15 15:31:27 +01:00
for (; itr_team2 != m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_ALLIANCE + teamIndex ]. end (); ++ itr_team2 )
2009-03-02 17:02:27 -06:00
{
2009-03-05 19:02:08 -06:00
//if selection pool is full then break;
2009-04-08 16:33:46 -05:00
if ( ! ( * itr_team2 ) -> IsInvitedToBGInstanceGUID && ! m_SelectionPools [ otherTeam ]. AddGroup ( * itr_team2 , minPlayersPerTeam ))
2009-03-05 19:02:08 -06:00
break ;
2009-03-02 17:02:27 -06:00
}
2009-04-08 16:33:46 -05:00
if ( m_SelectionPools [ otherTeam ]. GetPlayerCount () != minPlayersPerTeam )
2009-03-02 17:02:27 -06:00
return false ;
2009-10-17 15:51:44 -07:00
2009-03-02 17:02:27 -06:00
//here we have correct 2 selections and we need to change one teams team and move selection pool teams to other team's queue
2009-10-17 16:20:24 -07:00
for ( GroupsQueueType :: iterator itr = m_SelectionPools [ otherTeam ]. SelectedGroups . begin (); itr != m_SelectionPools [ otherTeam ]. SelectedGroups . end (); ++ itr )
2009-03-02 17:02:27 -06:00
{
//set correct team
( * itr ) -> Team = otherTeamId ;
//add team to other queue
2010-02-15 15:31:27 +01:00
m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_ALLIANCE + otherTeam ]. push_front ( * itr );
2009-03-02 17:02:27 -06:00
//remove team from old queue
2009-03-02 17:07:18 -06:00
GroupsQueueType :: iterator itr2 = itr_team ;
++ itr2 ;
2010-02-15 15:31:27 +01:00
for (; itr2 != m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_ALLIANCE + teamIndex ]. end (); ++ itr2 )
2009-03-02 17:02:27 -06:00
{
2009-04-08 16:33:46 -05:00
if ( * itr2 == * itr )
2009-03-02 17:02:27 -06:00
{
2010-02-15 15:31:27 +01:00
m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_ALLIANCE + teamIndex ]. erase ( itr2 );
2009-03-02 17:02:27 -06:00
break ;
}
}
}
return true ;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
/*
2008-10-05 08:48:32 -05:00
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
2009-02-27 12:13:59 -06:00
should be called from BattleGround::RemovePlayer function in some cases
2008-10-02 16:23:55 -05:00
*/
2010-02-15 15:31:27 +01:00
void BattleGroundQueue :: Update ( BattleGroundTypeId bgTypeId , BattleGroundBracketId bracket_id , uint8 arenaType , bool isRated , uint32 arenaRating )
2008-10-02 16:23:55 -05:00
{
2009-02-27 12:56:00 -06:00
//if no players in queue - do nothing
2010-02-15 15:31:27 +01:00
if ( m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_ALLIANCE ]. empty () &&
m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_HORDE ]. empty () &&
m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_ALLIANCE ]. empty () &&
m_QueuedGroups [ bracket_id ][ BG_QUEUE_NORMAL_HORDE ]. empty () )
2008-10-02 16:23:55 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
//battleground with free slot for player should be always in the beggining of the queue
2010-02-15 15:31:27 +01:00
// maybe it would be better to create bgfreeslotqueue for each bracket_id
2008-10-05 08:48:32 -05:00
BGFreeSlotQueueType :: iterator itr , next ;
2009-03-02 17:07:18 -06:00
for ( itr = sBattleGroundMgr . BGFreeSlotQueue [ bgTypeId ]. begin (); itr != sBattleGroundMgr . BGFreeSlotQueue [ bgTypeId ]. end (); itr = next )
2008-10-02 16:23:55 -05:00
{
2008-10-05 08:48:32 -05:00
next = itr ;
++ next ;
2009-02-27 12:13:59 -06:00
// DO NOT allow queue manager to invite new player to arena
2010-02-15 15:31:27 +01:00
if ( ( * itr ) -> isBattleGround () && ( * itr ) -> GetTypeID () == bgTypeId && ( * itr ) -> GetBracketId () == bracket_id &&
2009-02-27 12:13:59 -06:00
( * itr ) -> GetStatus () > STATUS_WAIT_QUEUE && ( * itr ) -> GetStatus () < STATUS_WAIT_LEAVE )
2008-10-02 16:23:55 -05:00
{
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
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
// clear selection pools
m_SelectionPools [ BG_TEAM_ALLIANCE ]. Init ();
m_SelectionPools [ BG_TEAM_HORDE ]. Init ();
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
// call a function that does the job for us
2010-02-15 15:31:27 +01:00
FillPlayersToBG ( bg , bracket_id );
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
// now everything is set, invite players
2009-10-17 16:20:24 -07:00
for ( GroupsQueueType :: const_iterator citr = m_SelectionPools [ BG_TEAM_ALLIANCE ]. SelectedGroups . begin (); citr != m_SelectionPools [ BG_TEAM_ALLIANCE ]. SelectedGroups . end (); ++ citr )
2009-04-27 18:42:35 -05:00
InviteGroupToBG (( * citr ), bg , ( * citr ) -> Team );
2009-10-17 16:20:24 -07:00
for ( GroupsQueueType :: const_iterator citr = m_SelectionPools [ BG_TEAM_HORDE ]. SelectedGroups . begin (); citr != m_SelectionPools [ BG_TEAM_HORDE ]. SelectedGroups . end (); ++ citr )
2009-04-27 18:42:35 -05:00
InviteGroupToBG (( * citr ), bg , ( * citr ) -> Team );
2009-10-17 15:51:44 -07:00
2009-04-08 16:33:46 -05:00
if ( ! bg -> HasFreeSlots ())
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
// remove BG from BGFreeSlotQueue
2008-10-05 08:48:32 -05:00
bg -> RemoveFromBGFreeSlotQueue ();
}
2008-10-02 16:23:55 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
// finished iterating through the bgs with free slots, maybe we need to create a new bg
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
BattleGround * bg_template = sBattleGroundMgr . GetBattleGroundTemplate ( bgTypeId );
2009-04-08 16:33:46 -05:00
if ( ! bg_template )
2008-10-05 08:48:32 -05:00
{
sLog . outError ( "Battleground: Update: bg template not found for %u" , bgTypeId );
2008-10-02 16:23:55 -05:00
return ;
2008-10-05 08:48:32 -05:00
}
2010-02-15 15:31:27 +01:00
PvPDifficultyEntry const * bracketEntry = GetBattlegroundBracketById ( bg_template -> GetMapId (), bracket_id );
if ( ! bracketEntry )
{
sLog . outError ( "Battleground: Update: bg bracket entry not found for map %u bracket id %u" , bg_template -> GetMapId (), bracket_id );
return ;
}
2008-10-05 08:48:32 -05:00
// get the min. players per team, properly for larger arenas as well. (must have full teams for arena matches!)
uint32 MinPlayersPerTeam = bg_template -> GetMinPlayersPerTeam ();
uint32 MaxPlayersPerTeam = bg_template -> GetMaxPlayersPerTeam ();
2009-04-08 16:33:46 -05:00
if ( sBattleGroundMgr . isTesting ())
2009-02-27 12:13:59 -06:00
MinPlayersPerTeam = 1 ;
2009-04-08 16:33:46 -05:00
if ( bg_template -> isArena ())
2008-10-02 16:23:55 -05:00
{
2009-04-08 16:33:46 -05:00
if ( sBattleGroundMgr . isArenaTesting ())
2008-10-05 08:48:32 -05:00
{
MaxPlayersPerTeam = 1 ;
MinPlayersPerTeam = 1 ;
}
else
{
2009-02-27 12:13:59 -06:00
//this switch can be much shorter
MaxPlayersPerTeam = arenaType ;
MinPlayersPerTeam = arenaType ;
/*switch(arenaType)
2008-10-05 08:48:32 -05:00
{
case ARENA_TYPE_2v2:
MaxPlayersPerTeam = 2;
MinPlayersPerTeam = 2;
break;
case ARENA_TYPE_3v3:
MaxPlayersPerTeam = 3;
MinPlayersPerTeam = 3;
break;
case ARENA_TYPE_5v5:
MaxPlayersPerTeam = 5;
MinPlayersPerTeam = 5;
break;
2009-02-27 12:13:59 -06:00
}*/
2008-10-05 08:48:32 -05:00
}
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
m_SelectionPools [ BG_TEAM_ALLIANCE ]. Init ();
m_SelectionPools [ BG_TEAM_HORDE ]. Init ();
2009-10-17 15:51:44 -07:00
2009-04-08 16:33:46 -05:00
if ( bg_template -> isBattleGround ())
2009-02-10 00:59:10 -06:00
{
2009-02-27 12:13:59 -06:00
//check if there is premade against premade match
2010-02-15 15:31:27 +01:00
if ( CheckPremadeMatch ( bracket_id , MinPlayersPerTeam , MaxPlayersPerTeam ))
2009-02-10 00:59:10 -06:00
{
2009-02-27 12:13:59 -06:00
//create new battleground
2010-02-15 15:31:27 +01:00
BattleGround * bg2 = sBattleGroundMgr . CreateNewBattleGround ( bgTypeId , bracketEntry , 0 , false );
if ( ! bg2 )
2009-02-27 12:13:59 -06:00
{
sLog . outError ( "BattleGroundQueue::Update - Cannot create battleground: %u" , bgTypeId );
return ;
}
//invite those selection pools
2009-10-17 16:20:24 -07:00
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 )
2009-04-27 18:42:35 -05:00
InviteGroupToBG (( * citr ), bg2 , ( * citr ) -> Team );
2009-02-27 12:13:59 -06:00
//start bg
bg2 -> StartBattleGround ();
//clear structures
m_SelectionPools [ BG_TEAM_ALLIANCE ]. Init ();
m_SelectionPools [ BG_TEAM_HORDE ]. Init ();
2009-02-10 00:59:10 -06:00
}
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
// now check if there are in queues enough players to start new game of (normal battleground, or non-rated arena)
2009-04-08 16:33:46 -05:00
if ( ! isRated )
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
// if there are enough players in pools, start new battleground or non rated arena
2010-02-15 15:31:27 +01:00
if ( CheckNormalMatch ( bg_template , bracket_id , MinPlayersPerTeam , MaxPlayersPerTeam )
|| ( bg_template -> isArena () && CheckSkirmishForSameFaction ( bracket_id , MinPlayersPerTeam )) )
2008-10-02 16:23:55 -05:00
{
2009-02-27 12:13:59 -06:00
// we successfully created a pool
2010-02-15 15:31:27 +01:00
BattleGround * bg2 = sBattleGroundMgr . CreateNewBattleGround ( bgTypeId , bracketEntry , arenaType , false );
if ( ! bg2 )
2008-10-02 16:23:55 -05:00
{
2009-02-27 12:13:59 -06:00
sLog . outError ( "BattleGroundQueue::Update - Cannot create battleground: %u" , bgTypeId );
2008-10-05 08:48:32 -05:00
return ;
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
// invite those selection pools
2009-10-17 16:20:24 -07:00
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 )
2009-04-27 18:42:35 -05:00
InviteGroupToBG (( * citr ), bg2 , ( * citr ) -> Team );
2009-02-27 12:13:59 -06:00
// start bg
bg2 -> StartBattleGround ();
}
}
2009-04-08 16:33:46 -05:00
else if ( bg_template -> isArena ())
2009-02-27 12:13:59 -06:00
{
// found out the minimum and maximum ratings the newly added team should battle against
// arenaRating is the rating of the latest joined team, or 0
// 0 is on (automatic update call) and we must set it to team's with longest wait time
2009-04-08 16:33:46 -05:00
if ( ! arenaRating )
2009-02-27 12:13:59 -06:00
{
GroupQueueInfo * front1 = NULL ;
GroupQueueInfo * front2 = NULL ;
2010-02-15 15:31:27 +01:00
if ( ! m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_ALLIANCE ]. empty ())
2008-10-02 16:23:55 -05:00
{
2010-02-15 15:31:27 +01:00
front1 = m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_ALLIANCE ]. front ();
2009-02-27 12:13:59 -06:00
arenaRating = front1 -> ArenaTeamRating ;
2008-10-05 08:48:32 -05:00
}
2010-02-15 15:31:27 +01:00
if ( ! m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_HORDE ]. empty ())
2008-10-02 16:23:55 -05:00
{
2010-02-15 15:31:27 +01:00
front2 = m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_HORDE ]. front ();
2009-02-27 12:13:59 -06:00
arenaRating = front2 -> ArenaTeamRating ;
2008-10-05 08:48:32 -05:00
}
2009-04-08 16:33:46 -05:00
if ( front1 && front2 )
2008-12-26 17:08:59 -06:00
{
2009-04-08 16:33:46 -05:00
if ( front1 -> JoinTime < front2 -> JoinTime )
2009-02-27 12:13:59 -06:00
arenaRating = front1 -> ArenaTeamRating ;
2008-12-26 17:08:59 -06:00
}
2009-04-08 16:33:46 -05:00
else if ( ! front1 && ! front2 )
2009-02-27 12:13:59 -06:00
return ; //queues are empty
2008-10-05 08:48:32 -05:00
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
//set rating range
uint32 arenaMinRating = ( arenaRating <= sBattleGroundMgr . GetMaxRatingDifference ()) ? 0 : arenaRating - sBattleGroundMgr . GetMaxRatingDifference ();
uint32 arenaMaxRating = arenaRating + sBattleGroundMgr . GetMaxRatingDifference ();
// if max rating difference is set and the time past since server startup is greater than the rating discard time
// (after what time the ratings aren't taken into account when making teams) then
// 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 ();
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
// we need to find 2 teams which will play next game
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
GroupsQueueType :: iterator itr_team [ BG_TEAMS_COUNT ];
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
//optimalization : --- we dont need to use selection_pools - each update we select max 2 groups
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( uint32 i = BG_QUEUE_PREMADE_ALLIANCE ; i < BG_QUEUE_NORMAL_ALLIANCE ; i ++ )
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
// take the group that joined first
2010-02-15 15:31:27 +01:00
itr_team [ i ] = m_QueuedGroups [ bracket_id ][ i ]. begin ();
for (; itr_team [ i ] != m_QueuedGroups [ bracket_id ][ i ]. end (); ++ ( itr_team [ i ]))
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
// if group match conditions, then add it to pool
if ( ! ( * itr_team [ i ]) -> IsInvitedToBGInstanceGUID
&& ((( * itr_team [ i ]) -> ArenaTeamRating >= arenaMinRating && ( * itr_team [ i ]) -> ArenaTeamRating <= arenaMaxRating )
|| ( * itr_team [ i ]) -> JoinTime < discardTime ) )
{
m_SelectionPools [ i ]. AddGroup (( * itr_team [ i ]), MaxPlayersPerTeam );
// break for cycle to be able to start selecting another group from same faction queue
break ;
}
2008-10-05 08:48:32 -05:00
}
}
2009-02-27 12:13:59 -06:00
// now we are done if we have 2 groups - ali vs horde!
// if we don't have, we must try to continue search in same queue
// tmp variables are correctly set
// this code isn't much userfriendly - but it is supposed to continue search for mathing group in HORDE queue
2009-04-08 16:33:46 -05:00
if ( m_SelectionPools [ BG_TEAM_ALLIANCE ]. GetPlayerCount () == 0 && m_SelectionPools [ BG_TEAM_HORDE ]. GetPlayerCount ())
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
itr_team [ BG_TEAM_ALLIANCE ] = itr_team [ BG_TEAM_HORDE ];
++ itr_team [ BG_TEAM_ALLIANCE ];
2010-02-15 15:31:27 +01:00
for (; itr_team [ BG_TEAM_ALLIANCE ] != m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_HORDE ]. end (); ++ ( itr_team [ BG_TEAM_ALLIANCE ]))
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
if ( ! ( * itr_team [ BG_TEAM_ALLIANCE ]) -> IsInvitedToBGInstanceGUID
&& ((( * itr_team [ BG_TEAM_ALLIANCE ]) -> ArenaTeamRating >= arenaMinRating && ( * itr_team [ BG_TEAM_ALLIANCE ]) -> ArenaTeamRating <= arenaMaxRating )
|| ( * itr_team [ BG_TEAM_ALLIANCE ]) -> JoinTime < discardTime ) )
{
m_SelectionPools [ BG_TEAM_ALLIANCE ]. AddGroup (( * itr_team [ BG_TEAM_ALLIANCE ]), MaxPlayersPerTeam );
break ;
}
2008-10-05 08:48:32 -05:00
}
2009-02-27 12:13:59 -06:00
}
// this code isn't much userfriendly - but it is supposed to continue search for mathing group in ALLIANCE queue
2009-04-08 16:33:46 -05:00
if ( m_SelectionPools [ BG_TEAM_HORDE ]. GetPlayerCount () == 0 && m_SelectionPools [ BG_TEAM_ALLIANCE ]. GetPlayerCount ())
2009-02-27 12:13:59 -06:00
{
itr_team [ BG_TEAM_HORDE ] = itr_team [ BG_TEAM_ALLIANCE ];
++ itr_team [ BG_TEAM_HORDE ];
2010-02-15 15:31:27 +01:00
for (; itr_team [ BG_TEAM_HORDE ] != m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_ALLIANCE ]. end (); ++ ( itr_team [ BG_TEAM_HORDE ]))
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
if ( ! ( * itr_team [ BG_TEAM_HORDE ]) -> IsInvitedToBGInstanceGUID
&& ((( * itr_team [ BG_TEAM_HORDE ]) -> ArenaTeamRating >= arenaMinRating && ( * itr_team [ BG_TEAM_HORDE ]) -> ArenaTeamRating <= arenaMaxRating )
|| ( * itr_team [ BG_TEAM_HORDE ]) -> JoinTime < discardTime ) )
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
m_SelectionPools [ BG_TEAM_HORDE ]. AddGroup (( * itr_team [ BG_TEAM_HORDE ]), MaxPlayersPerTeam );
2008-10-05 08:48:32 -05:00
break ;
2008-10-02 16:23:55 -05:00
}
}
2009-02-27 12:13:59 -06:00
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
//if we have 2 teams, then start new arena and invite players!
2009-04-08 16:33:46 -05:00
if ( m_SelectionPools [ BG_TEAM_ALLIANCE ]. GetPlayerCount () && m_SelectionPools [ BG_TEAM_HORDE ]. GetPlayerCount ())
2009-02-27 12:13:59 -06:00
{
2010-02-15 15:31:27 +01:00
BattleGround * arena = sBattleGroundMgr . CreateNewBattleGround ( bgTypeId , bracketEntry , arenaType , true );
if ( ! arena )
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
sLog . outError ( "BattlegroundQueue::Update couldn't create arena instance for rated arena match!" );
return ;
2008-10-05 08:48:32 -05:00
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
( * ( 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 ;
sLog . outDebug ( "setting oposite teamrating for team %u to %u" , ( * ( itr_team [ BG_TEAM_HORDE ])) -> ArenaTeamId , ( * ( itr_team [ BG_TEAM_HORDE ])) -> OpponentsTeamRating );
// now we must move team if we changed its faction to another faction queue, because then we will spam log by errors in Queue::RemovePlayer
2009-04-08 16:33:46 -05:00
if (( * ( itr_team [ BG_TEAM_ALLIANCE ])) -> Team != ALLIANCE )
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:13:59 -06:00
// add to alliance queue
2010-02-15 15:31:27 +01:00
m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_ALLIANCE ]. push_front ( * ( itr_team [ BG_TEAM_ALLIANCE ]));
2009-02-27 12:13:59 -06:00
// erase from horde queue
2010-02-15 15:31:27 +01:00
m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_HORDE ]. erase ( itr_team [ BG_TEAM_ALLIANCE ]);
itr_team [ BG_TEAM_ALLIANCE ] = m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_ALLIANCE ]. begin ();
2008-10-05 08:48:32 -05:00
}
2009-04-08 16:33:46 -05:00
if (( * ( itr_team [ BG_TEAM_HORDE ])) -> Team != HORDE )
2008-12-19 16:05:13 -06:00
{
2010-02-15 15:31:27 +01:00
m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_HORDE ]. push_front ( * ( itr_team [ BG_TEAM_HORDE ]));
m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_ALLIANCE ]. erase ( itr_team [ BG_TEAM_HORDE ]);
itr_team [ BG_TEAM_HORDE ] = m_QueuedGroups [ bracket_id ][ BG_QUEUE_PREMADE_HORDE ]. begin ();
2008-12-19 16:05:13 -06:00
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
InviteGroupToBG ( * ( itr_team [ BG_TEAM_ALLIANCE ]), arena , ALLIANCE );
InviteGroupToBG ( * ( itr_team [ BG_TEAM_HORDE ]), arena , HORDE );
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
sLog . outDebug ( "Starting rated arena match!" );
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
arena -> StartBattleGround ();
2008-10-02 16:23:55 -05:00
}
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
/*********************************************************/
/*** BATTLEGROUND QUEUE EVENTS ***/
/*********************************************************/
2009-10-17 15:51:44 -07:00
2008-11-14 17:03:03 -06:00
bool BGQueueInviteEvent :: Execute ( uint64 /*e_time*/ , uint32 /*p_time*/ )
2008-10-02 16:23:55 -05:00
{
Player * plr = objmgr . GetPlayer ( m_PlayerGuid );
// player logged off (we should do nothing, he is correctly removed from queue in another procedure)
2009-04-08 16:33:46 -05:00
if ( ! plr )
2008-10-02 16:23:55 -05:00
return true ;
2009-10-17 15:51:44 -07:00
2009-02-27 12:57:33 -06:00
BattleGround * bg = sBattleGroundMgr . GetBattleGround ( m_BgInstanceGUID , m_BgTypeId );
2009-04-08 16:29:28 -05:00
//if battleground ended and its instance deleted - do nothing
2009-04-08 16:33:46 -05:00
if ( ! bg )
2008-10-02 16:23:55 -05:00
return true ;
2009-10-17 15:51:44 -07:00
2009-02-13 19:56:22 -06:00
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr :: BGQueueTypeId ( bg -> GetTypeID (), bg -> GetArenaType ());
2009-02-09 22:08:06 -06:00
uint32 queueSlot = plr -> GetBattleGroundQueueIndex ( bgQueueTypeId );
2010-02-15 15:31:27 +01:00
if ( queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES ) // player is in queue or in battleground
2008-10-02 16:23:55 -05:00
{
2009-04-08 16:29:28 -05:00
// check if player is invited to this bg
2010-02-15 15:31:27 +01:00
BattleGroundQueue & bgQueue = sBattleGroundMgr . m_BattleGroundQueues [ bgQueueTypeId ];
if ( bgQueue . IsPlayerInvited ( m_PlayerGuid , m_BgInstanceGUID , m_RemoveTime ))
2008-10-02 16:23:55 -05:00
{
2009-02-09 22:08:06 -06:00
WorldPacket data ;
2009-04-08 16:29:28 -05:00
//we must send remaining time in queue
2010-02-15 15:31:27 +01:00
sBattleGroundMgr . BuildBattleGroundStatusPacket ( & data , bg , queueSlot , STATUS_WAIT_JOIN , INVITE_ACCEPT_WAIT_TIME - INVITATION_REMIND_TIME , 0 , m_ArenaType );
2009-02-09 22:08:06 -06:00
plr -> GetSession () -> SendPacket ( & data );
2008-10-02 16:23:55 -05:00
}
}
return true ; //event will be deleted
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void BGQueueInviteEvent :: Abort ( uint64 /*e_time*/ )
{
2009-04-08 16:29:28 -05:00
//do nothing
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2009-04-08 16:29:28 -05:00
/*
this event has many possibilities when it is executed:
1. player is in battleground ( he clicked enter on invitation window )
2. player left battleground queue and he isn't there any more
3. player left battleground queue and he joined it again and IsInvitedToBGInstanceGUID = 0
4. player left queue and he joined again and he has been invited to same battleground again -> we should not remove him from queue yet
5. player is invited to bg and he didn't choose what to do and timer expired - only in this condition we should call queue::RemovePlayer
we must remove player in the 5. case even if battleground object doesn't exist!
*/
2008-10-02 16:23:55 -05:00
bool BGQueueRemoveEvent :: Execute ( uint64 /*e_time*/ , uint32 /*p_time*/ )
{
Player * plr = objmgr . GetPlayer ( m_PlayerGuid );
if ( ! plr )
// player logged off (we should do nothing, he is correctly removed from queue in another procedure)
return true ;
2009-10-17 15:51:44 -07:00
2009-02-27 12:57:33 -06:00
BattleGround * bg = sBattleGroundMgr . GetBattleGround ( m_BgInstanceGUID , m_BgTypeId );
2009-04-08 16:29:28 -05:00
//battleground can be deleted already when we are removing queue info
//bg pointer can be NULL! so use it carefully!
2009-10-17 15:51:44 -07:00
2009-04-08 16:29:28 -05:00
uint32 queueSlot = plr -> GetBattleGroundQueueIndex ( m_BgQueueTypeId );
2010-02-15 15:31:27 +01:00
if ( queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES ) // player is in queue, or in Battleground
2008-10-02 16:23:55 -05:00
{
2009-04-08 16:29:28 -05:00
// check if player is in queue for this BG and if we are removing his invite event
2010-02-15 15:31:27 +01:00
BattleGroundQueue & bgQueue = sBattleGroundMgr . m_BattleGroundQueues [ m_BgQueueTypeId ];
if ( bgQueue . IsPlayerInvited ( m_PlayerGuid , m_BgInstanceGUID , m_RemoveTime ))
2008-10-02 16:23:55 -05:00
{
2009-04-08 16:29:28 -05:00
sLog . outDebug ( "Battleground: removing player %u from bg queue for instance %u because of not pressing enter battle in time." , plr -> GetGUIDLow (), m_BgInstanceGUID );
2009-10-17 15:51:44 -07:00
2009-04-08 16:29:28 -05:00
plr -> RemoveBattleGroundQueueId ( m_BgQueueTypeId );
2010-02-15 15:31:27 +01:00
bgQueue . RemovePlayer ( m_PlayerGuid , true );
2009-04-08 16:29:28 -05:00
//update queues if battleground isn't ended
2010-02-15 15:31:27 +01:00
if ( bg && bg -> isBattleGround () && bg -> GetStatus () != STATUS_WAIT_LEAVE )
sBattleGroundMgr . ScheduleQueueUpdate ( 0 , 0 , m_BgQueueTypeId , m_BgTypeId , bg -> GetBracketId ());
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
WorldPacket data ;
2009-03-13 18:06:36 -06:00
sBattleGroundMgr . BuildBattleGroundStatusPacket ( & data , bg , queueSlot , STATUS_NONE , 0 , 0 , 0 );
2008-10-02 16:23:55 -05:00
plr -> GetSession () -> SendPacket ( & data );
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
//event will be deleted
return true ;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void BGQueueRemoveEvent :: Abort ( uint64 /*e_time*/ )
{
2009-04-08 16:29:28 -05:00
//do nothing
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
/*********************************************************/
/*** BATTLEGROUND MANAGER ***/
/*********************************************************/
2009-10-17 15:51:44 -07:00
2009-01-18 19:01:41 -06:00
BattleGroundMgr :: BattleGroundMgr () : m_AutoDistributionTimeChecker ( 0 ), m_ArenaTesting ( false )
2008-10-02 16:23:55 -05:00
{
2009-10-17 16:20:24 -07:00
for ( uint32 i = BATTLEGROUND_TYPE_NONE ; i < MAX_BATTLEGROUND_TYPE_ID ; i ++ )
2009-02-27 12:57:33 -06:00
m_BattleGrounds [ i ]. clear ();
2009-01-18 19:01:41 -06:00
m_NextRatingDiscardUpdate = sWorld . getConfig ( CONFIG_ARENA_RATING_DISCARD_TIMER );
2009-02-10 00:39:03 -06:00
m_Testing = false ;
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
BattleGroundMgr ::~ BattleGroundMgr ()
{
2009-03-09 17:07:12 -06:00
DeleteAllBattleGrounds ();
2009-02-10 09:55:16 -06:00
}
2009-10-17 15:51:44 -07:00
2009-03-09 17:07:12 -06:00
void BattleGroundMgr :: DeleteAllBattleGrounds ()
2009-02-10 09:55:16 -06:00
{
2009-11-20 19:11:28 -08:00
for ( uint32 i = BATTLEGROUND_TYPE_NONE ; i < MAX_BATTLEGROUND_TYPE_ID ; ++ i )
2008-10-05 08:48:32 -05:00
{
2009-11-20 19:11:28 -08:00
for ( BattleGroundSet :: iterator itr = m_BattleGrounds [ i ]. begin (); itr != m_BattleGrounds [ i ]. end ();)
2009-02-27 12:57:33 -06:00
{
BattleGround * bg = itr -> second ;
m_BattleGrounds [ i ]. erase ( itr ++ );
2010-02-15 15:31:27 +01:00
if ( ! m_ClientBattleGroundIds [ i ][ bg -> GetBracketId ()]. empty ())
m_ClientBattleGroundIds [ i ][ bg -> GetBracketId ()]. erase ( bg -> GetClientInstanceID ());
2009-02-27 12:57:33 -06:00
delete bg ;
}
2008-10-05 08:48:32 -05:00
}
2009-10-17 15:51:44 -07:00
2009-02-10 09:55:16 -06:00
// destroy template battlegrounds that listed only in queues (other already terminated)
2009-10-17 16:20:24 -07:00
for ( uint32 bgTypeId = 0 ; bgTypeId < MAX_BATTLEGROUND_TYPE_ID ; ++ bgTypeId )
2009-02-10 09:55:16 -06:00
{
// ~BattleGround call unregistring BG from queue
while ( ! BGFreeSlotQueue [ bgTypeId ]. empty ())
delete BGFreeSlotQueue [ bgTypeId ]. front ();
}
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
// used to update running battlegrounds, and delete finished ones
2009-01-21 16:18:57 -06:00
void BattleGroundMgr :: Update ( uint32 diff )
2008-10-02 16:23:55 -05:00
{
2008-10-05 08:48:32 -05:00
BattleGroundSet :: iterator itr , next ;
2009-11-20 19:11:28 -08:00
for ( uint32 i = BATTLEGROUND_TYPE_NONE ; i < MAX_BATTLEGROUND_TYPE_ID ; ++ i )
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:58:02 -06:00
itr = m_BattleGrounds [ i ]. begin ();
// skip updating battleground template
2009-04-08 16:33:46 -05:00
if ( itr != m_BattleGrounds [ i ]. end ())
2009-02-27 12:58:02 -06:00
++ itr ;
2009-10-17 16:20:24 -07:00
for (; itr != m_BattleGrounds [ i ]. end (); itr = next )
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:57:33 -06:00
next = itr ;
++ next ;
itr -> second -> Update ( diff );
// use the SetDeleteThis variable
// direct deletion caused crashes
2009-04-08 16:33:46 -05:00
if ( itr -> second -> m_SetDeleteThis )
2009-02-27 12:57:33 -06:00
{
BattleGround * bg = itr -> second ;
m_BattleGrounds [ i ]. erase ( itr );
2010-02-15 15:31:27 +01:00
if ( ! m_ClientBattleGroundIds [ i ][ bg -> GetBracketId ()]. empty ())
m_ClientBattleGroundIds [ i ][ bg -> GetBracketId ()]. erase ( bg -> GetClientInstanceID ());
2009-02-27 12:57:33 -06:00
delete bg ;
}
2008-10-05 08:48:32 -05:00
}
}
2009-10-17 15:51:44 -07:00
2009-08-24 19:34:56 -05:00
// update scheduled queues
if ( ! m_QueueUpdateScheduler . empty ())
{
2010-02-15 15:31:27 +01:00
std :: vector < uint64 > scheduled ;
{
//copy vector and clear the other
scheduled = std :: vector < uint64 > ( m_QueueUpdateScheduler );
m_QueueUpdateScheduler . clear ();
//release lock
}
2009-08-24 19:34:56 -05:00
for ( uint8 i = 0 ; i < scheduled . size (); i ++ )
{
2010-02-15 15:31:27 +01:00
uint32 arenaRating = scheduled [ i ] >> 32 ;
uint8 arenaType = scheduled [ i ] >> 24 & 255 ;
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundQueueTypeId ( scheduled [ i ] >> 16 & 255 );
2009-09-11 16:25:11 -07:00
BattleGroundTypeId bgTypeId = BattleGroundTypeId (( scheduled [ i ] >> 8 ) & 255 );
2010-02-15 15:31:27 +01:00
BattleGroundBracketId bracket_id = BattleGroundBracketId ( scheduled [ i ] & 255 );
m_BattleGroundQueues [ bgQueueTypeId ]. Update ( bgTypeId , bracket_id , arenaType , arenaRating > 0 , arenaRating );
2009-08-24 19:34:56 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
// if rating difference counts, maybe force-update queues
2009-04-08 16:33:46 -05:00
if ( sWorld . getConfig ( CONFIG_ARENA_MAX_RATING_DIFFERENCE ) && sWorld . getConfig ( CONFIG_ARENA_RATING_DISCARD_TIMER ))
2008-10-05 08:48:32 -05:00
{
// it's time to force update
2009-04-08 16:33:46 -05:00
if ( m_NextRatingDiscardUpdate < diff )
2008-10-05 08:48:32 -05:00
{
2010-02-15 15:31:27 +01:00
// forced update for rated arenas (scan all, but skipped non rated)
2009-02-27 12:13:59 -06:00
sLog . outDebug ( "BattleGroundMgr: UPDATING ARENA QUEUES" );
2010-02-15 15:31:27 +01:00
for ( int qtype = BATTLEGROUND_QUEUE_2v2 ; qtype <= BATTLEGROUND_QUEUE_5v5 ; ++ qtype )
for ( int bracket = BG_BRACKET_ID_FIRST ; bracket < MAX_BATTLEGROUND_BRACKETS ; ++ bracket )
m_BattleGroundQueues [ qtype ]. Update (
BATTLEGROUND_AA , BattleGroundBracketId ( bracket ),
BattleGroundMgr :: BGArenaType ( BattleGroundQueueTypeId ( qtype )), true , 0 );
2009-01-18 19:01:41 -06:00
m_NextRatingDiscardUpdate = sWorld . getConfig ( CONFIG_ARENA_RATING_DISCARD_TIMER );
2008-12-19 16:05:13 -06:00
}
else
2008-10-05 08:48:32 -05:00
m_NextRatingDiscardUpdate -= diff ;
}
2009-04-08 16:33:46 -05:00
if ( sWorld . getConfig ( CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS ))
2008-10-05 08:48:32 -05:00
{
2009-04-08 16:33:46 -05:00
if ( m_AutoDistributionTimeChecker < diff )
2008-10-05 08:48:32 -05:00
{
2009-12-24 10:20:15 +01:00
if ( time ( NULL ) > m_NextAutoDistributionTime )
2008-10-05 08:48:32 -05:00
{
DistributeArenaPoints ();
2009-12-24 10:20:15 +01:00
m_NextAutoDistributionTime = time ( NULL ) + BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY * sWorld . getConfig ( CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS );
2009-05-31 16:15:12 -05:00
CharacterDatabase . PExecute ( "UPDATE saved_variables SET NextArenaPointDistributionTime = '" UI64FMTD "'" , m_NextAutoDistributionTime );
2008-10-05 08:48:32 -05:00
}
m_AutoDistributionTimeChecker = 600000 ; // check 10 minutes
}
else
m_AutoDistributionTimeChecker -= diff ;
}
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2009-03-13 18:06:36 -06:00
void BattleGroundMgr :: BuildBattleGroundStatusPacket ( WorldPacket * data , BattleGround * bg , uint8 QueueSlot , uint8 StatusID , uint32 Time1 , uint32 Time2 , uint8 arenatype )
2008-10-02 16:23:55 -05:00
{
2010-02-14 19:13:14 -07:00
// we can be in 2 queues in same time...
2009-10-17 15:51:44 -07:00
2009-04-08 16:33:46 -05:00
if ( StatusID == 0 || ! bg )
2008-10-02 16:23:55 -05:00
{
2010-02-14 19:13:14 -07:00
data -> Initialize ( SMSG_BATTLEFIELD_STATUS , 4 + 8 );
* data << uint32 ( QueueSlot ); // queue id (0...1)
2008-10-02 16:23:55 -05:00
* data << uint64 ( 0 );
return ;
}
2009-10-17 15:51:44 -07:00
2010-02-14 19:13:14 -07:00
data -> Initialize ( SMSG_BATTLEFIELD_STATUS , ( 4 + 8 + 1 + 1 + 4 + 1 + 4 + 4 + 4 ));
* data << uint32 ( QueueSlot ); // queue id (0...1) - player can be in 2 queues in time
2009-12-23 12:47:57 +01:00
// The following segment is read as uint64 in client but can be appended as their original type.
* data << uint8 ( arenatype );
sLog . outDebug ( "BattleGroundMgr::BuildBattleGroundStatusPacket: arenatype = %u for bg instanceID %u, TypeID %u." , arenatype , bg -> GetClientInstanceID (), bg -> GetTypeID ());
* data << uint8 ( bg -> isArena () ? 0xC : 0x2 );
* data << uint32 ( bg -> GetTypeID ());
* data << uint16 ( 0x1F90 );
// End of uint64 segment, decomposed this way for simplicity
2010-02-14 19:13:14 -07:00
* data << uint8 ( 0 ); // 3.3.0
* data << uint8 ( 0 ); // 3.3.0
2009-03-10 15:30:44 -06:00
* data << uint32 ( bg -> GetClientInstanceID ());
2008-10-02 16:23:55 -05:00
// alliance/horde for BG and skirmish/rated for Arenas
2009-03-09 17:08:07 -06:00
// following displays the minimap-icon 0 = faction icon 1 = arenaicon
2009-12-23 12:47:57 +01:00
* data << uint8 ( bg -> isRated ()); // 1 for rated match, 0 for bg or non rated match
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
* data << uint32 ( StatusID ); // status
switch ( StatusID )
{
case STATUS_WAIT_QUEUE : // status_in_queue
* data << uint32 ( Time1 ); // average wait time, milliseconds
2009-03-13 18:06:36 -06:00
* data << uint32 ( Time2 ); // time in queue, updated every minute!, milliseconds
2008-10-02 16:23:55 -05:00
break ;
case STATUS_WAIT_JOIN : // status_invite
* data << uint32 ( bg -> GetMapId ()); // map id
* data << uint32 ( Time1 ); // time to remove from queue, milliseconds
break ;
case STATUS_IN_PROGRESS : // status_in_progress
* data << uint32 ( bg -> GetMapId ()); // map id
2009-03-13 18:06:36 -06:00
* data << uint32 ( Time1 ); // time to bg auto leave, 0 at bg start, 120000 after bg end, milliseconds
2008-10-02 16:23:55 -05:00
* data << uint32 ( Time2 ); // time from bg start, milliseconds
2010-01-27 13:40:01 +01:00
* data << uint8 ( /*bg->isArena() ? 0 :*/ 1 ); // unk, possibly 0 == preparation phase, 1 == battle
2008-10-02 16:23:55 -05:00
break ;
default :
sLog . outError ( "Unknown BG status!" );
break ;
}
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void BattleGroundMgr :: BuildPvpLogDataPacket ( WorldPacket * data , BattleGround * bg )
{
2009-12-25 19:12:42 +01:00
uint8 type = ( bg -> isArena () ? 1 : 0 );
2009-12-27 11:27:38 +01:00
// 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
2008-10-02 16:23:55 -05:00
{
2009-12-27 11:27:38 +01:00
// it seems this must be according to BG_WINNER_A/H and _NOT_ BG_TEAM_A/H
for ( int i = 1 ; i >= 0 ; -- i )
2008-10-05 08:48:32 -05:00
{
2010-01-25 02:38:18 +01:00
uint32 pointsLost = bg -> m_ArenaTeamRatingChanges [ i ] < 0 ? abs ( bg -> m_ArenaTeamRatingChanges [ i ]) : 0 ;
uint32 pointsGained = bg -> m_ArenaTeamRatingChanges [ i ] > 0 ? bg -> m_ArenaTeamRatingChanges [ i ] : 0 ;
* data << uint32 ( pointsLost ); // Rating Lost
* data << uint32 ( pointsGained ); // Rating gained
* data << uint32 ( 0 ); // Matchmaking Value
2009-12-27 11:27:38 +01:00
sLog . outDebug ( "rating change: %d" , bg -> m_ArenaTeamRatingChanges [ i ]);
2008-10-05 08:48:32 -05:00
}
2009-12-27 11:27:38 +01:00
for ( int i = 1 ; i >= 0 ; -- i )
2008-10-02 16:23:55 -05:00
{
2009-12-27 11:27:38 +01:00
uint32 at_id = bg -> m_ArenaTeamIds [ i ];
ArenaTeam * at = objmgr . GetArenaTeamById ( at_id );
if ( at )
* data << at -> GetName ();
else
* data << ( uint8 ) 0 ;
2008-10-02 16:23:55 -05:00
}
}
2009-10-17 15:51:44 -07:00
2009-04-08 16:33:46 -05:00
if ( bg -> GetStatus () != STATUS_WAIT_LEAVE )
2008-10-02 16:23:55 -05:00
{
2009-12-27 11:27:38 +01:00
* data << uint8 ( 0 ); // bg not ended
2008-10-02 16:23:55 -05:00
}
else
{
2009-12-27 11:27:38 +01:00
* data << uint8 ( 1 ); // bg ended
* data << uint8 ( bg -> GetWinner ()); // who win
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2009-12-27 11:27:38 +01:00
* data << ( int32 )( bg -> GetPlayerScoresSize ());
2009-10-17 16:20:24 -07:00
for ( BattleGround :: BattleGroundScoreMap :: const_iterator itr = bg -> GetPlayerScoresBegin (); itr != bg -> GetPlayerScoresEnd (); ++ itr )
2008-10-02 16:23:55 -05:00
{
2009-12-27 11:27:38 +01:00
* data << ( uint64 ) itr -> first ;
* data << ( int32 ) itr -> second -> KillingBlows ;
if ( type == 0 )
2008-10-05 08:48:32 -05:00
{
2009-12-27 11:27:38 +01:00
* data << ( int32 ) itr -> second -> HonorableKills ;
* data << ( int32 ) itr -> second -> Deaths ;
* data << ( int32 )( itr -> second -> BonusHonor );
2008-10-05 08:48:32 -05:00
}
2009-12-27 11:27:38 +01:00
else
2008-10-02 16:23:55 -05:00
{
2009-12-27 11:27:38 +01:00
Player * plr = objmgr . GetPlayer ( itr -> first );
uint32 team = bg -> GetPlayerTeam ( itr -> first );
if ( ! team && plr )
2010-01-27 13:40:01 +01:00
team = plr -> GetBGTeam ();
* data << uint8 ( team == ALLIANCE ? 1 : 0 ); // green or yellow
2010-01-25 02:38:18 +01:00
2008-10-02 16:23:55 -05:00
}
2009-12-27 11:27:38 +01:00
* data << ( int32 ) itr -> second -> DamageDone ; // damage done
* data << ( int32 ) itr -> second -> HealingDone ; // healing done
2008-10-05 08:48:32 -05:00
switch ( bg -> GetTypeID ()) // battleground specific things
2008-10-02 16:23:55 -05:00
{
case BATTLEGROUND_AV :
2009-12-27 11:27:38 +01:00
* data << ( uint32 ) 0x00000005 ; // count of next fields
* data << ( uint32 )(( BattleGroundAVScore * ) itr -> second ) -> GraveyardsAssaulted ; // GraveyardsAssaulted
* data << ( uint32 )(( BattleGroundAVScore * ) itr -> second ) -> GraveyardsDefended ; // GraveyardsDefended
* data << ( uint32 )(( BattleGroundAVScore * ) itr -> second ) -> TowersAssaulted ; // TowersAssaulted
* data << ( uint32 )(( BattleGroundAVScore * ) itr -> second ) -> TowersDefended ; // TowersDefended
* data << ( uint32 )(( BattleGroundAVScore * ) itr -> second ) -> MinesCaptured ; // MinesCaptured
2008-10-02 16:23:55 -05:00
break ;
case BATTLEGROUND_WS :
2009-12-27 11:27:38 +01:00
* data << ( uint32 ) 0x00000002 ; // count of next fields
* data << ( uint32 )(( BattleGroundWGScore * ) itr -> second ) -> FlagCaptures ; // flag captures
* data << ( uint32 )(( BattleGroundWGScore * ) itr -> second ) -> FlagReturns ; // flag returns
2008-10-02 16:23:55 -05:00
break ;
case BATTLEGROUND_AB :
2009-12-27 11:27:38 +01:00
* data << ( uint32 ) 0x00000002 ; // count of next fields
* data << ( uint32 )(( BattleGroundABScore * ) itr -> second ) -> BasesAssaulted ; // bases asssulted
* data << ( uint32 )(( BattleGroundABScore * ) itr -> second ) -> BasesDefended ; // bases defended
2008-10-02 16:23:55 -05:00
break ;
case BATTLEGROUND_EY :
2009-12-27 11:27:38 +01:00
* data << ( uint32 ) 0x00000001 ; // count of next fields
* data << ( uint32 )(( BattleGroundEYScore * ) itr -> second ) -> FlagCaptures ; // flag captures
2008-10-02 16:23:55 -05:00
break ;
case BATTLEGROUND_NA :
case BATTLEGROUND_BE :
case BATTLEGROUND_AA :
case BATTLEGROUND_RL :
2010-02-14 19:13:14 -07:00
case BATTLEGROUND_SA :
* data << uint32 ( 2 );
* data << uint32 ((( BattleGroundSAScore * ) itr -> second ) -> demolishers_destroyed );
* data << uint32 ((( BattleGroundSAScore * ) itr -> second ) -> gates_destroyed );
break ;
2008-12-24 09:58:26 -06:00
case BATTLEGROUND_DS : // wotlk
case BATTLEGROUND_RV : // wotlk
2009-12-17 10:43:12 +01:00
case BATTLEGROUND_IC : // wotlk
case BATTLEGROUND_ABG : // wotlk
2009-12-27 11:27:38 +01:00
* data << ( int32 ) 0 ; // 0
2008-10-02 16:23:55 -05:00
break ;
default :
sLog . outDebug ( "Unhandled MSG_PVP_LOG_DATA for BG id %u" , bg -> GetTypeID ());
2009-12-27 11:27:38 +01:00
* data << ( int32 ) 0 ;
2008-10-02 16:23:55 -05:00
break ;
}
}
}
2009-10-17 15:51:44 -07:00
2009-02-09 22:08:06 -06:00
void BattleGroundMgr :: BuildGroupJoinedBattlegroundPacket ( WorldPacket * data , BattleGroundTypeId bgTypeId )
2008-10-02 16:23:55 -05:00
{
/*bgTypeId is:
0 - Your group has joined a battleground queue, but you are not eligible
1 - Your group has joined the queue for AV
2 - Your group has joined the queue for WS
3 - Your group has joined the queue for AB
4 - Your group has joined the queue for NA
5 - Your group has joined the queue for BE Arena
6 - Your group has joined the queue for All Arenas
7 - Your group has joined the queue for EotS*/
data -> Initialize ( SMSG_GROUP_JOINED_BATTLEGROUND , 4 );
* data << uint32 ( bgTypeId );
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void BattleGroundMgr :: BuildUpdateWorldStatePacket ( WorldPacket * data , uint32 field , uint32 value )
{
data -> Initialize ( SMSG_UPDATE_WORLD_STATE , 4 + 4 );
* data << uint32 ( field );
* data << uint32 ( value );
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void BattleGroundMgr :: BuildPlaySoundPacket ( WorldPacket * data , uint32 soundid )
{
data -> Initialize ( SMSG_PLAY_SOUND , 4 );
* data << uint32 ( soundid );
}
2009-10-17 15:51:44 -07:00
2009-03-09 17:07:40 -06:00
void BattleGroundMgr :: BuildPlayerLeftBattleGroundPacket ( WorldPacket * data , const uint64 & guid )
2008-10-02 16:23:55 -05:00
{
data -> Initialize ( SMSG_BATTLEGROUND_PLAYER_LEFT , 8 );
2009-03-09 17:07:40 -06:00
* data << uint64 ( guid );
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void BattleGroundMgr :: BuildPlayerJoinedBattleGroundPacket ( WorldPacket * data , Player * plr )
{
data -> Initialize ( SMSG_BATTLEGROUND_PLAYER_JOINED , 8 );
* data << uint64 ( plr -> GetGUID ());
}
2009-10-17 15:51:44 -07:00
2009-04-29 00:31:03 -05:00
BattleGround * BattleGroundMgr :: GetBattleGroundThroughClientInstance ( uint32 instanceId , BattleGroundTypeId bgTypeId )
2009-03-10 15:30:44 -06:00
{
//cause at HandleBattleGroundJoinOpcode the clients sends the instanceid he gets from
//SMSG_BATTLEFIELD_LIST we need to find the battleground with this clientinstance-id
BattleGround * bg = GetBattleGroundTemplate ( bgTypeId );
2009-04-08 16:33:46 -05:00
if ( ! bg )
2009-03-10 15:30:44 -06:00
return NULL ;
2009-10-17 15:51:44 -07:00
2009-04-08 16:33:46 -05:00
if ( bg -> isArena ())
2009-03-10 15:30:44 -06:00
return GetBattleGround ( instanceId , bgTypeId );
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( BattleGroundSet :: iterator itr = m_BattleGrounds [ bgTypeId ]. begin (); itr != m_BattleGrounds [ bgTypeId ]. end (); ++ itr )
2009-03-10 15:30:44 -06:00
{
2009-04-08 16:33:46 -05:00
if ( itr -> second -> GetClientInstanceID () == instanceId )
2009-03-10 15:30:44 -06:00
return itr -> second ;
}
return NULL ;
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:57:33 -06:00
BattleGround * BattleGroundMgr :: GetBattleGround ( uint32 InstanceID , BattleGroundTypeId bgTypeId )
{
2009-08-01 00:20:32 +02:00
if ( ! InstanceID )
return NULL ;
2009-02-27 12:57:33 -06:00
//search if needed
BattleGroundSet :: iterator itr ;
2009-04-08 16:33:46 -05:00
if ( bgTypeId == BATTLEGROUND_TYPE_NONE )
2009-02-27 12:57:33 -06:00
{
2009-10-17 16:20:24 -07:00
for ( uint32 i = BATTLEGROUND_AV ; i < MAX_BATTLEGROUND_TYPE_ID ; i ++ )
2009-02-27 12:57:33 -06:00
{
itr = m_BattleGrounds [ i ]. find ( InstanceID );
2009-04-08 16:33:46 -05:00
if ( itr != m_BattleGrounds [ i ]. end ())
2009-02-27 12:57:33 -06:00
return itr -> second ;
}
return NULL ;
}
itr = m_BattleGrounds [ bgTypeId ]. find ( InstanceID );
return ( ( itr != m_BattleGrounds [ bgTypeId ]. end ()) ? itr -> second : NULL );
}
2009-10-17 15:51:44 -07:00
2009-02-09 22:08:06 -06:00
BattleGround * BattleGroundMgr :: GetBattleGroundTemplate ( BattleGroundTypeId bgTypeId )
2008-10-05 08:48:32 -05:00
{
2009-02-27 12:57:33 -06:00
//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 ;
2008-10-05 08:48:32 -05:00
}
2009-10-17 15:51:44 -07:00
2010-02-15 15:31:27 +01:00
uint32 BattleGroundMgr :: CreateClientVisibleInstanceId ( BattleGroundTypeId bgTypeId , BattleGroundBracketId bracket_id )
2009-03-10 15:30:44 -06:00
{
2009-04-08 16:33:46 -05:00
if ( IsArenaType ( bgTypeId ))
2009-03-10 15:30:44 -06:00
return 0 ; //arenas don't have client-instanceids
2009-10-17 15:51:44 -07:00
2009-03-10 15:30:44 -06:00
// we create here an instanceid, which is just for
// displaying this to the client and without any other use..
// the client-instanceIds are unique for each battleground-type
// the instance-id just needs to be as low as possible, beginning with 1
// the following works, because std::set is default ordered with "<"
// the optimalization would be to use as bitmask std::vector<uint32> - but that would only make code unreadable
uint32 lastId = 0 ;
2010-02-15 15:31:27 +01:00
for ( std :: set < uint32 >:: iterator itr = m_ClientBattleGroundIds [ bgTypeId ][ bracket_id ]. begin (); itr != m_ClientBattleGroundIds [ bgTypeId ][ bracket_id ]. end ();)
2009-03-10 15:30:44 -06:00
{
if ( ( ++ lastId ) != * itr ) //if there is a gap between the ids, we will break..
break ;
lastId = * itr ;
}
2010-02-15 15:31:27 +01:00
m_ClientBattleGroundIds [ bgTypeId ][ bracket_id ]. insert ( lastId + 1 );
2009-03-10 15:30:44 -06:00
return lastId + 1 ;
}
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
// create a new battleground that will really be used to play
2010-02-15 15:31:27 +01:00
BattleGround * BattleGroundMgr :: CreateNewBattleGround ( BattleGroundTypeId bgTypeId , PvPDifficultyEntry const * bracketEntry , uint8 arenaType , bool isRated )
2008-10-05 08:48:32 -05:00
{
// get the template BG
BattleGround * bg_template = GetBattleGroundTemplate ( bgTypeId );
2009-04-08 16:33:46 -05:00
if ( ! bg_template )
2008-10-05 08:48:32 -05:00
{
sLog . outError ( "BattleGround: CreateNewBattleGround - bg template not found for %u" , bgTypeId );
2009-02-09 22:08:06 -06:00
return NULL ;
2008-10-05 08:48:32 -05:00
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
//for arenas there is random map used
2009-04-08 16:33:46 -05:00
if ( bg_template -> isArena ())
2009-02-27 12:13:59 -06:00
{
2010-02-14 19:13:14 -07:00
// for type enter in arenas
uint32 arenaswitch = urand ( 1 , 3 );
if ( sWorld . getConfig ( CONFIG_ARENA_LK_ARENAS_ENABLE ) == 1 )
arenaswitch = urand ( 0 , 4 ); // Enable Ring of Valor and Dalaran Sewers arenas - in these arenas problem with LoS
else
arenaswitch = urand ( 1 , 3 ); // Disable WoTLK Arenas (Ring of Valor, Dalaran Sewers)
BattleGroundTypeId arenas [] = { BATTLEGROUND_RV , BATTLEGROUND_NA , BATTLEGROUND_BE , BATTLEGROUND_RL , BATTLEGROUND_DS };
uint32 arena_num = arenaswitch ;
2009-02-27 12:13:59 -06:00
bgTypeId = arenas [ arena_num ];
bg_template = GetBattleGroundTemplate ( bgTypeId );
2009-04-08 16:33:46 -05:00
if ( ! bg_template )
2009-02-27 12:13:59 -06:00
{
sLog . outError ( "BattleGround: CreateNewBattleGround - bg template not found for %u" , bgTypeId );
return NULL ;
}
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
BattleGround * bg = NULL ;
2008-10-05 08:48:32 -05:00
// create a copy of the BG template
switch ( bgTypeId )
{
2008-12-19 16:05:13 -06:00
case BATTLEGROUND_AV :
bg = new BattleGroundAV ( * ( BattleGroundAV * ) bg_template );
2008-10-05 08:48:32 -05:00
break ;
2008-12-19 16:05:13 -06:00
case BATTLEGROUND_WS :
bg = new BattleGroundWS ( * ( BattleGroundWS * ) bg_template );
2008-10-05 08:48:32 -05:00
break ;
2008-12-19 16:05:13 -06:00
case BATTLEGROUND_AB :
bg = new BattleGroundAB ( * ( BattleGroundAB * ) bg_template );
2008-10-05 08:48:32 -05:00
break ;
2008-12-19 16:05:13 -06:00
case BATTLEGROUND_NA :
bg = new BattleGroundNA ( * ( BattleGroundNA * ) bg_template );
2008-10-05 08:48:32 -05:00
break ;
2008-12-19 16:05:13 -06:00
case BATTLEGROUND_BE :
bg = new BattleGroundBE ( * ( BattleGroundBE * ) bg_template );
2008-10-05 08:48:32 -05:00
break ;
2008-12-19 16:05:13 -06:00
case BATTLEGROUND_AA :
bg = new BattleGroundAA ( * ( BattleGroundAA * ) bg_template );
2008-10-05 08:48:32 -05:00
break ;
2008-12-19 16:05:13 -06:00
case BATTLEGROUND_EY :
bg = new BattleGroundEY ( * ( BattleGroundEY * ) bg_template );
2008-10-05 08:48:32 -05:00
break ;
2008-12-19 16:05:13 -06:00
case BATTLEGROUND_RL :
bg = new BattleGroundRL ( * ( BattleGroundRL * ) bg_template );
2008-10-05 08:48:32 -05:00
break ;
2009-01-04 23:25:27 -06:00
case BATTLEGROUND_SA :
bg = new BattleGroundSA ( * ( BattleGroundSA * ) bg_template );
break ;
case BATTLEGROUND_DS :
bg = new BattleGroundDS ( * ( BattleGroundDS * ) bg_template );
break ;
case BATTLEGROUND_RV :
bg = new BattleGroundRV ( * ( BattleGroundRV * ) bg_template );
break ;
2009-12-17 10:43:12 +01:00
case BATTLEGROUND_IC :
bg = new BattleGroundIC ( * ( BattleGroundIC * ) bg_template );
break ;
case BATTLEGROUND_ABG :
bg = new BattleGroundABG ( * ( BattleGroundABG * ) bg_template );
break ;
2008-10-05 08:48:32 -05:00
default :
2009-02-13 20:10:14 -06:00
//error, but it is handled few lines above
2008-10-05 08:48:32 -05:00
return 0 ;
}
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
// generate a new instance id
bg -> SetInstanceID ( MapManager :: Instance (). GenerateInstanceId ()); // set instance id
2010-02-15 15:31:27 +01:00
bg -> SetClientInstanceID ( CreateClientVisibleInstanceId ( bgTypeId , bracketEntry -> GetBracketId ()));
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
// reset the new bg (set status to status_wait_queue from status_none)
bg -> Reset ();
2009-10-17 15:51:44 -07:00
2009-02-27 12:13:59 -06:00
// start the joining of the bg
bg -> SetStatus ( STATUS_WAIT_JOIN );
2010-02-15 15:31:27 +01:00
bg -> SetBracket ( bracketEntry );
2009-02-27 12:13:59 -06:00
bg -> SetArenaType ( arenaType );
bg -> SetRated ( isRated );
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
return bg ;
}
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
// used to create the BG templates
2009-02-13 20:10:14 -06:00
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 )
2008-10-02 16:23:55 -05:00
{
// Create the BG
BattleGround * bg = NULL ;
switch ( bgTypeId )
{
case BATTLEGROUND_AV : bg = new BattleGroundAV ; break ;
case BATTLEGROUND_WS : bg = new BattleGroundWS ; break ;
case BATTLEGROUND_AB : bg = new BattleGroundAB ; break ;
case BATTLEGROUND_NA : bg = new BattleGroundNA ; break ;
case BATTLEGROUND_BE : bg = new BattleGroundBE ; break ;
case BATTLEGROUND_AA : bg = new BattleGroundAA ; break ;
case BATTLEGROUND_EY : bg = new BattleGroundEY ; break ;
case BATTLEGROUND_RL : bg = new BattleGroundRL ; break ;
2009-01-04 23:25:27 -06:00
case BATTLEGROUND_SA : bg = new BattleGroundSA ; break ;
case BATTLEGROUND_DS : bg = new BattleGroundDS ; break ;
case BATTLEGROUND_RV : bg = new BattleGroundRV ; break ;
2009-12-17 10:43:12 +01:00
case BATTLEGROUND_IC : bg = new BattleGroundIC ; break ;
case BATTLEGROUND_ABG : bg = new BattleGroundABG ; break ;
default :
bg = new BattleGround ;
break ;
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
bg -> SetMapId ( MapID );
bg -> SetTypeID ( bgTypeId );
2009-02-13 20:10:14 -06:00
bg -> SetInstanceID ( 0 );
bg -> SetArenaorBGType ( IsArena );
2008-10-02 16:23:55 -05:00
bg -> SetMinPlayersPerTeam ( MinPlayersPerTeam );
bg -> SetMaxPlayersPerTeam ( MaxPlayersPerTeam );
2009-02-13 20:10:14 -06:00
bg -> SetMinPlayers ( MinPlayersPerTeam * 2 );
bg -> SetMaxPlayers ( MaxPlayersPerTeam * 2 );
2008-10-02 16:23:55 -05:00
bg -> SetName ( BattleGroundName );
bg -> SetTeamStartLoc ( ALLIANCE , Team1StartLocX , Team1StartLocY , Team1StartLocZ , Team1StartLocO );
bg -> SetTeamStartLoc ( HORDE , Team2StartLocX , Team2StartLocY , Team2StartLocZ , Team2StartLocO );
bg -> SetLevelRange ( LevelMin , LevelMax );
2009-10-17 15:51:44 -07:00
2009-02-27 12:58:02 -06:00
// add bg to update list
AddBattleGround ( bg -> GetInstanceID (), bg -> GetTypeID (), bg );
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
// return some not-null value, bgTypeId is good enough for me
2008-12-19 16:05:13 -06:00
return bgTypeId ;
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
void BattleGroundMgr :: CreateInitialBattleGrounds ()
{
float AStartLoc [ 4 ];
float HStartLoc [ 4 ];
uint32 MaxPlayersPerTeam , MinPlayersPerTeam , MinLvl , MaxLvl , start1 , start2 ;
BattlemasterListEntry const * bl ;
WorldSafeLocsEntry const * start ;
2009-02-13 20:10:14 -06:00
bool IsArena ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
// 0 1 2 3 4 5 6 7 8
2010-01-23 14:45:58 +01:00
QueryResult_AutoPtr result = WorldDatabase . Query ( "SELECT id, MinPlayersPerTeam,MaxPlayersPerTeam,MinLvl,MaxLvl,AllianceStartLoc,AllianceStartO,HordeStartLoc,HordeStartO FROM battleground_template" );
2009-10-17 15:51:44 -07:00
2009-04-08 16:33:46 -05:00
if ( ! result )
2008-10-02 16:23:55 -05:00
{
barGoLink bar ( 1 );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
bar . step ();
2009-10-17 15:51:44 -07:00
2009-04-03 16:36:20 -06:00
sLog . outString ();
2008-10-02 16:23:55 -05:00
sLog . outErrorDb ( ">> Loaded 0 battlegrounds. DB table `battleground_template` is empty." );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
barGoLink bar ( result -> GetRowCount ());
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
do
{
Field * fields = result -> Fetch ();
bar . step ();
2009-10-17 15:51:44 -07:00
2009-02-09 22:08:06 -06:00
uint32 bgTypeID_ = fields [ 0 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2009-02-09 22:08:06 -06:00
// can be overwrite by values from DB
bl = sBattlemasterListStore . LookupEntry ( bgTypeID_ );
2009-04-08 16:33:46 -05:00
if ( ! bl )
2008-10-02 16:23:55 -05:00
{
2009-02-13 20:10:14 -06:00
sLog . outError ( "Battleground ID %u not found in BattlemasterList.dbc. Battleground not created." , bgTypeID_ );
2008-10-02 16:23:55 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2009-02-09 22:08:06 -06:00
BattleGroundTypeId bgTypeID = BattleGroundTypeId ( bgTypeID_ );
2009-10-17 15:51:44 -07:00
2009-02-13 20:10:14 -06:00
IsArena = ( bl -> type == TYPE_ARENA );
MinPlayersPerTeam = fields [ 1 ]. GetUInt32 ();
MaxPlayersPerTeam = fields [ 2 ]. GetUInt32 ();
MinLvl = fields [ 3 ]. GetUInt32 ();
MaxLvl = fields [ 4 ]. GetUInt32 ();
//check values from DB
2009-04-08 16:33:46 -05:00
if ( MaxPlayersPerTeam == 0 || MinPlayersPerTeam == 0 || MinPlayersPerTeam > MaxPlayersPerTeam )
2009-02-13 20:10:14 -06:00
{
MaxPlayersPerTeam = bl -> maxplayersperteam ;
MinPlayersPerTeam = bl -> maxplayersperteam / 2 ;
}
2009-04-08 16:33:46 -05:00
if ( MinLvl == 0 || MaxLvl == 0 || MinLvl > MaxLvl )
2009-02-13 20:10:14 -06:00
{
2010-02-14 19:13:14 -07:00
//TO-DO: FIX ME
MinLvl = 0 ; //bl->minlvl;
MaxLvl = 80 ; //bl->maxlvl;
2009-02-13 20:10:14 -06:00
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
start1 = fields [ 5 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
start = sWorldSafeLocsStore . LookupEntry ( start1 );
2009-04-08 16:33:46 -05:00
if ( start )
2008-10-02 16:23:55 -05:00
{
AStartLoc [ 0 ] = start -> x ;
AStartLoc [ 1 ] = start -> y ;
AStartLoc [ 2 ] = start -> z ;
AStartLoc [ 3 ] = fields [ 6 ]. GetFloat ();
}
2009-12-17 10:43:12 +01:00
else if ( bgTypeID == BATTLEGROUND_AA || bgTypeID == BATTLEGROUND_ABG )
2008-10-02 16:23:55 -05:00
{
AStartLoc [ 0 ] = 0 ;
AStartLoc [ 1 ] = 0 ;
AStartLoc [ 2 ] = 0 ;
AStartLoc [ 3 ] = fields [ 6 ]. GetFloat ();
}
else
{
2009-02-13 20:10:14 -06:00
sLog . outErrorDb ( "Table `battleground_template` for id %u have non-existed WorldSafeLocs.dbc id %u in field `AllianceStartLoc`. BG not created." , bgTypeID , start1 );
2008-10-02 16:23:55 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
start2 = fields [ 7 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
start = sWorldSafeLocsStore . LookupEntry ( start2 );
2009-04-08 16:33:46 -05:00
if ( start )
2008-10-02 16:23:55 -05:00
{
HStartLoc [ 0 ] = start -> x ;
HStartLoc [ 1 ] = start -> y ;
HStartLoc [ 2 ] = start -> z ;
HStartLoc [ 3 ] = fields [ 8 ]. GetFloat ();
}
2009-12-17 10:43:12 +01:00
else if ( bgTypeID == BATTLEGROUND_AA || bgTypeID == BATTLEGROUND_ABG )
2008-10-02 16:23:55 -05:00
{
HStartLoc [ 0 ] = 0 ;
HStartLoc [ 1 ] = 0 ;
HStartLoc [ 2 ] = 0 ;
HStartLoc [ 3 ] = fields [ 8 ]. GetFloat ();
}
else
{
2009-02-13 20:10:14 -06:00
sLog . outErrorDb ( "Table `battleground_template` for id %u have non-existed WorldSafeLocs.dbc id %u in field `HordeStartLoc`. BG not created." , bgTypeID , start2 );
2008-10-02 16:23:55 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
//sLog.outDetail("Creating battleground %s, %u-%u", bl->name[sWorld.GetDBClang()], MinLvl, MaxLvl);
2009-04-08 16:33:46 -05:00
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 ]))
2008-10-02 16:23:55 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
++ count ;
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2009-04-03 16:36:20 -06:00
sLog . outString ();
2008-10-02 16:23:55 -05:00
sLog . outString ( ">> Loaded %u battlegrounds" , count );
}
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
void BattleGroundMgr :: InitAutomaticArenaPointDistribution ()
{
2009-04-08 16:33:46 -05:00
if ( sWorld . getConfig ( CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS ))
2008-10-05 08:48:32 -05:00
{
sLog . outDebug ( "Initializing Automatic Arena Point Distribution" );
2010-01-23 14:45:58 +01:00
QueryResult_AutoPtr result = CharacterDatabase . Query ( "SELECT NextArenaPointDistributionTime FROM saved_variables" );
2009-04-08 16:33:46 -05:00
if ( ! result )
2008-10-05 08:48:32 -05:00
{
2008-12-19 16:05:13 -06:00
sLog . outDebug ( "Battleground: Next arena point distribution time not found in SavedVariables, reseting it now." );
2009-12-24 10:20:15 +01:00
m_NextAutoDistributionTime = time ( NULL ) + BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY * sWorld . getConfig ( CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS );
2009-05-31 16:15:12 -05:00
CharacterDatabase . PExecute ( "INSERT INTO saved_variables (NextArenaPointDistributionTime) VALUES ('" UI64FMTD "')" , m_NextAutoDistributionTime );
2008-10-05 08:48:32 -05:00
}
else
2009-04-29 00:31:03 -05:00
m_NextAutoDistributionTime = time_t (( * result )[ 0 ]. GetUInt64 ());
2008-10-05 08:48:32 -05:00
sLog . outDebug ( "Automatic Arena Point Distribution initialized." );
}
}
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
void BattleGroundMgr :: DistributeArenaPoints ()
{
// used to distribute arena points based on last week's stats
2009-02-10 00:59:10 -06:00
sWorld . SendWorldText ( LANG_DIST_ARENA_POINTS_START );
2009-10-17 15:51:44 -07:00
2009-02-10 00:59:10 -06:00
sWorld . SendWorldText ( LANG_DIST_ARENA_POINTS_ONLINE_START );
2009-10-17 15:51:44 -07:00
2008-12-19 16:05:13 -06:00
//temporary structure for storing maximum points to add values for all players
std :: map < uint32 , uint32 > PlayerPoints ;
2009-10-17 15:51:44 -07:00
2008-12-19 16:05:13 -06:00
//at first update all points for all team members
2009-10-17 16:20:24 -07:00
for ( ObjectMgr :: ArenaTeamMap :: iterator team_itr = objmgr . GetArenaTeamMapBegin (); team_itr != objmgr . GetArenaTeamMapEnd (); ++ team_itr )
2009-04-08 16:33:46 -05:00
if ( ArenaTeam * at = team_itr -> second )
2008-12-19 16:05:13 -06:00
at -> UpdateArenaPointsHelper ( PlayerPoints );
2009-10-17 15:51:44 -07:00
2008-12-19 16:05:13 -06:00
//cycle that gives points to all players
for ( std :: map < uint32 , uint32 >:: iterator plr_itr = PlayerPoints . begin (); plr_itr != PlayerPoints . end (); ++ plr_itr )
{
2009-09-30 03:29:08 -07:00
//add points to player
2008-12-19 16:05:13 -06:00
Player * pl = objmgr . GetPlayer ( plr_itr -> first );
if ( pl )
2009-10-13 19:59:34 -07:00
{
CharacterDatabase . PExecute ( "UPDATE characters SET arena_pending_points = '%u' WHERE guid = '%u'" , plr_itr -> second , plr_itr -> first );
2008-12-19 16:05:13 -06:00
pl -> ModifyArenaPoints ( plr_itr -> second );
2009-10-13 19:59:34 -07:00
}
2009-09-30 03:29:08 -07:00
else
{
2009-10-13 19:59:34 -07:00
CharacterDatabase . PExecute ( "UPDATE characters SET arena_pending_points = 0 WHERE guid = '%u'" , plr_itr -> first );
2009-09-30 03:29:08 -07:00
CharacterDatabase . _UpdateDataBlobValue ( plr_itr -> first , PLAYER_FIELD_ARENA_CURRENCY ,
2009-09-30 04:18:07 -07:00
std :: min ( int32 ( plr_itr -> second ), int32 ( sWorld . getConfig ( CONFIG_MAX_ARENA_POINTS ))));
2009-09-30 03:29:08 -07:00
}
2008-12-19 16:05:13 -06:00
}
2009-10-17 15:51:44 -07:00
2008-12-19 16:05:13 -06:00
PlayerPoints . clear ();
2009-10-17 15:51:44 -07:00
2009-02-10 00:59:10 -06:00
sWorld . SendWorldText ( LANG_DIST_ARENA_POINTS_ONLINE_END );
2009-10-17 15:51:44 -07:00
2009-02-10 00:59:10 -06:00
sWorld . SendWorldText ( LANG_DIST_ARENA_POINTS_TEAM_START );
2009-10-17 16:20:24 -07:00
for ( ObjectMgr :: ArenaTeamMap :: iterator titr = objmgr . GetArenaTeamMapBegin (); titr != objmgr . GetArenaTeamMapEnd (); ++ titr )
2008-10-05 08:48:32 -05:00
{
2009-04-08 16:33:46 -05:00
if ( ArenaTeam * at = titr -> second )
2008-10-05 08:48:32 -05:00
{
2008-12-19 16:05:13 -06:00
at -> FinishWeek (); // set played this week etc values to 0 in memory, too
at -> SaveToDB (); // save changes
at -> NotifyStatsChanged (); // notify the players of the changes
2008-10-05 08:48:32 -05:00
}
}
2009-10-17 15:51:44 -07:00
2009-02-10 00:59:10 -06:00
sWorld . SendWorldText ( LANG_DIST_ARENA_POINTS_TEAM_END );
2009-10-17 15:51:44 -07:00
2009-02-10 00:59:10 -06:00
sWorld . SendWorldText ( LANG_DIST_ARENA_POINTS_END );
2008-10-05 08:48:32 -05:00
}
2009-10-17 15:51:44 -07:00
2009-06-11 00:45:59 -05:00
void BattleGroundMgr :: BuildBattleGroundListPacket ( WorldPacket * data , const uint64 & guid , Player * plr , BattleGroundTypeId bgTypeId , uint8 fromWhere )
2008-10-02 16:23:55 -05:00
{
2009-04-27 18:42:35 -05:00
if ( ! plr )
return ;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
data -> Initialize ( SMSG_BATTLEFIELD_LIST );
* data << uint64 ( guid ); // battlemaster guid
2009-06-11 00:45:59 -05:00
* data << uint8 ( fromWhere ); // from where you joined
2008-10-02 16:23:55 -05:00
* data << uint32 ( bgTypeId ); // battleground id
if ( bgTypeId == BATTLEGROUND_AA ) // arena
{
2009-06-11 00:45:59 -05:00
* data << uint8 ( 4 ); // unk
2010-02-14 19:13:14 -07:00
* data << uint8 ( 0 ); // unk
2009-06-11 00:45:59 -05:00
* data << uint32 ( 0 ); // unk (count?)
2008-10-02 16:23:55 -05:00
}
else // battleground
{
2010-02-14 19:13:14 -07:00
* data << uint8 ( 0 ); // unk, different for each bg type
* data << uint8 ( 0 ); // unk
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
size_t count_pos = data -> wpos ();
uint32 count = 0 ;
2010-02-14 19:13:14 -07:00
* data << uint32 ( 0 ); // number of bg instances
2009-10-17 15:51:44 -07:00
2010-02-15 15:31:27 +01:00
if ( BattleGround * bgTemplate = sBattleGroundMgr . GetBattleGroundTemplate ( bgTypeId ))
2008-10-02 16:23:55 -05:00
{
2010-02-15 15:31:27 +01:00
// expected bracket entry
if ( PvPDifficultyEntry const * bracketEntry = GetBattlegroundBracketByLevel ( bgTemplate -> GetMapId (), plr -> getLevel ()))
{
BattleGroundBracketId bracketId = bracketEntry -> GetBracketId ();
for ( std :: set < uint32 >:: iterator itr = m_ClientBattleGroundIds [ bgTypeId ][ bracketId ]. begin (); itr != m_ClientBattleGroundIds [ bgTypeId ][ bracketId ]. end (); ++ itr )
{
* data << uint32 ( * itr );
++ count ;
}
data -> put < uint32 > ( count_pos , count );
}
2008-10-02 16:23:55 -05:00
}
}
}
2009-10-17 15:51:44 -07:00
2009-02-27 12:57:33 -06:00
void BattleGroundMgr :: SendToBattleGround ( Player * pl , uint32 instanceId , BattleGroundTypeId bgTypeId )
2008-10-02 16:23:55 -05:00
{
2009-02-27 12:57:33 -06:00
BattleGround * bg = GetBattleGround ( instanceId , bgTypeId );
2009-04-08 16:33:46 -05:00
if ( bg )
2008-10-02 16:23:55 -05:00
{
uint32 mapid = bg -> GetMapId ();
float x , y , z , O ;
2008-10-05 08:48:32 -05:00
uint32 team = pl -> GetBGTeam ();
2009-04-08 16:33:46 -05:00
if ( team == 0 )
2008-10-05 08:48:32 -05:00
team = pl -> GetTeam ();
bg -> GetTeamStartLoc ( team , x , y , z , O );
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
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 );
}
2008-10-05 08:48:32 -05:00
else
{
sLog . outError ( "player %u trying to port to non-existent bg instance %u" , pl -> GetGUIDLow (), instanceId );
}
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2009-01-18 19:01:41 -06:00
void BattleGroundMgr :: SendAreaSpiritHealerQueryOpcode ( Player * pl , BattleGround * bg , const uint64 & guid )
2008-10-02 16:23:55 -05:00
{
WorldPacket data ( SMSG_AREA_SPIRIT_HEALER_TIME , 12 );
uint32 time_ = 30000 - bg -> GetLastResurrectTime (); // resurrect every 30 seconds
2009-04-08 16:33:46 -05:00
if ( time_ == uint32 ( - 1 ))
2008-10-02 16:23:55 -05:00
time_ = 0 ;
data << guid << time_ ;
pl -> GetSession () -> SendPacket ( & data );
}
2009-10-17 15:51:44 -07:00
2009-02-09 22:08:06 -06:00
bool BattleGroundMgr :: IsArenaType ( BattleGroundTypeId bgTypeId )
2008-10-05 08:48:32 -05:00
{
return ( bgTypeId == BATTLEGROUND_AA ||
bgTypeId == BATTLEGROUND_BE ||
bgTypeId == BATTLEGROUND_NA ||
2009-11-27 02:03:50 +01:00
bgTypeId == BATTLEGROUND_DS ||
bgTypeId == BATTLEGROUND_RV ||
2009-12-17 10:43:12 +01:00
bgTypeId == BATTLEGROUND_RL ||
bgTypeId == BATTLEGROUND_DS );
2008-10-05 08:48:32 -05:00
}
2009-10-17 15:51:44 -07:00
2009-02-13 19:56:22 -06:00
BattleGroundQueueTypeId BattleGroundMgr :: BGQueueTypeId ( BattleGroundTypeId bgTypeId , uint8 arenaType )
2008-10-05 08:48:32 -05:00
{
switch ( bgTypeId )
{
2009-01-18 19:01:41 -06:00
case BATTLEGROUND_WS :
return BATTLEGROUND_QUEUE_WS ;
case BATTLEGROUND_AB :
return BATTLEGROUND_QUEUE_AB ;
case BATTLEGROUND_AV :
return BATTLEGROUND_QUEUE_AV ;
case BATTLEGROUND_EY :
return BATTLEGROUND_QUEUE_EY ;
case BATTLEGROUND_SA :
return BATTLEGROUND_QUEUE_SA ;
2009-12-17 10:43:12 +01:00
case BATTLEGROUND_IC :
return BATTLEGROUND_QUEUE_IC ;
case BATTLEGROUND_ABG :
return BATTLEGROUND_QUEUE_NONE ;
2009-01-18 19:01:41 -06:00
case BATTLEGROUND_AA :
case BATTLEGROUND_NA :
case BATTLEGROUND_RL :
case BATTLEGROUND_BE :
case BATTLEGROUND_DS :
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 :
2009-02-13 19:56:22 -06:00
return BATTLEGROUND_QUEUE_NONE ;
2009-01-18 19:01:41 -06:00
}
2008-10-05 08:48:32 -05:00
default :
2009-02-13 19:56:22 -06:00
return BATTLEGROUND_QUEUE_NONE ;
2008-10-05 08:48:32 -05:00
}
}
2009-10-17 15:51:44 -07:00
2009-02-13 19:56:22 -06:00
BattleGroundTypeId BattleGroundMgr :: BGTemplateId ( BattleGroundQueueTypeId bgQueueTypeId )
2008-10-05 08:48:32 -05:00
{
switch ( bgQueueTypeId )
{
2009-01-18 19:01:41 -06:00
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 ;
2009-12-17 10:43:12 +01:00
case BATTLEGROUND_QUEUE_IC :
return BATTLEGROUND_IC ;
2009-01-18 19:01:41 -06:00
case BATTLEGROUND_QUEUE_2v2 :
case BATTLEGROUND_QUEUE_3v3 :
case BATTLEGROUND_QUEUE_5v5 :
return BATTLEGROUND_AA ;
default :
2009-02-09 22:08:06 -06:00
return BattleGroundTypeId ( 0 ); // used for unknown template (it existed and do nothing)
2008-10-05 08:48:32 -05:00
}
}
2009-10-17 15:51:44 -07:00
2009-02-13 19:56:22 -06:00
uint8 BattleGroundMgr :: BGArenaType ( BattleGroundQueueTypeId bgQueueTypeId )
2008-10-05 08:48:32 -05:00
{
switch ( bgQueueTypeId )
{
2009-01-18 19:01:41 -06:00
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 ;
2008-10-05 08:48:32 -05:00
}
}
2009-10-17 15:51:44 -07:00
2009-02-10 00:39:03 -06:00
void BattleGroundMgr :: ToggleTesting ()
{
m_Testing = ! m_Testing ;
2009-04-08 16:33:46 -05:00
if ( m_Testing )
2009-02-10 00:59:10 -06:00
sWorld . SendWorldText ( LANG_DEBUG_BG_ON );
2009-02-10 00:39:03 -06:00
else
2009-02-10 00:59:10 -06:00
sWorld . SendWorldText ( LANG_DEBUG_BG_OFF );
2009-02-10 00:39:03 -06:00
}
2009-10-17 15:51:44 -07:00
2008-10-05 08:48:32 -05:00
void BattleGroundMgr :: ToggleArenaTesting ()
{
m_ArenaTesting = ! m_ArenaTesting ;
2009-04-08 16:33:46 -05:00
if ( m_ArenaTesting )
2009-02-10 00:59:10 -06:00
sWorld . SendWorldText ( LANG_DEBUG_ARENA_ON );
2008-12-19 16:05:13 -06:00
else
2009-02-10 00:59:10 -06:00
sWorld . SendWorldText ( LANG_DEBUG_ARENA_OFF );
2008-10-05 08:48:32 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-17 16:36:07 -05:00
void BattleGroundMgr :: SetHolidayWeekends ( uint32 mask )
{
2009-10-17 16:20:24 -07:00
for ( uint32 bgtype = 1 ; bgtype < MAX_BATTLEGROUND_TYPE_ID ; ++ bgtype )
2008-10-17 16:36:07 -05:00
{
2009-02-09 22:08:06 -06:00
if ( BattleGround * bg = GetBattleGroundTemplate ( BattleGroundTypeId ( bgtype )))
2008-10-17 16:36:07 -05:00
{
bg -> SetHoliday ( mask & ( 1 << bgtype ));
}
}
}
2009-10-17 15:51:44 -07:00
2010-02-15 15:31:27 +01:00
void BattleGroundMgr :: ScheduleQueueUpdate ( uint32 arenaRating , uint8 arenaType , BattleGroundQueueTypeId bgQueueTypeId , BattleGroundTypeId bgTypeId , BattleGroundBracketId bracket_id )
2009-08-24 19:34:56 -05:00
{
2009-09-11 16:25:11 -07:00
//This method must be atomic, TODO add mutex
2010-02-15 15:31:27 +01:00
//we will use only 1 number created of bgTypeId and bracket_id
uint64 schedule_id = (( uint64 ) arenaRating << 32 ) | ( arenaType << 24 ) | ( bgQueueTypeId << 16 ) | ( bgTypeId << 8 ) | bracket_id ;
2009-08-24 19:34:56 -05:00
bool found = false ;
for ( uint8 i = 0 ; i < m_QueueUpdateScheduler . size (); i ++ )
{
if ( m_QueueUpdateScheduler [ i ] == schedule_id )
{
found = true ;
break ;
}
}
if ( ! found )
m_QueueUpdateScheduler . push_back ( schedule_id );
}
2009-10-17 15:51:44 -07:00
2009-02-09 22:08:06 -06:00
uint32 BattleGroundMgr :: GetMaxRatingDifference () const
{
2009-02-27 12:13:59 -06:00
// this is for stupid people who can't use brain and set max rating difference to 0
uint32 diff = sWorld . getConfig ( CONFIG_ARENA_MAX_RATING_DIFFERENCE );
if ( diff == 0 )
diff = 5000 ;
return diff ;
2009-02-09 22:08:06 -06:00
}
2009-10-17 15:51:44 -07:00
2009-02-09 22:08:06 -06:00
uint32 BattleGroundMgr :: GetRatingDiscardTimer () const
{
return sWorld . getConfig ( CONFIG_ARENA_RATING_DISCARD_TIMER );
}
2009-10-17 15:51:44 -07:00
2009-02-09 22:08:06 -06:00
uint32 BattleGroundMgr :: GetPrematureFinishTime () const
{
return sWorld . getConfig ( CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER );
}
2009-10-17 15:51:44 -07:00
2009-02-09 22:08:06 -06:00
void BattleGroundMgr :: LoadBattleMastersEntry ()
{
mBattleMastersMap . clear (); // need for reload case
2009-10-17 15:51:44 -07:00
2010-01-23 14:45:58 +01:00
QueryResult_AutoPtr result = WorldDatabase . Query ( "SELECT entry,bg_template FROM battlemaster_entry" );
2009-10-17 15:51:44 -07:00
2009-02-09 22:08:06 -06:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2009-04-08 16:33:46 -05:00
if ( ! result )
2009-02-09 22:08:06 -06:00
{
barGoLink bar ( 1 );
bar . step ();
2009-10-17 15:51:44 -07:00
2009-04-03 16:36:20 -06:00
sLog . outString ();
2009-02-09 22:08:06 -06:00
sLog . outString ( ">> Loaded 0 battlemaster entries - table is empty!" );
return ;
}
2009-10-17 15:51:44 -07:00
2009-02-09 22:08:06 -06:00
barGoLink bar ( result -> GetRowCount () );
2009-10-17 15:51:44 -07:00
2009-02-09 22:08:06 -06:00
do
{
++ count ;
bar . step ();
2009-10-17 15:51:44 -07:00
2009-02-09 22:08:06 -06:00
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2009-02-09 22:08:06 -06:00
uint32 entry = fields [ 0 ]. GetUInt32 ();
uint32 bgTypeId = fields [ 1 ]. GetUInt32 ();
if ( ! sBattlemasterListStore . LookupEntry ( bgTypeId ))
{
sLog . outErrorDb ( "Table `battlemaster_entry` contain entry %u for not existed battleground type %u, ignored." , entry , bgTypeId );
continue ;
}
2009-10-17 15:51:44 -07:00
2009-02-09 22:08:06 -06:00
mBattleMastersMap [ entry ] = BattleGroundTypeId ( bgTypeId );
2009-10-17 15:51:44 -07:00
2009-02-09 22:08:06 -06:00
} while ( result -> NextRow () );
2009-10-17 15:51:44 -07:00
2009-04-03 16:36:20 -06:00
sLog . outString ();
2009-02-09 22:08:06 -06:00
sLog . outString ( ">> Loaded %u battlemaster entries" , count );
2009-02-18 22:39:00 +01:00
}
2009-10-09 20:48:55 -07:00
bool BattleGroundMgr :: IsBGWeekend ( BattleGroundTypeId bgTypeId )
{
switch ( bgTypeId )
{
case BATTLEGROUND_AV :
return IsHolidayActive ( HOLIDAY_CALL_TO_ARMS_AV );
case BATTLEGROUND_EY :
return IsHolidayActive ( HOLIDAY_CALL_TO_ARMS_EY );
case BATTLEGROUND_WS :
return IsHolidayActive ( HOLIDAY_CALL_TO_ARMS_WS );
case BATTLEGROUND_SA :
return IsHolidayActive ( HOLIDAY_CALL_TO_ARMS_SA );
default :
return false ;
}
}
2009-12-17 10:43:12 +01:00
void BattleGroundMgr :: DoCompleteAchievement ( uint32 achievement , Player * player )
{
2009-12-18 13:41:30 -08:00
AchievementEntry const * AE = GetAchievementStore () -> LookupEntry ( achievement );
if ( ! player )
{
//Map::PlayerList const &PlayerList = this->GetPlayers();
//GroupsQueueType::iterator group = SelectedGroups.begin();
//if (!PlayerList.isEmpty())
//for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
// for (GroupsQueueType::iterator itr = group; itr != SelectedGroups.end(); ++itr)
// if (Player *pPlayer = itr->getSource())
// pPlayer->CompletedAchievement(AE);
}
else
{
player -> CompletedAchievement ( AE );
}
2009-12-17 10:43:12 +01:00
}