--HG--
branch : trunk
This commit is contained in:
Brian
2010-02-15 07:55:01 -07:00
22 changed files with 614 additions and 562 deletions
+36 -20
View File
@@ -135,7 +135,7 @@ BattleGround::BattleGround()
m_ClientInstanceID = 0; m_ClientInstanceID = 0;
m_EndTime = 0; m_EndTime = 0;
m_LastResurrectTime = 0; m_LastResurrectTime = 0;
m_QueueId = QUEUE_ID_MAX_LEVEL_19; m_BracketId = BG_BRACKET_ID_FIRST;
m_InvitedAlliance = 0; m_InvitedAlliance = 0;
m_InvitedHorde = 0; m_InvitedHorde = 0;
m_ArenaType = 0; m_ArenaType = 0;
@@ -503,11 +503,13 @@ void BattleGround::SendPacketToAll(WorldPacket *packet)
{ {
for (BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) for (BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{ {
if (itr->second.OfflineRemoveTime)
continue;
Player *plr = objmgr.GetPlayer(itr->first); Player *plr = objmgr.GetPlayer(itr->first);
if (plr) if (plr)
plr->GetSession()->SendPacket(packet); plr->GetSession()->SendPacket(packet);
else else
sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); sLog.outError("BattleGround:SendPacketToAll: Player (GUID: %u) not found!", GUID_LOPART(itr->first));
} }
} }
@@ -515,11 +517,12 @@ void BattleGround::SendPacketToTeam(uint32 TeamID, WorldPacket *packet, Player *
{ {
for (BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) for (BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{ {
if (itr->second.OfflineRemoveTime)
continue;
Player *plr = objmgr.GetPlayer(itr->first); Player *plr = objmgr.GetPlayer(itr->first);
if (!plr) if (!plr)
{ {
sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); sLog.outError("BattleGround:SendPacketToTeam: Player (GUID: %u) not found!", GUID_LOPART(itr->first));
continue; continue;
} }
@@ -547,11 +550,13 @@ void BattleGround::PlaySoundToTeam(uint32 SoundID, uint32 TeamID)
for (BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) for (BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{ {
if (itr->second.OfflineRemoveTime)
continue;
Player *plr = objmgr.GetPlayer(itr->first); Player *plr = objmgr.GetPlayer(itr->first);
if (!plr) if (!plr)
{ {
sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); sLog.outError("BattleGround:PlaySoundToTeam: Player (GUID: %u) not found!", GUID_LOPART(itr->first));
continue; continue;
} }
@@ -570,11 +575,13 @@ void BattleGround::CastSpellOnTeam(uint32 SpellID, uint32 TeamID)
{ {
for (BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) for (BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{ {
if (itr->second.OfflineRemoveTime)
continue;
Player *plr = objmgr.GetPlayer(itr->first); Player *plr = objmgr.GetPlayer(itr->first);
if (!plr) if (!plr)
{ {
sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); sLog.outError("BattleGround:CastSpellOnTeam: Player (GUID: %u) not found!", GUID_LOPART(itr->first));
continue; continue;
} }
@@ -606,11 +613,13 @@ void BattleGround::RewardHonorToTeam(uint32 Honor, uint32 TeamID)
{ {
for (BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) for (BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{ {
if (itr->second.OfflineRemoveTime)
continue;
Player *plr = objmgr.GetPlayer(itr->first); Player *plr = objmgr.GetPlayer(itr->first);
if (!plr) if (!plr)
{ {
sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); sLog.outError("BattleGround:RewardHonorToTeam: Player (GUID: %u) not found!", GUID_LOPART(itr->first));
continue; continue;
} }
@@ -631,11 +640,13 @@ void BattleGround::RewardReputationToTeam(uint32 faction_id, uint32 Reputation,
for (BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) for (BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{ {
if (itr->second.OfflineRemoveTime)
continue;
Player *plr = objmgr.GetPlayer(itr->first); Player *plr = objmgr.GetPlayer(itr->first);
if (!plr) if (!plr)
{ {
sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); sLog.outError("BattleGround:RewardReputationToTeam: Player (GUID: %u) not found!", GUID_LOPART(itr->first));
continue; continue;
} }
@@ -722,10 +733,9 @@ void BattleGround::EndBattleGround(uint32 winner)
for (BattleGroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) for (BattleGroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{ {
Player *plr = objmgr.GetPlayer(itr->first);
uint32 team = itr->second.Team; uint32 team = itr->second.Team;
if (!plr) if (itr->second.OfflineRemoveTime)
{ {
//if rated arena match - make member lost! //if rated arena match - make member lost!
if (isArena() && isRated() && winner_arena_team && loser_arena_team && winner_arena_team != loser_arena_team) if (isArena() && isRated() && winner_arena_team && loser_arena_team && winner_arena_team != loser_arena_team)
@@ -735,9 +745,11 @@ void BattleGround::EndBattleGround(uint32 winner)
else else
loser_arena_team->OfflineMemberLost(itr->first, winner_rating); loser_arena_team->OfflineMemberLost(itr->first, winner_rating);
} }
sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first));
continue; continue;
} }
Player *plr = objmgr.GetPlayer(itr->first);
if (!plr)
sLog.outError("BattleGround:EndBattleGround Player (GUID: %u) not found!", GUID_LOPART(itr->first));
// should remove spirit of redemption // should remove spirit of redemption
if(plr->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) if(plr->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
@@ -1077,7 +1089,7 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
{ {
// a player has left the battleground, so there are free slots -> add to queue // a player has left the battleground, so there are free slots -> add to queue
AddToBGFreeSlotQueue(); AddToBGFreeSlotQueue();
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, GetQueueId()); sBattleGroundMgr.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, GetBracketId());
} }
// Let others know // Let others know
WorldPacket data; WorldPacket data;
@@ -1104,7 +1116,6 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
// this method is called when no players remains in battleground // this method is called when no players remains in battleground
void BattleGround::Reset() void BattleGround::Reset()
{ {
SetQueueId(QUEUE_ID_MAX_LEVEL_19);
SetWinner(WINNER_NONE); SetWinner(WINNER_NONE);
SetStatus(STATUS_WAIT_QUEUE); SetStatus(STATUS_WAIT_QUEUE);
SetStartTime(0); SetStartTime(0);
@@ -1279,16 +1290,15 @@ void BattleGround::EventPlayerLoggedOut(Player* player)
m_Players[player->GetGUID()].OfflineRemoveTime = sWorld.GetGameTime() + MAX_OFFLINE_TIME; m_Players[player->GetGUID()].OfflineRemoveTime = sWorld.GetGameTime() + MAX_OFFLINE_TIME;
if (GetStatus() == STATUS_IN_PROGRESS) if (GetStatus() == STATUS_IN_PROGRESS)
{ {
if (isBattleGround()) // drop flag and handle other cleanups
EventPlayerDroppedFlag(player); RemovePlayer(player, player->GetGUID());
else
{ // 1 player is logging out, if it is the last, then end arena!
//1 player is logging out, if it is the last, then end arena! if (isArena())
if (GetAlivePlayersCountByTeam(player->GetTeam()) <= 1 && GetPlayersCountByTeam(GetOtherTeam(player->GetTeam()))) if (GetAlivePlayersCountByTeam(player->GetTeam()) <= 1 && GetPlayersCountByTeam(GetOtherTeam(player->GetTeam())))
EndBattleGround(GetOtherTeam(player->GetTeam())); EndBattleGround(GetOtherTeam(player->GetTeam()));
}
return;
} }
player->LeaveBattleground(); player->LeaveBattleground();
} }
@@ -1919,3 +1929,9 @@ bool BattleGround::IsTeamScoreInRange(uint32 team, uint32 minScore, uint32 maxSc
uint32 score = (m_TeamScores[team_idx] < 0) ? 0 : uint32(m_TeamScores[team_idx]); uint32 score = (m_TeamScores[team_idx] < 0) ? 0 : uint32(m_TeamScores[team_idx]);
return score >= minScore && score <= maxScore; return score >= minScore && score <= maxScore;
} }
void BattleGround::SetBracket( PvPDifficultyEntry const* bracketEntry )
{
m_BracketId = bracketEntry->GetBracketId();
SetLevelRange(bracketEntry->minLevel,bracketEntry->maxLevel);
}
+5 -21
View File
@@ -23,6 +23,7 @@
#include "Common.h" #include "Common.h"
#include "SharedDefines.h" #include "SharedDefines.h"
#include "DBCEnums.h"
class Creature; class Creature;
class GameObject; class GameObject;
@@ -31,6 +32,7 @@ class Player;
class WorldPacket; class WorldPacket;
class BattleGroundMap; class BattleGroundMap;
struct PvPDifficultyEntry;
struct WorldSafeLocsEntry; struct WorldSafeLocsEntry;
enum BattleGroundSounds enum BattleGroundSounds
@@ -166,19 +168,6 @@ enum BattleGroundQueueTypeId
MAX_BATTLEGROUND_QUEUE_TYPES MAX_BATTLEGROUND_QUEUE_TYPES
}; };
enum BGQueueIdBasedOnLevel // queue_id for level ranges
{
QUEUE_ID_MAX_LEVEL_19 = 0,
QUEUE_ID_MAX_LEVEL_29 = 1,
QUEUE_ID_MAX_LEVEL_39 = 2,
QUEUE_ID_MAX_LEVEL_49 = 3,
QUEUE_ID_MAX_LEVEL_59 = 4,
QUEUE_ID_MAX_LEVEL_69 = 5,
QUEUE_ID_MAX_LEVEL_79 = 6,
QUEUE_ID_MAX_LEVEL_80 = 7
};
#define MAX_BATTLEGROUND_QUEUES 8
enum ScoreType enum ScoreType
{ {
SCORE_KILLING_BLOWS = 1, SCORE_KILLING_BLOWS = 1,
@@ -325,7 +314,7 @@ class BattleGround
// Get methods: // Get methods:
char const* GetName() const { return m_Name; } char const* GetName() const { return m_Name; }
BattleGroundTypeId GetTypeID() const { return m_TypeID; } BattleGroundTypeId GetTypeID() const { return m_TypeID; }
BGQueueIdBasedOnLevel GetQueueId() const { return m_QueueId; } BattleGroundBracketId GetBracketId() const { return m_BracketId; }
uint32 GetInstanceID() const { return m_InstanceID; } uint32 GetInstanceID() const { return m_InstanceID; }
BattleGroundStatus GetStatus() const { return m_Status; } BattleGroundStatus GetStatus() const { return m_Status; }
uint32 GetClientInstanceID() const { return m_ClientInstanceID; } uint32 GetClientInstanceID() const { return m_ClientInstanceID; }
@@ -351,12 +340,7 @@ class BattleGround
void SetName(char const* Name) { m_Name = Name; } void SetName(char const* Name) { m_Name = Name; }
void SetTypeID(BattleGroundTypeId TypeID) { m_TypeID = TypeID; } void SetTypeID(BattleGroundTypeId TypeID) { m_TypeID = TypeID; }
//here we can count minlevel and maxlevel for players //here we can count minlevel and maxlevel for players
void SetQueueId(BGQueueIdBasedOnLevel ID) void SetBracket(PvPDifficultyEntry const* bracketEntry);
{
m_QueueId = ID;
uint8 diff = (m_TypeID == BATTLEGROUND_AV) ? 1 : 0;
this->SetLevelRange((ID + 1) * 10 + diff, (ID + 2) * 10 - ((diff + 1) % 2));
}
void SetInstanceID(uint32 InstanceID) { m_InstanceID = InstanceID; } void SetInstanceID(uint32 InstanceID) { m_InstanceID = InstanceID; }
void SetStatus(BattleGroundStatus Status) { m_Status = Status; } void SetStatus(BattleGroundStatus Status) { m_Status = Status; }
void SetClientInstanceID(uint32 InstanceID) { m_ClientInstanceID = InstanceID; } void SetClientInstanceID(uint32 InstanceID) { m_ClientInstanceID = InstanceID; }
@@ -588,7 +572,7 @@ class BattleGround
uint32 m_StartTime; uint32 m_StartTime;
int32 m_EndTime; // it is set to 120000 when bg is ending and it decreases itself int32 m_EndTime; // it is set to 120000 when bg is ending and it decreases itself
uint32 m_LastResurrectTime; uint32 m_LastResurrectTime;
BGQueueIdBasedOnLevel m_QueueId; BattleGroundBracketId m_BracketId;
uint8 m_ArenaType; // 2=2v2, 3=3v3, 5=5v5 uint8 m_ArenaType; // 2=2v2, 3=3v3, 5=5v5
bool m_InBGFreeSlotQueue; // used to make sure that BG is only once inserted into the BattleGroundMgr.BGFreeSlotQueue[bgTypeId] deque bool m_InBGFreeSlotQueue; // used to make sure that BG is only once inserted into the BattleGroundMgr.BGFreeSlotQueue[bgTypeId] deque
bool m_SetDeleteThis; // used for safe deletion of the bg after end / all players leave bool m_SetDeleteThis; // used for safe deletion of the bg after end / all players leave
+2 -2
View File
@@ -153,7 +153,7 @@ void BattleGroundEY::CheckSomeoneJoinedPoint()
Player *plr = objmgr.GetPlayer(m_PlayersNearPoint[EY_POINTS_MAX][j]); Player *plr = objmgr.GetPlayer(m_PlayersNearPoint[EY_POINTS_MAX][j]);
if (!plr) if (!plr)
{ {
sLog.outError("BattleGroundEY: Player (GUID: %u) not found!", GUID_LOPART(m_PlayersNearPoint[EY_POINTS_MAX][j])); sLog.outError("BattleGroundEY:CheckSomeoneJoinedPoint: Player (GUID: %u) not found!", GUID_LOPART(m_PlayersNearPoint[EY_POINTS_MAX][j]));
++j; ++j;
continue; continue;
} }
@@ -193,7 +193,7 @@ void BattleGroundEY::CheckSomeoneLeftPoint()
Player *plr = objmgr.GetPlayer(m_PlayersNearPoint[i][j]); Player *plr = objmgr.GetPlayer(m_PlayersNearPoint[i][j]);
if (!plr) if (!plr)
{ {
sLog.outError("BattleGroundEY: Player (GUID: %u) not found!", GUID_LOPART(m_PlayersNearPoint[i][j])); sLog.outError("BattleGroundEY:CheckSomeoneLeftPoint Player (GUID: %u) not found!", GUID_LOPART(m_PlayersNearPoint[i][j]));
//move not existed player to "free space" - this will cause many error showing in log, but it is a very important bug //move not existed player to "free space" - this will cause many error showing in log, but it is a very important bug
m_PlayersNearPoint[EY_POINTS_MAX].push_back(m_PlayersNearPoint[i][j]); m_PlayersNearPoint[EY_POINTS_MAX].push_back(m_PlayersNearPoint[i][j]);
m_PlayersNearPoint[i].erase(m_PlayersNearPoint[i].begin() + j); m_PlayersNearPoint[i].erase(m_PlayersNearPoint[i].begin() + j);
+136 -174
View File
@@ -112,6 +112,11 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
return; return;
} }
// expected bracket entry
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),_player->getLevel());
if (!bracketEntry)
return;
// check queueing conditions // check queueing conditions
if (!joinAsGroup) if (!joinAsGroup)
{ {
@@ -137,7 +142,7 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
// no group found, error // no group found, error
if (!grp) if (!grp)
return; return;
uint32 err = grp->CanJoinBattleGroundQueue(bgTypeId, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0); uint32 err = grp->CanJoinBattleGroundQueue(bg, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0);
isPremade = (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam()); isPremade = (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam());
if (err != BG_JOIN_ERR_OK) if (err != BG_JOIN_ERR_OK)
{ {
@@ -148,11 +153,12 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
// if we're here, then the conditions to join a bg are met. We can proceed in joining. // if we're here, then the conditions to join a bg are met. We can proceed in joining.
// _player->GetGroup() was already checked, grp is already initialized // _player->GetGroup() was already checked, grp is already initialized
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, isPremade, 0); BattleGroundQueue& bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId];
uint32 avgTime = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel(bgTypeId));
if (joinAsGroup /* && _player->GetGroup()*/) if (joinAsGroup /* && _player->GetGroup()*/)
{ {
sLog.outDebug("Battleground: the following players are joining as group:"); sLog.outDebug("Battleground: the following players are joining as group:");
GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, 0, false, isPremade, 0);
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
{ {
Player *member = itr->getSource(); Player *member = itr->getSource();
@@ -166,13 +172,14 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
member->GetSession()->SendPacket(&data); member->GetSession()->SendPacket(&data);
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId); sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId);
member->GetSession()->SendPacket(&data); member->GetSession()->SendPacket(&data);
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(member, ginfo);
sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName()); sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName());
} }
sLog.outDebug("Battleground: group end"); sLog.outDebug("Battleground: group end");
} }
else else
{ {
GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, 0, false, isPremade, 0);
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
// already checked if queueSlot is valid, now just get it // already checked if queueSlot is valid, now just get it
uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId); uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId);
@@ -180,13 +187,9 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
// send status packet (in queue) // send status packet (in queue)
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType); sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType);
SendPacket(&data); SendPacket(&data);
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo);
sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName()); sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
} }
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(bgTypeId)); sBattleGroundMgr.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
if (!ginfo->IsInvitedToBGInstanceGUID)
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AnnounceWorld(ginfo, _player->GetGUID(), true);
} }
void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv_data*/ ) void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv_data*/ )
@@ -303,7 +306,6 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data )
uint8 type; // arenatype if arena uint8 type; // arenatype if arena
uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1 uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1
uint32 instanceId;
uint32 bgTypeId_; // type id from dbc uint32 bgTypeId_; // type id from dbc
uint16 unk; // 0x1F90 constant? uint16 unk; // 0x1F90 constant?
uint8 action; // enter battle 0x1, leave queue 0x0 uint8 action; // enter battle 0x1, leave queue 0x0
@@ -312,186 +314,137 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data )
if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
{ {
sLog.outError("Battleground: invalid bgtype (%u) received.", bgTypeId_); sLog.outError("BattlegroundHandler: invalid bgtype (%u) received.", bgTypeId_);
// update battleground slots for the player to fix his UI and sent data. return;
// this is a HACK, I don't know why the client starts sending invalid packets in the first place. }
// it usually happens with extremely high latency (if debugging / stepping in the code for example) if (!_player->InBattleGroundQueue())
if (_player->InBattleGroundQueue()) {
{ sLog.outError("BattlegroundHandler: Invalid CMSG_BATTLEFIELD_PORT received from player (%u), he is not in bg_queue.", _player->GetGUIDLow());
// update all queues, send invitation info if player is invited, queue info if queued
for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
{
BattleGroundQueueTypeId bgQueueTypeId = _player->GetBattleGroundQueueTypeId(i);
if (!bgQueueTypeId)
continue;
BattleGroundTypeId bgTypeId = BattleGroundMgr::BGTemplateId(bgQueueTypeId);
BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers;
BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = qpMap.find(_player->GetGUID());
// if the player is not in queue, continue or no group information - this should never happen
if (itrPlayerStatus == qpMap.end() || !itrPlayerStatus->second.GroupInfo)
continue;
BattleGround * bg = NULL;
// get possibly needed data from groupinfo
uint8 arenatype = itrPlayerStatus->second.GroupInfo->ArenaType;
uint8 status = 0;
if (!itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID)
{
// not invited to bg, get template
bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
status = STATUS_WAIT_QUEUE;
}
else
{
// get the bg we're invited to
bg = sBattleGroundMgr.GetBattleGround(itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID, bgTypeId);
status = STATUS_WAIT_JOIN;
}
// if bg not found, then continue, don't invite if already in the instance
if (!bg || (_player->InBattleGround() && _player->GetBattleGround() && _player->GetBattleGround()->GetInstanceID() == bg->GetInstanceID()))
continue;
// re - invite player with proper data
WorldPacket data;
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, status, INVITE_ACCEPT_WAIT_TIME, 0, arenatype);
SendPacket(&data);
}
}
return; return;
} }
//get GroupQueueInfo from BattleGroundQueue //get GroupQueueInfo from BattleGroundQueue
BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_); BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_);
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, type); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, type);
BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers; BattleGroundQueue& bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId];
BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = qpMap.find(_player->GetGUID()); //we must use temporary variable, because GroupQueueInfo pointer can be deleted in BattleGroundQueue::RemovePlayer() function
if (itrPlayerStatus == qpMap.end()) GroupQueueInfo ginfo;
if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
{ {
sLog.outError("Battleground: itrplayerstatus not found."); sLog.outError("BattlegroundHandler: itrplayerstatus not found.");
return; return;
} }
instanceId = itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID;
// if action == 1, then instanceId is required // if action == 1, then instanceId is required
if (!instanceId && action == 1) if (!ginfo.IsInvitedToBGInstanceGUID && action == 1)
{ {
sLog.outError("Battleground: instance not found."); sLog.outError("BattlegroundHandler: instance not found.");
return; return;
} }
BattleGround *bg = sBattleGroundMgr.GetBattleGround(instanceId, bgTypeId); BattleGround *bg = sBattleGroundMgr.GetBattleGround(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
// bg template might and must be used in case of leaving queue, when instance is not created yet // bg template might and must be used in case of leaving queue, when instance is not created yet
if (!bg && action == 0) if (!bg && action == 0)
bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId); bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
if (!bg) if (!bg)
{ {
sLog.outError("Battleground: bg_template not found for type id %u.", bgTypeId); sLog.outError("BattlegroundHandler: bg_template not found for type id %u.", bgTypeId);
return; return;
} }
if (_player->InBattleGroundQueue()) // expected bracket entry
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),_player->getLevel());
if (!bracketEntry)
return;
//some checks if player isn't cheating - it is not exactly cheating, but we cannot allow it
if (action == 1 && ginfo.ArenaType == 0)
{ {
//we must use temporary variables, because GroupQueueInfo pointer can be deleted in BattleGroundQueue::RemovePlayer() function! //if player is trying to enter battleground (not arena!) and he has deserter debuff, we must just remove him from queue
uint32 team = itrPlayerStatus->second.GroupInfo->Team; if (!_player->CanJoinToBattleground())
uint32 arenaType = itrPlayerStatus->second.GroupInfo->ArenaType;
uint32 isRated = itrPlayerStatus->second.GroupInfo->IsRated;
uint32 rating = itrPlayerStatus->second.GroupInfo->ArenaTeamRating;
uint32 opponentsRating = itrPlayerStatus->second.GroupInfo->OpponentsTeamRating;
//some checks if player isn't cheating - it is not exactly cheating, but we cannot allow it
if (action == 1 && arenaType == 0)
{ {
//if player is trying to enter battleground (not arena!) and he has deserter debuff, we must just remove him from queue //send bg command result to show nice message
if (!_player->CanJoinToBattleground()) WorldPacket data2(SMSG_GROUP_JOINED_BATTLEGROUND, 4);
{ data2 << uint32(0xFFFFFFFE);
//send bg command result to show nice message _player->GetSession()->SendPacket(&data2);
WorldPacket data2(SMSG_GROUP_JOINED_BATTLEGROUND, 4); action = 0;
data2 << uint32(0xFFFFFFFE); sLog.outDebug("Battleground: player %s (%u) has a deserter debuff, do not port him to battleground!", _player->GetName(), _player->GetGUIDLow());
_player->GetSession()->SendPacket(&data2);
action = 0;
sLog.outDebug("Battleground: player %s (%u) has a deserter debuff, do not port him to battleground!", _player->GetName(), _player->GetGUIDLow());
}
//if player don't match battleground max level, then do not allow him to enter! (this might happen when player leveled up during his waiting in queue
if (_player->getLevel() > bg->GetMaxLevel())
{
sLog.outError("Battleground: Player %s (%u) has level higher than maxlevel of battleground! Do not port him to battleground!", _player->GetName(), _player->GetGUIDLow());
action = 0;
}
} }
uint32 queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId); //if player don't match battleground max level, then do not allow him to enter! (this might happen when player leveled up during his waiting in queue
WorldPacket data; if (_player->getLevel() > bg->GetMaxLevel())
switch( action )
{ {
case 1: // port to battleground sLog.outError("Battleground: Player %s (%u) has level (%u) higher than maxlevel (%u) of battleground (%u)! Do not port him to battleground!",
if (!_player->IsInvitedForBattleGroundQueueType(bgQueueTypeId)) _player->GetName(), _player->GetGUIDLow(), _player->getLevel(), bg->GetMaxLevel(), bg->GetTypeID());
return; // cheating? action = 0;
}
}
uint32 queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId);
WorldPacket data;
switch( action )
{
case 1: // port to battleground
if (!_player->IsInvitedForBattleGroundQueueType(bgQueueTypeId))
return; // cheating?
if (!_player->InBattleGround())
_player->SetBattleGroundEntryPoint(); _player->SetBattleGroundEntryPoint();
// resurrect the player // resurrect the player
if (!_player->isAlive()) if (!_player->isAlive())
{ {
_player->ResurrectPlayer(1.0f); _player->ResurrectPlayer(1.0f);
_player->SpawnCorpseBones(); _player->SpawnCorpseBones();
} }
// stop taxi flight at port // stop taxi flight at port
if (_player->isInFlight()) if (_player->isInFlight())
{ {
_player->GetMotionMaster()->MovementExpired(); _player->GetMotionMaster()->MovementExpired();
_player->CleanupAfterTaxiFlight(); _player->m_taxi.ClearTaxiDestinations();
}
} sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType());
_player->GetSession()->SendPacket(&data);
// remove battleground queue status from BGmgr
bgQueue.RemovePlayer(_player->GetGUID(), false);
// this is still needed here if battleground "jumping" shouldn't add deserter debuff
// also this is required to prevent stuck at old battleground after SetBattleGroundId set to new
if (BattleGround *currentBg = _player->GetBattleGround())
currentBg->RemovePlayerAtLeave(_player->GetGUID(), false, true);
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType()); // set the destination instance id
_player->GetSession()->SendPacket(&data); _player->SetBattleGroundId(bg->GetInstanceID(), bgTypeId);
// remove battleground queue status from BGmgr // set the destination team
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(_player->GetGUID(), false); _player->SetBGTeam(ginfo.Team);
// this is still needed here if battleground "jumping" shouldn't add deserter debuff // bg->HandleBeforeTeleportToBattleGround(_player);
// also this is required to prevent stuck at old battleground after SetBattleGroundId set to new sBattleGroundMgr.SendToBattleGround(_player, ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
if (BattleGround *currentBg = _player->GetBattleGround()) // add only in HandleMoveWorldPortAck()
currentBg->RemovePlayerAtLeave(_player->GetGUID(), false, true); // bg->AddPlayer(_player,team);
sLog.outDebug("Battleground: player %s (%u) joined battle for bg %u, bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetInstanceID(), bg->GetTypeID(), bgQueueTypeId);
// set the destination instance id break;
_player->SetBattleGroundId(bg->GetInstanceID(), bgTypeId); case 0: // leave queue
// set the destination team // if player leaves rated arena match before match start, it is counted as he played but he lost
_player->SetBGTeam(team); if (ginfo.IsRated)
// clear AFK {
if(_player->isAFK()) ArenaTeam * at = objmgr.GetArenaTeamById(ginfo.Team);
_player->ToggleAFK(); if (at)
// bg->HandleBeforeTeleportToBattleGround(_player);
sBattleGroundMgr.SendToBattleGround(_player, instanceId, bgTypeId);
// add only in HandleMoveWorldPortAck()
// bg->AddPlayer(_player,team);
sLog.outDebug("Battleground: player %s (%u) joined battle for bg %u, bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetInstanceID(), bg->GetTypeID(), bgQueueTypeId);
break;
case 0: // leave queue
// if player leaves rated arena match before match start, it is counted as he played but he lost
if (isRated)
{ {
ArenaTeam * at = objmgr.GetArenaTeamById(team); sLog.outDebug("UPDATING memberLost's personal arena rating for %u by opponents rating: %u, because he has left queue!", GUID_LOPART(_player->GetGUID()), ginfo.OpponentsTeamRating);
if (at) at->MemberLost(_player, ginfo.OpponentsTeamRating);
{ at->SaveToDB();
sLog.outDebug("UPDATING memberLost's personal arena rating for %u by opponents rating: %u, because he has left queue!", GUID_LOPART(_player->GetGUID()), opponentsRating);
at->MemberLost(_player, opponentsRating);
at->SaveToDB();
}
} }
_player->RemoveBattleGroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs }
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0); _player->RemoveBattleGroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(_player->GetGUID(), true); sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0);
// player left queue, we should update it - do not update Arena Queue bgQueue.RemovePlayer(_player->GetGUID(), true);
if (!arenaType) // player left queue, we should update it - do not update Arena Queue
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(bgTypeId), arenaType, isRated, rating); if (!ginfo.ArenaType)
SendPacket(&data); sBattleGroundMgr.ScheduleQueueUpdate(ginfo.ArenaTeamRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
sLog.outDebug("Battleground: player %s (%u) left queue for bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetTypeID(), bgQueueTypeId); SendPacket(&data);
break; sLog.outDebug("Battleground: player %s (%u) left queue for bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetTypeID(), bgQueueTypeId);
default: break;
sLog.outError("Battleground port: unknown action %u", action); default:
break; sLog.outError("Battleground port: unknown action %u", action);
} break;
} }
} }
@@ -544,16 +497,16 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ )
} }
//we are sending update to player about queue - he can be invited there! //we are sending update to player about queue - he can be invited there!
//get GroupQueueInfo for queue status //get GroupQueueInfo for queue status
BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers; BattleGroundQueue& bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId];
BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = qpMap.find(_player->GetGUID()); GroupQueueInfo ginfo;
if (itrPlayerStatus == qpMap.end()) if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
continue; continue;
if (itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID) if (ginfo.IsInvitedToBGInstanceGUID)
{ {
bg = sBattleGroundMgr.GetBattleGround(itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID, bgTypeId); bg = sBattleGroundMgr.GetBattleGround(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
if (!bg) if (!bg)
continue; continue;
uint32 remainingTime = getMSTimeDiff(getMSTime(), itrPlayerStatus->second.GroupInfo->RemoveInviteTime); uint32 remainingTime = getMSTimeDiff(getMSTime(), ginfo.RemoveInviteTime);
// send status invited to BattleGround // send status invited to BattleGround
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_JOIN, remainingTime, 0, arenaType); sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_JOIN, remainingTime, 0, arenaType);
SendPacket(&data); SendPacket(&data);
@@ -563,9 +516,15 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ )
bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId); bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
if (!bg) if (!bg)
continue; continue;
uint32 avgTime = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].GetAverageQueueWaitTime(itrPlayerStatus->second.GroupInfo, _player->GetBattleGroundQueueIdFromLevel(bgTypeId));
// expected bracket entry
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),_player->getLevel());
if (!bracketEntry)
continue;
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(&ginfo, bracketEntry->GetBracketId());
// send status in BattleGround Queue // send status in BattleGround Queue
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_QUEUE, avgTime, getMSTimeDiff(itrPlayerStatus->second.GroupInfo->JoinTime, getMSTime()), arenaType); sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_QUEUE, avgTime, getMSTimeDiff(ginfo.JoinTime, getMSTime()), arenaType);
SendPacket(&data); SendPacket(&data);
} }
} }
@@ -657,8 +616,8 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
} }
//check existance //check existance
BattleGround* bg = NULL; BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(BATTLEGROUND_AA);
if (!(bg = sBattleGroundMgr.GetBattleGroundTemplate(BATTLEGROUND_AA))) if (!bg)
{ {
sLog.outError("Battleground: template bg (all arenas) not found"); sLog.outError("Battleground: template bg (all arenas) not found");
return; return;
@@ -666,6 +625,9 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
BattleGroundTypeId bgTypeId = bg->GetTypeID(); BattleGroundTypeId bgTypeId = bg->GetTypeID();
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype);
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),_player->getLevel());
if (!bracketEntry)
return;
// check queueing conditions // check queueing conditions
if (!asGroup) if (!asGroup)
@@ -684,7 +646,7 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
// no group found, error // no group found, error
if (!grp) if (!grp)
return; return;
uint32 err = grp->CanJoinBattleGroundQueue(bgTypeId, bgQueueTypeId, arenatype, arenatype, (bool)isRated, arenaslot); uint32 err = grp->CanJoinBattleGroundQueue(bg, bgQueueTypeId, arenatype, arenatype, (bool)isRated, arenaslot);
if (err != BG_JOIN_ERR_OK) if (err != BG_JOIN_ERR_OK)
{ {
SendBattleGroundOrArenaJoinError(err); SendBattleGroundOrArenaJoinError(err);
@@ -725,8 +687,7 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
arenaRating = avg_pers_rating; arenaRating = avg_pers_rating;
} }
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, arenatype, isRated, false, arenaRating, ateamId); BattleGroundQueue &bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId];
uint32 avgTime = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel(bgTypeId));
if (asGroup) if (asGroup)
{ {
sLog.outDebug("Battleground: arena join as group start"); sLog.outDebug("Battleground: arena join as group start");
@@ -738,6 +699,8 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
else else
bg->SetRated(false); bg->SetRated(false);
GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, isRated, false, arenaRating, ateamId);
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
{ {
Player *member = itr->getSource(); Player *member = itr->getSource();
@@ -751,25 +714,24 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
member->GetSession()->SendPacket(&data); member->GetSession()->SendPacket(&data);
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId); sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId);
member->GetSession()->SendPacket(&data); member->GetSession()->SendPacket(&data);
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(member, ginfo);
sLog.outDebug("Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName()); sLog.outDebug("Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName());
} }
sLog.outDebug("Battleground: arena join as group end"); sLog.outDebug("Battleground: arena join as group end");
if (isRated) //announce to world ... removed
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AnnounceWorld(ginfo, _player->GetGUID(), true);
} }
else else
{ {
GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, arenatype, isRated, false, arenaRating, ateamId);
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId); uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId);
WorldPacket data; WorldPacket data;
// send status packet (in queue) // send status packet (in queue)
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype); sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype);
SendPacket(&data); SendPacket(&data);
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo);
sLog.outDebug("Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName()); sLog.outDebug("Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
} }
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(bgTypeId), arenatype, isRated, arenaRating); sBattleGroundMgr.ScheduleQueueUpdate(arenaRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
} }
void WorldSession::HandleReportPvPAFK( WorldPacket & recv_data ) void WorldSession::HandleReportPvPAFK( WorldPacket & recv_data )
+236 -226
View File
@@ -56,13 +56,13 @@ INSTANTIATE_SINGLETON_1( BattleGroundMgr );
BattleGroundQueue::BattleGroundQueue() BattleGroundQueue::BattleGroundQueue()
{ {
for (uint32 i = 0; i < BG_TEAMS_COUNT; i++) for (uint32 i = 0; i < BG_TEAMS_COUNT; ++i)
{ {
for (uint32 j = 0; j < MAX_BATTLEGROUND_QUEUES; j++) for (uint32 j = 0; j < MAX_BATTLEGROUND_BRACKETS; ++j)
{ {
m_SumOfWaitTimes[i][j] = 0; m_SumOfWaitTimes[i][j] = 0;
m_WaitTimeLastPlayer[i][j] = 0; m_WaitTimeLastPlayer[i][j] = 0;
for (uint32 k = 0; k < COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME; k++) for (uint32 k = 0; k < COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME; ++k)
m_WaitTimes[i][j][k] = 0; m_WaitTimes[i][j][k] = 0;
} }
} }
@@ -71,9 +71,9 @@ BattleGroundQueue::BattleGroundQueue()
BattleGroundQueue::~BattleGroundQueue() BattleGroundQueue::~BattleGroundQueue()
{ {
m_QueuedPlayers.clear(); m_QueuedPlayers.clear();
for (int i = 0; i < MAX_BATTLEGROUND_QUEUES; i++) for (int i = 0; i < MAX_BATTLEGROUND_BRACKETS; ++i)
{ {
for (uint32 j = 0; j < BG_QUEUE_GROUP_TYPES_COUNT; j++) for (uint32 j = 0; j < BG_QUEUE_GROUP_TYPES_COUNT; ++j)
{ {
for (GroupsQueueType::iterator itr = m_QueuedGroups[i][j].begin(); itr!= m_QueuedGroups[i][j].end(); ++itr) for (GroupsQueueType::iterator itr = m_QueuedGroups[i][j].begin(); itr!= m_QueuedGroups[i][j].end(); ++itr)
delete (*itr); delete (*itr);
@@ -149,14 +149,12 @@ bool BattleGroundQueue::SelectionPool::AddGroup(GroupQueueInfo *ginfo, uint32 de
/*** BATTLEGROUND QUEUES ***/ /*** BATTLEGROUND QUEUES ***/
/*********************************************************/ /*********************************************************/
// add group to bg queue with the given leader and bg specifications // add group or player (grp == NULL) to bg queue with the given leader and bg specifications
GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, BattleGroundTypeId BgTypeId, uint8 ArenaType, bool isRated, bool isPremade, uint32 arenaRating, uint32 arenateamid) GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, Group* grp, BattleGroundTypeId BgTypeId, PvPDifficultyEntry const* backetEntry, uint8 ArenaType, bool isRated, bool isPremade, uint32 arenaRating, uint32 arenateamid)
{ {
BGQueueIdBasedOnLevel queue_id = leader->GetBattleGroundQueueIdFromLevel(BgTypeId); BattleGroundBracketId bracketId = backetEntry->GetBracketId();
// create new ginfo // create new ginfo
// cannot use the method like in addplayer, because that could modify an in-queue group's stats
// (e.g. leader leaving queue then joining as individual again)
GroupQueueInfo* ginfo = new GroupQueueInfo; GroupQueueInfo* ginfo = new GroupQueueInfo;
ginfo->BgTypeId = BgTypeId; ginfo->BgTypeId = BgTypeId;
ginfo->ArenaType = ArenaType; ginfo->ArenaType = ArenaType;
@@ -177,27 +175,84 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, BattleGroundTypeId
index += BG_TEAMS_COUNT; index += BG_TEAMS_COUNT;
if (ginfo->Team == HORDE) if (ginfo->Team == HORDE)
index++; index++;
sLog.outDebug("Adding Group to BattleGroundQueue bgTypeId : %u, queue_id : %u, index : %u", BgTypeId, queue_id, index); sLog.outDebug("Adding Group to BattleGroundQueue bgTypeId : %u, bracket_id : %u, index : %u", BgTypeId, bracketId, index);
m_QueuedGroups[queue_id][index].push_back(ginfo); uint32 lastOnlineTime = getMSTime();
//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);
}
//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);
//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, because it is needed to add players to this group info
return ginfo; return ginfo;
} }
//add player to playermap void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BattleGroundBracketId bracket_id)
void BattleGroundQueue::AddPlayer(Player *plr, GroupQueueInfo *ginfo)
{
//if player isn't in queue, he is added, if already is, then values are overwritten, no memory leak
PlayerQueueInfo& info = m_QueuedPlayers[plr->GetGUID()];
info.LastOnlineTime = getMSTime();
info.GroupInfo = ginfo;
// add the pinfo to ginfo's list
ginfo->Players[plr->GetGUID()] = &info;
}
void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id)
{ {
uint32 timeInQueue = getMSTimeDiff(ginfo->JoinTime, getMSTime()); uint32 timeInQueue = getMSTimeDiff(ginfo->JoinTime, getMSTime());
uint8 team_index = BG_TEAM_ALLIANCE; //default set to BG_TEAM_ALLIANCE - or non rated arenas! uint8 team_index = BG_TEAM_ALLIANCE; //default set to BG_TEAM_ALLIANCE - or non rated arenas!
@@ -213,19 +268,19 @@ void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* g
} }
//store pointer to arrayindex of player that was added first //store pointer to arrayindex of player that was added first
uint32* lastPlayerAddedPointer = &(m_WaitTimeLastPlayer[team_index][queue_id]); uint32* lastPlayerAddedPointer = &(m_WaitTimeLastPlayer[team_index][bracket_id]);
//remove his time from sum //remove his time from sum
m_SumOfWaitTimes[team_index][queue_id] -= m_WaitTimes[team_index][queue_id][(*lastPlayerAddedPointer)]; m_SumOfWaitTimes[team_index][bracket_id] -= m_WaitTimes[team_index][bracket_id][(*lastPlayerAddedPointer)];
//set average time to new //set average time to new
m_WaitTimes[team_index][queue_id][(*lastPlayerAddedPointer)] = timeInQueue; m_WaitTimes[team_index][bracket_id][(*lastPlayerAddedPointer)] = timeInQueue;
//add new time to sum //add new time to sum
m_SumOfWaitTimes[team_index][queue_id] += timeInQueue; m_SumOfWaitTimes[team_index][bracket_id] += timeInQueue;
//set index of last player added to next one //set index of last player added to next one
(*lastPlayerAddedPointer)++; (*lastPlayerAddedPointer)++;
(*lastPlayerAddedPointer) %= COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME; (*lastPlayerAddedPointer) %= COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME;
} }
uint32 BattleGroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id) uint32 BattleGroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BattleGroundBracketId bracket_id)
{ {
uint8 team_index = BG_TEAM_ALLIANCE; //default set to BG_TEAM_ALLIANCE - or non rated arenas! uint8 team_index = BG_TEAM_ALLIANCE; //default set to BG_TEAM_ALLIANCE - or non rated arenas!
if (!ginfo->ArenaType) if (!ginfo->ArenaType)
@@ -239,8 +294,8 @@ uint32 BattleGroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueue
team_index = BG_TEAM_HORDE; //for rated arenas use BG_TEAM_HORDE team_index = BG_TEAM_HORDE; //for rated arenas use BG_TEAM_HORDE
} }
//check if there is enought values(we always add values > 0) //check if there is enought values(we always add values > 0)
if (m_WaitTimes[team_index][queue_id][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME - 1] ) if (m_WaitTimes[team_index][bracket_id][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME - 1] )
return (m_SumOfWaitTimes[team_index][queue_id] / COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME); return (m_SumOfWaitTimes[team_index][bracket_id] / COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME);
else else
//if there aren't enough values return 0 - not available //if there aren't enough values return 0 - not available
return 0; return 0;
@@ -251,7 +306,7 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
{ {
//Player *plr = objmgr.GetPlayer(guid); //Player *plr = objmgr.GetPlayer(guid);
int32 queue_id = -1; // signed for proper for-loop finish int32 bracket_id = -1; // signed for proper for-loop finish
QueuedPlayersMap::iterator itr; QueuedPlayersMap::iterator itr;
//remove player from map, if he's there //remove player from map, if he's there
@@ -269,17 +324,17 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
// variable index removes useless searching in other team's queue // variable index removes useless searching in other team's queue
uint32 index = (group->Team == HORDE) ? BG_TEAM_HORDE : BG_TEAM_ALLIANCE; uint32 index = (group->Team == HORDE) ? BG_TEAM_HORDE : BG_TEAM_ALLIANCE;
for (int32 queue_id_tmp = MAX_BATTLEGROUND_QUEUES - 1; queue_id_tmp >= 0 && queue_id == -1; --queue_id_tmp) for (int32 bracket_id_tmp = MAX_BATTLEGROUND_BRACKETS - 1; bracket_id_tmp >= 0 && bracket_id == -1; --bracket_id_tmp)
{ {
//we must check premade and normal team's queue - because when players from premade are joining bg, //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 //they leave groupinfo so we can't use its players size to find out index
for (uint32 j = index; j < BG_QUEUE_GROUP_TYPES_COUNT; j += BG_QUEUE_NORMAL_ALLIANCE) for (uint32 j = index; j < BG_QUEUE_GROUP_TYPES_COUNT; j += BG_QUEUE_NORMAL_ALLIANCE)
{ {
for (group_itr_tmp = m_QueuedGroups[queue_id_tmp][j].begin(); group_itr_tmp != m_QueuedGroups[queue_id_tmp][j].end(); ++group_itr_tmp) for(group_itr_tmp = m_QueuedGroups[bracket_id_tmp][j].begin(); group_itr_tmp != m_QueuedGroups[bracket_id_tmp][j].end(); ++group_itr_tmp)
{ {
if ((*group_itr_tmp) == group) if ((*group_itr_tmp) == group)
{ {
queue_id = queue_id_tmp; bracket_id = bracket_id_tmp;
group_itr = group_itr_tmp; group_itr = group_itr_tmp;
//we must store index to be able to erase iterator //we must store index to be able to erase iterator
index = j; index = j;
@@ -289,12 +344,12 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
} }
} }
//player can't be in queue without group, but just in case //player can't be in queue without group, but just in case
if (queue_id == -1) if (bracket_id == -1)
{ {
sLog.outError("BattleGroundQueue: ERROR Cannot find groupinfo for player GUID: %u", GUID_LOPART(guid)); sLog.outError("BattleGroundQueue: ERROR Cannot find groupinfo for player GUID: %u", GUID_LOPART(guid));
return; return;
} }
sLog.outDebug("BattleGroundQueue: Removing player GUID %u, from queue_id %u", GUID_LOPART(guid), (uint32)queue_id); sLog.outDebug("BattleGroundQueue: Removing player GUID %u, from bracket_id %u", GUID_LOPART(guid), (uint32)bracket_id);
// ALL variables are correctly set // ALL variables are correctly set
// We can ignore leveling up in queue - it should not cause crash // We can ignore leveling up in queue - it should not cause crash
@@ -317,9 +372,9 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
// remove player queue info // remove player queue info
m_QueuedPlayers.erase(itr); m_QueuedPlayers.erase(itr);
//if we left BG queue(not porting) OR if arena team left queue for rated match // announce to world if arena team left queue for rated match, show only once
if ((decreaseInvitedCount && !group->ArenaType) || (group->ArenaType && group->IsRated && group->Players.empty())) if (group->ArenaType && group->IsRated && group->Players.empty() && sWorld.getConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE))
AnnounceWorld(group, guid, false); sWorld.SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT, group->ArenaType, group->ArenaType, group->ArenaTeamRating);
//if player leaves queue and he is invited to rated arena match, then he have to loose //if player leaves queue and he is invited to rated arena match, then he have to loose
if (group->IsInvitedToBGInstanceGUID && group->IsRated && decreaseInvitedCount) if (group->IsInvitedToBGInstanceGUID && group->IsRated && decreaseInvitedCount)
@@ -340,7 +395,7 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
// remove group queue info if needed // remove group queue info if needed
if (group->Players.empty()) if (group->Players.empty())
{ {
m_QueuedGroups[queue_id][index].erase(group_itr); m_QueuedGroups[bracket_id][index].erase(group_itr);
delete group; delete group;
} }
// if group wasn't empty, so it wasn't deleted, and player have left a rated // if group wasn't empty, so it wasn't deleted, and player have left a rated
@@ -366,78 +421,22 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
} }
} }
//Announce world message //returns true when player pl_guid is in queue and is invited to bgInstanceGuid
void BattleGroundQueue::AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue) bool BattleGroundQueue::IsPlayerInvited(const uint64& pl_guid, const uint32 bgInstanceGuid, const uint32 removeTime)
{ {
if(ginfo->ArenaType) //if Arena QueuedPlayersMap::const_iterator qItr = m_QueuedPlayers.find(pl_guid);
{ return ( qItr != m_QueuedPlayers.end()
if (sWorld.getConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE) && ginfo->IsRated) && qItr->second.GroupInfo->IsInvitedToBGInstanceGUID == bgInstanceGuid
{ && qItr->second.GroupInfo->RemoveInviteTime == removeTime );
BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(ginfo->BgTypeId); }
if (!bg)
return;
char const* bgName = bg->GetName(); bool BattleGroundQueue::GetPlayerGroupInfoData(const uint64& guid, GroupQueueInfo* ginfo)
if (isAddedToQueue) {
{ QueuedPlayersMap::const_iterator qItr = m_QueuedPlayers.find(guid);
if (sWorld.getConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_PLAYERONLY)) if (qItr == m_QueuedPlayers.end())
{ return false;
if(Player *plr = objmgr.GetPlayer(playerGUID)) *ginfo = *(qItr->second.GroupInfo);
ChatHandler(plr).PSendSysMessage(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN, bgName, ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating); return true;
}
else
sWorld.SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN, bgName, ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating);
}
else
{
if (sWorld.getConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_PLAYERONLY))
{
if(Player *plr = objmgr.GetPlayer(playerGUID))
ChatHandler(plr).PSendSysMessage(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT, bgName, ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating);
}
else
sWorld.SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT, bgName, ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating);
}
}
}
else //if BG
{
if (sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE))
{
Player *plr = objmgr.GetPlayer(playerGUID);
BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(ginfo->BgTypeId);
if (!bg || !plr)
return;
BGQueueIdBasedOnLevel queue_id = plr->GetBattleGroundQueueIdFromLevel(bg->GetTypeID());
char const* bgName = bg->GetName();
uint32 MinPlayers = bg->GetMinPlayersPerTeam();
uint32 qHorde = 0;
uint32 qAlliance = 0;
uint32 q_min_level = (queue_id + 1) * 10;
uint32 q_max_level = std::min(q_min_level + 9, sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
GroupsQueueType::const_iterator itr;
for (itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr)
if (!(*itr)->IsInvitedToBGInstanceGUID)
qAlliance += (*itr)->Players.size();
for (itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].end(); ++itr)
if (!(*itr)->IsInvitedToBGInstanceGUID)
qHorde += (*itr)->Players.size();
// Show queue status to player only (when joining queue)
if (sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
{
ChatHandler(plr).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF,
bgName, q_min_level, q_max_level, qAlliance, MinPlayers, qHorde, MinPlayers);
}
// System message
else
{
sWorld.SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD,
bgName, q_min_level, q_max_level, qAlliance, MinPlayers, qHorde, MinPlayers);
}
}
}
} }
bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side) bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side)
@@ -453,7 +452,7 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b
ginfo->IsInvitedToBGInstanceGUID = bg->GetInstanceID(); ginfo->IsInvitedToBGInstanceGUID = bg->GetInstanceID();
BattleGroundTypeId bgTypeId = bg->GetTypeID(); BattleGroundTypeId bgTypeId = bg->GetTypeID();
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, bg->GetArenaType()); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, bg->GetArenaType());
BGQueueIdBasedOnLevel queue_id = bg->GetQueueId(); BattleGroundBracketId bracket_id = bg->GetBracketId();
// set ArenaTeamId for rated matches // set ArenaTeamId for rated matches
if (bg->isArena() && bg->isRated()) if (bg->isArena() && bg->isRated())
@@ -471,7 +470,7 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b
continue; continue;
// invite the player // invite the player
PlayerInvitedToBGUpdateAverageWaitTime(ginfo, queue_id); PlayerInvitedToBGUpdateAverageWaitTime(ginfo, bracket_id);
//sBattleGroundMgr.InvitePlayer(plr, bg, ginfo->Team); //sBattleGroundMgr.InvitePlayer(plr, bg, ginfo->Team);
// set invited player counters // set invited player counters
@@ -480,7 +479,7 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b
plr->SetInviteForBattleGroundQueueType(bgQueueTypeId, ginfo->IsInvitedToBGInstanceGUID); plr->SetInviteForBattleGroundQueueType(bgQueueTypeId, ginfo->IsInvitedToBGInstanceGUID);
// create remind invite events // create remind invite events
BGQueueInviteEvent* inviteEvent = new BGQueueInviteEvent(plr->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, ginfo->RemoveInviteTime); BGQueueInviteEvent* inviteEvent = new BGQueueInviteEvent(plr->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, ginfo->ArenaType, ginfo->RemoveInviteTime);
plr->m_Events.AddEvent(inviteEvent, plr->m_Events.CalculateTime(INVITATION_REMIND_TIME)); plr->m_Events.AddEvent(inviteEvent, plr->m_Events.CalculateTime(INVITATION_REMIND_TIME));
// create automatic remove events // create automatic remove events
BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(plr->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, bgQueueTypeId, ginfo->RemoveInviteTime); BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(plr->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, bgQueueTypeId, ginfo->RemoveInviteTime);
@@ -507,22 +506,22 @@ This function is inviting players to already running battlegrounds
Invitation type is based on config file Invitation type is based on config file
large groups are disadvantageous, because they will be kicked first if invitation type = 1 large groups are disadvantageous, because they will be kicked first if invitation type = 1
*/ */
void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel queue_id) void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BattleGroundBracketId bracket_id)
{ {
int32 hordeFree = bg->GetFreeSlotsForTeam(HORDE); int32 hordeFree = bg->GetFreeSlotsForTeam(HORDE);
int32 aliFree = bg->GetFreeSlotsForTeam(ALLIANCE); int32 aliFree = bg->GetFreeSlotsForTeam(ALLIANCE);
//iterator for iterating through bg queue //iterator for iterating through bg queue
GroupsQueueType::const_iterator Ali_itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].begin(); GroupsQueueType::const_iterator Ali_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].begin();
//count of groups in queue - used to stop cycles //count of groups in queue - used to stop cycles
uint32 aliCount = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].size(); uint32 aliCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].size();
//index to queue which group is current //index to queue which group is current
uint32 aliIndex = 0; uint32 aliIndex = 0;
for (; aliIndex < aliCount && m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*Ali_itr), aliFree); aliIndex++) for (; aliIndex < aliCount && m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*Ali_itr), aliFree); aliIndex++)
++Ali_itr; ++Ali_itr;
//the same thing for horde //the same thing for horde
GroupsQueueType::const_iterator Horde_itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].begin(); GroupsQueueType::const_iterator Horde_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].begin();
uint32 hordeCount = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].size(); uint32 hordeCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].size();
uint32 hordeIndex = 0; uint32 hordeIndex = 0;
for (; hordeIndex < hordeCount && m_SelectionPools[BG_TEAM_HORDE].AddGroup((*Horde_itr), hordeFree); hordeIndex++) for (; hordeIndex < hordeCount && m_SelectionPools[BG_TEAM_HORDE].AddGroup((*Horde_itr), hordeFree); hordeIndex++)
++Horde_itr; ++Horde_itr;
@@ -585,22 +584,22 @@ void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel
// this method checks if premade versus premade battleground is possible // this method checks if premade versus premade battleground is possible
// then after 30 mins (default) in queue it moves premade group to normal queue // 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 // it tries to invite as much players as it can - to MaxPlayersPerTeam, because premade groups have more than MinPlayersPerTeam players
bool BattleGroundQueue::CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam) bool BattleGroundQueue::CheckPremadeMatch(BattleGroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam)
{ {
//check match //check match
if (!m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].empty() && !m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].empty()) if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty() && !m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty())
{ {
//start premade match //start premade match
//if groups aren't invited //if groups aren't invited
GroupsQueueType::const_iterator ali_group, horde_group; GroupsQueueType::const_iterator ali_group, horde_group;
for (ali_group = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].begin(); ali_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].end(); ++ali_group) 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)
if (!(*ali_group)->IsInvitedToBGInstanceGUID) if (!(*ali_group)->IsInvitedToBGInstanceGUID)
break; break;
for (horde_group = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].begin(); horde_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].end(); ++horde_group) 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)
if (!(*horde_group)->IsInvitedToBGInstanceGUID) if (!(*horde_group)->IsInvitedToBGInstanceGUID)
break; break;
if (ali_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].end() && horde_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].end()) if (ali_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].end() && horde_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].end())
{ {
m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*ali_group), MaxPlayersPerTeam); m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*ali_group), MaxPlayersPerTeam);
m_SelectionPools[BG_TEAM_HORDE].AddGroup((*horde_group), MaxPlayersPerTeam); m_SelectionPools[BG_TEAM_HORDE].AddGroup((*horde_group), MaxPlayersPerTeam);
@@ -609,7 +608,7 @@ bool BattleGroundQueue::CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32
GroupsQueueType::const_iterator itr; GroupsQueueType::const_iterator itr;
for (uint32 i = 0; i < BG_TEAMS_COUNT; i++) for (uint32 i = 0; i < BG_TEAMS_COUNT; i++)
{ {
for (itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin(); itr != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++itr) for(itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++itr)
{ {
//if itr can join BG and player count is less that maxPlayers, then add group to selectionpool //if itr can join BG and player count is less that maxPlayers, then add group to selectionpool
if (!(*itr)->IsInvitedToBGInstanceGUID && !m_SelectionPools[i].AddGroup((*itr), maxPlayers)) if (!(*itr)->IsInvitedToBGInstanceGUID && !m_SelectionPools[i].AddGroup((*itr), maxPlayers))
@@ -627,14 +626,14 @@ bool BattleGroundQueue::CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32
uint32 time_before = getMSTime() - sWorld.getConfig(CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH); uint32 time_before = getMSTime() - sWorld.getConfig(CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH);
for (uint32 i = 0; i < BG_TEAMS_COUNT; i++) for (uint32 i = 0; i < BG_TEAMS_COUNT; i++)
{ {
if (!m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE + i].empty()) if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE + i].empty())
{ {
GroupsQueueType::iterator itr = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE + i].begin(); GroupsQueueType::iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE + i].begin();
if (!(*itr)->IsInvitedToBGInstanceGUID && ((*itr)->JoinTime < time_before || (*itr)->Players.size() < MinPlayersPerTeam)) if (!(*itr)->IsInvitedToBGInstanceGUID && ((*itr)->JoinTime < time_before || (*itr)->Players.size() < MinPlayersPerTeam))
{ {
//we must insert group to normal queue and erase pointer from premade queue //we must insert group to normal queue and erase pointer from premade queue
m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + i].push_front((*itr)); m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].push_front((*itr));
m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE + i].erase(itr); m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE + i].erase(itr);
} }
} }
} }
@@ -643,13 +642,13 @@ bool BattleGroundQueue::CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32
} }
// this method tries to create battleground or arena with MinPlayersPerTeam against MinPlayersPerTeam // this method tries to create battleground or arena with MinPlayersPerTeam against MinPlayersPerTeam
bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BGQueueIdBasedOnLevel queue_id, uint32 minPlayers, uint32 maxPlayers) bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BattleGroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers)
{ {
GroupsQueueType::const_iterator itr_team[BG_TEAMS_COUNT]; GroupsQueueType::const_iterator itr_team[BG_TEAMS_COUNT];
for (uint32 i = 0; i < BG_TEAMS_COUNT; i++) for (uint32 i = 0; i < BG_TEAMS_COUNT; i++)
{ {
itr_team[i] = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin(); itr_team[i] = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin();
for (; itr_team[i] != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++(itr_team[i])) for(; itr_team[i] != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++(itr_team[i]))
{ {
if (!(*(itr_team[i]))->IsInvitedToBGInstanceGUID) if (!(*(itr_team[i]))->IsInvitedToBGInstanceGUID)
{ {
@@ -668,7 +667,7 @@ bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BGQueueIdBas
{ {
//we will try to invite more groups to team with less players indexed by j //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; ++(itr_team[j]); //this will not cause a crash, because for cycle above reached break;
for (; itr_team[j] != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + j].end(); ++(itr_team[j])) for(; itr_team[j] != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + j].end(); ++(itr_team[j]))
{ {
if (!(*(itr_team[j]))->IsInvitedToBGInstanceGUID) if (!(*(itr_team[j]))->IsInvitedToBGInstanceGUID)
if (!m_SelectionPools[j].AddGroup(*(itr_team[j]), m_SelectionPools[(j + 1) % BG_TEAMS_COUNT].GetPlayerCount())) if (!m_SelectionPools[j].AddGroup(*(itr_team[j]), m_SelectionPools[(j + 1) % BG_TEAMS_COUNT].GetPlayerCount()))
@@ -686,7 +685,7 @@ bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BGQueueIdBas
} }
// this method will check if we can invite players to same faction skirmish match // this method will check if we can invite players to same faction skirmish match
bool BattleGroundQueue::CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_id, uint32 minPlayersPerTeam) bool BattleGroundQueue::CheckSkirmishForSameFaction(BattleGroundBracketId bracket_id, uint32 minPlayersPerTeam)
{ {
if (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() < minPlayersPerTeam && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() < minPlayersPerTeam) if (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() < minPlayersPerTeam && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() < minPlayersPerTeam)
return false; return false;
@@ -704,16 +703,16 @@ bool BattleGroundQueue::CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_
//store last ginfo pointer //store last ginfo pointer
GroupQueueInfo* ginfo = m_SelectionPools[teamIndex].SelectedGroups.back(); GroupQueueInfo* ginfo = m_SelectionPools[teamIndex].SelectedGroups.back();
//set itr_team to group that was added to selection pool latest //set itr_team to group that was added to selection pool latest
GroupsQueueType::iterator itr_team = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].begin(); GroupsQueueType::iterator itr_team = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].begin();
for (; itr_team != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr_team) for(; itr_team != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr_team)
if (ginfo == *itr_team) if (ginfo == *itr_team)
break; break;
if (itr_team == m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end()) if (itr_team == m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end())
return false; return false;
GroupsQueueType::iterator itr_team2 = itr_team; GroupsQueueType::iterator itr_team2 = itr_team;
++itr_team2; ++itr_team2;
//invite players to other selection pool //invite players to other selection pool
for (; itr_team2 != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr_team2) for(; itr_team2 != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr_team2)
{ {
//if selection pool is full then break; //if selection pool is full then break;
if (!(*itr_team2)->IsInvitedToBGInstanceGUID && !m_SelectionPools[otherTeam].AddGroup(*itr_team2, minPlayersPerTeam)) if (!(*itr_team2)->IsInvitedToBGInstanceGUID && !m_SelectionPools[otherTeam].AddGroup(*itr_team2, minPlayersPerTeam))
@@ -728,15 +727,15 @@ bool BattleGroundQueue::CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_
//set correct team //set correct team
(*itr)->Team = otherTeamId; (*itr)->Team = otherTeamId;
//add team to other queue //add team to other queue
m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + otherTeam].push_front(*itr); m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + otherTeam].push_front(*itr);
//remove team from old queue //remove team from old queue
GroupsQueueType::iterator itr2 = itr_team; GroupsQueueType::iterator itr2 = itr_team;
++itr2; ++itr2;
for (; itr2 != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr2) for(; itr2 != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr2)
{ {
if (*itr2 == *itr) if (*itr2 == *itr)
{ {
m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].erase(itr2); m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].erase(itr2);
break; break;
} }
} }
@@ -749,24 +748,24 @@ this method is called when group is inserted, or player / group is removed from
it must be called after fully adding the members of a group to ensure group joining it must be called after fully adding the members of a group to ensure group joining
should be called from BattleGround::RemovePlayer function in some cases should be called from BattleGround::RemovePlayer function in some cases
*/ */
void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated, uint32 arenaRating) void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id, uint8 arenaType, bool isRated, uint32 arenaRating)
{ {
//if no players in queue - do nothing //if no players in queue - do nothing
if( m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].empty() && if( m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty() &&
m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].empty() && m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty() &&
m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].empty() && m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].empty() &&
m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].empty() ) m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].empty() )
return; return;
//battleground with free slot for player should be always in the beggining of the queue //battleground with free slot for player should be always in the beggining of the queue
// maybe it would be better to create bgfreeslotqueue for each queue_id_based_on_level // maybe it would be better to create bgfreeslotqueue for each bracket_id
BGFreeSlotQueueType::iterator itr, next; BGFreeSlotQueueType::iterator itr, next;
for (itr = sBattleGroundMgr.BGFreeSlotQueue[bgTypeId].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[bgTypeId].end(); itr = next) for (itr = sBattleGroundMgr.BGFreeSlotQueue[bgTypeId].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[bgTypeId].end(); itr = next)
{ {
next = itr; next = itr;
++next; ++next;
// DO NOT allow queue manager to invite new player to arena // DO NOT allow queue manager to invite new player to arena
if( (*itr)->isBattleGround() && (*itr)->GetTypeID() == bgTypeId && (*itr)->GetQueueId() == queue_id && if( (*itr)->isBattleGround() && (*itr)->GetTypeID() == bgTypeId && (*itr)->GetBracketId() == bracket_id &&
(*itr)->GetStatus() > STATUS_WAIT_QUEUE && (*itr)->GetStatus() < STATUS_WAIT_LEAVE ) (*itr)->GetStatus() > STATUS_WAIT_QUEUE && (*itr)->GetStatus() < STATUS_WAIT_LEAVE )
{ {
BattleGround* bg = *itr; //we have to store battleground pointer here, because when battleground is full, it is removed from free queue (not yet implemented!!) BattleGround* bg = *itr; //we have to store battleground pointer here, because when battleground is full, it is removed from free queue (not yet implemented!!)
@@ -777,7 +776,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
m_SelectionPools[BG_TEAM_HORDE].Init(); m_SelectionPools[BG_TEAM_HORDE].Init();
// call a function that does the job for us // call a function that does the job for us
FillPlayersToBG(bg, queue_id); FillPlayersToBG(bg, bracket_id);
// now everything is set, invite players // now everything is set, invite players
for (GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.end(); ++citr) for (GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.end(); ++citr)
@@ -801,6 +800,14 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
sLog.outError("Battleground: Update: bg template not found for %u", bgTypeId); sLog.outError("Battleground: Update: bg template not found for %u", bgTypeId);
return; return;
} }
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;
}
// get the min. players per team, properly for larger arenas as well. (must have full teams for arena matches!) // 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 MinPlayersPerTeam = bg_template->GetMinPlayersPerTeam();
uint32 MaxPlayersPerTeam = bg_template->GetMaxPlayersPerTeam(); uint32 MaxPlayersPerTeam = bg_template->GetMaxPlayersPerTeam();
@@ -842,11 +849,11 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
if (bg_template->isBattleGround()) if (bg_template->isBattleGround())
{ {
//check if there is premade against premade match //check if there is premade against premade match
if (CheckPremadeMatch(queue_id, MinPlayersPerTeam, MaxPlayersPerTeam)) if (CheckPremadeMatch(bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam))
{ {
//create new battleground //create new battleground
BattleGround * bg2 = NULL; BattleGround * bg2 = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, bracketEntry, 0, false);
if (!(bg2 = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, queue_id, 0, false))) if (!bg2)
{ {
sLog.outError("BattleGroundQueue::Update - Cannot create battleground: %u", bgTypeId); sLog.outError("BattleGroundQueue::Update - Cannot create battleground: %u", bgTypeId);
return; return;
@@ -867,12 +874,12 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
if (!isRated) if (!isRated)
{ {
// if there are enough players in pools, start new battleground or non rated arena // if there are enough players in pools, start new battleground or non rated arena
if (CheckNormalMatch(bg_template, queue_id, MinPlayersPerTeam, MaxPlayersPerTeam) if (CheckNormalMatch(bg_template, bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam)
|| (bg_template->isArena() && CheckSkirmishForSameFaction(queue_id, MinPlayersPerTeam)) ) || (bg_template->isArena() && CheckSkirmishForSameFaction(bracket_id, MinPlayersPerTeam)) )
{ {
// we successfully created a pool // we successfully created a pool
BattleGround * bg2 = NULL; BattleGround * bg2 = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, bracketEntry, arenaType, false);
if (!(bg2 = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, queue_id, arenaType, false))) if (!bg2)
{ {
sLog.outError("BattleGroundQueue::Update - Cannot create battleground: %u", bgTypeId); sLog.outError("BattleGroundQueue::Update - Cannot create battleground: %u", bgTypeId);
return; return;
@@ -895,14 +902,14 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
{ {
GroupQueueInfo* front1 = NULL; GroupQueueInfo* front1 = NULL;
GroupQueueInfo* front2 = NULL; GroupQueueInfo* front2 = NULL;
if (!m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].empty()) if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty())
{ {
front1 = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].front(); front1 = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].front();
arenaRating = front1->ArenaTeamRating; arenaRating = front1->ArenaTeamRating;
} }
if (!m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].empty()) if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty())
{ {
front2 = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].front(); front2 = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].front();
arenaRating = front2->ArenaTeamRating; arenaRating = front2->ArenaTeamRating;
} }
if (front1 && front2) if (front1 && front2)
@@ -932,8 +939,8 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
for (uint32 i = BG_QUEUE_PREMADE_ALLIANCE; i < BG_QUEUE_NORMAL_ALLIANCE; i++) for (uint32 i = BG_QUEUE_PREMADE_ALLIANCE; i < BG_QUEUE_NORMAL_ALLIANCE; i++)
{ {
// take the group that joined first // take the group that joined first
itr_team[i] = m_QueuedGroups[queue_id][i].begin(); itr_team[i] = m_QueuedGroups[bracket_id][i].begin();
for (; itr_team[i] != m_QueuedGroups[queue_id][i].end(); ++(itr_team[i])) for(; itr_team[i] != m_QueuedGroups[bracket_id][i].end(); ++(itr_team[i]))
{ {
// if group match conditions, then add it to pool // if group match conditions, then add it to pool
if( !(*itr_team[i])->IsInvitedToBGInstanceGUID if( !(*itr_team[i])->IsInvitedToBGInstanceGUID
@@ -954,7 +961,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
{ {
itr_team[BG_TEAM_ALLIANCE] = itr_team[BG_TEAM_HORDE]; itr_team[BG_TEAM_ALLIANCE] = itr_team[BG_TEAM_HORDE];
++itr_team[BG_TEAM_ALLIANCE]; ++itr_team[BG_TEAM_ALLIANCE];
for (; itr_team[BG_TEAM_ALLIANCE] != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].end(); ++(itr_team[BG_TEAM_ALLIANCE])) for(; itr_team[BG_TEAM_ALLIANCE] != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].end(); ++(itr_team[BG_TEAM_ALLIANCE]))
{ {
if( !(*itr_team[BG_TEAM_ALLIANCE])->IsInvitedToBGInstanceGUID 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])->ArenaTeamRating >= arenaMinRating && (*itr_team[BG_TEAM_ALLIANCE])->ArenaTeamRating <= arenaMaxRating)
@@ -970,7 +977,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
{ {
itr_team[BG_TEAM_HORDE] = itr_team[BG_TEAM_ALLIANCE]; itr_team[BG_TEAM_HORDE] = itr_team[BG_TEAM_ALLIANCE];
++itr_team[BG_TEAM_HORDE]; ++itr_team[BG_TEAM_HORDE];
for (; itr_team[BG_TEAM_HORDE] != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].end(); ++(itr_team[BG_TEAM_HORDE])) for(; itr_team[BG_TEAM_HORDE] != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].end(); ++(itr_team[BG_TEAM_HORDE]))
{ {
if( !(*itr_team[BG_TEAM_HORDE])->IsInvitedToBGInstanceGUID 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])->ArenaTeamRating >= arenaMinRating && (*itr_team[BG_TEAM_HORDE])->ArenaTeamRating <= arenaMaxRating)
@@ -985,8 +992,8 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
//if we have 2 teams, then start new arena and invite players! //if we have 2 teams, then start new arena and invite players!
if (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount()) if (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount())
{ {
BattleGround* arena = NULL; BattleGround* arena = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, bracketEntry, arenaType, true);
if (!(arena = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, queue_id, arenaType, true))) if (!arena)
{ {
sLog.outError("BattlegroundQueue::Update couldn't create arena instance for rated arena match!"); sLog.outError("BattlegroundQueue::Update couldn't create arena instance for rated arena match!");
return; return;
@@ -1000,16 +1007,16 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
if ((*(itr_team[BG_TEAM_ALLIANCE]))->Team != ALLIANCE) if ((*(itr_team[BG_TEAM_ALLIANCE]))->Team != ALLIANCE)
{ {
// add to alliance queue // add to alliance queue
m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].push_front(*(itr_team[BG_TEAM_ALLIANCE])); m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].push_front(*(itr_team[BG_TEAM_ALLIANCE]));
// erase from horde queue // erase from horde queue
m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].erase(itr_team[BG_TEAM_ALLIANCE]); m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].erase(itr_team[BG_TEAM_ALLIANCE]);
itr_team[BG_TEAM_ALLIANCE] = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].begin(); itr_team[BG_TEAM_ALLIANCE] = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].begin();
} }
if ((*(itr_team[BG_TEAM_HORDE]))->Team != HORDE) if ((*(itr_team[BG_TEAM_HORDE]))->Team != HORDE)
{ {
m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].push_front(*(itr_team[BG_TEAM_HORDE])); m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].push_front(*(itr_team[BG_TEAM_HORDE]));
m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].erase(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[queue_id][BG_QUEUE_PREMADE_HORDE].begin(); itr_team[BG_TEAM_HORDE] = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].begin();
} }
InviteGroupToBG(*(itr_team[BG_TEAM_ALLIANCE]), arena, ALLIANCE); InviteGroupToBG(*(itr_team[BG_TEAM_ALLIANCE]), arena, ALLIANCE);
@@ -1040,17 +1047,15 @@ bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType()); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId); uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId);
if( queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES ) // player is in queue or in battleground if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue or in battleground
{ {
// check if player is invited to this bg // check if player is invited to this bg
BattleGroundQueue::QueuedPlayersMap const& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers; BattleGroundQueue &bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId];
BattleGroundQueue::QueuedPlayersMap::const_iterator qItr = qpMap.find(m_PlayerGuid); if (bgQueue.IsPlayerInvited(m_PlayerGuid, m_BgInstanceGUID, m_RemoveTime))
if( qItr != qpMap.end() && qItr->second.GroupInfo->IsInvitedToBGInstanceGUID == m_BgInstanceGUID
&& qItr->second.GroupInfo->RemoveInviteTime == m_RemoveTime )
{ {
WorldPacket data; WorldPacket data;
//we must send remaining time in queue //we must send remaining time in queue
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME - INVITATION_REMIND_TIME, 0, qItr->second.GroupInfo->ArenaType); sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME - INVITATION_REMIND_TIME, 0, m_ArenaType);
plr->GetSession()->SendPacket(&data); plr->GetSession()->SendPacket(&data);
} }
} }
@@ -1083,22 +1088,19 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
//bg pointer can be NULL! so use it carefully! //bg pointer can be NULL! so use it carefully!
uint32 queueSlot = plr->GetBattleGroundQueueIndex(m_BgQueueTypeId); uint32 queueSlot = plr->GetBattleGroundQueueIndex(m_BgQueueTypeId);
if( queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES ) // player is in queue, or in Battleground if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue, or in Battleground
{ {
// check if player is in queue for this BG and if we are removing his invite event // check if player is in queue for this BG and if we are removing his invite event
BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[m_BgQueueTypeId].m_QueuedPlayers; BattleGroundQueue &bgQueue = sBattleGroundMgr.m_BattleGroundQueues[m_BgQueueTypeId];
BattleGroundQueue::QueuedPlayersMap::iterator qMapItr = qpMap.find(m_PlayerGuid); if (bgQueue.IsPlayerInvited(m_PlayerGuid, m_BgInstanceGUID, m_RemoveTime))
if( qMapItr != qpMap.end() && qMapItr->second.GroupInfo
&& qMapItr->second.GroupInfo->IsInvitedToBGInstanceGUID == m_BgInstanceGUID
&& qMapItr->second.GroupInfo->RemoveInviteTime == m_RemoveTime )
{ {
sLog.outDebug("Battleground: removing player %u from bg queue for instance %u because of not pressing enter battle in time.",plr->GetGUIDLow(),m_BgInstanceGUID); sLog.outDebug("Battleground: removing player %u from bg queue for instance %u because of not pressing enter battle in time.",plr->GetGUIDLow(),m_BgInstanceGUID);
plr->RemoveBattleGroundQueueId(m_BgQueueTypeId); plr->RemoveBattleGroundQueueId(m_BgQueueTypeId);
sBattleGroundMgr.m_BattleGroundQueues[m_BgQueueTypeId].RemovePlayer(m_PlayerGuid, true); bgQueue.RemovePlayer(m_PlayerGuid, true);
//update queues if battleground isn't ended //update queues if battleground isn't ended
if (bg) if (bg && bg->isBattleGround() && bg->GetStatus() != STATUS_WAIT_LEAVE)
sBattleGroundMgr.ScheduleQueueUpdate(m_BgQueueTypeId, m_BgTypeId, bg->GetQueueId()); sBattleGroundMgr.ScheduleQueueUpdate(0, 0, m_BgQueueTypeId, m_BgTypeId, bg->GetBracketId());
WorldPacket data; WorldPacket data;
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0); sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0);
@@ -1140,8 +1142,8 @@ void BattleGroundMgr::DeleteAllBattleGrounds()
{ {
BattleGround * bg = itr->second; BattleGround * bg = itr->second;
m_BattleGrounds[i].erase(itr++); m_BattleGrounds[i].erase(itr++);
if (!m_ClientBattleGroundIds[i][bg->GetQueueId()].empty()) if (!m_ClientBattleGroundIds[i][bg->GetBracketId()].empty())
m_ClientBattleGroundIds[i][bg->GetQueueId()].erase(bg->GetClientInstanceID()); m_ClientBattleGroundIds[i][bg->GetBracketId()].erase(bg->GetClientInstanceID());
delete bg; delete bg;
} }
} }
@@ -1176,8 +1178,8 @@ void BattleGroundMgr::Update(uint32 diff)
{ {
BattleGround * bg = itr->second; BattleGround * bg = itr->second;
m_BattleGrounds[i].erase(itr); m_BattleGrounds[i].erase(itr);
if (!m_ClientBattleGroundIds[i][bg->GetQueueId()].empty()) if (!m_ClientBattleGroundIds[i][bg->GetBracketId()].empty())
m_ClientBattleGroundIds[i][bg->GetQueueId()].erase(bg->GetClientInstanceID()); m_ClientBattleGroundIds[i][bg->GetBracketId()].erase(bg->GetClientInstanceID());
delete bg; delete bg;
} }
} }
@@ -1186,18 +1188,22 @@ void BattleGroundMgr::Update(uint32 diff)
// update scheduled queues // update scheduled queues
if (!m_QueueUpdateScheduler.empty()) if (!m_QueueUpdateScheduler.empty())
{ {
//copy vector and clear the other std::vector<uint64> scheduled;
// TODO add lock {
// TODO maybe std::list would be better and then unlock after end of cycle //copy vector and clear the other
std::vector<uint32> scheduled(m_QueueUpdateScheduler); scheduled = std::vector<uint64>(m_QueueUpdateScheduler);
m_QueueUpdateScheduler.clear(); m_QueueUpdateScheduler.clear();
// TODO drop lock //release lock
}
for (uint8 i = 0; i < scheduled.size(); i++) for (uint8 i = 0; i < scheduled.size(); i++)
{ {
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundQueueTypeId(scheduled[i] >> 16); uint32 arenaRating = scheduled[i] >> 32;
uint8 arenaType = scheduled[i] >> 24 & 255;
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundQueueTypeId(scheduled[i] >> 16 & 255);
BattleGroundTypeId bgTypeId = BattleGroundTypeId((scheduled[i] >> 8) & 255); BattleGroundTypeId bgTypeId = BattleGroundTypeId((scheduled[i] >> 8) & 255);
BGQueueIdBasedOnLevel queue_id = BGQueueIdBasedOnLevel(scheduled[i] & 255); BattleGroundBracketId bracket_id = BattleGroundBracketId(scheduled[i] & 255);
m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, queue_id); m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, bracket_id, arenaType, arenaRating > 0, arenaRating);
} }
} }
@@ -1207,14 +1213,14 @@ void BattleGroundMgr::Update(uint32 diff)
// it's time to force update // it's time to force update
if (m_NextRatingDiscardUpdate < diff) if (m_NextRatingDiscardUpdate < diff)
{ {
// forced update for level 70 rated arenas // forced update for rated arenas (scan all, but skipped non rated)
sLog.outDebug("BattleGroundMgr: UPDATING ARENA QUEUES"); sLog.outDebug("BattleGroundMgr: UPDATING ARENA QUEUES");
m_BattleGroundQueues[BATTLEGROUND_QUEUE_2v2].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_79, ARENA_TYPE_2v2, true, 0); for(int qtype = BATTLEGROUND_QUEUE_2v2; qtype <= BATTLEGROUND_QUEUE_5v5; ++qtype)
m_BattleGroundQueues[BATTLEGROUND_QUEUE_2v2].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_80, ARENA_TYPE_2v2, true, 0); for(int bracket = BG_BRACKET_ID_FIRST; bracket < MAX_BATTLEGROUND_BRACKETS; ++bracket)
m_BattleGroundQueues[BATTLEGROUND_QUEUE_3v3].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_79, ARENA_TYPE_3v3, true, 0); m_BattleGroundQueues[qtype].Update(
m_BattleGroundQueues[BATTLEGROUND_QUEUE_3v3].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_80, ARENA_TYPE_3v3, true, 0); BATTLEGROUND_AA, BattleGroundBracketId(bracket),
m_BattleGroundQueues[BATTLEGROUND_QUEUE_5v5].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_79, ARENA_TYPE_5v5, true, 0); BattleGroundMgr::BGArenaType(BattleGroundQueueTypeId(qtype)), true, 0);
m_BattleGroundQueues[BATTLEGROUND_QUEUE_5v5].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_80, ARENA_TYPE_5v5, true, 0);
m_NextRatingDiscardUpdate = sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER); m_NextRatingDiscardUpdate = sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER);
} }
else else
@@ -1484,7 +1490,7 @@ BattleGround * BattleGroundMgr::GetBattleGroundTemplate(BattleGroundTypeId bgTyp
return m_BattleGrounds[bgTypeId].empty() ? NULL : m_BattleGrounds[bgTypeId].begin()->second; return m_BattleGrounds[bgTypeId].empty() ? NULL : m_BattleGrounds[bgTypeId].begin()->second;
} }
uint32 BattleGroundMgr::CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id) uint32 BattleGroundMgr::CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id)
{ {
if (IsArenaType(bgTypeId)) if (IsArenaType(bgTypeId))
return 0; //arenas don't have client-instanceids return 0; //arenas don't have client-instanceids
@@ -1496,18 +1502,18 @@ uint32 BattleGroundMgr::CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeI
// the following works, because std::set is default ordered with "<" // 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 // the optimalization would be to use as bitmask std::vector<uint32> - but that would only make code unreadable
uint32 lastId = 0; uint32 lastId = 0;
for (std::set<uint32>::iterator itr = m_ClientBattleGroundIds[bgTypeId][queue_id].begin(); itr != m_ClientBattleGroundIds[bgTypeId][queue_id].end();) for(std::set<uint32>::iterator itr = m_ClientBattleGroundIds[bgTypeId][bracket_id].begin(); itr != m_ClientBattleGroundIds[bgTypeId][bracket_id].end();)
{ {
if( (++lastId) != *itr) //if there is a gap between the ids, we will break.. if( (++lastId) != *itr) //if there is a gap between the ids, we will break..
break; break;
lastId = *itr; lastId = *itr;
} }
m_ClientBattleGroundIds[bgTypeId][queue_id].insert(lastId + 1); m_ClientBattleGroundIds[bgTypeId][bracket_id].insert(lastId + 1);
return lastId + 1; return lastId + 1;
} }
// create a new battleground that will really be used to play // create a new battleground that will really be used to play
BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated) BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeId, PvPDifficultyEntry const* bracketEntry, uint8 arenaType, bool isRated)
{ {
// get the template BG // get the template BG
BattleGround *bg_template = GetBattleGroundTemplate(bgTypeId); BattleGround *bg_template = GetBattleGroundTemplate(bgTypeId);
@@ -1589,14 +1595,14 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeI
// generate a new instance id // generate a new instance id
bg->SetInstanceID(MapManager::Instance().GenerateInstanceId()); // set instance id bg->SetInstanceID(MapManager::Instance().GenerateInstanceId()); // set instance id
bg->SetClientInstanceID(CreateClientVisibleInstanceId(bgTypeId, queue_id)); bg->SetClientInstanceID(CreateClientVisibleInstanceId(bgTypeId, bracketEntry->GetBracketId()));
// reset the new bg (set status to status_wait_queue from status_none) // reset the new bg (set status to status_wait_queue from status_none)
bg->Reset(); bg->Reset();
// start the joining of the bg // start the joining of the bg
bg->SetStatus(STATUS_WAIT_JOIN); bg->SetStatus(STATUS_WAIT_JOIN);
bg->SetQueueId(queue_id); bg->SetBracket(bracketEntry);
bg->SetArenaType(arenaType); bg->SetArenaType(arenaType);
bg->SetRated(isRated); bg->SetRated(isRated);
@@ -1843,9 +1849,6 @@ void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint6
if (!plr) if (!plr)
return; return;
uint32 PlayerLevel = 10;
PlayerLevel = plr->getLevel();
data->Initialize(SMSG_BATTLEFIELD_LIST); data->Initialize(SMSG_BATTLEFIELD_LIST);
*data << uint64(guid); // battlemaster guid *data << uint64(guid); // battlemaster guid
*data << uint8(fromWhere); // from where you joined *data << uint8(fromWhere); // from where you joined
@@ -1865,13 +1868,20 @@ void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint6
uint32 count = 0; uint32 count = 0;
*data << uint32(0); // number of bg instances *data << uint32(0); // number of bg instances
uint32 queue_id = plr->GetBattleGroundQueueIdFromLevel(bgTypeId); if(BattleGround* bgTemplate = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId))
for (std::set<uint32>::iterator itr = m_ClientBattleGroundIds[bgTypeId][queue_id].begin(); itr != m_ClientBattleGroundIds[bgTypeId][queue_id].end(); ++itr)
{ {
*data << uint32(*itr); // expected bracket entry
++count; 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);
}
} }
data->put<uint32>( count_pos , count);
} }
} }
@@ -2026,11 +2036,11 @@ void BattleGroundMgr::SetHolidayWeekends(uint32 mask)
} }
} }
void BattleGroundMgr::ScheduleQueueUpdate(BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id) void BattleGroundMgr::ScheduleQueueUpdate(uint32 arenaRating, uint8 arenaType, BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id)
{ {
//This method must be atomic, TODO add mutex //This method must be atomic, TODO add mutex
//we will use only 1 number created of bgTypeId and queue_id //we will use only 1 number created of bgTypeId and bracket_id
uint32 schedule_id = (bgQueueTypeId << 16) | (bgTypeId << 8) | queue_id; uint64 schedule_id = ((uint64)arenaRating << 32) | (arenaType << 24) | (bgQueueTypeId << 16) | (bgTypeId << 8) | bracket_id;
bool found = false; bool found = false;
for (uint8 i = 0; i < m_QueueUpdateScheduler.size(); i++) for (uint8 i = 0; i < m_QueueUpdateScheduler.size(); i++)
{ {
+23 -23
View File
@@ -24,6 +24,7 @@
#include "Common.h" #include "Common.h"
#include "Policies/Singleton.h" #include "Policies/Singleton.h"
#include "DBCEnums.h"
#include "BattleGround.h" #include "BattleGround.h"
typedef std::map<uint32, BattleGround*> BattleGroundSet; typedef std::map<uint32, BattleGround*> BattleGroundSet;
@@ -74,20 +75,18 @@ class BattleGroundQueue
BattleGroundQueue(); BattleGroundQueue();
~BattleGroundQueue(); ~BattleGroundQueue();
void Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType = 0, bool isRated = false, uint32 minRating = 0); void Update(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id, uint8 arenaType = 0, bool isRated = false, uint32 minRating = 0);
void FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel queue_id); void FillPlayersToBG(BattleGround* bg, BattleGroundBracketId bracket_id);
bool CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam); bool CheckPremadeMatch(BattleGroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam);
bool CheckNormalMatch(BattleGround* bg_template, BGQueueIdBasedOnLevel queue_id, uint32 minPlayers, uint32 maxPlayers); bool CheckNormalMatch(BattleGround* bg_template, BattleGroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers);
bool CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_id, uint32 minPlayersPerTeam); bool CheckSkirmishForSameFaction(BattleGroundBracketId bracket_id, uint32 minPlayersPerTeam);
GroupQueueInfo * AddGroup(Player * leader, BattleGroundTypeId bgTypeId, uint8 ArenaType, bool isRated, bool isPremade, uint32 ArenaRating, uint32 ArenaTeamId = 0); GroupQueueInfo * AddGroup(Player* leader, Group* group, BattleGroundTypeId bgTypeId, PvPDifficultyEntry const* backetEntry, uint8 ArenaType, bool isRated, bool isPremade, uint32 ArenaRating, uint32 ArenaTeamId = 0);
void AddPlayer(Player *plr, GroupQueueInfo *ginfo);
void RemovePlayer(const uint64& guid, bool decreaseInvitedCount); void RemovePlayer(const uint64& guid, bool decreaseInvitedCount);
void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id); bool IsPlayerInvited(const uint64& pl_guid, const uint32 bgInstanceGuid, const uint32 removeTime);
uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id); bool GetPlayerGroupInfoData(const uint64& guid, GroupQueueInfo* ginfo);
void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BattleGroundBracketId bracket_id);
void DecreaseGroupLength(uint32 queueId, uint32 AsGroup); uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BattleGroundBracketId bracket_id);
void AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue);
typedef std::map<uint64, PlayerQueueInfo> QueuedPlayersMap; typedef std::map<uint64, PlayerQueueInfo> QueuedPlayersMap;
QueuedPlayersMap m_QueuedPlayers; QueuedPlayersMap m_QueuedPlayers;
@@ -104,7 +103,7 @@ class BattleGroundQueue
BG_QUEUE_NORMAL_ALLIANCE is used for normal (or small) alliance groups or non-rated arena matches 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 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]; GroupsQueueType m_QueuedGroups[MAX_BATTLEGROUND_BRACKETS][BG_QUEUE_GROUP_TYPES_COUNT];
// class to select and invite groups to bg // class to select and invite groups to bg
class SelectionPool class SelectionPool
@@ -126,9 +125,9 @@ class BattleGroundQueue
private: private:
bool InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side); bool InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side);
uint32 m_WaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME]; uint32 m_WaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME];
uint32 m_WaitTimeLastPlayer[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES]; uint32 m_WaitTimeLastPlayer[BG_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS];
uint32 m_SumOfWaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES]; uint32 m_SumOfWaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS];
}; };
/* /*
@@ -138,8 +137,8 @@ class BattleGroundQueue
class BGQueueInviteEvent : public BasicEvent class BGQueueInviteEvent : public BasicEvent
{ {
public: public:
BGQueueInviteEvent(const uint64& pl_guid, uint32 BgInstanceGUID, BattleGroundTypeId BgTypeId, uint32 removeTime) : BGQueueInviteEvent(const uint64& pl_guid, uint32 BgInstanceGUID, BattleGroundTypeId BgTypeId, uint8 arenaType, uint32 removeTime) :
m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID), m_BgTypeId(BgTypeId), m_RemoveTime(removeTime) m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID), m_BgTypeId(BgTypeId), m_ArenaType(arenaType), m_RemoveTime(removeTime)
{ {
}; };
virtual ~BGQueueInviteEvent() {}; virtual ~BGQueueInviteEvent() {};
@@ -150,6 +149,7 @@ class BGQueueInviteEvent : public BasicEvent
uint64 m_PlayerGuid; uint64 m_PlayerGuid;
uint32 m_BgInstanceGUID; uint32 m_BgInstanceGUID;
BattleGroundTypeId m_BgTypeId; BattleGroundTypeId m_BgTypeId;
uint8 m_ArenaType;
uint32 m_RemoveTime; uint32 m_RemoveTime;
}; };
@@ -201,13 +201,13 @@ class BattleGroundMgr
BattleGround* GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId); //there must be uint32 because MAX_BATTLEGROUND_TYPE_ID means unknown BattleGround* GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId); //there must be uint32 because MAX_BATTLEGROUND_TYPE_ID means unknown
BattleGround* GetBattleGroundTemplate(BattleGroundTypeId bgTypeId); BattleGround* GetBattleGroundTemplate(BattleGroundTypeId bgTypeId);
BattleGround* CreateNewBattleGround(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated); BattleGround* CreateNewBattleGround(BattleGroundTypeId bgTypeId, PvPDifficultyEntry const* bracketEntry, uint8 arenaType, bool isRated);
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); 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);
void AddBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId, BattleGround* BG) { m_BattleGrounds[bgTypeId][InstanceID] = BG; }; void AddBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId, BattleGround* BG) { m_BattleGrounds[bgTypeId][InstanceID] = BG; };
void RemoveBattleGround(uint32 instanceID, BattleGroundTypeId bgTypeId) { m_BattleGrounds[bgTypeId].erase(instanceID); } void RemoveBattleGround(uint32 instanceID, BattleGroundTypeId bgTypeId) { m_BattleGrounds[bgTypeId].erase(instanceID); }
uint32 CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id); uint32 CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id);
void CreateInitialBattleGrounds(); void CreateInitialBattleGrounds();
void DeleteAllBattleGrounds(); void DeleteAllBattleGrounds();
@@ -220,7 +220,7 @@ class BattleGroundMgr
BGFreeSlotQueueType BGFreeSlotQueue[MAX_BATTLEGROUND_TYPE_ID]; BGFreeSlotQueueType BGFreeSlotQueue[MAX_BATTLEGROUND_TYPE_ID];
void ScheduleQueueUpdate(BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id); void ScheduleQueueUpdate(uint32 arenaRating, uint8 arenaType, BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id);
uint32 GetMaxRatingDifference() const; uint32 GetMaxRatingDifference() const;
uint32 GetRatingDiscardTimer() const; uint32 GetRatingDiscardTimer() const;
uint32 GetPrematureFinishTime() const; uint32 GetPrematureFinishTime() const;
@@ -256,8 +256,8 @@ class BattleGroundMgr
/* Battlegrounds */ /* Battlegrounds */
BattleGroundSet m_BattleGrounds[MAX_BATTLEGROUND_TYPE_ID]; BattleGroundSet m_BattleGrounds[MAX_BATTLEGROUND_TYPE_ID];
std::vector<uint32>m_QueueUpdateScheduler; std::vector<uint64> m_QueueUpdateScheduler;
std::set<uint32> m_ClientBattleGroundIds[MAX_BATTLEGROUND_TYPE_ID][MAX_BATTLEGROUND_QUEUES]; //the instanceids just visible for the client std::set<uint32> m_ClientBattleGroundIds[MAX_BATTLEGROUND_TYPE_ID][MAX_BATTLEGROUND_BRACKETS]; //the instanceids just visible for the client
uint32 m_NextRatingDiscardUpdate; uint32 m_NextRatingDiscardUpdate;
time_t m_NextAutoDistributionTime; time_t m_NextAutoDistributionTime;
uint32 m_AutoDistributionTimeChecker; uint32 m_AutoDistributionTimeChecker;
+59 -44
View File
@@ -190,7 +190,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
case CHAT_MSG_EMOTE: case CHAT_MSG_EMOTE:
case CHAT_MSG_YELL: case CHAT_MSG_YELL:
{ {
std::string msg = ""; std::string msg;
recv_data >> msg; recv_data >> msg;
if(msg.empty()) if(msg.empty())
@@ -227,9 +227,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
if(!normalizePlayerName(to)) if(!normalizePlayerName(to))
{ {
WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, (to.size()+1)); SendPlayerNotFoundNotice(to);
data<<to;
SendPacket(&data);
break; break;
} }
@@ -238,9 +236,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
uint32 pSecurity = player ? player->GetSession()->GetSecurity() : SEC_PLAYER; uint32 pSecurity = player ? player->GetSession()->GetSecurity() : SEC_PLAYER;
if (!player || (tSecurity == SEC_PLAYER && pSecurity > SEC_PLAYER && !player->isAcceptWhispers())) if (!player || (tSecurity == SEC_PLAYER && pSecurity > SEC_PLAYER && !player->isAcceptWhispers()))
{ {
WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, (to.size()+1)); SendPlayerNotFoundNotice(to);
data<<to;
SendPacket(&data);
return; return;
} }
@@ -250,9 +246,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
uint32 sideb = player->GetTeam(); uint32 sideb = player->GetTeam();
if( sidea != sideb ) if( sidea != sideb )
{ {
WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, (to.size()+1)); SendPlayerNotFoundNotice(to);
data<<to;
SendPacket(&data);
return; return;
} }
} }
@@ -263,12 +257,13 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
return; return;
} }
GetPlayer()->Whisper(msg, lang,player->GetGUID()); GetPlayer()->Whisper(msg, lang, player->GetGUID());
} break; } break;
case CHAT_MSG_PARTY: case CHAT_MSG_PARTY:
case CHAT_MSG_PARTY_LEADER:
{ {
std::string msg = ""; std::string msg;
recv_data >> msg; recv_data >> msg;
if(msg.empty()) if(msg.empty())
@@ -285,22 +280,28 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
// if player is in battleground, he cannot say to battleground members by /p // if player is in battleground, he cannot say to battleground members by /p
Group *group = GetPlayer()->GetOriginalGroup(); Group *group = GetPlayer()->GetOriginalGroup();
// so if player hasn't OriginalGroup and his player->GetGroup() is BG raid, then return if(!group)
if( !group && (!(group = GetPlayer()->GetGroup()) || group->isBGGroup()) ) {
group = _player->GetGroup();
if(!group || group->isBGGroup())
return;
}
if((type == CHAT_MSG_PARTY_LEADER) && !group->IsLeader(_player->GetGUID()))
return; return;
WorldPacket data; WorldPacket data;
ChatHandler::FillMessageData(&data, this, CHAT_MSG_PARTY, lang, NULL, 0, msg.c_str(),NULL); ChatHandler::FillMessageData(&data, this, type, lang, NULL, 0, msg.c_str(), NULL);
group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID())); group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID()));
if(sWorld.getConfig(CONFIG_CHATLOG_PARTY)) if(sWorld.getConfig(CONFIG_CHATLOG_PARTY))
sLog.outChat("[PARTY] Player %s tells group with leader %s: %s", sLog.outChat("[PARTY] Player %s tells group with leader %s: %s",
GetPlayer()->GetName(), group->GetLeaderName(), msg.c_str()); GetPlayer()->GetName(), group->GetLeaderName(), msg.c_str());
} } break;
break;
case CHAT_MSG_GUILD: case CHAT_MSG_GUILD:
{ {
std::string msg = ""; std::string msg;
recv_data >> msg; recv_data >> msg;
if(msg.empty()) if(msg.empty())
@@ -318,6 +319,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
if (GetPlayer()->GetGuildId()) if (GetPlayer()->GetGuildId())
{ {
Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
if (guild) if (guild)
guild->BroadcastToGuild(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); guild->BroadcastToGuild(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
@@ -337,7 +339,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
} }
case CHAT_MSG_OFFICER: case CHAT_MSG_OFFICER:
{ {
std::string msg = ""; std::string msg;
recv_data >> msg; recv_data >> msg;
if(msg.empty()) if(msg.empty())
@@ -355,6 +357,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
if (GetPlayer()->GetGuildId()) if (GetPlayer()->GetGuildId())
{ {
Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
if (guild) if (guild)
guild->BroadcastToOfficers(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); guild->BroadcastToOfficers(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
@@ -366,7 +369,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
} }
case CHAT_MSG_RAID: case CHAT_MSG_RAID:
{ {
std::string msg=""; std::string msg;
recv_data >> msg; recv_data >> msg;
if(msg.empty()) if(msg.empty())
@@ -383,12 +386,15 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
// if player is in battleground, he cannot say to battleground members by /ra // if player is in battleground, he cannot say to battleground members by /ra
Group *group = GetPlayer()->GetOriginalGroup(); Group *group = GetPlayer()->GetOriginalGroup();
// so if player hasn't OriginalGroup and his player->GetGroup() is BG raid or his group isn't raid, then return if(!group)
if ((!group && !(group = GetPlayer()->GetGroup())) || group->isBGGroup() || !group->isRaidGroup()) {
return; group = GetPlayer()->GetGroup();
if(!group || group->isBGGroup() || !group->isRaidGroup())
return;
}
WorldPacket data; WorldPacket data;
ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID, lang, "", 0, msg.c_str(),NULL); ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID, lang, "", 0, msg.c_str(), NULL);
group->BroadcastPacket(&data, false); group->BroadcastPacket(&data, false);
if(sWorld.getConfig(CONFIG_CHATLOG_RAID)) if(sWorld.getConfig(CONFIG_CHATLOG_RAID))
@@ -397,7 +403,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
} break; } break;
case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_LEADER:
{ {
std::string msg=""; std::string msg;
recv_data >> msg; recv_data >> msg;
if(msg.empty()) if(msg.empty())
@@ -414,11 +420,15 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
// if player is in battleground, he cannot say to battleground members by /ra // if player is in battleground, he cannot say to battleground members by /ra
Group *group = GetPlayer()->GetOriginalGroup(); Group *group = GetPlayer()->GetOriginalGroup();
if( !group && !(group = GetPlayer()->GetGroup()) || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID())) if(!group)
return; {
group = GetPlayer()->GetGroup();
if(!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(_player->GetGUID()))
return;
}
WorldPacket data; WorldPacket data;
ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_LEADER, lang, "", 0, msg.c_str(),NULL); ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_LEADER, lang, "", 0, msg.c_str(), NULL);
group->BroadcastPacket(&data, false); group->BroadcastPacket(&data, false);
if(sWorld.getConfig(CONFIG_CHATLOG_RAID)) if(sWorld.getConfig(CONFIG_CHATLOG_RAID))
@@ -427,7 +437,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
} break; } break;
case CHAT_MSG_RAID_WARNING: case CHAT_MSG_RAID_WARNING:
{ {
std::string msg=""; std::string msg;
recv_data >> msg; recv_data >> msg;
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
@@ -442,7 +452,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
WorldPacket data; WorldPacket data;
//in battleground, raid warning is sent only to players in battleground - code is ok //in battleground, raid warning is sent only to players in battleground - code is ok
ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_WARNING, lang, "", 0, msg.c_str(),NULL); ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_WARNING, lang, "", 0, msg.c_str(), NULL);
group->BroadcastPacket(&data, false); group->BroadcastPacket(&data, false);
if(sWorld.getConfig(CONFIG_CHATLOG_RAID)) if(sWorld.getConfig(CONFIG_CHATLOG_RAID))
@@ -452,7 +462,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
case CHAT_MSG_BATTLEGROUND: case CHAT_MSG_BATTLEGROUND:
{ {
std::string msg=""; std::string msg;
recv_data >> msg; recv_data >> msg;
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
@@ -467,7 +477,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
return; return;
WorldPacket data; WorldPacket data;
ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND, lang, "", 0, msg.c_str(),NULL); ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND, lang, "", 0, msg.c_str(), NULL);
group->BroadcastPacket(&data, false); group->BroadcastPacket(&data, false);
if(sWorld.getConfig(CONFIG_CHATLOG_BGROUND)) if(sWorld.getConfig(CONFIG_CHATLOG_BGROUND))
@@ -477,7 +487,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
case CHAT_MSG_BATTLEGROUND_LEADER: case CHAT_MSG_BATTLEGROUND_LEADER:
{ {
std::string msg=""; std::string msg;
recv_data >> msg; recv_data >> msg;
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
@@ -486,13 +496,13 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
if(msg.empty()) if(msg.empty())
break; break;
//battleground raid is always in Player->GetGroup(), never in GetOriginalGroup() // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
Group *group = GetPlayer()->GetGroup(); Group *group = GetPlayer()->GetGroup();
if(!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID())) if(!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID()))
return; return;
WorldPacket data; WorldPacket data;
ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND_LEADER, lang, "", 0, msg.c_str(),NULL); ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND_LEADER, lang, "", 0, msg.c_str(), NULL);
group->BroadcastPacket(&data, false); group->BroadcastPacket(&data, false);
if(sWorld.getConfig(CONFIG_CHATLOG_BGROUND)) if(sWorld.getConfig(CONFIG_CHATLOG_BGROUND))
@@ -502,9 +512,8 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
case CHAT_MSG_CHANNEL: case CHAT_MSG_CHANNEL:
{ {
std::string channel = "", msg = ""; std::string channel, msg;
recv_data >> channel; recv_data >> channel;
recv_data >> msg; recv_data >> msg;
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
@@ -518,10 +527,10 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
{ {
Channel *chn = cMgr->GetChannel(channel,_player);
if(chn) if(Channel *chn = cMgr->GetChannel(channel, _player))
{ {
chn->Say(_player->GetGUID(),msg.c_str(),lang); chn->Say(_player->GetGUID(), msg.c_str(), lang);
if((chn->HasFlag(CHANNEL_FLAG_TRADE) || if((chn->HasFlag(CHANNEL_FLAG_TRADE) ||
chn->HasFlag(CHANNEL_FLAG_GENERAL) || chn->HasFlag(CHANNEL_FLAG_GENERAL) ||
@@ -670,15 +679,15 @@ void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
Trinity::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit); Trinity::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit);
Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > emote_do(emote_builder); Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > emote_do(emote_builder);
Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > > emote_worker(GetPlayer(),sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),emote_do); Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > > emote_worker(GetPlayer(), sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), emote_do);
TypeContainerVisitor<Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > >, WorldTypeMapContainer > message(emote_worker); TypeContainerVisitor<Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder> >, WorldTypeMapContainer> message(emote_worker);
cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE)); cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit); GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
//Send scripted event call //Send scripted event call
if (unit && unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->AI()) if (unit && unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->AI())
((Creature*)unit)->AI()->ReceiveEmote(GetPlayer(),text_emote); ((Creature*)unit)->AI()->ReceiveEmote(GetPlayer(), text_emote);
} }
void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data ) void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data )
@@ -695,7 +704,7 @@ void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data )
return; return;
WorldPacket data; WorldPacket data;
ChatHandler::FillMessageData(&data, this, CHAT_MSG_IGNORED, LANG_UNIVERSAL, NULL, GetPlayer()->GetGUID(), GetPlayer()->GetName(),NULL); ChatHandler::FillMessageData(&data, this, CHAT_MSG_IGNORED, LANG_UNIVERSAL, NULL, GetPlayer()->GetGUID(), GetPlayer()->GetName(), NULL);
player->GetSession()->SendPacket(&data); player->GetSession()->SendPacket(&data);
} }
@@ -704,3 +713,9 @@ void WorldSession::HandleChannelDeclineInvite(WorldPacket &recvPacket)
sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
} }
void WorldSession::SendPlayerNotFoundNotice(std::string name)
{
WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, name.size()+1);
data << name;
SendPacket(&data);
}
+9
View File
@@ -32,6 +32,15 @@
// also see MAX_LEVEL and GT_MAX_LEVEL define // also see MAX_LEVEL and GT_MAX_LEVEL define
#define STRONG_MAX_LEVEL 255 #define STRONG_MAX_LEVEL 255
enum BattleGroundBracketId // bracketId for level ranges
{
BG_BRACKET_ID_FIRST = 0,
BG_BRACKET_ID_LAST = 15
};
// must be max value in PvPDificulty slot+1
#define MAX_BATTLEGROUND_BRACKETS 16
enum AreaTeams enum AreaTeams
{ {
AREATEAM_NONE = 0, AREATEAM_NONE = 0,
+33 -1
View File
@@ -107,6 +107,8 @@ MapDifficultyMap sMapDifficultyMap;
DBCStorage <MovieEntry> sMovieStore(MovieEntryfmt); DBCStorage <MovieEntry> sMovieStore(MovieEntryfmt);
DBCStorage <PvPDifficultyEntry> sPvPDifficultyStore(PvPDifficultyfmt);
DBCStorage <QuestSortEntry> sQuestSortStore(QuestSortEntryfmt); DBCStorage <QuestSortEntry> sQuestSortStore(QuestSortEntryfmt);
DBCStorage <QuestXPEntry> sQuestXPStore(QuestXPfmt); DBCStorage <QuestXPEntry> sQuestXPStore(QuestXPfmt);
DBCStorage <QuestFactionRewEntry> sQuestFactionRewardStore(QuestFactionRewardfmt); DBCStorage <QuestFactionRewEntry> sQuestFactionRewardStore(QuestFactionRewardfmt);
@@ -216,7 +218,7 @@ void LoadDBCStores(const std::string& dataPath)
{ {
std::string dbcPath = dataPath+"dbc/"; std::string dbcPath = dataPath+"dbc/";
const uint32 DBCFilesCount = 83; const uint32 DBCFilesCount = 84;
barGoLink bar(DBCFilesCount); barGoLink bar(DBCFilesCount);
@@ -329,6 +331,12 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMovieStore, dbcPath,"Movie.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMovieStore, dbcPath,"Movie.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sPvPDifficultyStore, dbcPath,"PvpDifficulty.dbc");
for(uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i)
if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i))
if (entry->bracketId > MAX_BATTLEGROUND_BRACKETS)
assert(false && "Need update MAX_BATTLEGROUND_BRACKETS by DBC data");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestXPStore, dbcPath,"QuestXP.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestXPStore, dbcPath,"QuestXP.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestFactionRewardStore, dbcPath,"QuestFactionReward.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestFactionRewardStore, dbcPath,"QuestFactionReward.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc");
@@ -720,6 +728,30 @@ MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty)
return itr != sMapDifficultyMap.end() ? &itr->second : NULL; return itr != sMapDifficultyMap.end() ? &itr->second : NULL;
} }
PvPDifficultyEntry const* GetBattlegroundBracketByLevel( uint32 mapid, uint32 level )
{
// prevent out-of-range levels for dbc data
if (level > DEFAULT_MAX_LEVEL)
level = DEFAULT_MAX_LEVEL;
for(uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i)
if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i))
if (entry->mapId == mapid && entry->minLevel <= level && entry->maxLevel >= level)
return entry;
return NULL;
}
PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattleGroundBracketId id)
{
for(uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i)
if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i))
if (entry->mapId == mapid && entry->GetBracketId() == id)
return entry;
return NULL;
}
uint32 const* GetTalentTabPages(uint8 cls) uint32 const* GetTalentTabPages(uint8 cls)
{ {
return sTalentTabPages[cls]; return sTalentTabPages[cls];
+3
View File
@@ -59,6 +59,9 @@ MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty);
uint32 const* /*[3]*/ GetTalentTabPages(uint8 cls); uint32 const* /*[3]*/ GetTalentTabPages(uint8 cls);
PvPDifficultyEntry const* GetBattlegroundBracketByLevel(uint32 mapid, uint32 level);
PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattleGroundBracketId id);
extern DBCStorage <AchievementEntry> sAchievementStore; extern DBCStorage <AchievementEntry> sAchievementStore;
extern DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore; extern DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore;
extern DBCStorage <AreaTableEntry> sAreaStore;// recommend access using functions extern DBCStorage <AreaTableEntry> sAreaStore;// recommend access using functions
+13
View File
@@ -1190,6 +1190,19 @@ struct MovieEntry
//uint32 unk2; // 2 always 100 //uint32 unk2; // 2 always 100
}; };
struct PvPDifficultyEntry
{
//uint32 id; // 0 m_ID
uint32 mapId; // 1
uint32 bracketId; // 2
uint32 minLevel; // 3
uint32 maxLevel; // 4
uint32 difficulty; // 5
// helpers
BattleGroundBracketId GetBracketId() const { return BattleGroundBracketId(bracketId); }
};
struct QuestSortEntry struct QuestSortEntry
{ {
uint32 id; // 0 m_ID uint32 id; // 0 m_ID
+1
View File
@@ -81,6 +81,7 @@ const char MovieEntryfmt[]="nxx";
const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx"; const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx";
const char QuestXPfmt[]="niiiiiiiiii"; const char QuestXPfmt[]="niiiiiiiiii";
const char QuestFactionRewardfmt[]="niiiiiiiiii"; const char QuestFactionRewardfmt[]="niiiiiiiiii";
const char PvPDifficultyfmt[]="diiiii";
const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii"; const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii";
const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiii"; const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiii";
const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiiixiiii"; const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiiixiiii";
+8 -4
View File
@@ -1456,7 +1456,7 @@ void Group::UpdateLooterGuid( Creature* creature, bool ifneed )
SendUpdate(); SendUpdate();
} }
uint32 Group::CanJoinBattleGroundQueue(BattleGroundTypeId bgTypeId, BattleGroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot) uint32 Group::CanJoinBattleGroundQueue(BattleGround const* bgOrTemplate, BattleGroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot)
{ {
// check for min / max count // check for min / max count
uint32 memberscount = GetMembersCount(); uint32 memberscount = GetMembersCount();
@@ -1471,7 +1471,10 @@ uint32 Group::CanJoinBattleGroundQueue(BattleGroundTypeId bgTypeId, BattleGround
if(!reference) if(!reference)
return BG_JOIN_ERR_OFFLINE_MEMBER; return BG_JOIN_ERR_OFFLINE_MEMBER;
BGQueueIdBasedOnLevel queue_id = reference->GetBattleGroundQueueIdFromLevel(bgTypeId); PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bgOrTemplate->GetMapId(),reference->getLevel());
if(!bracketEntry)
return BG_JOIN_ERR_OFFLINE_MEMBER;
uint32 arenaTeamId = reference->GetArenaTeamId(arenaSlot); uint32 arenaTeamId = reference->GetArenaTeamId(arenaSlot);
uint32 team = reference->GetTeam(); uint32 team = reference->GetTeam();
@@ -1486,7 +1489,8 @@ uint32 Group::CanJoinBattleGroundQueue(BattleGroundTypeId bgTypeId, BattleGround
if(member->GetTeam() != team) if(member->GetTeam() != team)
return BG_JOIN_ERR_MIXED_FACTION; return BG_JOIN_ERR_MIXED_FACTION;
// not in the same battleground level braket, don't let join // not in the same battleground level braket, don't let join
if(member->GetBattleGroundQueueIdFromLevel(bgTypeId) != queue_id) PvPDifficultyEntry const* memberBracketEntry = GetBattlegroundBracketByLevel(bracketEntry->mapId,member->getLevel());
if(memberBracketEntry != bracketEntry)
return BG_JOIN_ERR_MIXED_LEVELS; return BG_JOIN_ERR_MIXED_LEVELS;
// don't let join rated matches if the arena team id doesn't match // don't let join rated matches if the arena team id doesn't match
if(isRated && member->GetArenaTeamId(arenaSlot) != arenaTeamId) if(isRated && member->GetArenaTeamId(arenaSlot) != arenaTeamId)
@@ -1495,7 +1499,7 @@ uint32 Group::CanJoinBattleGroundQueue(BattleGroundTypeId bgTypeId, BattleGround
if(member->InBattleGroundQueueForBattleGroundQueueType(bgQueueTypeId)) if(member->InBattleGroundQueueForBattleGroundQueueType(bgQueueTypeId))
return BG_JOIN_ERR_GROUP_MEMBER_ALREADY_IN_QUEUE; return BG_JOIN_ERR_GROUP_MEMBER_ALREADY_IN_QUEUE;
// check for deserter debuff in case not arena queue // check for deserter debuff in case not arena queue
if(bgTypeId != BATTLEGROUND_AA && !member->CanJoinToBattleground()) if(bgOrTemplate->GetTypeID() != BATTLEGROUND_AA && !member->CanJoinToBattleground())
return BG_JOIN_ERR_GROUP_DESERTER; return BG_JOIN_ERR_GROUP_DESERTER;
// check if member can join any more battleground queues // check if member can join any more battleground queues
if(!member->HasFreeBattleGroundQueueId()) if(!member->HasFreeBattleGroundQueueId())
+1 -1
View File
@@ -266,7 +266,7 @@ class Group
void ConvertToRaid(); void ConvertToRaid();
void SetBattlegroundGroup(BattleGround *bg) { m_bgGroup = bg; } void SetBattlegroundGroup(BattleGround *bg) { m_bgGroup = bg; }
uint32 CanJoinBattleGroundQueue(BattleGroundTypeId bgTypeId, BattleGroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot); uint32 CanJoinBattleGroundQueue(BattleGround const* bgOrTemplate, BattleGroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot);
void ChangeMembersGroup(const uint64 &guid, const uint8 &group); void ChangeMembersGroup(const uint64 &guid, const uint8 &group);
void ChangeMembersGroup(Player *player, const uint8 &group); void ChangeMembersGroup(Player *player, const uint8 &group);
+4 -4
View File
@@ -219,10 +219,10 @@ BattleGroundMap* MapInstanced::CreateBattleGround(uint32 InstanceId, BattleGroun
sLog.outDebug("MapInstanced::CreateBattleGround: map bg %d for %d created.", InstanceId, GetId()); sLog.outDebug("MapInstanced::CreateBattleGround: map bg %d for %d created.", InstanceId, GetId());
// 0-59 normal spawn 60-69 difficulty_1, 70-79 difficulty_2, 80 dufficulty_3 PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),bg->GetMinLevel());
uint8 spawnMode = (bg->GetQueueId() > QUEUE_ID_MAX_LEVEL_59) ? (bg->GetQueueId() - QUEUE_ID_MAX_LEVEL_59) : 0;
while (!GetMapDifficultyData(GetId(), Difficulty(spawnMode))) uint8 spawnMode = bracketEntry ? bracketEntry->difficulty : REGULAR_DIFFICULTY;
spawnMode--;
BattleGroundMap *map = new BattleGroundMap(GetId(), GetGridExpiry(), InstanceId, this, spawnMode); BattleGroundMap *map = new BattleGroundMap(GetId(), GetGridExpiry(), InstanceId, this, spawnMode);
ASSERT(map->IsBattleGroundOrArena()); ASSERT(map->IsBattleGroundOrArena());
map->SetBG(bg); map->SetBG(bg);
+9 -16
View File
@@ -3676,10 +3676,10 @@ void Player::RemoveArenaSpellCooldowns()
next = itr; next = itr;
++next; ++next;
SpellEntry const * entry = sSpellStore.LookupEntry(itr->first); SpellEntry const * entry = sSpellStore.LookupEntry(itr->first);
// check if spellentry is present and if the cooldown is less than 15 mins // check if spellentry is present and if the cooldown is less than 10 mins
if( entry && if( entry &&
entry->RecoveryTime <= 15 * MINUTE * IN_MILISECONDS && entry->RecoveryTime <= 10 * MINUTE * IN_MILISECONDS &&
entry->CategoryRecoveryTime <= 15 * MINUTE * IN_MILISECONDS ) entry->CategoryRecoveryTime <= 10 * MINUTE * IN_MILISECONDS )
{ {
// remove & notify // remove & notify
RemoveSpellCooldown(itr->first, true); RemoveSpellCooldown(itr->first, true);
@@ -20687,24 +20687,17 @@ bool Player::GetBGAccessByLevel(BattleGroundTypeId bgTypeId) const
if(!bg) if(!bg)
return false; return false;
if(getLevel() < bg->GetMinLevel() || getLevel() > bg->GetMaxLevel()) // limit check leel to dbc compatible level range
uint32 level = getLevel();
if (level > DEFAULT_MAX_LEVEL)
level = DEFAULT_MAX_LEVEL;
if(level < bg->GetMinLevel() || level > bg->GetMaxLevel())
return false; return false;
return true; return true;
} }
BGQueueIdBasedOnLevel Player::GetBattleGroundQueueIdFromLevel(BattleGroundTypeId bgTypeId) const
{
// for ranges 0 - 19, 20 - 29, 30 - 39, 40 - 49, 50 - 59, 60 - 69, 70 - 79, 80
uint32 queue_id = ( getLevel() / 10) - 1;
if (queue_id >= MAX_BATTLEGROUND_QUEUES)
{
sLog.outError("BattleGround: too high queue_id %u this shouldn't happen", queue_id);
return QUEUE_ID_MAX_LEVEL_80;
}
return BGQueueIdBasedOnLevel(queue_id);
}
float Player::GetReputationPriceDiscount( Creature const* pCreature ) const float Player::GetReputationPriceDiscount( Creature const* pCreature ) const
{ {
FactionTemplateEntry const* vendor_faction = pCreature->getFactionTemplateEntry(); FactionTemplateEntry const* vendor_faction = pCreature->getFactionTemplateEntry();
-2
View File
@@ -1982,8 +1982,6 @@ class Player : public Unit, public GridObject<Player>
BattleGroundTypeId GetBattleGroundTypeId() const { return m_bgData.bgTypeID; } BattleGroundTypeId GetBattleGroundTypeId() const { return m_bgData.bgTypeID; }
BattleGround* GetBattleGround() const; BattleGround* GetBattleGround() const;
BGQueueIdBasedOnLevel GetBattleGroundQueueIdFromLevel(BattleGroundTypeId bgTypeId) const;
bool InBattleGroundQueue() const bool InBattleGroundQueue() const
{ {
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
+20 -21
View File
@@ -6219,27 +6219,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
triggered_spell_id = 28810; triggered_spell_id = 28810;
break; break;
} }
// Earthen Power (Rank 1, 2)
case 51523:
case 51524:
{
// Totem itself must be a caster of this spell
Unit* caster = NULL;
for (ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
{
if ((*itr)->GetEntry() != 2630)
continue;
caster = (*itr);
break;
}
if (!caster)
return false;
caster->CastSpell(caster, 59566, true, castItem, triggeredByAura, originalCaster);
return true;
}
} }
break; break;
} }
@@ -6851,6 +6830,26 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
{ {
switch(dummySpell->Id) switch(dummySpell->Id)
{ {
// Earthen Power (Rank 1, 2)
case 51523:
case 51524:
{
// Totem itself must be a caster of this spell
Unit* caster = NULL;
for (ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr) {
if ((*itr)->GetEntry() != 2630)
continue;
caster = (*itr);
break;
}
if (!caster)
return false;
caster->CastSpell(caster, 59566, true, castItem, triggeredByAura, originalCaster);
return true;
}
// Tidal Force // Tidal Force
case 55198: case 55198:
{ {
+1
View File
@@ -555,6 +555,7 @@ class WorldSession
bool processChatmessageFurtherAfterSecurityChecks(std::string&, uint32); bool processChatmessageFurtherAfterSecurityChecks(std::string&, uint32);
void HandleMessagechatOpcode(WorldPacket& recvPacket); void HandleMessagechatOpcode(WorldPacket& recvPacket);
void SendPlayerNotFoundNotice(std::string name);
void HandleTextEmoteOpcode(WorldPacket& recvPacket); void HandleTextEmoteOpcode(WorldPacket& recvPacket);
void HandleChatIgnoredOpcode(WorldPacket& recvPacket); void HandleChatIgnoredOpcode(WorldPacket& recvPacket);
+1 -1
View File
@@ -163,7 +163,7 @@ bool GossipSelect_npc_thorim(Player* pPlayer, Creature* pCreature, uint32 uiSend
break; break;
case GOSSIP_ACTION_INFO_DEF+4: case GOSSIP_ACTION_INFO_DEF+4:
pPlayer->CLOSE_GOSSIP_MENU(); pPlayer->CLOSE_GOSSIP_MENU();
pPlayer->AreaExploredOrEventHappens(QUEST_SIBLING_RIVALRY); pPlayer->CompleteQuest(QUEST_SIBLING_RIVALRY);
break; break;
} }
return true; return true;
@@ -91,21 +91,29 @@ struct instance_halls_of_lightning : public ScriptedInstance
m_uiBjarngrimDoorGUID = pGo->GetGUID(); m_uiBjarngrimDoorGUID = pGo->GetGUID();
if (m_auiEncounter[0] == DONE) if (m_auiEncounter[0] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE); pGo->SetGoState(GO_STATE_ACTIVE);
else
pGo->SetGoState(GO_STATE_READY);
break; break;
case GO_VOLKHAN_DOOR: case GO_VOLKHAN_DOOR:
m_uiVolkhanDoorGUID = pGo->GetGUID(); m_uiVolkhanDoorGUID = pGo->GetGUID();
if (m_auiEncounter[1] == DONE) if (m_auiEncounter[1] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE); pGo->SetGoState(GO_STATE_ACTIVE);
else
pGo->SetGoState(GO_STATE_READY);
break; break;
case GO_IONAR_DOOR: case GO_IONAR_DOOR:
m_uiIonarDoorGUID = pGo->GetGUID(); m_uiIonarDoorGUID = pGo->GetGUID();
if (m_auiEncounter[2] == DONE) if (m_auiEncounter[2] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE); pGo->SetGoState(GO_STATE_ACTIVE);
else
pGo->SetGoState(GO_STATE_READY);
break; break;
case GO_LOKEN_DOOR: case GO_LOKEN_DOOR:
m_uiLokenDoorGUID = pGo->GetGUID(); m_uiLokenDoorGUID = pGo->GetGUID();
if (m_auiEncounter[3] == DONE) if (m_auiEncounter[3] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE); pGo->SetGoState(GO_STATE_ACTIVE);
else
pGo->SetGoState(GO_STATE_READY);
break; break;
case GO_LOKEN_THRONE: case GO_LOKEN_THRONE:
m_uiLokenGlobeGUID = pGo->GetGUID(); m_uiLokenGlobeGUID = pGo->GetGUID();
@@ -222,6 +222,8 @@ struct boss_svala_sorrowgraveAI : public ScriptedAI
Creature* pRitualChanneler[3]; Creature* pRitualChanneler[3];
Unit* pSacrificeTarget; Unit* pSacrificeTarget;
bool bSacrificed;
ScriptedInstance* pInstance; ScriptedInstance* pInstance;
@@ -231,6 +233,8 @@ struct boss_svala_sorrowgraveAI : public ScriptedAI
uiCallFlamesTimer = 10000; uiCallFlamesTimer = 10000;
uiRitualOfSwordTimer = 20000; uiRitualOfSwordTimer = 20000;
uiSacrificeTimer = 8000; uiSacrificeTimer = 8000;
bSacrificed = false;
Phase = NORMAL; Phase = NORMAL;
@@ -276,7 +280,7 @@ struct boss_svala_sorrowgraveAI : public ScriptedAI
} }
} else uiCallFlamesTimer -= diff; } else uiCallFlamesTimer -= diff;
if (uiRitualOfSwordTimer <= diff) if (!bSacrificed && uiRitualOfSwordTimer <= diff)
{ {
pSacrificeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); pSacrificeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
if (pSacrificeTarget) if (pSacrificeTarget)
@@ -294,7 +298,7 @@ struct boss_svala_sorrowgraveAI : public ScriptedAI
if (mob_ritual_channelerAI *pChannelerAI = CAST_AI(mob_ritual_channelerAI,pRitualChanneler[i]->AI())) if (mob_ritual_channelerAI *pChannelerAI = CAST_AI(mob_ritual_channelerAI,pRitualChanneler[i]->AI()))
pChannelerAI->AttackStartNoMove(pSacrificeTarget); pChannelerAI->AttackStartNoMove(pSacrificeTarget);
uiRitualOfSwordTimer = urand(18000,22000); bSacrificed = true;
} }
} else uiRitualOfSwordTimer -= diff; } else uiRitualOfSwordTimer -= diff;