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
*
2009-02-04 12:04:12 +01:00
* Copyright (C) 2008-2009 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-10-14 11:57:03 -05: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-10-14 11:57:03 -05:00
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2008-10-02 16:23:55 -05:00
*/
#ifndef __BATTLEGROUNDMGR_H
#define __BATTLEGROUNDMGR_H
2009-02-09 22:08:06 -06:00
#include "Common.h"
2009-03-29 17:18:01 -06:00
#include "Policies/Singleton.h"
2008-10-02 16:23:55 -05:00
#include "BattleGround.h"
typedef std :: map < uint32 , BattleGround *> BattleGroundSet ;
2009-02-27 12:13:59 -06:00
2009-03-02 17:07:18 -06:00
//this container can't be deque, because deque doesn't like removing the last element - if you remove it, it invalidates next iterator and crash appears
typedef std :: list < BattleGround *> BGFreeSlotQueueType ;
2008-10-02 16:23:55 -05:00
2009-02-09 22:08:06 -06:00
typedef UNORDERED_MAP < uint32 , BattleGroundTypeId > BattleMastersMap ;
2008-10-02 16:23:55 -05:00
2009-02-09 22:08:06 -06:00
#define BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY 86400 // seconds in a day
2009-03-10 15:29:50 -06:00
#define COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME 10
2008-10-05 08:48:32 -05:00
struct GroupQueueInfo ; // type predefinition
struct PlayerQueueInfo // stores information for players in queue
2008-10-02 16:23:55 -05:00
{
uint32 LastOnlineTime ; // for tracking and removing offline players from queue after 5 minutes
2008-10-05 08:48:32 -05:00
GroupQueueInfo * GroupInfo ; // pointer to the associated groupqueueinfo
2008-10-02 16:23:55 -05:00
};
2008-10-05 08:48:32 -05:00
struct GroupQueueInfo // stores information about the group in queue (also used when joined as solo!)
2008-10-02 16:23:55 -05:00
{
2008-10-05 08:48:32 -05:00
std :: map < uint64 , PlayerQueueInfo *> Players ; // player queue info map
uint32 Team ; // Player team (ALLIANCE/HORDE)
2009-02-09 22:08:06 -06:00
BattleGroundTypeId BgTypeId ; // battleground type id
2008-12-19 16:05:13 -06:00
bool IsRated ; // rated
2008-10-05 08:48:32 -05:00
uint8 ArenaType ; // 2v2, 3v3, 5v5 or 0 when BG
uint32 ArenaTeamId ; // team id if rated match
uint32 JoinTime ; // time when group was added
2009-03-13 18:06:36 -06:00
uint32 RemoveInviteTime ; // time when we will remove invite for players in group
2008-10-05 08:48:32 -05:00
uint32 IsInvitedToBGInstanceGUID ; // was invited to certain BG
uint32 ArenaTeamRating ; // if rated match, inited to the rating of the team
2008-12-19 16:05:13 -06:00
uint32 OpponentsTeamRating ; // for rated arena matches
2008-10-02 16:23:55 -05:00
};
2009-02-27 12:13:59 -06:00
enum BattleGroundQueueGroupTypes
{
BG_QUEUE_PREMADE_ALLIANCE = 0 ,
BG_QUEUE_PREMADE_HORDE = 1 ,
BG_QUEUE_NORMAL_ALLIANCE = 2 ,
BG_QUEUE_NORMAL_HORDE = 3
};
#define BG_QUEUE_GROUP_TYPES_COUNT 4
2008-10-05 08:48:32 -05:00
class BattleGround ;
2008-10-02 16:23:55 -05:00
class BattleGroundQueue
{
public :
BattleGroundQueue ();
~ BattleGroundQueue ();
2009-02-27 12:13:59 -06:00
void Update ( BattleGroundTypeId bgTypeId , BGQueueIdBasedOnLevel queue_id , uint8 arenaType = 0 , bool isRated = false , uint32 minRating = 0 );
2008-10-02 16:23:55 -05:00
2009-02-27 12:13:59 -06:00
void FillPlayersToBG ( BattleGround * bg , BGQueueIdBasedOnLevel queue_id );
2009-03-02 16:38:36 -06:00
bool CheckPremadeMatch ( BGQueueIdBasedOnLevel queue_id , uint32 MinPlayersPerTeam , uint32 MaxPlayersPerTeam );
bool CheckNormalMatch ( BattleGround * bg_template , BGQueueIdBasedOnLevel queue_id , uint32 minPlayers , uint32 maxPlayers );
2009-03-02 17:02:27 -06:00
bool CheckSkirmishForSameFaction ( BGQueueIdBasedOnLevel queue_id , uint32 minPlayersPerTeam );
2009-02-27 12:13:59 -06:00
GroupQueueInfo * AddGroup ( Player * leader , BattleGroundTypeId bgTypeId , uint8 ArenaType , bool isRated , bool isPremade , uint32 ArenaRating , uint32 ArenaTeamId = 0 );
2008-12-19 16:05:13 -06:00
void AddPlayer ( Player * plr , GroupQueueInfo * ginfo );
2009-01-18 19:01:41 -06:00
void RemovePlayer ( const uint64 & guid , bool decreaseInvitedCount );
2009-03-10 15:29:50 -06:00
void PlayerInvitedToBGUpdateAverageWaitTime ( GroupQueueInfo * ginfo , BGQueueIdBasedOnLevel queue_id );
uint32 GetAverageQueueWaitTime ( GroupQueueInfo * ginfo , BGQueueIdBasedOnLevel queue_id );
2008-10-05 08:48:32 -05:00
void DecreaseGroupLength ( uint32 queueId , uint32 AsGroup );
void BGEndedRemoveInvites ( BattleGround * bg );
2009-01-18 19:01:41 -06:00
void AnnounceWorld ( GroupQueueInfo * ginfo , const uint64 & playerGUID , bool isAddedToQueue );
2008-10-02 16:23:55 -05:00
2008-10-05 08:48:32 -05:00
typedef std :: map < uint64 , PlayerQueueInfo > QueuedPlayersMap ;
2009-02-27 12:13:59 -06:00
QueuedPlayersMap m_QueuedPlayers ;
//we need constant add to begin and constant remove / add from the end, therefore deque suits our problem well
2009-03-02 16:38:36 -06:00
typedef std :: list < GroupQueueInfo *> GroupsQueueType ;
2009-02-27 12:13:59 -06:00
/*
This two dimensional array is used to store All queued groups
First dimension specifies the bgTypeId
Second dimension specifies the player's group types -
BG_QUEUE_PREMADE_ALLIANCE is used for premade alliance groups and alliance rated arena teams
BG_QUEUE_PREMADE_HORDE is used for premade horde groups and horde rated arena teams
BG_QUEUE_NORMAL_ALLIANCE is used for normal (or small) alliance groups or non-rated arena matches
BG_QUEUE_NORMAL_HORDE is used for normal (or small) horde groups or non-rated arena matches
*/
GroupsQueueType m_QueuedGroups [ MAX_BATTLEGROUND_QUEUES ][ BG_QUEUE_GROUP_TYPES_COUNT ];
2008-10-05 08:48:32 -05:00
// class to select and invite groups to bg
class SelectionPool
{
public :
2009-02-27 12:13:59 -06:00
void Init ();
bool AddGroup ( GroupQueueInfo * ginfo , uint32 desiredCount );
bool KickGroup ( uint32 size );
2008-10-05 08:48:32 -05:00
uint32 GetPlayerCount () const { return PlayerCount ;}
public :
2009-02-27 12:13:59 -06:00
GroupsQueueType SelectedGroups ;
2008-10-05 08:48:32 -05:00
private :
uint32 PlayerCount ;
};
2009-02-27 12:13:59 -06:00
//one selection pool for horde, other one for alliance
SelectionPool m_SelectionPools [ BG_TEAMS_COUNT ];
2008-10-05 08:48:32 -05:00
private :
bool InviteGroupToBG ( GroupQueueInfo * ginfo , BattleGround * bg , uint32 side );
2009-03-10 15:29:50 -06:00
uint32 m_WaitTimes [ BG_TEAMS_COUNT ][ MAX_BATTLEGROUND_QUEUES ][ COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME ];
uint32 m_WaitTimeLastPlayer [ BG_TEAMS_COUNT ][ MAX_BATTLEGROUND_QUEUES ];
uint32 m_SumOfWaitTimes [ BG_TEAMS_COUNT ][ MAX_BATTLEGROUND_QUEUES ];
2008-10-02 16:23:55 -05:00
};
/*
This class is used to invite player to BG again, when minute lasts from his first invitation
it is capable to solve all possibilities
*/
class BGQueueInviteEvent : public BasicEvent
{
public :
2009-02-27 12:57:33 -06:00
BGQueueInviteEvent ( const uint64 & pl_guid , uint32 BgInstanceGUID , BattleGroundTypeId BgTypeId ) :
m_PlayerGuid ( pl_guid ), m_BgInstanceGUID ( BgInstanceGUID ), m_BgTypeId ( BgTypeId )
{
};
2008-10-02 16:23:55 -05:00
virtual ~ BGQueueInviteEvent () {};
virtual bool Execute ( uint64 e_time , uint32 p_time );
virtual void Abort ( uint64 e_time );
private :
uint64 m_PlayerGuid ;
uint32 m_BgInstanceGUID ;
2009-02-27 12:57:33 -06:00
BattleGroundTypeId m_BgTypeId ;
2008-10-02 16:23:55 -05:00
};
/*
This class is used to remove player from BG queue after 2 minutes from first invitation
*/
class BGQueueRemoveEvent : public BasicEvent
{
public :
2009-02-27 12:57:33 -06:00
BGQueueRemoveEvent ( const uint64 & pl_guid , uint32 bgInstanceGUID , BattleGroundTypeId BgTypeId , uint32 playersTeam ) :
m_PlayerGuid ( pl_guid ), m_BgInstanceGUID ( bgInstanceGUID ), m_BgTypeId ( BgTypeId ), m_PlayersTeam ( playersTeam )
2009-01-18 19:01:41 -06:00
{
};
2008-10-02 16:23:55 -05:00
virtual ~ BGQueueRemoveEvent () {};
virtual bool Execute ( uint64 e_time , uint32 p_time );
virtual void Abort ( uint64 e_time );
private :
uint64 m_PlayerGuid ;
uint32 m_BgInstanceGUID ;
uint32 m_PlayersTeam ;
2009-02-27 12:57:33 -06:00
BattleGroundTypeId m_BgTypeId ;
2008-10-02 16:23:55 -05:00
};
class BattleGroundMgr
{
public :
/* Construction */
BattleGroundMgr ();
~ BattleGroundMgr ();
2009-01-21 16:18:57 -06:00
void Update ( uint32 diff );
2008-10-02 16:23:55 -05:00
/* Packet Building */
void BuildPlayerJoinedBattleGroundPacket ( WorldPacket * data , Player * plr );
2009-03-09 17:07:40 -06:00
void BuildPlayerLeftBattleGroundPacket ( WorldPacket * data , const uint64 & guid );
2009-02-09 22:08:06 -06:00
void BuildBattleGroundListPacket ( WorldPacket * data , const uint64 & guid , Player * plr , BattleGroundTypeId bgTypeId );
void BuildGroupJoinedBattlegroundPacket ( WorldPacket * data , BattleGroundTypeId bgTypeId );
2008-10-02 16:23:55 -05:00
void BuildUpdateWorldStatePacket ( WorldPacket * data , uint32 field , uint32 value );
void BuildPvpLogDataPacket ( WorldPacket * data , BattleGround * bg );
2009-03-13 18:06:36 -06:00
void BuildBattleGroundStatusPacket ( WorldPacket * data , BattleGround * bg , uint8 QueueSlot , uint8 StatusID , uint32 Time1 , uint32 Time2 , uint8 arenatype );
2008-10-02 16:23:55 -05:00
void BuildPlaySoundPacket ( WorldPacket * data , uint32 soundid );
2009-01-18 19:01:41 -06:00
void SendAreaSpiritHealerQueryOpcode ( Player * pl , BattleGround * bg , const uint64 & guid );
2009-02-27 12:13:59 -06:00
2008-10-02 16:23:55 -05:00
/* Player invitation */
// called from Queue update, or from Addplayer to queue
2009-02-27 12:57:33 -06:00
void InvitePlayer ( Player * plr , uint32 bgInstanceGUID , BattleGroundTypeId bgTypeId , uint32 team );
2008-10-02 16:23:55 -05:00
/* Battlegrounds */
2009-03-10 15:30:44 -06:00
BattleGround * GetBattleGroundThroughClientInstance ( uint32 instanceId , BattleGroundTypeId bgTypeId , BGQueueIdBasedOnLevel queue_id );
2009-02-27 12:57:33 -06:00
BattleGround * GetBattleGround ( uint32 InstanceID , BattleGroundTypeId bgTypeId ); //there must be uint32 because MAX_BATTLEGROUND_TYPE_ID means unknown
2008-10-02 16:23:55 -05:00
2009-03-10 15:30:44 -06:00
BattleGround * GetBattleGroundTemplate ( BattleGroundTypeId bgTypeId );
BattleGround * CreateNewBattleGround ( BattleGroundTypeId bgTypeId , BGQueueIdBasedOnLevel queue_id , uint8 arenaType , bool isRated );
2008-10-05 08:48:32 -05:00
2009-02-13 20:10:14 -06:00
uint32 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
2009-02-27 12:57:33 -06:00
void AddBattleGround ( uint32 InstanceID , BattleGroundTypeId bgTypeId , BattleGround * BG ) { m_BattleGrounds [ bgTypeId ][ InstanceID ] = BG ; };
void RemoveBattleGround ( uint32 instanceID , BattleGroundTypeId bgTypeId ) { m_BattleGrounds [ bgTypeId ]. erase ( instanceID ); }
2009-03-10 15:30:44 -06:00
uint32 CreateClientVisibleInstanceId ( BattleGroundTypeId bgTypeId , BGQueueIdBasedOnLevel queue_id );
2008-10-02 16:23:55 -05:00
void CreateInitialBattleGrounds ();
2009-03-09 17:07:12 -06:00
void DeleteAllBattleGrounds ();
2008-10-02 16:23:55 -05:00
2009-02-27 12:57:33 -06:00
void SendToBattleGround ( Player * pl , uint32 InstanceID , BattleGroundTypeId bgTypeId );
2008-10-02 16:23:55 -05:00
/* Battleground queues */
//these queues are instantiated when creating BattlegroundMrg
2008-10-05 08:48:32 -05:00
BattleGroundQueue m_BattleGroundQueues [ MAX_BATTLEGROUND_QUEUE_TYPES ]; // public, because we need to access them in BG handler code
2008-10-02 16:23:55 -05:00
2009-02-09 22:08:06 -06:00
BGFreeSlotQueueType BGFreeSlotQueue [ MAX_BATTLEGROUND_TYPE_ID ];
2008-10-02 16:23:55 -05:00
2009-02-09 22:08:06 -06:00
uint32 GetMaxRatingDifference () const ;
uint32 GetRatingDiscardTimer () const ;
uint32 GetPrematureFinishTime () const ;
2008-10-05 08:48:32 -05:00
void InitAutomaticArenaPointDistribution ();
void DistributeArenaPoints ();
void ToggleArenaTesting ();
2009-02-10 00:39:03 -06:00
void ToggleTesting ();
2008-10-05 08:48:32 -05:00
2008-10-17 16:36:07 -05:00
void SetHolidayWeekends ( uint32 mask );
2009-02-09 22:08:06 -06:00
void LoadBattleMastersEntry ();
BattleGroundTypeId GetBattleMasterBG ( uint32 entry ) const
{
BattleMastersMap :: const_iterator itr = mBattleMastersMap . find ( entry );
if ( itr != mBattleMastersMap . end ())
return itr -> second ;
return BATTLEGROUND_WS ;
}
2009-01-18 19:01:41 -06:00
bool isArenaTesting () const { return m_ArenaTesting ; }
2009-02-10 00:39:03 -06:00
bool isTesting () const { return m_Testing ; }
2009-01-18 19:01:41 -06:00
2009-02-09 22:08:06 -06:00
static bool IsArenaType ( BattleGroundTypeId bgTypeId );
static bool IsBattleGroundType ( BattleGroundTypeId bgTypeId ) { return ! BattleGroundMgr :: IsArenaType ( bgTypeId ); }
2009-02-13 19:56:22 -06:00
static BattleGroundQueueTypeId BGQueueTypeId ( BattleGroundTypeId bgTypeId , uint8 arenaType );
static BattleGroundTypeId BGTemplateId ( BattleGroundQueueTypeId bgQueueTypeId );
static uint8 BGArenaType ( BattleGroundQueueTypeId bgQueueTypeId );
2008-10-02 16:23:55 -05:00
private :
2009-02-09 22:08:06 -06:00
BattleMastersMap mBattleMastersMap ;
2008-10-02 16:23:55 -05:00
/* Battlegrounds */
2009-02-27 12:57:33 -06:00
BattleGroundSet m_BattleGrounds [ MAX_BATTLEGROUND_TYPE_ID ];
2009-03-10 15:30:44 -06:00
std :: set < uint32 > m_ClientBattleGroundIds [ MAX_BATTLEGROUND_TYPE_ID ][ MAX_BATTLEGROUND_QUEUES ]; //the instanceids just visible for the client
2008-10-05 08:48:32 -05:00
uint32 m_NextRatingDiscardUpdate ;
uint64 m_NextAutoDistributionTime ;
uint32 m_AutoDistributionTimeChecker ;
bool m_ArenaTesting ;
2009-02-10 00:39:03 -06:00
bool m_Testing ;
2008-10-02 16:23:55 -05:00
};
2008-10-14 11:57:03 -05:00
#define sBattleGroundMgr Trinity::Singleton<BattleGroundMgr>::Instance()
2008-10-02 16:23:55 -05:00
#endif
2009-02-17 20:07:49 -06:00