Core/Battlegrounds: Minor optimization when checking if player left start zone

This commit is contained in:
Spp
2012-10-04 11:31:00 +02:00
parent ddf494d78b
commit 2a55f2d9e0
4 changed files with 171 additions and 151 deletions

View File

@@ -162,6 +162,7 @@ Battleground::Battleground()
m_MapId = 0;
m_Map = NULL;
m_StartMaxDist = 0.0f;
m_TeamStartLocX[TEAM_ALLIANCE] = 0;
m_TeamStartLocX[TEAM_HORDE] = 0;
@@ -178,8 +179,6 @@ Battleground::Battleground()
m_ArenaTeamIds[TEAM_ALLIANCE] = 0;
m_ArenaTeamIds[TEAM_HORDE] = 0;
m_StartMaxDist = 0.0f;
m_ArenaTeamRatingChanges[TEAM_ALLIANCE] = 0;
m_ArenaTeamRatingChanges[TEAM_HORDE] = 0;
@@ -261,7 +260,10 @@ void Battleground::Update(uint32 diff)
{
case STATUS_WAIT_JOIN:
if (GetPlayersSize())
{
_ProcessJoin(diff);
_CheckSafePositions(diff);
}
break;
case STATUS_IN_PROGRESS:
_ProcessOfflineQueue();
@@ -294,11 +296,37 @@ void Battleground::Update(uint32 diff)
// Update start time and reset stats timer
m_StartTime += diff;
m_ResetStatTimer += diff;
m_ValidStartPositionTimer += diff;
PostUpdateImpl(diff);
}
inline void Battleground::_CheckSafePositions(uint32 diff)
{
float maxDist = GetStartMaxDist();
if (!maxDist)
return;
m_ValidStartPositionTimer += diff;
if (m_ValidStartPositionTimer >= CHECK_PLAYER_POSITION_INVERVAL)
{
m_ValidStartPositionTimer = 0;
Position pos;
float x, y, z, o;
for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
if (Player* player = ObjectAccessor::FindPlayer(itr->first))
{
player->GetPosition(&pos);
GetTeamStartLoc(player->GetBGTeam(), x, y, z, o);
if (pos.GetExactDistSq(x, y, z) > maxDist)
{
sLog->outDebug(LOG_FILTER_BATTLEGROUND, "BATTLEGROUND: Sending %s back to start location (map: %u) (possible exploit)", player->GetName(), GetMapId());
player->TeleportTo(GetMapId(), x, y, z, o);
}
}
}
}
inline void Battleground::_ProcessOfflineQueue()
{
// remove offline players from bg after 5 minutes
@@ -315,7 +343,6 @@ inline void Battleground::_ProcessOfflineQueue()
}
}
}
}
inline void Battleground::_ProcessRessurect(uint32 diff)
@@ -530,33 +557,6 @@ inline void Battleground::_ProcessJoin(uint32 diff)
sWorld->SendWorldText(LANG_BG_STARTED_ANNOUNCE_WORLD, GetName(), GetMinLevel(), GetMaxLevel());
}
}
// Find if the player left our start zone; if so, teleport it back
if (m_ValidStartPositionTimer > 1000)
{
m_ValidStartPositionTimer = 0;
float maxDist = GetStartMaxDist();
if (maxDist > 0.0f)
{
for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
{
if (Player *plr = ObjectAccessor::FindPlayer(itr->first))
{
float x, y, z, o;
uint32 team = plr->GetBGTeam();
GetTeamStartLoc(team, x, y, z, o);
float dist = plr->GetDistance(x, y, z);
if (dist >= maxDist)
{
sLog->outError(LOG_FILTER_BATTLEGROUND, "BATTLEGROUND: Sending %s back to start location (map: %u) (possible exploit)", plr->GetName(), GetMapId());
plr->TeleportTo(GetMapId(), x, y, z, o);
}
}
}
}
}
}
inline void Battleground::_ProcessLeave(uint32 diff)
@@ -581,7 +581,7 @@ inline void Battleground::_ProcessLeave(uint32 diff)
}
}
inline Player* Battleground::_GetPlayer(uint64 guid, bool offlineRemove, const char* context) const
inline Player* Battleground::_GetPlayer(uint64 guid, bool offlineRemove, char const* context) const
{
Player* player = NULL;
if (!offlineRemove)
@@ -594,17 +594,17 @@ inline Player* Battleground::_GetPlayer(uint64 guid, bool offlineRemove, const c
return player;
}
inline Player* Battleground::_GetPlayer(BattlegroundPlayerMap::iterator itr, const char* context)
inline Player* Battleground::_GetPlayer(BattlegroundPlayerMap::iterator itr, char const* context)
{
return _GetPlayer(itr->first, itr->second.OfflineRemoveTime, context);
}
inline Player* Battleground::_GetPlayer(BattlegroundPlayerMap::const_iterator itr, const char* context) const
inline Player* Battleground::_GetPlayer(BattlegroundPlayerMap::const_iterator itr, char const* context) const
{
return _GetPlayer(itr->first, itr->second.OfflineRemoveTime, context);
}
inline Player* Battleground::_GetPlayerForTeam(uint32 teamId, BattlegroundPlayerMap::const_iterator itr, const char* context) const
inline Player* Battleground::_GetPlayerForTeam(uint32 teamId, BattlegroundPlayerMap::const_iterator itr, char const* context) const
{
Player* player = _GetPlayer(itr, context);
if (player)
@@ -674,7 +674,7 @@ void Battleground::RemoveAuraOnTeam(uint32 SpellID, uint32 TeamID)
player->RemoveAura(SpellID);
}
void Battleground::YellToAll(Creature* creature, const char* text, uint32 language)
void Battleground::YellToAll(Creature* creature, char const* text, uint32 language)
{
for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
if (Player* player = _GetPlayer(itr, "YellToAll"))
@@ -718,17 +718,18 @@ void Battleground::EndBattleground(uint32 winner)
{
RemoveFromBGFreeSlotQueue();
ArenaTeam* winner_arena_team = NULL;
ArenaTeam* loser_arena_team = NULL;
uint32 loser_team_rating = 0;
uint32 loser_matchmaker_rating = 0;
int32 loser_change = 0;
int32 loser_matchmaker_change = 0;
uint32 winner_team_rating = 0;
uint32 winner_matchmaker_rating = 0;
int32 winner_change = 0;
int32 winner_matchmaker_change = 0;
WorldPacket data;
ArenaTeam* winnerArenaTeam = NULL;
ArenaTeam* loserArenaTeam = NULL;
uint32 loserTeamRating = 0;
uint32 loserMatchmakerRating = 0;
int32 loserChange = 0;
int32 loserMatchmakerChange = 0;
uint32 winnerTeamRating = 0;
uint32 winnerMatchmakerRating = 0;
int32 winnerChange = 0;
int32 winnerMatchmakerChange = 0;
int32 winmsg_id = 0;
if (winner == ALLIANCE)
@@ -759,25 +760,26 @@ void Battleground::EndBattleground(uint32 winner)
// arena rating calculation
if (isArena() && isRated())
{
winner_arena_team = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(winner));
loser_arena_team = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(winner)));
if (winner_arena_team && loser_arena_team && winner_arena_team != loser_arena_team)
winnerArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(winner));
loserArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(winner)));
if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam)
{
if (winner != WINNER_NONE)
{
loser_team_rating = loser_arena_team->GetRating();
loser_matchmaker_rating = GetArenaMatchmakerRating(GetOtherTeam(winner));
winner_team_rating = winner_arena_team->GetRating();
winner_matchmaker_rating = GetArenaMatchmakerRating(winner);
winner_matchmaker_change = winner_arena_team->WonAgainst(winner_matchmaker_rating, loser_matchmaker_rating, winner_change);
loser_matchmaker_change = loser_arena_team->LostAgainst(loser_matchmaker_rating, winner_matchmaker_rating, loser_change);
sLog->outDebug(LOG_FILTER_ARENAS, "match Type: %u --- Winner: old rating: %u, rating gain: %d, old MMR: %u, MMR gain: %d --- Loser: old rating: %u, rating loss: %d, old MMR: %u, MMR loss: %d ---", m_ArenaType, winner_team_rating, winner_change, winner_matchmaker_rating,
winner_matchmaker_change, loser_team_rating, loser_change, loser_matchmaker_rating, loser_matchmaker_change);
SetArenaMatchmakerRating(winner, winner_matchmaker_rating + winner_matchmaker_change);
SetArenaMatchmakerRating(GetOtherTeam(winner), loser_matchmaker_rating + loser_matchmaker_change);
SetArenaTeamRatingChangeForTeam(winner, winner_change);
SetArenaTeamRatingChangeForTeam(GetOtherTeam(winner), loser_change);
sLog->outDebug(LOG_FILTER_ARENAS, "Arena match Type: %u for Team1Id: %u - Team2Id: %u ended. WinnerTeamId: %u. Winner rating: +%d, Loser rating: %d", m_ArenaType, m_ArenaTeamIds[TEAM_ALLIANCE], m_ArenaTeamIds[TEAM_HORDE], winner_arena_team->GetId(), winner_change, loser_change);
loserTeamRating = loserArenaTeam->GetRating();
loserMatchmakerRating = GetArenaMatchmakerRating(GetOtherTeam(winner));
winnerTeamRating = winnerArenaTeam->GetRating();
winnerMatchmakerRating = GetArenaMatchmakerRating(winner);
winnerMatchmakerChange = winnerArenaTeam->WonAgainst(winnerMatchmakerRating, loserMatchmakerRating, winnerChange);
loserMatchmakerChange = loserArenaTeam->LostAgainst(loserMatchmakerRating, winnerMatchmakerRating, loserChange);
sLog->outDebug(LOG_FILTER_ARENAS, "match Type: %u --- Winner: old rating: %u, rating gain: %d, old MMR: %u, MMR gain: %d --- Loser: old rating: %u, rating loss: %d, old MMR: %u, MMR loss: %d ---", m_ArenaType, winnerTeamRating, winnerChange, winnerMatchmakerRating,
winnerMatchmakerChange, loserTeamRating, loserChange, loserMatchmakerRating, loserMatchmakerChange);
SetArenaMatchmakerRating(winner, winnerMatchmakerRating + winnerMatchmakerChange);
SetArenaMatchmakerRating(GetOtherTeam(winner), loserMatchmakerRating + loserMatchmakerChange);
SetArenaTeamRatingChangeForTeam(winner, winnerChange);
SetArenaTeamRatingChangeForTeam(GetOtherTeam(winner), loserChange);
sLog->outDebug(LOG_FILTER_ARENAS, "Arena match Type: %u for Team1Id: %u - Team2Id: %u ended. WinnerTeamId: %u. Winner rating: +%d, Loser rating: %d", m_ArenaType, m_ArenaTeamIds[TEAM_ALLIANCE], m_ArenaTeamIds[TEAM_HORDE], winnerArenaTeam->GetId(), winnerChange, loserChange);
if (sWorld->getBoolConfig(CONFIG_ARENA_LOG_EXTENDED_INFO))
for (Battleground::BattlegroundScoreMap::const_iterator itr = GetPlayerScoresBegin(); itr != GetPlayerScoresEnd(); ++itr)
if (Player* player = ObjectAccessor::FindPlayer(itr->first))
@@ -788,8 +790,8 @@ void Battleground::EndBattleground(uint32 winner)
{
SetArenaTeamRatingChangeForTeam(ALLIANCE, ARENA_TIMELIMIT_POINTS_LOSS);
SetArenaTeamRatingChangeForTeam(HORDE, ARENA_TIMELIMIT_POINTS_LOSS);
winner_arena_team->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS);
loser_arena_team->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS);
winnerArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS);
loserArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS);
}
}
else
@@ -799,6 +801,11 @@ void Battleground::EndBattleground(uint32 winner)
}
}
WorldPacket pvpLogData;
sBattlegroundMgr->BuildPvpLogDataPacket(&pvpLogData, this);
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
uint8 aliveWinners = GetAlivePlayersCountByTeam(winner);
for (BattlegroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
@@ -807,12 +814,12 @@ void Battleground::EndBattleground(uint32 winner)
if (itr->second.OfflineRemoveTime)
{
//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() && winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam)
{
if (team == winner)
winner_arena_team->OfflineMemberLost(itr->first, loser_matchmaker_rating, winner_matchmaker_change);
winnerArenaTeam->OfflineMemberLost(itr->first, loserMatchmakerRating, winnerMatchmakerChange);
else
loser_arena_team->OfflineMemberLost(itr->first, winner_matchmaker_rating, loser_matchmaker_change);
loserArenaTeam->OfflineMemberLost(itr->first, winnerMatchmakerRating, loserMatchmakerChange);
}
continue;
}
@@ -841,23 +848,20 @@ void Battleground::EndBattleground(uint32 winner)
player->getHostileRefManager().deleteReferences();
}
//this line is obsolete - team is set ALWAYS
//if (!team) team = player->GetTeam();
// per player calculation
if (isArena() && isRated() && winner_arena_team && loser_arena_team && winner_arena_team != loser_arena_team)
if (isArena() && isRated() && winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam)
{
if (team == winner)
{
// update achievement BEFORE personal rating update
uint32 rating = player->GetArenaPersonalRating(winner_arena_team->GetSlot());
uint32 rating = player->GetArenaPersonalRating(winnerArenaTeam->GetSlot());
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1);
winner_arena_team->MemberWon(player, loser_matchmaker_rating, winner_matchmaker_change);
winnerArenaTeam->MemberWon(player, loserMatchmakerRating, winnerMatchmakerChange);
}
else
{
loser_arena_team->MemberLost(player, winner_matchmaker_rating, loser_matchmaker_change);
loserArenaTeam->MemberLost(player, winnerMatchmakerRating, loserMatchmakerChange);
// Arena lost => reset the win_rated_arena having the "no_lose" condition
player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE);
@@ -893,27 +897,23 @@ void Battleground::EndBattleground(uint32 winner)
BlockMovement(player);
sBattlegroundMgr->BuildPvpLogDataPacket(&data, this);
player->GetSession()->SendPacket(&data);
player->GetSession()->SendPacket(&pvpLogData);
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
WorldPacket data;
sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType());
player->GetSession()->SendPacket(&data);
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1);
}
if (isArena() && isRated() && winner_arena_team && loser_arena_team && winner_arena_team != loser_arena_team)
if (isArena() && isRated() && winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam)
{
// update arena points only after increasing the player's match count!
//obsolete: winner_arena_team->UpdateArenaPointsHelper();
//obsolete: loser_arena_team->UpdateArenaPointsHelper();
// save the stat changes
winner_arena_team->SaveToDB();
loser_arena_team->SaveToDB();
winnerArenaTeam->SaveToDB();
loserArenaTeam->SaveToDB();
// send updated arena team stats to players
// this way all arena team members will get notified, not only the ones who participated in this match
winner_arena_team->NotifyStatsChanged();
loser_arena_team->NotifyStatsChanged();
winnerArenaTeam->NotifyStatsChanged();
loserArenaTeam->NotifyStatsChanged();
}
if (winmsg_id)
@@ -923,7 +923,7 @@ void Battleground::EndBattleground(uint32 winner)
uint32 Battleground::GetBonusHonorFromKill(uint32 kills) const
{
//variable kills means how many honorable kills you scored (so we need kills * honor_for_one_kill)
uint32 maxLevel = std::min(GetMaxLevel(), 80U);
uint32 maxLevel = std::min<uint32>(GetMaxLevel(), 80U);
return Trinity::Honor::hk_honor_at_level(maxLevel, float(kills));
}
@@ -994,10 +994,10 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
if (isRated() && GetStatus() == STATUS_IN_PROGRESS)
{
//left a rated match while the encounter was in progress, consider as loser
ArenaTeam* winner_arena_team = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(team)));
ArenaTeam* loser_arena_team = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(team));
if (winner_arena_team && loser_arena_team && winner_arena_team != loser_arena_team)
loser_arena_team->MemberLost(player, GetArenaMatchmakerRating(GetOtherTeam(team)));
ArenaTeam* winnerArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(team)));
ArenaTeam* loserArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(team));
if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam)
loserArenaTeam->MemberLost(player, GetArenaMatchmakerRating(GetOtherTeam(team)));
}
}
if (SendPacket)
@@ -1167,6 +1167,7 @@ void Battleground::AddPlayer(Player* player)
player->CastSpell(player, SPELL_ARENA_PREPARATION, true);
player->ResetAllPowers();
}
WorldPacket teammate;
teammate.Initialize(SMSG_ARENA_OPPONENT_UPDATE, 8);
teammate << uint64(player->GetGUID());
@@ -1676,7 +1677,7 @@ void Battleground::SendWarningToAll(int32 entry, ...)
if (!entry)
return;
const char *format = sObjectMgr->GetTrinityStringForDBCLocale(entry);
char const *format = sObjectMgr->GetTrinityStringForDBCLocale(entry);
char str[1024];
va_list ap;
@@ -1718,7 +1719,7 @@ void Battleground::EndNow()
}
// To be removed
const char* Battleground::GetTrinityString(int32 entry)
char const* Battleground::GetTrinityString(int32 entry)
{
// FIXME: now we have different DBC locales and need localized message for each target client
return sObjectMgr->GetTrinityStringForDBCLocale(entry);

View File

@@ -104,6 +104,7 @@ enum BattlegroundSpells
enum BattlegroundTimeIntervals
{
CHECK_PLAYER_POSITION_INVERVAL = 1000, // ms
RESURRECTION_INTERVAL = 30000, // ms
//REMIND_INTERVAL = 10000, // ms
INVITATION_REMIND_TIME = 20000, // ms
@@ -319,11 +320,9 @@ class Battleground
return true;
}
virtual void Reset(); // resets all common properties for battlegrounds, must be implemented and called in BG subclass
virtual void StartingEventCloseDoors() {}
virtual void StartingEventOpenDoors() {}
virtual void ResetBGSubclass() // must be implemented in BG subclass
{
}
virtual void StartingEventCloseDoors() { }
virtual void StartingEventOpenDoors() { }
virtual void ResetBGSubclass() { } // must be implemented in BG subclass
virtual void DestroyGate(Player* /*player*/, GameObject* /*go*/) {}
@@ -438,6 +437,7 @@ class Battleground
Z = m_TeamStartLocZ[idx];
O = m_TeamStartLocO[idx];
}
void SetStartMaxDist(float startMaxDist) { m_StartMaxDist = startMaxDist; }
float GetStartMaxDist() const { return m_StartMaxDist; }
@@ -584,6 +584,7 @@ class Battleground
void _ProcessProgress(uint32 diff);
void _ProcessLeave(uint32 diff);
void _ProcessJoin(uint32 diff);
void _CheckSafePositions(uint32 diff);
// Scorekeeping
BattlegroundScoreMap PlayerScores; // Player scores
@@ -644,7 +645,7 @@ class Battleground
*
* @see Update(), PostUpdateImpl().
*/
virtual bool PreUpdateImpl(uint32 /* diff */) { return true; };
virtual bool PreUpdateImpl(uint32 /* diff */) { return true; }
/**
* @brief Post-update hook.
@@ -657,7 +658,7 @@ class Battleground
*
* @see Update(), PreUpdateImpl().
*/
virtual void PostUpdateImpl(uint32 /* diff */) { };
virtual void PostUpdateImpl(uint32 /* diff */) { }
// Player lists
std::vector<uint64> m_ResurrectQueue; // Player GUID
@@ -700,4 +701,3 @@ class Battleground
uint32 ScriptId;
};
#endif

