Skip to content

Commit c28345e

Browse files
committed
Core/Battleground: refactored BattlegroundScore
(original code by Machiavelli)
1 parent df164bf commit c28345e

28 files changed

Lines changed: 545 additions & 454 deletions
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
3+
*
4+
* This program is free software; you can redistribute it and/or modify it
5+
* under the terms of the GNU General Public License as published by the
6+
* Free Software Foundation; either version 2 of the License, or (at your
7+
* option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12+
* more details.
13+
*
14+
* You should have received a copy of the GNU General Public License along
15+
* with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#ifndef TRINITY_ARENA_SCORE_H
19+
#define TRINITY_ARENA_SCORE_H
20+
21+
#include "BattlegroundScore.h"
22+
#include "SharedDefines.h"
23+
24+
struct ArenaScore : public BattlegroundScore
25+
{
26+
friend class BattlegroundBE;
27+
friend class BattlegroundDS;
28+
friend class BattlegroundNA;
29+
friend class BattlegroundRL;
30+
friend class BattlegroundRV;
31+
32+
protected:
33+
ArenaScore(uint64 playerGuid, uint32 team) : BattlegroundScore(playerGuid), TeamId(team == ALLIANCE ? 1 : 0) { }
34+
35+
void AppendToPacket(WorldPacket& data) final
36+
{
37+
data << uint64(PlayerGuid);
38+
39+
data << uint32(KillingBlows);
40+
data << uint8(TeamId);
41+
data << uint32(DamageDone);
42+
data << uint32(HealingDone);
43+
data << uint32(0); // Objectives Count
44+
}
45+
46+
// For Logging purpose
47+
std::string ToString() const override
48+
{
49+
std::ostringstream stream;
50+
stream << "Damage done: " << DamageDone << ", Healing done: " << HealingDone << ", Killing blows: " << KillingBlows;
51+
return stream.str();
52+
}
53+
54+
uint8 TeamId; // TEAM_ALLIANCE or TEAM_HORDE
55+
};
56+
57+
struct ArenaTeamScore
58+
{
59+
friend class Battleground;
60+
61+
protected:
62+
ArenaTeamScore() : RatingChange(0), MatchmakerRating(0) { }
63+
64+
virtual ~ArenaTeamScore() { }
65+
66+
void Assign(int32 ratingChange, uint32 matchMakerRating, std::string const& teamName)
67+
{
68+
RatingChange = ratingChange;
69+
MatchmakerRating = matchMakerRating;
70+
TeamName = teamName;
71+
}
72+
73+
void BuildRatingInfoBlock(WorldPacket& data)
74+
{
75+
uint32 ratingLost = std::abs(std::min(RatingChange, 0));
76+
uint32 ratingWon = std::max(RatingChange, 0);
77+
78+
data << uint32(ratingLost);
79+
data << uint32(ratingWon);
80+
data << uint32(MatchmakerRating);
81+
}
82+
83+
void BuildTeamInfoBlock(WorldPacket& data)
84+
{
85+
data << TeamName;
86+
}
87+
88+
int32 RatingChange;
89+
uint32 MatchmakerRating;
90+
std::string TeamName;
91+
};
92+
93+
#endif // TRINITY_ARENA_SCORE_H

src/server/game/Battlegrounds/ArenaTeam.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ class ArenaTeam
130130
uint8 GetSlot() const { return GetSlotByType(GetType()); }
131131
static uint8 GetSlotByType(uint32 type);
132132
uint64 GetCaptain() const { return CaptainGuid; }
133-
std::string const& GetName() const { return TeamName; }
133+
std::string const& GetName() const { return TeamName; }
134134
const ArenaTeamStats& GetStats() const { return Stats; }
135135

136136
uint32 GetRating() const { return Stats.Rating; }

src/server/game/Battlegrounds/Battleground.cpp

Lines changed: 71 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@
1616
* with this program. If not, see <http://www.gnu.org/licenses/>.
1717
*/
1818

19+
#include "ArenaScore.h"
1920
#include "ArenaTeam.h"
2021
#include "ArenaTeamMgr.h"
2122
#include "Battleground.h"
2223
#include "BattlegroundMgr.h"
24+
#include "BattlegroundScore.h"
2325
#include "Creature.h"
2426
#include "CreatureTextMgr.h"
2527
#include "Chat.h"
@@ -165,12 +167,13 @@ Battleground::Battleground()
165167
m_ArenaTeamIds[TEAM_ALLIANCE] = 0;
166168
m_ArenaTeamIds[TEAM_HORDE] = 0;
167169

168-
m_ArenaTeamRatingChanges[TEAM_ALLIANCE] = 0;
169-
m_ArenaTeamRatingChanges[TEAM_HORDE] = 0;
170-
171170
m_ArenaTeamMMR[TEAM_ALLIANCE] = 0;
172171
m_ArenaTeamMMR[TEAM_HORDE] = 0;
173172

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+
174177
m_BgRaids[TEAM_ALLIANCE] = NULL;
175178
m_BgRaids[TEAM_HORDE] = NULL;
176179

@@ -222,6 +225,10 @@ Battleground::~Battleground()
222225

223226
for (BattlegroundScoreMap::const_iterator itr = PlayerScores.begin(); itr != PlayerScores.end(); ++itr)
224227
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];
225232
}
226233

