From b9712d36d2c285be14cf7bb9bd5cc1f4c9c58cf3 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 9 Jan 2010 03:36:27 +0300 Subject: [PATCH] Use PVPDificulty.dbc for bg/arena bracket selection (levels and difficulty) --- src/game/BattleGround.cpp | 7 +++- src/game/BattleGround.h | 25 ++------------ src/game/BattleGroundHandler.cpp | 48 ++++++++++++++++--------- src/game/BattleGroundMgr.cpp | 75 ++++++++++++++++++++++++---------------- src/game/BattleGroundMgr.h | 5 +-- src/game/DBCEnums.h | 9 +++++ src/game/DBCStores.cpp | 33 +++++++++++++++++- src/game/DBCStores.h | 4 +++ src/game/DBCStructure.h | 13 +++++++ src/game/DBCfmt.h | 1 + src/game/Group.cpp | 12 ++++--- src/game/Group.h | 2 +- src/game/MapInstanced.cpp | 9 +++-- src/game/Player.cpp | 19 ++++------ src/game/Player.h | 3 -- 15 files changed, 167 insertions(+), 98 deletions(-) diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index 95a9ccbfe..241e4bfbd 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -1129,7 +1129,6 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac // this method is called when no players remains in battleground void BattleGround::Reset() { - SetBracketId(BG_BRACKET_ID_FIRST); SetWinner(WINNER_NONE); SetStatus(STATUS_WAIT_QUEUE); SetStartTime(0); @@ -1835,3 +1834,9 @@ bool BattleGround::IsTeamScoreInRange(uint32 team, uint32 minScore, uint32 maxSc uint32 score = (m_TeamScores[team_idx] < 0) ? 0 : uint32(m_TeamScores[team_idx]); return score >= minScore && score <= maxScore; } + +void BattleGround::SetBracket( PvPDifficultyEntry const* bracketEntry ) +{ + m_BracketId = bracketEntry->GetBracketId(); + SetLevelRange(bracketEntry->minLevel,bracketEntry->maxLevel); +} \ No newline at end of file diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h index bbf2895ba..da7523ac8 100644 --- a/src/game/BattleGround.h +++ b/src/game/BattleGround.h @@ -38,6 +38,7 @@ class Player; class WorldPacket; class BattleGroundMap; +struct PvPDifficultyEntry; struct WorldSafeLocsEntry; struct BattleGroundEventIdx @@ -165,23 +166,6 @@ enum BattleGroundQueueTypeId }; #define MAX_BATTLEGROUND_QUEUE_TYPES 10 -enum BattleGroundBracketId // bracketId for level ranges -{ - BG_BRACKET_ID_FIRST = 0, - - BG_BRACKET_ID_MAX_LEVEL_19 = 0, - BG_BRACKET_ID_MAX_LEVEL_29 = 1, - BG_BRACKET_ID_MAX_LEVEL_39 = 2, - BG_BRACKET_ID_MAX_LEVEL_49 = 3, - BG_BRACKET_ID_MAX_LEVEL_59 = 4, - BG_BRACKET_ID_MAX_LEVEL_69 = 5, - BG_BRACKET_ID_MAX_LEVEL_79 = 6, - BG_BRACKET_ID_MAX_LEVEL_80 = 7, - - BG_BRACKET_ID_LAST = 7 -}; -#define MAX_BATTLEGROUND_BRACKETS 8 - enum ScoreType { SCORE_KILLING_BLOWS = 1, @@ -338,12 +322,7 @@ class BattleGround void SetName(char const* Name) { m_Name = Name; } void SetTypeID(BattleGroundTypeId TypeID) { m_TypeID = TypeID; } //here we can count minlevel and maxlevel for players - void SetBracketId(BattleGroundBracketId ID) - { - m_BracketId = ID; - uint8 diff = (m_TypeID == BATTLEGROUND_AV) ? 1 : 0; - this->SetLevelRange((ID + 1) * 10 + diff, (ID + 2) * 10 - ((diff + 1) % 2)); - } + void SetBracket(PvPDifficultyEntry const* bracketEntry); void SetInstanceID(uint32 InstanceID) { m_InstanceID = InstanceID; } void SetStatus(BattleGroundStatus Status) { m_Status = Status; } void SetClientInstanceID(uint32 InstanceID) { m_ClientInstanceID = InstanceID; } diff --git a/src/game/BattleGroundHandler.cpp b/src/game/BattleGroundHandler.cpp index 0fde9951d..6ec383021 100644 --- a/src/game/BattleGroundHandler.cpp +++ b/src/game/BattleGroundHandler.cpp @@ -115,7 +115,10 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data ) return; } - BattleGroundBracketId bgBracketId = _player->GetBattleGroundBracketIdFromLevel(); + // expected bracket entry + PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),_player->getLevel()); + if (!bracketEntry) + return; // check queueing conditions if (!joinAsGroup) @@ -142,7 +145,7 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data ) // no group found, error if (!grp) 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()); if (err != BG_JOIN_ERR_OK) { @@ -157,8 +160,8 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data ) if (joinAsGroup /* && _player->GetGroup()*/) { sLog.outDebug("Battleground: the following players are joining as group:"); - GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bgBracketId, 0, false, isPremade, 0); - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundBracketIdFromLevel()); + 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()) { Player *member = itr->getSource(); @@ -178,8 +181,8 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data ) } else { - GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bgBracketId, 0, false, isPremade, 0); - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundBracketIdFromLevel()); + 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 uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId); @@ -189,7 +192,7 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data ) SendPacket(&data); 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.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, _player->GetBattleGroundBracketIdFromLevel()); + sBattleGroundMgr.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); } void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv_data*/ ) @@ -352,6 +355,11 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data ) return; } + // 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) { @@ -433,7 +441,7 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data ) bgQueue.RemovePlayer(_player->GetGUID(), true); // player left queue, we should update it - do not update Arena Queue if (!ginfo.ArenaType) - sBattleGroundMgr.ScheduleQueueUpdate(ginfo.ArenaTeamRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, _player->GetBattleGroundBracketIdFromLevel()); + sBattleGroundMgr.ScheduleQueueUpdate(ginfo.ArenaTeamRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); SendPacket(&data); sLog.outDebug("Battleground: player %s (%u) left queue for bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetTypeID(), bgQueueTypeId); break; @@ -515,7 +523,13 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ ) bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId); if (!bg) continue; - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(&ginfo, _player->GetBattleGroundBracketIdFromLevel()); + + // 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 sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_QUEUE, avgTime, getMSTimeDiff(ginfo.JoinTime, getMSTime()), arenaType); SendPacket(&data); @@ -618,7 +632,9 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data ) BattleGroundTypeId bgTypeId = bg->GetTypeID(); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype); - BattleGroundBracketId bgBracketId = _player->GetBattleGroundBracketIdFromLevel(); + PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),_player->getLevel()); + if (!bracketEntry) + return; // check queueing conditions if (!asGroup) @@ -637,7 +653,7 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data ) // no group found, error if (!grp) 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) { SendBattleGroundOrArenaJoinError(err); @@ -685,8 +701,8 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data ) if (isRated) sLog.outDebug("Battleground: arena team id %u, leader %s queued with rating %u for type %u",_player->GetArenaTeamId(arenaslot),_player->GetName(),arenaRating,arenatype); - GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bgBracketId, arenatype, isRated, false, arenaRating, ateamId); - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundBracketIdFromLevel()); + 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()) { Player *member = itr->getSource(); @@ -707,8 +723,8 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data ) } else { - GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bgBracketId, arenatype, isRated, false, arenaRating, ateamId); - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundBracketIdFromLevel()); + 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); WorldPacket data; @@ -717,7 +733,7 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data ) SendPacket(&data); 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.ScheduleQueueUpdate(arenaRating, arenatype, bgQueueTypeId, bgTypeId, _player->GetBattleGroundBracketIdFromLevel()); + sBattleGroundMgr.ScheduleQueueUpdate(arenaRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); } void WorldSession::HandleReportPvPAFK( WorldPacket & recv_data ) diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp index 42865e575..7cbe1b27a 100644 --- a/src/game/BattleGroundMgr.cpp +++ b/src/game/BattleGroundMgr.cpp @@ -148,8 +148,10 @@ bool BattleGroundQueue::SelectionPool::AddGroup(GroupQueueInfo *ginfo, uint32 de /*********************************************************/ // add group or player (grp == NULL) to bg queue with the given leader and bg specifications -GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, Group* grp, BattleGroundTypeId BgTypeId, BattleGroundBracketId bracket_id, 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) { + BattleGroundBracketId bracketId = backetEntry->GetBracketId(); + // create new ginfo GroupQueueInfo* ginfo = new GroupQueueInfo; ginfo->BgTypeId = BgTypeId; @@ -171,7 +173,7 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, Group* grp, BattleG index += BG_TEAMS_COUNT; if (ginfo->Team == HORDE) index++; - sLog.outDebug("Adding Group to BattleGroundQueue bgTypeId : %u, bracket_id : %u, index : %u", BgTypeId, bracket_id, index); + sLog.outDebug("Adding Group to BattleGroundQueue bgTypeId : %u, bracket_id : %u, index : %u", BgTypeId, bracketId, index); uint32 lastOnlineTime = getMSTime(); @@ -207,37 +209,37 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, Group* grp, BattleG } //add GroupInfo to m_QueuedGroups - m_QueuedGroups[bracket_id][index].push_back(ginfo); + m_QueuedGroups[bracketId][index].push_back(ginfo); //announce to world, this code needs mutex if (!isRated && !isPremade && sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE)) { - BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(ginfo->BgTypeId); - if (bg) + 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 = (bracket_id + 1) * 10; + uint32 q_min_level = backetEntry->minLevel; + uint32 q_max_level = backetEntry->maxLevel; GroupsQueueType::const_iterator itr; - for(itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].end(); ++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[bracket_id][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].end(); ++itr) + 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_min_level + 10, + 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_min_level + 10, + 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); } } @@ -800,6 +802,14 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BattleGroundBracketI sLog.outError("Battleground: Update: bg template not found for %u", bgTypeId); 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!) uint32 MinPlayersPerTeam = bg_template->GetMinPlayersPerTeam(); uint32 MaxPlayersPerTeam = bg_template->GetMaxPlayersPerTeam(); @@ -844,7 +854,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BattleGroundBracketI if (CheckPremadeMatch(bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam)) { //create new battleground - BattleGround * bg2 = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, bracket_id, 0, false); + BattleGround * bg2 = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, bracketEntry, 0, false); if (!bg2) { sLog.outError("BattleGroundQueue::Update - Cannot create battleground: %u", bgTypeId); @@ -870,7 +880,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BattleGroundBracketI || (bg_template->isArena() && CheckSkirmishForSameFaction(bracket_id, MinPlayersPerTeam)) ) { // we successfully created a pool - BattleGround * bg2 = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, bracket_id, arenaType, false); + BattleGround * bg2 = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, bracketEntry, arenaType, false); if (!bg2) { sLog.outError("BattleGroundQueue::Update - Cannot create battleground: %u", bgTypeId); @@ -984,8 +994,8 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BattleGroundBracketI //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()) { - BattleGround* arena = NULL; - if (!(arena = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, bracket_id, arenaType, true))) + BattleGround* arena = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, bracketEntry, arenaType, true); + if (!arena) { sLog.outError("BattlegroundQueue::Update couldn't create arena instance for rated arena match!"); return; @@ -1207,14 +1217,14 @@ void BattleGroundMgr::Update(uint32 diff) // it's time to force update 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"); - m_BattleGroundQueues[BATTLEGROUND_QUEUE_2v2].Update(BATTLEGROUND_AA, BG_BRACKET_ID_MAX_LEVEL_79, ARENA_TYPE_2v2, true, 0); - m_BattleGroundQueues[BATTLEGROUND_QUEUE_2v2].Update(BATTLEGROUND_AA, BG_BRACKET_ID_MAX_LEVEL_80, ARENA_TYPE_2v2, true, 0); - m_BattleGroundQueues[BATTLEGROUND_QUEUE_3v3].Update(BATTLEGROUND_AA, BG_BRACKET_ID_MAX_LEVEL_79, ARENA_TYPE_3v3, true, 0); - m_BattleGroundQueues[BATTLEGROUND_QUEUE_3v3].Update(BATTLEGROUND_AA, BG_BRACKET_ID_MAX_LEVEL_80, ARENA_TYPE_3v3, true, 0); - m_BattleGroundQueues[BATTLEGROUND_QUEUE_5v5].Update(BATTLEGROUND_AA, BG_BRACKET_ID_MAX_LEVEL_79, ARENA_TYPE_5v5, true, 0); - m_BattleGroundQueues[BATTLEGROUND_QUEUE_5v5].Update(BATTLEGROUND_AA, BG_BRACKET_ID_MAX_LEVEL_80, ARENA_TYPE_5v5, true, 0); + for(int qtype = BATTLEGROUND_QUEUE_2v2; qtype <= BATTLEGROUND_QUEUE_5v5; ++qtype) + for(int bracket = BG_BRACKET_ID_FIRST; bracket < MAX_BATTLEGROUND_BRACKETS; ++bracket) + m_BattleGroundQueues[qtype].Update( + BATTLEGROUND_AA, BattleGroundBracketId(bracket), + BattleGroundMgr::BGArenaType(BattleGroundQueueTypeId(qtype)), true, 0); + m_NextRatingDiscardUpdate = sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER); } else @@ -1494,7 +1504,7 @@ uint32 BattleGroundMgr::CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeI } // create a new battleground that will really be used to play -BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id, uint8 arenaType, bool isRated) +BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeId, PvPDifficultyEntry const* bracketEntry, uint8 arenaType, bool isRated) { // get the template BG BattleGround *bg_template = GetBattleGroundTemplate(bgTypeId); @@ -1568,14 +1578,14 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeI // generate a new instance id bg->SetInstanceID(sMapMgr.GenerateInstanceId()); // set instance id - bg->SetClientInstanceID(CreateClientVisibleInstanceId(bgTypeId, bracket_id)); + bg->SetClientInstanceID(CreateClientVisibleInstanceId(bgTypeId, bracketEntry->GetBracketId())); // reset the new bg (set status to status_wait_queue from status_none) bg->Reset(); // start the joining of the bg bg->SetStatus(STATUS_WAIT_JOIN); - bg->SetBracketId(bracket_id); + bg->SetBracket(bracketEntry); bg->SetArenaType(arenaType); bg->SetRated(isRated); @@ -1841,13 +1851,20 @@ void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint6 uint32 count = 0; *data << uint32(0); // number of bg instances - uint32 bracket_id = plr->GetBattleGroundBracketIdFromLevel(); - for(std::set::iterator itr = m_ClientBattleGroundIds[bgTypeId][bracket_id].begin(); itr != m_ClientBattleGroundIds[bgTypeId][bracket_id].end();++itr) + if(BattleGround* bgTemplate = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId)) { - *data << uint32(*itr); - ++count; + // expected bracket entry + if(PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bgTemplate->GetMapId(),plr->getLevel())) + { + BattleGroundBracketId bracketId = bracketEntry->GetBracketId(); + for(std::set::iterator itr = m_ClientBattleGroundIds[bgTypeId][bracketId].begin(); itr != m_ClientBattleGroundIds[bgTypeId][bracketId].end();++itr) + { + *data << uint32(*itr); + ++count; + } + data->put( count_pos , count); + } } - data->put( count_pos , count); } } diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h index 7317dedb3..73352f669 100644 --- a/src/game/BattleGroundMgr.h +++ b/src/game/BattleGroundMgr.h @@ -22,6 +22,7 @@ #include "Common.h" #include "Policies/Singleton.h" #include "Utilities/EventProcessor.h" +#include "DBCEnums.h" #include "BattleGround.h" #include "ace/Recursive_Thread_Mutex.h" @@ -81,7 +82,7 @@ class BattleGroundQueue bool CheckPremadeMatch(BattleGroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam); bool CheckNormalMatch(BattleGround* bg_template, BattleGroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers); bool CheckSkirmishForSameFaction(BattleGroundBracketId bracket_id, uint32 minPlayersPerTeam); - GroupQueueInfo * AddGroup(Player* leader, Group* group, BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id, 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 RemovePlayer(const uint64& guid, bool decreaseInvitedCount); bool IsPlayerInvited(const uint64& pl_guid, const uint32 bgInstanceGuid, const uint32 removeTime); bool GetPlayerGroupInfoData(const uint64& guid, GroupQueueInfo* ginfo); @@ -203,7 +204,7 @@ class BattleGroundMgr BattleGround* GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId); //there must be uint32 because MAX_BATTLEGROUND_TYPE_ID means unknown BattleGround* GetBattleGroundTemplate(BattleGroundTypeId bgTypeId); - BattleGround* CreateNewBattleGround(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_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); diff --git a/src/game/DBCEnums.h b/src/game/DBCEnums.h index 973881d46..8170f5627 100644 --- a/src/game/DBCEnums.h +++ b/src/game/DBCEnums.h @@ -32,6 +32,15 @@ // also see MAX_LEVEL and GT_MAX_LEVEL define #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 { AREATEAM_NONE = 0, diff --git a/src/game/DBCStores.cpp b/src/game/DBCStores.cpp index dd59368f0..ff4ce8811 100644 --- a/src/game/DBCStores.cpp +++ b/src/game/DBCStores.cpp @@ -105,6 +105,7 @@ MapDifficultyMap sMapDifficultyMap; DBCStorage sMovieStore(MovieEntryfmt); DBCStorage sQuestSortStore(QuestSortEntryfmt); +DBCStorage sPvPDifficultyStore(PvPDifficultyfmt); DBCStorage sRandomPropertiesPointsStore(RandomPropertiesPointsfmt); DBCStorage sScalingStatDistributionStore(ScalingStatDistributionfmt); @@ -206,7 +207,7 @@ void LoadDBCStores(const std::string& dataPath) { std::string dbcPath = dataPath+"dbc/"; - const uint32 DBCFilesCount = 81; + const uint32 DBCFilesCount = 82; barGoLink bar( DBCFilesCount ); @@ -305,6 +306,12 @@ void LoadDBCStores(const std::string& dataPath) 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,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,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatDistributionStore, dbcPath,"ScalingStatDistribution.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatValuesStore, dbcPath,"ScalingStatValues.dbc"); @@ -678,6 +685,30 @@ MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty) 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(uint32 cls) { return sTalentTabPages[cls]; diff --git a/src/game/DBCStores.h b/src/game/DBCStores.h index cb965b0f5..d4ff85467 100644 --- a/src/game/DBCStores.h +++ b/src/game/DBCStores.h @@ -60,6 +60,9 @@ MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty); uint32 const* /*[3]*/ GetTalentTabPages(uint32 cls); +PvPDifficultyEntry const* GetBattlegroundBracketByLevel(uint32 mapid, uint32 level); +PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattleGroundBracketId id); + extern DBCStorage sAchievementStore; extern DBCStorage sAchievementCriteriaStore; extern DBCStorage sAreaStore;// recommend access using functions @@ -117,6 +120,7 @@ extern DBCStorage sMapStore; extern MapDifficultyMap sMapDifficultyMap; extern DBCStorage sMovieStore; extern DBCStorage sQuestSortStore; +//extern DBCStorage sPvPDifficultyStore; -- use GetBattlegroundSlotByLevel for access extern DBCStorage sRandomPropertiesPointsStore; extern DBCStorage sScalingStatDistributionStore; extern DBCStorage sScalingStatValuesStore; diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h index 8ca275afe..12d384ae3 100644 --- a/src/game/DBCStructure.h +++ b/src/game/DBCStructure.h @@ -1141,6 +1141,19 @@ struct MovieEntry //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 { uint32 id; // 0 m_ID diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h index d2814a947..a71e9dee1 100644 --- a/src/game/DBCfmt.h +++ b/src/game/DBCfmt.h @@ -76,6 +76,7 @@ const char MapEntryfmt[]="nxixxssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx const char MapDifficultyEntryfmt[]="diixxxxxxxxxxxxxxxxxiix"; const char MovieEntryfmt[]="nxx"; const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx"; +const char PvPDifficultyfmt[]="diiiii"; const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii"; const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiii"; const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiiixiiii"; diff --git a/src/game/Group.cpp b/src/game/Group.cpp index 15d85a9f6..9f88a1fb3 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -1462,7 +1462,7 @@ void Group::UpdateLooterGuid( Creature* creature, bool ifneed ) 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 uint32 memberscount = GetMembersCount(); @@ -1477,7 +1477,10 @@ uint32 Group::CanJoinBattleGroundQueue(BattleGroundTypeId bgTypeId, BattleGround if(!reference) return BG_JOIN_ERR_OFFLINE_MEMBER; - BattleGroundBracketId bracket_id = reference->GetBattleGroundBracketIdFromLevel(); + PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bgOrTemplate->GetMapId(),reference->getLevel()); + if(!bracketEntry) + return BG_JOIN_ERR_OFFLINE_MEMBER; + uint32 arenaTeamId = reference->GetArenaTeamId(arenaSlot); uint32 team = reference->GetTeam(); @@ -1492,7 +1495,8 @@ uint32 Group::CanJoinBattleGroundQueue(BattleGroundTypeId bgTypeId, BattleGround if(member->GetTeam() != team) return BG_JOIN_ERR_MIXED_FACTION; // not in the same battleground level braket, don't let join - if(member->GetBattleGroundBracketIdFromLevel() != bracket_id) + PvPDifficultyEntry const* memberBracketEntry = GetBattlegroundBracketByLevel(bracketEntry->mapId,member->getLevel()); + if(memberBracketEntry != bracketEntry) return BG_JOIN_ERR_MIXED_LEVELS; // don't let join rated matches if the arena team id doesn't match if(isRated && member->GetArenaTeamId(arenaSlot) != arenaTeamId) @@ -1501,7 +1505,7 @@ uint32 Group::CanJoinBattleGroundQueue(BattleGroundTypeId bgTypeId, BattleGround if(member->InBattleGroundQueueForBattleGroundQueueType(bgQueueTypeId)) return BG_JOIN_ERR_GROUP_MEMBER_ALREADY_IN_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; // check if member can join any more battleground queues if(!member->HasFreeBattleGroundQueueId()) diff --git a/src/game/Group.h b/src/game/Group.h index da51b2b2c..dc22b184f 100644 --- a/src/game/Group.h +++ b/src/game/Group.h @@ -257,7 +257,7 @@ class MANGOS_DLL_SPEC Group void ConvertToRaid(); 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(Player *player, const uint8 &group); diff --git a/src/game/MapInstanced.cpp b/src/game/MapInstanced.cpp index 1afd2b2e9..e3a60e562 100644 --- a/src/game/MapInstanced.cpp +++ b/src/game/MapInstanced.cpp @@ -216,11 +216,10 @@ BattleGroundMap* MapInstanced::CreateBattleGroundMap(uint32 InstanceId, BattleGr sLog.outDebug("MapInstanced::CreateBattleGroundMap: instance:%d for map:%d and bgType:%d created.", InstanceId, GetId(), bg->GetTypeID()); - // 0-59 normal spawn 60-69 difficulty_1, 70-79 difficulty_2, 80 dufficulty_3 - uint8 spawnMode = (bg->GetBracketId() > BG_BRACKET_ID_MAX_LEVEL_59) ? (bg->GetBracketId() - BG_BRACKET_ID_MAX_LEVEL_59) : 0; - // some bgs don't have different spawnmodes, with this we can stay close to dbc-data - while (!GetMapDifficultyData(GetId(), Difficulty(spawnMode))) - spawnMode--; + PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),bg->GetMinLevel()); + + uint8 spawnMode = bracketEntry ? bracketEntry->difficulty : REGULAR_DIFFICULTY; + BattleGroundMap *map = new BattleGroundMap(GetId(), GetGridExpiry(), InstanceId, this, spawnMode); ASSERT(map->IsBattleGroundOrArena()); map->SetBG(bg); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 6d5f7de6d..7201caa4f 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -19173,24 +19173,17 @@ bool Player::GetBGAccessByLevel(BattleGroundTypeId bgTypeId) const if(!bg) 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 true; } -BattleGroundBracketId Player::GetBattleGroundBracketIdFromLevel() const -{ - // for ranges 0 - 19, 20 - 29, 30 - 39, 40 - 49, 50 - 59, 60 - 69, 70 - 79, 80 - uint32 bracket_id = ( getLevel() / 10) - 1; - if( bracket_id >= MAX_BATTLEGROUND_BRACKETS ) - { - sLog.outError("BattleGround: too high bracket_id %u for player %u (acc: %u) with level %u", bracket_id, GetGUIDLow(), GetSession()->GetAccountId(), getLevel()); - return BG_BRACKET_ID_LAST; - } - return BattleGroundBracketId(bracket_id); -} - float Player::GetReputationPriceDiscount( Creature const* pCreature ) const { FactionTemplateEntry const* vendor_faction = pCreature->getFactionTemplateEntry(); diff --git a/src/game/Player.h b/src/game/Player.h index d8734ce28..2bdb0c82a 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -2016,9 +2016,6 @@ class MANGOS_DLL_SPEC Player : public Unit BattleGroundTypeId GetBattleGroundTypeId() const { return m_bgData.bgTypeID; } BattleGround* GetBattleGround() const; - - BattleGroundBracketId GetBattleGroundBracketIdFromLevel() const; - bool InBattleGroundQueue() const { for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) -- 2.11.4.GIT