/* * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * 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 MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the 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, see . */ #ifndef __BATTLEGROUNDQUEUE_H #define __BATTLEGROUNDQUEUE_H #include "Common.h" #include "DBCEnums.h" #include "Battleground.h" #include "EventProcessor.h" //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 BGFreeSlotQueueContainer; #define COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME 10 struct GroupQueueInfo; // type predefinition struct PlayerQueueInfo // stores information for players in queue { uint32 LastOnlineTime; // for tracking and removing offline players from queue after 5 minutes GroupQueueInfo* GroupInfo; // pointer to the associated groupqueueinfo }; struct GroupQueueInfo // stores information about the group in queue (also used when joined as solo!) { std::map Players; // player queue info map ::Team Team; // Player team (ALLIANCE/HORDE) uint32 JoinTime; // time when group was added uint32 RemoveInviteTime; // time when we will remove invite for players in group uint32 IsInvitedToBGInstanceGUID; // was invited to certain BG uint32 ArenaTeamRating; // if rated match, inited to the rating of the team uint32 ArenaMatchmakerRating; // if rated match, inited to the rating of the team uint32 OpponentsTeamRating; // for rated arena matches uint32 OpponentsMatchmakerRating; // for rated arena matches }; 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 enum BattlegroundQueueInvitationType { BG_QUEUE_INVITATION_TYPE_NO_BALANCE = 0, // no balance: N+M vs N players BG_QUEUE_INVITATION_TYPE_BALANCED = 1, // teams balanced: N+1 vs N players BG_QUEUE_INVITATION_TYPE_EVEN = 2 // teams even: N vs N players }; class Battleground; class TC_GAME_API BattlegroundQueue { public: BattlegroundQueue(BattlegroundQueueTypeId queueId); ~BattlegroundQueue(); void BattlegroundQueueUpdate(uint32 diff, BattlegroundBracketId bracket_id, uint32 minRating = 0); void UpdateEvents(uint32 diff); void FillPlayersToBG(Battleground* bg, BattlegroundBracketId bracket_id); bool CheckPremadeMatch(BattlegroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam); bool CheckNormalMatch(BattlegroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers); bool CheckSkirmishForSameFaction(BattlegroundBracketId bracket_id, uint32 minPlayersPerTeam); GroupQueueInfo* AddGroup(Player const* leader, Group const* group, Team team, PVPDifficultyEntry const* bracketEntry, bool isPremade, uint32 ArenaRating, uint32 MatchmakerRating); void RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount); bool IsPlayerInvited(ObjectGuid pl_guid, const uint32 bgInstanceGuid, const uint32 removeTime); bool GetPlayerGroupInfoData(ObjectGuid guid, GroupQueueInfo* ginfo); void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BattlegroundBracketId bracket_id); uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BattlegroundBracketId bracket_id) const; typedef std::map QueuedPlayersMap; QueuedPlayersMap m_QueuedPlayers; //do NOT use deque because deque.erase() invalidates ALL iterators typedef std::list GroupsQueueType; /* 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_BRACKETS][BG_QUEUE_GROUP_TYPES_COUNT]; // class to select and invite groups to bg class SelectionPool { public: SelectionPool(): PlayerCount(0) { } void Init(); bool AddGroup(GroupQueueInfo* ginfo, uint32 desiredCount); bool KickGroup(uint32 size); uint32 GetPlayerCount() const {return PlayerCount;} public: GroupsQueueType SelectedGroups; private: uint32 PlayerCount; }; //one selection pool for horde, other one for alliance SelectionPool m_SelectionPools[PVP_TEAMS_COUNT]; uint32 GetPlayersInQueue(TeamId id); BattlegroundQueueTypeId GetQueueId() const { return m_queueId; } private: BattlegroundQueueTypeId m_queueId; bool InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, Team side); uint32 m_WaitTimes[PVP_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME]; uint32 m_WaitTimeLastPlayer[PVP_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS]; uint32 m_SumOfWaitTimes[PVP_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS]; // Event handler EventProcessor m_events; }; /* 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: BGQueueInviteEvent(ObjectGuid pl_guid, uint32 BgInstanceGUID, BattlegroundTypeId BgTypeId, uint32 removeTime, BattlegroundQueueTypeId queueId) : m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID), m_BgTypeId(BgTypeId), m_RemoveTime(removeTime), m_QueueId(queueId) { } virtual bool Execute(uint64 e_time, uint32 p_time) override; virtual void Abort(uint64 e_time) override; private: ObjectGuid m_PlayerGuid; uint32 m_BgInstanceGUID; BattlegroundTypeId m_BgTypeId; uint32 m_RemoveTime; BattlegroundQueueTypeId m_QueueId; }; /* This class is used to remove player from BG queue after 1 minute 20 seconds from first invitation We must store removeInvite time in case player left queue and joined and is invited again We must store bgQueueTypeId, because battleground can be deleted already, when player entered it */ class BGQueueRemoveEvent : public BasicEvent { public: BGQueueRemoveEvent(ObjectGuid pl_guid, uint32 bgInstanceGUID, BattlegroundQueueTypeId bgQueueTypeId, uint32 removeTime) : m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_RemoveTime(removeTime), m_BgQueueTypeId(bgQueueTypeId) { } virtual bool Execute(uint64 e_time, uint32 p_time) override; virtual void Abort(uint64 e_time) override; private: ObjectGuid m_PlayerGuid; uint32 m_BgInstanceGUID; uint32 m_RemoveTime; BattlegroundQueueTypeId m_BgQueueTypeId; }; #endif