227234
void Battleground::Update(uint32 diff)
@@ -771,49 +778,50 @@ void Battleground::EndBattleground(uint32 winner)
771778

772779
if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam)
773780
{
781+
loserTeamRating = loserArenaTeam->GetRating();
782+
loserMatchmakerRating = GetArenaMatchmakerRating(GetOtherTeam(winner));
783+
winnerTeamRating = winnerArenaTeam->GetRating();
784+
winnerMatchmakerRating = GetArenaMatchmakerRating(winner);
785+
774786
if (winner != WINNER_NONE)
775787
{
776-
loserTeamRating = loserArenaTeam->GetRating();
777-
loserMatchmakerRating = GetArenaMatchmakerRating(GetOtherTeam(winner));
778-
winnerTeamRating = winnerArenaTeam->GetRating();
779-
winnerMatchmakerRating = GetArenaMatchmakerRating(winner);
780788
winnerMatchmakerChange = winnerArenaTeam->WonAgainst(winnerMatchmakerRating, loserMatchmakerRating, winnerChange);
781789
loserMatchmakerChange = loserArenaTeam->LostAgainst(loserMatchmakerRating, winnerMatchmakerRating, loserChange);
782790
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,
783791
winnerMatchmakerChange, loserTeamRating, loserChange, loserMatchmakerRating, loserMatchmakerChange);
784792
SetArenaMatchmakerRating(winner, winnerMatchmakerRating + winnerMatchmakerChange);
785793
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+
788801
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);
789802
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)))
792805
{
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());
797809
}
798810
}
799811
// Deduct 16 points from each teams arena-rating if there are no winners after 45+2 minutes
800812
else
801813
{
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+
804817
winnerArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS);
805818
loserArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS);
806819
}
807820
}
808-
else
809-
{
810-
SetArenaTeamRatingChangeForTeam(ALLIANCE, 0);
811-
SetArenaTeamRatingChangeForTeam(HORDE, 0);
812-
}
813821
}
814822

815823
WorldPacket pvpLogData;
816-
sBattlegroundMgr->BuildPvpLogDataPacket(&pvpLogData, this);
824+
BuildPvPLogDataPacket(pvpLogData);
817825

818826
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
819827

@@ -958,7 +966,7 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
958966
participant = true;
959967
}
960968

961-
BattlegroundScoreMap::iterator itr2 = PlayerScores.find(guid);
969+
BattlegroundScoreMap::iterator itr2 = PlayerScores.find(GUID_LOPART(guid));
962970
if (itr2 != PlayerScores.end())
963971
{
964972
delete itr2->second; // delete player's score
@@ -1349,47 +1357,48 @@ bool Battleground::HasFreeSlots() const
13491357
return GetPlayersSize() < GetMaxPlayers();
13501358
}
13511359

1352-
void Battleground::UpdatePlayerScore(Player* Source, uint32 type, uint32 value, bool doAddHonor)
1360+
void Battleground::BuildPvPLogDataPacket(WorldPacket& data)
13531361
{
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)
13581366

1359-
switch (type)
1367+
if (type) // arena
13601368
{
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);
13921375
}
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;
13931402
}
13941403

13951404
void Battleground::AddPlayerToResurrectQueue(uint64 npc_guid, uint64 player_guid)
@@ -1868,7 +1877,7 @@ void Battleground::PlayerAddedToBGCheckIfBGIsRunning(Player* player)
18681877

18691878
BlockMovement(player);
18701879

1871-
sBattlegroundMgr->BuildPvpLogDataPacket(&data, this);
1880+
BuildPvPLogDataPacket(data);
18721881
player->SendDirectMessage(&data);
18731882

18741883
sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType(), player->GetBGTeam());

0 commit comments

Comments
 (0)