Updates the arena rating system to use Matchmaker Rating.

The arena_team_stats sql in this commit sets all ratings to 0.
You start with 0 Team Rating and 1500 Matchmaker Rating.
Personal rating is moved to character_arena_stats, and will not reset when disbanding an arena team.
This new system is based on all the info I could get, but Blizzard didn't leak much info about the new system.
At least this system is really close to the official system.
Any issues found should be reported in an issue.
Huge thanks go to Aokromes for the intensive testing he has done with me.
Also thanks to Parzival for hearing me out and giving his ideas.
Fixes issue #3189

--HG--
branch : trunk
This commit is contained in:
Liberate
2010-08-27 18:18:26 +02:00
parent e2dc4c3a66
commit 9bd804dece
17 changed files with 256 additions and 128 deletions
+115 -39
View File
@@ -32,6 +32,14 @@ void ArenaTeamMember::ModifyPersonalRating(Player* plr, int32 mod, uint32 slot)
plr->SetArenaTeamInfoField(slot, ARENA_TEAM_PERSONAL_RATING, personal_rating);
}
void ArenaTeamMember::ModifyMatchmakerRating(int32 mod, uint32 slot)
{
if (int32(matchmaker_rating) + mod < 0)
matchmaker_rating = 0;
else
matchmaker_rating += mod;
}
ArenaTeam::ArenaTeam()
{
m_TeamId = 0;
@@ -102,6 +110,8 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid)
{
std::string plName;
uint8 plClass;
uint32 plPRating;
uint32 plMMRating;
// arena team is full (can't have more than type * 2 players!)
if (GetMembersSize() >= GetType() * 2)
@@ -137,6 +147,18 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid)
}
}
QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT personal_rating, matchmaker_rating FROM character_arena_stats WHERE guid='%u' AND slot='%u'", GUID_LOPART(PlayerGuid), GetSlot());
if (!result)
{
plPRating = 0;
plMMRating = 1500;
}
else
{
plPRating = (*result)[0].GetUInt32();
plMMRating = (*result)[1].GetUInt32();
}
// remove all player signs from another petitions
// this will be prevent attempt joining player to many arenateams and corrupt arena team data integrity
Player::RemovePetitionsAndSigns(PlayerGuid, GetType());
@@ -149,9 +171,10 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid)
newmember.games_week = 0;
newmember.wins_season = 0;
newmember.wins_week = 0;
newmember.personal_rating = 0;
newmember.personal_rating = plPRating;
newmember.matchmaker_rating = plMMRating;
if (sWorld.getIntConfig(CONFIG_ARENA_START_PERSONAL_RATING) > 0)
/* if (sWorld.getIntConfig(CONFIG_ARENA_START_PERSONAL_RATING) > 0)
newmember.personal_rating = sWorld.getIntConfig(CONFIG_ARENA_START_PERSONAL_RATING);
else
{
@@ -160,17 +183,16 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid)
else
if (GetRating() >= 1000)
newmember.personal_rating = 1000;
}
}*/
m_members.push_back(newmember);
CharacterDatabase.PExecute("INSERT INTO arena_team_member (arenateamid, guid, personal_rating) VALUES ('%u', '%u', '%u')", m_TeamId, GUID_LOPART(newmember.guid), newmember.personal_rating);
CharacterDatabase.PExecute("INSERT INTO arena_team_member (arenateamid, guid) VALUES ('%u', '%u')", m_TeamId, GUID_LOPART(newmember.guid));
if (pl)
{
pl->SetInArenaTeam(m_TeamId, GetSlot(), GetType());
pl->SetArenaTeamIdInvited(0);
pl->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_PERSONAL_RATING, newmember.personal_rating);
// hide promote/remove buttons
if (m_CaptainGuid != PlayerGuid)
@@ -233,15 +255,30 @@ bool ArenaTeam::LoadMembersFromDB(QueryResult_AutoPtr arenaTeamMembersResult)
//we loaded all members for this arena_team already, break cycle
break;
uint32 player_guid = fields[1].GetUInt32();
QueryResult_AutoPtr result = CharacterDatabase.PQuery(
"SELECT personal_rating, matchmaker_rating FROM character_arena_stats WHERE guid = '%u' AND slot = '%u'", player_guid, GetSlot());
uint32 personalrating = 0;
uint32 matchmakerrating = 1500;
if (result)
{
personalrating = (*result)[0].GetUInt32();
matchmakerrating = (*result)[1].GetUInt32();
}
ArenaTeamMember newmember;
newmember.guid = MAKE_NEW_GUID(fields[1].GetUInt32(), 0, HIGHGUID_PLAYER);
newmember.games_week = fields[2].GetUInt32();
newmember.wins_week = fields[3].GetUInt32();
newmember.games_season = fields[4].GetUInt32();
newmember.wins_season = fields[5].GetUInt32();
newmember.personal_rating = fields[6].GetUInt32();
newmember.name = fields[7].GetCppString();
newmember.Class = fields[8].GetUInt8();
newmember.guid = MAKE_NEW_GUID(player_guid, 0, HIGHGUID_PLAYER);
newmember.games_week = fields[2].GetUInt32();
newmember.wins_week = fields[3].GetUInt32();
newmember.games_season = fields[4].GetUInt32();
newmember.wins_season = fields[5].GetUInt32();
newmember.name = fields[6].GetCppString();
newmember.Class = fields[7].GetUInt8();
newmember.personal_rating = personalrating;
newmember.matchmaker_rating = matchmakerrating;
//check if member exists in characters table
if (newmember.name.empty())
@@ -563,6 +600,22 @@ uint32 ArenaTeam::GetPoints(uint32 MemberRating)
return (uint32) points;
}
uint32 ArenaTeam::GetAverageMMR(Group *group) const
{
if (!group) //should never happen
return 0;
uint32 matchmakerrating = 0;
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
if (group->IsMember(itr->guid))
matchmakerrating += itr->matchmaker_rating;
}
matchmakerrating /= GetType();
return matchmakerrating;
}
float ArenaTeam::GetChanceAgainst(uint32 own_rating, uint32 enemy_rating)
{
// returns the chance to win against a team with the given rating, used in the rating adjustment calculation
@@ -598,9 +651,13 @@ int32 ArenaTeam::WonAgainst(uint32 againstRating)
// called when the team has won
// 'chance' calculation - to beat the opponent
float chance = GetChanceAgainst(m_stats.rating, againstRating);
float K = (m_stats.rating < 1000) ? 48.0f : 32.0f;
// calculate the rating modification (ELO system with k=32 or k=48 if rating<1000)
int32 mod = (int32)floor(K* (1.0f - chance));
// calculate the rating modification
// simulation on how it works. Not much info on how it really works
int32 mod;
if (m_stats.rating < 1500)
mod = (int32)ceil(48.0f * (1.0f - chance) * (1.0f - chance));
else
mod = (int32)ceil(24.0f * (1.0f - chance));
// modify the team stats accordingly
FinishGame(mod);
@@ -611,7 +668,7 @@ int32 ArenaTeam::WonAgainst(uint32 againstRating)
return mod;
}
int32 ArenaTeam::LostAgainst(uint32 againstRating)
int32 ArenaTeam::LostAgainst(uint32 againstRating, bool winnerlowrating)
{
// called when the team has lost
//'chance' calculation - to loose to the opponent
@@ -621,9 +678,14 @@ int32 ArenaTeam::LostAgainst(uint32 againstRating)
FinishGame(0);
return 0;
}
// calculate the rating lost
// there is not much info on the formula, but this is a very good simulation
int32 mod;
if (winnerlowrating)
mod = (int32)floor(48.0f * chance * chance) * -1;
else
mod = (int32)floor(24.0f * (0.0f - chance));
float K = 32.0f;
int32 mod = (int32)ceil(K * (0.0f - chance));
// modify the team stats accordingly
FinishGame(mod);
@@ -631,7 +693,7 @@ int32 ArenaTeam::LostAgainst(uint32 againstRating)
return mod;
}
void ArenaTeam::MemberLost(Player * plr, uint32 againstRating)
void ArenaTeam::MemberLost(Player * plr, uint32 againstMatchmakerRating)
{
// called for each participant of a match after losing
for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
@@ -639,11 +701,15 @@ void ArenaTeam::MemberLost(Player * plr, uint32 againstRating)
if (itr->guid == plr->GetGUID())
{
// update personal rating
float chance = GetChanceAgainst(itr->personal_rating, againstRating);
float K = (itr->personal_rating < 1000) ? 48.0f : 32.0f;
// calculate the rating modification (ELO system with k=32 or k=48 if rating<1000)
int32 mod = (int32)ceil(K * (0.0f - chance));
float chance = GetChanceAgainst(itr->personal_rating, m_stats.rating);
// calculate the rating modification
int32 mod = (int32)floor(24.0f * (0.0f - chance));
itr->ModifyPersonalRating(plr, mod, GetSlot());
// update matchmaker rating
chance = GetChanceAgainst(itr->matchmaker_rating, againstMatchmakerRating);
// calculate the rating modification
mod = (int32)floor(24.0f * (0.0f - chance));
itr->ModifyMatchmakerRating(mod, GetSlot());
// update personal played stats
itr->games_week +=1;
itr->games_season +=1;
@@ -655,7 +721,7 @@ void ArenaTeam::MemberLost(Player * plr, uint32 againstRating)
}
}
void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstRating)
void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstMatchmakerRating)
{
// called for offline player after ending rated arena match!
for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
@@ -663,14 +729,15 @@ void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstRating)
if (itr->guid == guid)
{
// update personal rating
float chance = GetChanceAgainst(itr->personal_rating, againstRating);
float K = (itr->personal_rating < 1000) ? 48.0f : 32.0f;
// calculate the rating modification (ELO system with k=32 or k=48 if rating<1000)
int32 mod = (int32)ceil(K * (0.0f - chance));
if (int32(itr->personal_rating) + mod < 0)
itr->personal_rating = 0;
else
itr->personal_rating += mod;
float chance = GetChanceAgainst(itr->personal_rating, m_stats.rating);
// calculate the rating modification
int32 mod = (int32)ceil(24.0f * (0.0f - chance));
itr->ModifyPersonalRating(NULL, mod, GetSlot());
// update matchmaker rating
chance = GetChanceAgainst(itr->matchmaker_rating, againstMatchmakerRating);
// calculate the rating modification
mod = (int32)ceil(24.0f * (0.0f - chance));
itr->ModifyMatchmakerRating(mod, GetSlot());
// update personal played stats
itr->games_week +=1;
itr->games_season +=1;
@@ -679,19 +746,25 @@ void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstRating)
}
}
void ArenaTeam::MemberWon(Player * plr, uint32 againstRating)
void ArenaTeam::MemberWon(Player * plr, uint32 againstMatchmakerRating)
{
// called for each participant after winning a match
for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
if (itr->guid == plr->GetGUID())
{
uint32 matchmakerrating = itr->matchmaker_rating;
// update personal rating
float chance = GetChanceAgainst(itr->personal_rating, againstRating);
float K = (itr->personal_rating < 1000) ? 48.0f : 32.0f;
// calculate the rating modification (ELO system with k=32 or k=48 if rating<1000)
int32 mod = (int32)floor(K* (1.0f - chance));
float chance = GetChanceAgainst(itr->personal_rating, m_stats.rating);
// calculate the rating modification
int32 mod = (int32)ceil(24.0f * (1.0f - chance));
itr->ModifyPersonalRating(plr, mod, GetSlot());
// update matchmaker rating
chance = GetChanceAgainst(matchmakerrating, againstMatchmakerRating);
// calculate the rating modification
mod = (int32)ceil(24.0f * (1.0f - chance));
itr->ModifyMatchmakerRating(mod, GetSlot());
// update personal stats
itr->games_week +=1;
itr->games_season +=1;
@@ -741,7 +814,10 @@ void ArenaTeam::SaveToDB()
SQLTransaction trans = CharacterDatabase.BeginTransaction();
trans->PAppend("UPDATE arena_team_stats SET rating = '%u',games = '%u',played = '%u',rank = '%u',wins = '%u',wins2 = '%u' WHERE arenateamid = '%u'", m_stats.rating, m_stats.games_week, m_stats.games_season, m_stats.rank, m_stats.wins_week, m_stats.wins_season, GetId());
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
trans->PAppend("UPDATE arena_team_member SET played_week = '%u', wons_week = '%u', played_season = '%u', wons_season = '%u', personal_rating = '%u' WHERE arenateamid = '%u' AND guid = '%u'", itr->games_week, itr->wins_week, itr->games_season, itr->wins_season, itr->personal_rating, m_TeamId, GUID_LOPART(itr->guid));
{
trans->PAppend("UPDATE arena_team_member SET played_week = '%u', wons_week = '%u', played_season = '%u', wons_season = '%u' WHERE arenateamid = '%u' AND guid = '%u'", itr->games_week, itr->wins_week, itr->games_season, itr->wins_season, m_TeamId, GUID_LOPART(itr->guid));
trans->PAppend("REPLACE INTO character_arena_stats (guid,slot,personal_rating,matchmaker_rating) VALUES ('%u', '%u', '%u', '%u')", GUID_LOPART(itr->guid), GetSlot(), itr->personal_rating, itr->matchmaker_rating);
}
CharacterDatabase.CommitTransaction(trans);
}
+7 -4
View File
@@ -101,8 +101,10 @@ struct ArenaTeamMember
uint32 games_season;
uint32 wins_season;
uint32 personal_rating;
uint32 matchmaker_rating;
void ModifyPersonalRating(Player* plr, int32 mod, uint32 slot);
void ModifyMatchmakerRating(int32 mod, uint32 slot);
};
struct ArenaTeamStats
@@ -137,6 +139,7 @@ class ArenaTeam
const ArenaTeamStats& GetStats() const { return m_stats; }
void SetStats(uint32 stat_type, uint32 value);
uint32 GetRating() const { return m_stats.rating; }
uint32 GetAverageMMR(Group *group) const;
uint32 GetEmblemStyle() const { return m_EmblemStyle; }
uint32 GetEmblemColor() const { return m_EmblemColor; }
@@ -196,10 +199,10 @@ class ArenaTeam
uint32 GetPoints(uint32 MemberRating);
float GetChanceAgainst(uint32 own_rating, uint32 enemy_rating);
int32 WonAgainst(uint32 againstRating);
void MemberWon(Player * plr, uint32 againstRating);
int32 LostAgainst(uint32 againstRating);
void MemberLost(Player * plr, uint32 againstRating);
void OfflineMemberLost(uint64 guid, uint32 againstRating);
void MemberWon(Player * plr, uint32 againstMatchmakerRating);
int32 LostAgainst(uint32 againstRating, bool winnerlowrating);
void MemberLost(Player * plr, uint32 againstMatchmakerRating);
void OfflineMemberLost(uint64 guid, uint32 againstMatchmakerRating);
void UpdateArenaPointsHelper(std::map<uint32, uint32> & PlayerPoints);
+20 -13
View File
@@ -687,8 +687,10 @@ void Battleground::EndBattleground(uint32 winner)
ArenaTeam * winner_arena_team = NULL;
ArenaTeam * loser_arena_team = NULL;
uint32 loser_rating = 0;
uint32 winner_rating = 0;
uint32 loser_team_rating = 0;
uint32 loser_matchmaker_rating = 0;
uint32 winner_team_rating = 0;
uint32 winner_matchmaker_rating = 0;
WorldPacket data;
int32 winmsg_id = 0;
@@ -724,13 +726,18 @@ void Battleground::EndBattleground(uint32 winner)
loser_arena_team = sObjectMgr.GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(winner)));
if (winner_arena_team && loser_arena_team && winner_arena_team != loser_arena_team)
{
loser_rating = loser_arena_team->GetStats().rating;
winner_rating = winner_arena_team->GetStats().rating;
int32 winner_change = winner_arena_team->WonAgainst(loser_rating);
int32 loser_change = loser_arena_team->LostAgainst(winner_rating);
sLog.outDebug("--- Winner rating: %u, Loser rating: %u, Winner change: %u, Losser change: %u ---", winner_rating, loser_rating, winner_change, loser_change);
loser_team_rating = loser_arena_team->GetRating();
loser_matchmaker_rating = loser_arena_team->GetAverageMMR(GetBgRaid(GetOtherTeam(winner)));
winner_team_rating = winner_arena_team->GetRating();
winner_matchmaker_rating = winner_arena_team->GetAverageMMR(GetBgRaid(winner));
int32 winner_change = winner_arena_team->WonAgainst(loser_matchmaker_rating);
int32 loser_change = loser_arena_team->LostAgainst(winner_matchmaker_rating, winner_team_rating < 1500);
sLog.outDebug("--- Winner rating: %u, Loser rating: %u, Winner MMR: %u, Loser MMR: %u, Winner change: %u, Losser change: %u ---", winner_team_rating, loser_team_rating,
winner_matchmaker_rating, loser_matchmaker_rating, winner_change, loser_change);
SetArenaTeamRatingChangeForTeam(winner, winner_change);
SetArenaTeamRatingChangeForTeam(GetOtherTeam(winner), loser_change);
SetArenaMatchmakerRating(winner, winner_matchmaker_rating);
SetArenaMatchmakerRating(GetOtherTeam(winner), loser_matchmaker_rating);
sLog.outArena("Arena match Type: %u for Team1Id: %u - Team2Id: %u ended. WinnerTeamId: %u. RatingChange: %i.", m_ArenaType, m_ArenaTeamIds[BG_TEAM_ALLIANCE], m_ArenaTeamIds[BG_TEAM_HORDE], winner_arena_team->GetId(), winner_change);
}
else
@@ -750,9 +757,9 @@ void Battleground::EndBattleground(uint32 winner)
if (isArena() && isRated() && winner_arena_team && loser_arena_team && winner_arena_team != loser_arena_team)
{
if (team == winner)
winner_arena_team->OfflineMemberLost(itr->first, loser_rating);
winner_arena_team->OfflineMemberLost(itr->first, loser_matchmaker_rating);
else
loser_arena_team->OfflineMemberLost(itr->first, winner_rating);
loser_arena_team->OfflineMemberLost(itr->first, winner_matchmaker_rating);
}
continue;
}
@@ -792,11 +799,11 @@ void Battleground::EndBattleground(uint32 winner)
if (member)
plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, member->personal_rating);
winner_arena_team->MemberWon(plr,loser_rating);
winner_arena_team->MemberWon(plr,loser_matchmaker_rating);
}
else
{
loser_arena_team->MemberLost(plr,winner_rating);
loser_arena_team->MemberLost(plr, winner_matchmaker_rating);
// Arena lost => reset the win_rated_arena having the "no_loose" condition
plr->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, ACHIEVEMENT_CRITERIA_CONDITION_NO_LOOSE);
@@ -949,7 +956,7 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
ArenaTeam * winner_arena_team = sObjectMgr.GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(team)));
ArenaTeam * loser_arena_team = sObjectMgr.GetArenaTeamById(GetArenaTeamIdForTeam(team));
if (winner_arena_team && loser_arena_team && winner_arena_team != loser_arena_team)
loser_arena_team->MemberLost(plr,winner_arena_team->GetRating());
loser_arena_team->MemberLost(plr, winner_arena_team->GetAverageMMR(GetBgRaid(team)));
}
}
if (SendPacket)
@@ -971,7 +978,7 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
ArenaTeam * others_arena_team = sObjectMgr.GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(team)));
ArenaTeam * players_arena_team = sObjectMgr.GetArenaTeamById(GetArenaTeamIdForTeam(team));
if (others_arena_team && players_arena_team)
players_arena_team->OfflineMemberLost(guid, others_arena_team->GetRating());
players_arena_team->OfflineMemberLost(guid, others_arena_team->GetAverageMMR(GetBgRaid(GetOtherTeam(team))));
}
}
@@ -513,6 +513,8 @@ class Battleground
uint32 GetArenaTeamIdForTeam(uint32 Team) const { return m_ArenaTeamIds[GetTeamIndexByTeamId(Team)]; }
void SetArenaTeamRatingChangeForTeam(uint32 Team, int32 RatingChange) { m_ArenaTeamRatingChanges[GetTeamIndexByTeamId(Team)] = RatingChange; }
int32 GetArenaTeamRatingChangeForTeam(uint32 Team) const { return m_ArenaTeamRatingChanges[GetTeamIndexByTeamId(Team)]; }
void SetArenaMatchmakerRating(uint32 Team, uint32 MMR){ m_ArenaTeamMMR[GetTeamIndexByTeamId(Team)] = MMR; }
uint32 GetArenaMatchmakerRating(uint32 Team) { return m_ArenaTeamMMR[GetTeamIndexByTeamId(Team)]; }
void CheckArenaWinConditions();
void UpdateArenaWorldState();
@@ -649,6 +651,7 @@ class Battleground
uint32 m_ArenaTeamIds[BG_TEAMS_COUNT];
int32 m_ArenaTeamRatingChanges[BG_TEAMS_COUNT];
uint32 m_ArenaTeamMMR[BG_TEAMS_COUNT];
/* Limits */
uint32 m_LevelMin;
@@ -131,12 +131,12 @@ void BattlegroundMgr::Update(uint32 diff)
for (uint8 i = 0; i < scheduled.size(); i++)
{
uint32 arenaRating = scheduled[i] >> 32;
uint32 arenaMMRating = scheduled[i] >> 32;
uint8 arenaType = scheduled[i] >> 24 & 255;
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundQueueTypeId(scheduled[i] >> 16 & 255);
BattlegroundTypeId bgTypeId = BattlegroundTypeId((scheduled[i] >> 8) & 255);
BattlegroundBracketId bracket_id = BattlegroundBracketId(scheduled[i] & 255);
m_BattlegroundQueues[bgQueueTypeId].Update(bgTypeId, bracket_id, arenaType, arenaRating > 0, arenaRating);
m_BattlegroundQueues[bgQueueTypeId].Update(bgTypeId, bracket_id, arenaType, arenaMMRating > 0, arenaMMRating);
}
}
@@ -243,10 +243,11 @@ void BattlegroundMgr::BuildPvpLogDataPacket(WorldPacket *data, Battleground *bg)
{
uint32 pointsLost = bg->m_ArenaTeamRatingChanges[i] < 0 ? abs(bg->m_ArenaTeamRatingChanges[i]) : 0;
uint32 pointsGained = bg->m_ArenaTeamRatingChanges[i] > 0 ? bg->m_ArenaTeamRatingChanges[i] : 0;
uint32 MatchmakerRating = bg->m_ArenaTeamMMR[i];
*data << uint32(pointsLost); // Rating Lost
*data << uint32(pointsGained); // Rating gained
*data << uint32(0); // Matchmaking Value
*data << uint32(MatchmakerRating); // Matchmaking Value
sLog.outDebug("rating change: %d", bg->m_ArenaTeamRatingChanges[i]);
}
for (int i = 1; i >= 0; --i)
@@ -1058,11 +1059,11 @@ void BattlegroundMgr::SetHolidayWeekends(uint32 mask)
}
}
void BattlegroundMgr::ScheduleQueueUpdate(uint32 arenaRating, uint8 arenaType, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id)
void BattlegroundMgr::ScheduleQueueUpdate(uint32 arenaMatchmakerRating, uint8 arenaType, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id)
{
//This method must be atomic, TODO add mutex
//we will use only 1 number created of bgTypeId and bracket_id
uint64 schedule_id = ((uint64)arenaRating << 32) | (arenaType << 24) | (bgQueueTypeId << 16) | (bgTypeId << 8) | bracket_id;
uint64 schedule_id = ((uint64)arenaMatchmakerRating << 32) | (arenaType << 24) | (bgQueueTypeId << 16) | (bgTypeId << 8) | bracket_id;
bool found = false;
for (uint8 i = 0; i < m_QueueUpdateScheduler.size(); i++)
{
@@ -80,7 +80,7 @@ class BattlegroundMgr
BGFreeSlotQueueType BGFreeSlotQueue[MAX_BATTLEGROUND_TYPE_ID];
void ScheduleQueueUpdate(uint32 arenaRating, uint8 arenaType, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id);
void ScheduleQueueUpdate(uint32 arenaMatchmakerRating, uint8 arenaType, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id);
uint32 GetMaxRatingDifference() const;
uint32 GetRatingDiscardTimer() const;
uint32 GetPrematureFinishTime() const;
@@ -125,7 +125,7 @@ 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, PvPDifficultyEntry const* backetEntry, 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 MatchmakerRating, uint32 arenateamid)
{
BattlegroundBracketId bracketId = backetEntry->GetBracketId();
@@ -139,8 +139,10 @@ GroupQueueInfo * BattlegroundQueue::AddGroup(Player *leader, Group* grp, Battleg
ginfo->JoinTime = getMSTime();
ginfo->RemoveInviteTime = 0;
ginfo->Team = leader->GetTeam();
ginfo->ArenaTeamRating = arenaRating;
ginfo->ArenaTeamRating = ArenaRating;
ginfo->ArenaMatchmakerRating = MatchmakerRating;
ginfo->OpponentsTeamRating = 0;
ginfo->OpponentsMatchmakerRating = 0;
ginfo->Players.clear();
@@ -366,9 +368,9 @@ void BattlegroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
sLog.outDebug("UPDATING memberLost's personal arena rating for %u by opponents rating: %u", GUID_LOPART(guid), group->OpponentsTeamRating);
Player *plr = sObjectMgr.GetPlayer(guid);
if (plr)
at->MemberLost(plr, group->OpponentsTeamRating);
at->MemberLost(plr, group->OpponentsMatchmakerRating);
else
at->OfflineMemberLost(guid, group->OpponentsTeamRating);
at->OfflineMemberLost(guid, group->OpponentsMatchmakerRating);
at->SaveToDB();
}
}
@@ -886,17 +888,17 @@ void BattlegroundQueue::Update(BattlegroundTypeId bgTypeId, BattlegroundBracketI
if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty())
{
front1 = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].front();
arenaRating = front1->ArenaTeamRating;
arenaRating = front1->ArenaMatchmakerRating;
}
if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty())
{
front2 = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].front();
arenaRating = front2->ArenaTeamRating;
arenaRating = front2->ArenaMatchmakerRating;
}
if (front1 && front2)
{
if (front1->JoinTime < front2->JoinTime)
arenaRating = front1->ArenaTeamRating;
arenaRating = front1->ArenaMatchmakerRating;
}
else if (!front1 && !front2)
return; //queues are empty
@@ -925,7 +927,7 @@ void BattlegroundQueue::Update(BattlegroundTypeId bgTypeId, BattlegroundBracketI
{
// if group match conditions, then add it to pool
if (!(*itr_team[i])->IsInvitedToBGInstanceGUID
&& (((*itr_team[i])->ArenaTeamRating >= arenaMinRating && (*itr_team[i])->ArenaTeamRating <= arenaMaxRating)
&& (((*itr_team[i])->ArenaMatchmakerRating >= arenaMinRating && (*itr_team[i])->ArenaMatchmakerRating <= arenaMaxRating)
|| (*itr_team[i])->JoinTime < discardTime))
{
m_SelectionPools[i].AddGroup((*itr_team[i]), MaxPlayersPerTeam);
@@ -945,7 +947,7 @@ void BattlegroundQueue::Update(BattlegroundTypeId bgTypeId, BattlegroundBracketI
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
&& (((*itr_team[BG_TEAM_ALLIANCE])->ArenaTeamRating >= arenaMinRating && (*itr_team[BG_TEAM_ALLIANCE])->ArenaTeamRating <= arenaMaxRating)
&& (((*itr_team[BG_TEAM_ALLIANCE])->ArenaMatchmakerRating >= arenaMinRating && (*itr_team[BG_TEAM_ALLIANCE])->ArenaMatchmakerRating <= arenaMaxRating)
|| (*itr_team[BG_TEAM_ALLIANCE])->JoinTime < discardTime))
{
m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*itr_team[BG_TEAM_ALLIANCE]), MaxPlayersPerTeam);
@@ -961,7 +963,7 @@ void BattlegroundQueue::Update(BattlegroundTypeId bgTypeId, BattlegroundBracketI
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
&& (((*itr_team[BG_TEAM_HORDE])->ArenaTeamRating >= arenaMinRating && (*itr_team[BG_TEAM_HORDE])->ArenaTeamRating <= arenaMaxRating)
&& (((*itr_team[BG_TEAM_HORDE])->ArenaMatchmakerRating >= arenaMinRating && (*itr_team[BG_TEAM_HORDE])->ArenaMatchmakerRating <= arenaMaxRating)
|| (*itr_team[BG_TEAM_HORDE])->JoinTime < discardTime))
{
m_SelectionPools[BG_TEAM_HORDE].AddGroup((*itr_team[BG_TEAM_HORDE]), MaxPlayersPerTeam);
@@ -981,8 +983,10 @@ void BattlegroundQueue::Update(BattlegroundTypeId bgTypeId, BattlegroundBracketI
}
(*(itr_team[BG_TEAM_ALLIANCE]))->OpponentsTeamRating = (*(itr_team[BG_TEAM_HORDE]))->ArenaTeamRating;
(*(itr_team[BG_TEAM_ALLIANCE]))->OpponentsMatchmakerRating = (*(itr_team[BG_TEAM_HORDE]))->ArenaMatchmakerRating;
sLog.outDebug("setting oposite teamrating for team %u to %u", (*(itr_team[BG_TEAM_ALLIANCE]))->ArenaTeamId, (*(itr_team[BG_TEAM_ALLIANCE]))->OpponentsTeamRating);
(*(itr_team[BG_TEAM_HORDE]))->OpponentsTeamRating = (*(itr_team[BG_TEAM_ALLIANCE]))->ArenaTeamRating;
(*(itr_team[BG_TEAM_HORDE]))->OpponentsMatchmakerRating = (*(itr_team[BG_TEAM_ALLIANCE]))->ArenaMatchmakerRating;
sLog.outDebug("setting oposite teamrating for team %u to %u", (*(itr_team[BG_TEAM_HORDE]))->ArenaTeamId, (*(itr_team[BG_TEAM_HORDE]))->OpponentsTeamRating);
// now we must move team if we changed its faction to another faction queue, because then we will spam log by errors in Queue::RemovePlayer
if ((*(itr_team[BG_TEAM_ALLIANCE]))->Team != ALLIANCE)
@@ -50,7 +50,9 @@ struct GroupQueueInfo // stores informatio
uint32 RemoveInviteTime; // time when we will remove invite for players in group
uint32 IsInvitedToBGInstanceGUID; // was invited to certain BG
uint32 ArenaTeamRating; // if rated match, inited to the rating of the team
uint32 ArenaMatchmakerRating; // if rated match, inited to the rating of the team
uint32 OpponentsTeamRating; // for rated arena matches
uint32 OpponentsMatchmakerRating; // for rated arena matches
};
enum BattlegroundQueueGroupTypes
@@ -75,7 +77,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, PvPDifficultyEntry const* backetEntry, 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 MatchmakerRating, 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);