View File

@@ -509,60 +509,30 @@ uint32 BattlegroundMgr::CreateClientVisibleInstanceId(BattlegroundTypeId bgTypeI
}
// create a new battleground that will really be used to play
Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId bgTypeId, PvPDifficultyEntry const* bracketEntry, uint8 arenaType, bool isRated)
Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId originalBgTypeId, PvPDifficultyEntry const* bracketEntry, uint8 arenaType, bool isRated)
{
BattlegroundTypeId bgTypeId = originalBgTypeId;
bool isRandom = false;
switch (originalBgTypeId)
{
case BATTLEGROUND_RB:
isRandom = true;
case BATTLEGROUND_AA:
bgTypeId = GetRandomBG(originalBgTypeId);
break;
default:
break;
}
// get the template BG
Battleground* bg_template = GetBattlegroundTemplate(bgTypeId);
BattlegroundSelectionWeightMap* selectionWeights = NULL;
if (!bg_template)
{
sLog->outError(LOG_FILTER_BATTLEGROUND, "Battleground: CreateNewBattleground - bg template not found for %u", bgTypeId);
return NULL;
}
bool isRandom = false;
if (bg_template->isArena())
selectionWeights = &m_ArenaSelectionWeights;
else if (bgTypeId == BATTLEGROUND_RB)
{
selectionWeights = &m_BGSelectionWeights;
isRandom = true;
}
if (selectionWeights)
{
if (selectionWeights->empty())
return NULL;
uint32 Weight = 0;
uint32 selectedWeight = 0;
bgTypeId = BATTLEGROUND_TYPE_NONE;
// Get sum of all weights
for (BattlegroundSelectionWeightMap::const_iterator it = selectionWeights->begin(); it != selectionWeights->end(); ++it)
Weight += it->second;
if (!Weight)
return NULL;
// Select a random value
selectedWeight = urand(0, Weight-1);
// Select the correct bg (if we have in DB A(10), B(20), C(10), D(15) --> [0---A---9|10---B---29|30---C---39|40---D---54])
Weight = 0;
for (BattlegroundSelectionWeightMap::const_iterator it = selectionWeights->begin(); it != selectionWeights->end(); ++it)
{
Weight += it->second;
if (selectedWeight < Weight)
{
bgTypeId = it->first;
break;
}
}
bg_template = GetBattlegroundTemplate(bgTypeId);
if (!bg_template)
{
sLog->outError(LOG_FILTER_BATTLEGROUND, "Battleground: CreateNewBattleground - bg template not found for %u", bgTypeId);
return NULL;
}
}
Battleground* bg = NULL;
// create a copy of the BG template
@@ -732,8 +702,8 @@ void BattlegroundMgr::CreateInitialBattlegrounds()
data.MaxPlayersPerTeam = fields[2].GetUInt16();
data.LevelMin = fields[3].GetUInt8();
data.LevelMax = fields[4].GetUInt8();
data.StartMaxDist = fields[9].GetFloat();
uint8 spawn = fields[9].GetUInt8();
data.StartMaxDist = float(spawn * spawn);
data.scriptId = sObjectMgr->GetScriptId(fields[11].GetCString());
data.BattlegroundName = bl->name[sWorld->GetDefaultDbcLocale()];
@@ -1136,6 +1106,56 @@ bool BattlegroundMgr::IsBGWeekend(BattlegroundTypeId bgTypeId)
return IsHolidayActive(BGTypeToWeekendHolidayId(bgTypeId));
}
BattlegroundTypeId BattlegroundMgr::GetRandomBG(BattlegroundTypeId bgTypeId)
{
uint32 weight = 0;
BattlegroundTypeId returnBgTypeId = BATTLEGROUND_TYPE_NONE;
BattlegroundSelectionWeightMap selectionWeights;
if (bgTypeId == BATTLEGROUND_AA)
{
for (BattlegroundSelectionWeightMap::const_iterator it = m_ArenaSelectionWeights.begin(); it != m_ArenaSelectionWeights.end(); ++it)
{
if (it->second)
{
weight += it->second;
selectionWeights[it->first] = it->second;
}
}
}
else if (bgTypeId == BATTLEGROUND_RB)
{
for (BattlegroundSelectionWeightMap::const_iterator it = m_BGSelectionWeights.begin(); it != m_BGSelectionWeights.end(); ++it)
{
if (it->second)
{
weight += it->second;
selectionWeights[it->first] = it->second;
}
}
}
if (weight)
{
uint32 selectedWeight = 0;
// Select a random value
selectedWeight = urand(0, weight - 1);
// Select the correct bg (if we have in DB A(10), B(20), C(10), D(15) --> [0---A---9|10---B---29|30---C---39|40---D---54])
weight = 0;
for (BattlegroundSelectionWeightMap::const_iterator it = selectionWeights.begin(); it != selectionWeights.end(); ++it)
{
weight += it->second;
if (selectedWeight < weight)
{
returnBgTypeId = it->first;
break;
}
}
}
return returnBgTypeId;
}
BGFreeSlotQueueContainer& BattlegroundMgr::GetBGFreeSlotQueueStore(BattlegroundTypeId bgTypeId)
{
return bgDataStore[bgTypeId].BGFreeSlotQueue;

View File

@@ -140,14 +140,12 @@ class BattlegroundMgr
static bool IsArenaType(BattlegroundTypeId bgTypeId);
BattlegroundTypeId GetRandomBG(BattlegroundTypeId id);
BattleMastersMap mBattleMastersMap;
typedef std::map<BattlegroundTypeId, BattlegroundData> BattlegroundDataContainer;
BattlegroundDataContainer bgDataStore;
typedef std::map<BattlegroundTypeId, uint8> BattlegroundSelectionWeightMap; // TypeId and its selectionWeight
BattlegroundQueue m_BattlegroundQueues[MAX_BATTLEGROUND_QUEUE_TYPES];
typedef std::map<BattlegroundTypeId, uint8> BattlegroundSelectionWeightMap; // TypeId and its selectionWeight
BattlegroundSelectionWeightMap m_ArenaSelectionWeights;
BattlegroundSelectionWeightMap m_BGSelectionWeights;
std::vector<uint64> m_QueueUpdateScheduler;
@@ -156,6 +154,7 @@ class BattlegroundMgr
uint32 m_AutoDistributionTimeChecker;
bool m_ArenaTesting;
bool m_Testing;
BattleMastersMap mBattleMastersMap;
};
#define sBattlegroundMgr ACE_Singleton<BattlegroundMgr, ACE_Null_Mutex>::instance()