|
16 | 16 | * with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | */ |
18 | 18 |
|
| 19 | +#include "ArenaScore.h" |
19 | 20 | #include "ArenaTeam.h" |
20 | 21 | #include "ArenaTeamMgr.h" |
21 | 22 | #include "Battleground.h" |
22 | 23 | #include "BattlegroundMgr.h" |
| 24 | +#include "BattlegroundScore.h" |
23 | 25 | #include "Creature.h" |
24 | 26 | #include "CreatureTextMgr.h" |
25 | 27 | #include "Chat.h" |
@@ -165,12 +167,13 @@ Battleground::Battleground() |
165 | 167 | m_ArenaTeamIds[TEAM_ALLIANCE] = 0; |
166 | 168 | m_ArenaTeamIds[TEAM_HORDE] = 0; |
167 | 169 |
|
168 | | - m_ArenaTeamRatingChanges[TEAM_ALLIANCE] = 0; |
169 | | - m_ArenaTeamRatingChanges[TEAM_HORDE] = 0; |
170 | | - |
171 | 170 | m_ArenaTeamMMR[TEAM_ALLIANCE] = 0; |
172 | 171 | m_ArenaTeamMMR[TEAM_HORDE] = 0; |
173 | 172 |
|
| 173 | + // Iterate this way for consistency's sake - client expects it to be sent in this order |
| 174 | + for (int8 i = WINNER_ALLIANCE; i >= WINNER_HORDE; --i) |
| 175 | + _arenaTeamScores[i] = new ArenaTeamScore(); |
| 176 | + |
174 | 177 | m_BgRaids[TEAM_ALLIANCE] = NULL; |
175 | 178 | m_BgRaids[TEAM_HORDE] = NULL; |
176 | 179 |
|
@@ -222,6 +225,10 @@ Battleground::~Battleground() |
222 | 225 |
|
223 | 226 | for (BattlegroundScoreMap::const_iterator itr = PlayerScores.begin(); itr != PlayerScores.end(); ++itr) |
224 | 227 | delete itr->second; |
| 228 | + |
| 229 | + // Iterate this way for consistency's sake - client expects it to be sent in this order |
| 230 | + for (int8 i = WINNER_ALLIANCE; i >= WINNER_HORDE; --i) |
| 231 | + delete _arenaTeamScores[i]; |
225 | 232 | } |
226 | 233 |
|
227 | 234 | void Battleground::Update(uint32 diff) |
@@ -771,49 +778,50 @@ void Battleground::EndBattleground(uint32 winner) |
771 | 778 |
|
772 | 779 | if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) |
773 | 780 | { |
| 781 | + loserTeamRating = loserArenaTeam->GetRating(); |
| 782 | + loserMatchmakerRating = GetArenaMatchmakerRating(GetOtherTeam(winner)); |
| 783 | + winnerTeamRating = winnerArenaTeam->GetRating(); |
| 784 | + winnerMatchmakerRating = GetArenaMatchmakerRating(winner); |
| 785 | + |
774 | 786 | if (winner != WINNER_NONE) |
775 | 787 | { |
776 | | - loserTeamRating = loserArenaTeam->GetRating(); |
777 | | - loserMatchmakerRating = GetArenaMatchmakerRating(GetOtherTeam(winner)); |
778 | | - winnerTeamRating = winnerArenaTeam->GetRating(); |
779 | | - winnerMatchmakerRating = GetArenaMatchmakerRating(winner); |
780 | 788 | winnerMatchmakerChange = winnerArenaTeam->WonAgainst(winnerMatchmakerRating, loserMatchmakerRating, winnerChange); |
781 | 789 | loserMatchmakerChange = loserArenaTeam->LostAgainst(loserMatchmakerRating, winnerMatchmakerRating, loserChange); |
782 | 790 | TC_LOG_DEBUG("bg.arena", "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, |
783 | 791 | winnerMatchmakerChange, loserTeamRating, loserChange, loserMatchmakerRating, loserMatchmakerChange); |
784 | 792 | SetArenaMatchmakerRating(winner, winnerMatchmakerRating + winnerMatchmakerChange); |
785 | 793 | SetArenaMatchmakerRating(GetOtherTeam(winner), loserMatchmakerRating + loserMatchmakerChange); |
786 | | - SetArenaTeamRatingChangeForTeam(winner, winnerChange); |
787 | | - SetArenaTeamRatingChangeForTeam(GetOtherTeam(winner), loserChange); |
| 794 | + |
| 795 | + uint8 winnerId = GetWinner(); |
| 796 | + uint8 loserId = winnerId == WINNER_ALLIANCE ? WINNER_HORDE : winnerId; |
| 797 | + |
| 798 | + _arenaTeamScores[winnerId]->Assign(winnerChange, winnerMatchmakerRating + winnerMatchmakerChange, winnerArenaTeam->GetName()); |
| 799 | + _arenaTeamScores[loserId]->Assign(loserChange, loserMatchmakerRating + loserMatchmakerChange, loserArenaTeam->GetName()); |
| 800 | + |
788 | 801 | TC_LOG_DEBUG("bg.arena", "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); |
789 | 802 | if (sWorld->getBoolConfig(CONFIG_ARENA_LOG_EXTENDED_INFO)) |
790 | | - for (Battleground::BattlegroundScoreMap::const_iterator itr = GetPlayerScoresBegin(); itr != GetPlayerScoresEnd(); ++itr) |
791 | | - if (Player* player = ObjectAccessor::FindPlayer(itr->first)) |
| 803 | + for (auto const& score : PlayerScores) |
| 804 | + if (Player* player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(score.first, 0, HIGHGUID_PLAYER))) |
792 | 805 | { |
793 | | - TC_LOG_DEBUG("bg.arena", "Statistics match Type: %u for %s (GUID: " UI64FMTD ", Team: %d, IP: %s): %u damage, %u healing, %u killing blows", |
794 | | - m_ArenaType, player->GetName().c_str(), itr->first, player->GetArenaTeamId(m_ArenaType == 5 ? 2 : m_ArenaType == 3), |
795 | | - player->GetSession()->GetRemoteAddress().c_str(), itr->second->DamageDone, itr->second->HealingDone, |
796 | | - itr->second->KillingBlows); |
| 806 | + TC_LOG_DEBUG("bg.arena", "Statistics match Type: %u for %s (GUID: %u, Team: %d, IP: %s): %s", |
| 807 | + m_ArenaType, player->GetName().c_str(), score.first, player->GetArenaTeamId(m_ArenaType == 5 ? 2 : m_ArenaType == 3), |
| 808 | + player->GetSession()->GetRemoteAddress().c_str(), score.second->ToString().c_str()); |
797 | 809 | } |
798 | 810 | } |
799 | 811 | // Deduct 16 points from each teams arena-rating if there are no winners after 45+2 minutes |
800 | 812 | else |
801 | 813 | { |
802 | | - SetArenaTeamRatingChangeForTeam(ALLIANCE, ARENA_TIMELIMIT_POINTS_LOSS); |
803 | | - SetArenaTeamRatingChangeForTeam(HORDE, ARENA_TIMELIMIT_POINTS_LOSS); |
| 814 | + _arenaTeamScores[WINNER_ALLIANCE]->Assign(ARENA_TIMELIMIT_POINTS_LOSS, winnerMatchmakerRating + winnerMatchmakerChange, winnerArenaTeam->GetName()); |
| 815 | + _arenaTeamScores[WINNER_HORDE]->Assign(ARENA_TIMELIMIT_POINTS_LOSS, loserMatchmakerRating + loserMatchmakerChange, loserArenaTeam->GetName()); |
| 816 | + |
804 | 817 | winnerArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS); |
805 | 818 | loserArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS); |
806 | 819 | } |
807 | 820 | } |
808 | | - else |
809 | | - { |
810 | | - SetArenaTeamRatingChangeForTeam(ALLIANCE, 0); |
811 | | - SetArenaTeamRatingChangeForTeam(HORDE, 0); |
812 | | - } |
813 | 821 | } |
814 | 822 |
|
815 | 823 | WorldPacket pvpLogData; |
816 | | - sBattlegroundMgr->BuildPvpLogDataPacket(&pvpLogData, this); |
| 824 | + BuildPvPLogDataPacket(pvpLogData); |
817 | 825 |
|
818 | 826 | BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType()); |
819 | 827 |
|
@@ -958,7 +966,7 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac |
958 | 966 | participant = true; |
959 | 967 | } |
960 | 968 |
|
961 | | - BattlegroundScoreMap::iterator itr2 = PlayerScores.find(guid); |
| 969 | + BattlegroundScoreMap::iterator itr2 = PlayerScores.find(GUID_LOPART(guid)); |
962 | 970 | if (itr2 != PlayerScores.end()) |
963 | 971 | { |
964 | 972 | delete itr2->second; // delete player's score |
@@ -1349,47 +1357,48 @@ bool Battleground::HasFreeSlots() const |
1349 | 1357 | return GetPlayersSize() < GetMaxPlayers(); |
1350 | 1358 | } |
1351 | 1359 |
|
1352 | | -void Battleground::UpdatePlayerScore(Player* Source, uint32 type, uint32 value, bool doAddHonor) |
| 1360 | +void Battleground::BuildPvPLogDataPacket(WorldPacket& data) |
1353 | 1361 | { |
1354 | | - //this procedure is called from virtual function implemented in bg subclass |
1355 | | - BattlegroundScoreMap::const_iterator itr = PlayerScores.find(Source->GetGUID()); |
1356 | | - if (itr == PlayerScores.end()) // player not found... |
1357 | | - return; |
| 1362 | + uint8 type = (isArena() ? 1 : 0); |
| 1363 | + |
| 1364 | + data.Initialize(MSG_PVP_LOG_DATA, 1 + 1 + 4 + 40 * GetPlayerScoresSize()); |
| 1365 | + data << uint8(type); // type (battleground = 0 / arena = 1) |
1358 | 1366 |
|
1359 | | - switch (type) |
| 1367 | + if (type) // arena |
1360 | 1368 | { |
1361 | | - case SCORE_KILLING_BLOWS: // Killing blows |
1362 | | - itr->second->KillingBlows += value; |
1363 | | - break; |
1364 | | - case SCORE_DEATHS: // Deaths |
1365 | | - itr->second->Deaths += value; |
1366 | | - break; |
1367 | | - case SCORE_HONORABLE_KILLS: // Honorable kills |
1368 | | - itr->second->HonorableKills += value; |
1369 | | - break; |
1370 | | - case SCORE_BONUS_HONOR: // Honor bonus |
1371 | | - // do not add honor in arenas |
1372 | | - if (isBattleground()) |
1373 | | - { |
1374 | | - // reward honor instantly |
1375 | | - if (doAddHonor) |
1376 | | - Source->RewardHonor(NULL, 1, value); // RewardHonor calls UpdatePlayerScore with doAddHonor = false |
1377 | | - else |
1378 | | - itr->second->BonusHonor += value; |
1379 | | - } |
1380 | | - break; |
1381 | | - // used only in EY, but in MSG_PVP_LOG_DATA opcode |
1382 | | - case SCORE_DAMAGE_DONE: // Damage Done |
1383 | | - itr->second->DamageDone += value; |
1384 | | - break; |
1385 | | - case SCORE_HEALING_DONE: // Healing Done |
1386 | | - itr->second->HealingDone += value; |
1387 | | - break; |
1388 | | - default: |
1389 | | - TC_LOG_ERROR("bg.battleground", "Battleground::UpdatePlayerScore: unknown score type (%u) for BG (map: %u, instance id: %u)!", |
1390 | | - type, m_MapId, m_InstanceID); |
1391 | | - break; |
| 1369 | + // it seems this must be according to BG_WINNER_A/H and _NOT_ TEAM_A/H |
| 1370 | + for (int8 i = WINNER_ALLIANCE; i >= WINNER_HORDE; --i) |
| 1371 | + _arenaTeamScores[i]->BuildRatingInfoBlock(data); |
| 1372 | + |
| 1373 | + for (int8 i = WINNER_ALLIANCE; i >= WINNER_HORDE; --i) |
| 1374 | + _arenaTeamScores[i]->BuildTeamInfoBlock(data); |
1392 | 1375 | } |
| 1376 | + |
| 1377 | + if (GetStatus() == STATUS_WAIT_LEAVE) |
| 1378 | + { |
| 1379 | + data << uint8(1); // bg ended |
| 1380 | + data << uint8(GetWinner()); // who win |
| 1381 | + } |
| 1382 | + else |
| 1383 | + data << uint8(0); // bg not ended |
| 1384 | + |
| 1385 | + data << uint32(GetPlayerScoresSize()); |
| 1386 | + for (auto const& score : PlayerScores) |
| 1387 | + score.second->AppendToPacket(data); |
| 1388 | +} |
| 1389 | + |
| 1390 | +bool Battleground::UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor) |
| 1391 | +{ |
| 1392 | + BattlegroundScoreMap::const_iterator itr = PlayerScores.find(player->GetGUIDLow()); |
| 1393 | + if (itr == PlayerScores.end()) // player not found... |
| 1394 | + return false; |
| 1395 | + |
| 1396 | + itr->second->UpdateScore(type, value); |
| 1397 | + |
| 1398 | + if (type == SCORE_BONUS_HONOR && doAddHonor && isBattleground()) |
| 1399 | + player->RewardHonor(NULL, 1, value); // RewardHonor calls UpdatePlayerScore with doAddHonor = false |
| 1400 | + |
| 1401 | + return true; |
1393 | 1402 | } |
1394 | 1403 |
|
1395 | 1404 | void Battleground::AddPlayerToResurrectQueue(uint64 npc_guid, uint64 player_guid) |
@@ -1868,7 +1877,7 @@ void Battleground::PlayerAddedToBGCheckIfBGIsRunning(Player* player) |
1868 | 1877 |
|
1869 | 1878 | BlockMovement(player); |
1870 | 1879 |
|
1871 | | - sBattlegroundMgr->BuildPvpLogDataPacket(&data, this); |
| 1880 | + BuildPvPLogDataPacket(data); |
1872 | 1881 | player->SendDirectMessage(&data); |
1873 | 1882 |
|
1874 | 1883 | sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType(), player->GetBGTeam()); |
|
0 commit comments