diff options
21 files changed, 522 insertions, 763 deletions
diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp new file mode 100644 index 00000000000..9f7aa653b9e --- /dev/null +++ b/src/server/game/Battlegrounds/Arena.cpp @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "Arena.h" +#include "ArenaScore.h" +#include "ArenaTeamMgr.h" +#include "Language.h" +#include "ObjectAccessor.h" +#include "Player.h" +#include "World.h" +#include "WorldSession.h" + +Arena::Arena() +{ + StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; + StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S; + StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S; + StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE; + + StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE; + StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS; + StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS; + StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN; +} + +void Arena::AddPlayer(Player* player) +{ + Battleground::AddPlayer(player); + PlayerScores[player->GetGUIDLow()] = new ArenaScore(player->GetGUID(), player->GetBGTeam()); + + if (player->GetBGTeam() == ALLIANCE) // gold + { + if (player->GetTeam() == HORDE) + player->CastSpell(player, SPELL_HORDE_GOLD_FLAG, true); + else + player->CastSpell(player, SPELL_ALLIANCE_GOLD_FLAG, true); + } + else // green + { + if (player->GetTeam() == HORDE) + player->CastSpell(player, SPELL_HORDE_GREEN_FLAG, true); + else + player->CastSpell(player, SPELL_ALLIANCE_GREEN_FLAG, true); + } + + UpdateArenaWorldState(); +} + +void Arena::RemovePlayer(Player* /*player*/, uint64 /*guid*/, uint32 /*team*/) +{ + if (GetStatus() == STATUS_WAIT_LEAVE) + return; + + UpdateArenaWorldState(); + CheckWinConditions(); +} + +void Arena::FillInitialWorldStates(WorldPacket& data) +{ + data << uint32(ARENA_WORLD_STATE_ALIVE_PLAYERS_GREEN) << uint32(GetAlivePlayersCountByTeam(HORDE)); + data << uint32(ARENA_WORLD_STATE_ALIVE_PLAYERS_GOLD) << uint32(GetAlivePlayersCountByTeam(ALLIANCE)); +} + +void Arena::UpdateArenaWorldState() +{ + UpdateWorldState(ARENA_WORLD_STATE_ALIVE_PLAYERS_GREEN, GetAlivePlayersCountByTeam(HORDE)); + UpdateWorldState(ARENA_WORLD_STATE_ALIVE_PLAYERS_GOLD, GetAlivePlayersCountByTeam(ALLIANCE)); +} + +void Arena::HandleKillPlayer(Player* player, Player* killer) +{ + if (GetStatus() != STATUS_IN_PROGRESS) + return; + + Battleground::HandleKillPlayer(player, killer); + + UpdateArenaWorldState(); + CheckWinConditions(); +} + +void Arena::RemovePlayerAtLeave(uint64 guid, bool transport, bool sendPacket) +{ + if (isRated() && GetStatus() == STATUS_IN_PROGRESS) + { + BattlegroundPlayerMap::const_iterator itr = m_Players.find(guid); + if (itr != m_Players.end()) // check if the player was a participant of the match, or only entered through gm command (appear) + { + // if the player was a match participant, calculate rating + uint32 team = itr->second.Team; + + ArenaTeam* winnerArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(team))); + ArenaTeam* loserArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(team)); + + // left a rated match while the encounter was in progress, consider as loser + if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) + { + if (Player* player = _GetPlayer(itr->first, itr->second.OfflineRemoveTime, "Arena::RemovePlayerAtLeave")) + loserArenaTeam->MemberLost(player, GetArenaMatchmakerRating(GetOtherTeam(team))); + else + loserArenaTeam->OfflineMemberLost(guid, GetArenaMatchmakerRating(GetOtherTeam(team))); + } + } + } + + // remove player + Battleground::RemovePlayerAtLeave(guid, transport, sendPacket); +} + +void Arena::CheckWinConditions() +{ + if (!GetAlivePlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE)) + EndBattleground(HORDE); + else if (GetPlayersCountByTeam(ALLIANCE) && !GetAlivePlayersCountByTeam(HORDE)) + EndBattleground(ALLIANCE); +} + +void Arena::EndBattleground(uint32 winner) +{ + // arena rating calculation + if (isRated()) + { + uint32 loserTeamRating = 0; + uint32 loserMatchmakerRating = 0; + int32 loserChange = 0; + int32 loserMatchmakerChange = 0; + uint32 winnerTeamRating = 0; + uint32 winnerMatchmakerRating = 0; + int32 winnerChange = 0; + int32 winnerMatchmakerChange = 0; + + ArenaTeam* winnerArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(winner)); + ArenaTeam* loserArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(winner))); + + if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) + { + loserTeamRating = loserArenaTeam->GetRating(); + loserMatchmakerRating = GetArenaMatchmakerRating(GetOtherTeam(winner)); + winnerTeamRating = winnerArenaTeam->GetRating(); + winnerMatchmakerRating = GetArenaMatchmakerRating(winner); + + if (winner != 0) + { + winnerMatchmakerChange = winnerArenaTeam->WonAgainst(winnerMatchmakerRating, loserMatchmakerRating, winnerChange); + loserMatchmakerChange = loserArenaTeam->LostAgainst(loserMatchmakerRating, winnerMatchmakerRating, loserChange); + + 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 ---", + GetArenaType(), winnerTeamRating, winnerChange, winnerMatchmakerRating, winnerMatchmakerChange, + loserTeamRating, loserChange, loserMatchmakerRating, loserMatchmakerChange); + + SetArenaMatchmakerRating(winner, winnerMatchmakerRating + winnerMatchmakerChange); + SetArenaMatchmakerRating(GetOtherTeam(winner), loserMatchmakerRating + loserMatchmakerChange); + + // bg team that the client expects is different to TeamId + // alliance 1, horde 0 + uint8 winnerTeam = winner == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE; + uint8 loserTeam = winner == ALLIANCE ? BG_TEAM_HORDE : BG_TEAM_ALLIANCE; + + _arenaTeamScores[winnerTeam].Assign(winnerChange, winnerMatchmakerRating, winnerArenaTeam->GetName()); + _arenaTeamScores[loserTeam].Assign(loserChange, loserMatchmakerRating, loserArenaTeam->GetName()); + + TC_LOG_DEBUG("bg.arena", "Arena match Type: %u for Team1Id: %u - Team2Id: %u ended. WinnerTeamId: %u. Winner rating: +%d, Loser rating: %d", + GetArenaType(), GetArenaTeamIdByIndex(TEAM_ALLIANCE), GetArenaTeamIdByIndex(TEAM_HORDE), winnerArenaTeam->GetId(), winnerChange, loserChange); + + if (sWorld->getBoolConfig(CONFIG_ARENA_LOG_EXTENDED_INFO)) + for (auto const& score : PlayerScores) + if (Player* player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(score.first, 0, HIGHGUID_PLAYER))) + { + TC_LOG_DEBUG("bg.arena", "Statistics match Type: %u for %s (GUID: %u, Team: %d, IP: %s): %s", + GetArenaType(), player->GetName().c_str(), score.first, player->GetArenaTeamId(GetArenaType() == 5 ? 2 : GetArenaType() == 3), + player->GetSession()->GetRemoteAddress().c_str(), score.second->ToString().c_str()); + } + } + // Deduct 16 points from each teams arena-rating if there are no winners after 45+2 minutes + else + { + _arenaTeamScores[BG_TEAM_ALLIANCE].Assign(ARENA_TIMELIMIT_POINTS_LOSS, winnerMatchmakerRating, winnerArenaTeam->GetName()); + _arenaTeamScores[BG_TEAM_HORDE].Assign(ARENA_TIMELIMIT_POINTS_LOSS, loserMatchmakerRating, loserArenaTeam->GetName()); + + winnerArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS); + loserArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS); + } + + uint8 aliveWinners = GetAlivePlayersCountByTeam(winner); + + for (auto const& i : GetPlayers()) + { + uint32 team = i.second.Team; + + if (i.second.OfflineRemoveTime) + { + // if rated arena match - make member lost! + if (team == winner) + winnerArenaTeam->OfflineMemberLost(i.first, loserMatchmakerRating, winnerMatchmakerChange); + else + loserArenaTeam->OfflineMemberLost(i.first, winnerMatchmakerRating, loserMatchmakerChange); + continue; + } + + Player* player = _GetPlayer(i.first, i.second.OfflineRemoveTime, "Arena::EndBattleground"); + if (!player) + continue; + + // per player calculation + if (team == winner) + { + // update achievement BEFORE personal rating update + uint32 rating = player->GetArenaPersonalRating(winnerArenaTeam->GetSlot()); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA, GetMapId()); + + // Last standing - Rated 5v5 arena & be solely alive player + if (GetArenaType() == ARENA_TYPE_5v5 && aliveWinners == 1 && player->IsAlive()) + player->CastSpell(player, SPELL_LAST_MAN_STANDING, true); + + winnerArenaTeam->MemberWon(player, loserMatchmakerRating, winnerMatchmakerChange); + } + else + { + 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); + } + } + + // save the stat changes + 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 + winnerArenaTeam->NotifyStatsChanged(); + loserArenaTeam->NotifyStatsChanged(); + } + } + + // end battleground + Battleground::EndBattleground(winner); +}
\ No newline at end of file diff --git a/src/server/game/Battlegrounds/Arena.h b/src/server/game/Battlegrounds/Arena.h new file mode 100644 index 00000000000..8aea92d496d --- /dev/null +++ b/src/server/game/Battlegrounds/Arena.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TRINITY_ARENA_H +#define TRINITY_ARENA_H + +#include "Battleground.h" + +enum ArenaSpellIds +{ + SPELL_ALLIANCE_GOLD_FLAG = 32724, + SPELL_ALLIANCE_GREEN_FLAG = 32725, + SPELL_HORDE_GOLD_FLAG = 35774, + SPELL_HORDE_GREEN_FLAG = 35775, + + SPELL_LAST_MAN_STANDING = 26549 // Achievement Credit +}; + +enum ArenaWorldStates +{ + ARENA_WORLD_STATE_ALIVE_PLAYERS_GREEN = 3600, + ARENA_WORLD_STATE_ALIVE_PLAYERS_GOLD = 3601 +}; + +class Arena : public Battleground +{ + protected: + Arena(); + + void AddPlayer(Player* player) override; + void RemovePlayer(Player* /*player*/, uint64 /*guid*/, uint32 /*team*/) override; + + void FillInitialWorldStates(WorldPacket& data) override; + void UpdateArenaWorldState(); + + void HandleKillPlayer(Player* player, Player* killer) override; + + private: + void RemovePlayerAtLeave(uint64 guid, bool transport, bool sendPacket) override; + void CheckWinConditions() override; + void EndBattleground(uint32 winner) override; +}; + +#endif // TRINITY_ARENA_H diff --git a/src/server/game/Battlegrounds/ArenaScore.h b/src/server/game/Battlegrounds/ArenaScore.h index fdeb13adc3d..638275b1833 100644 --- a/src/server/game/Battlegrounds/ArenaScore.h +++ b/src/server/game/Battlegrounds/ArenaScore.h @@ -23,14 +23,10 @@ struct ArenaScore : public BattlegroundScore { - friend class BattlegroundBE; - friend class BattlegroundDS; - friend class BattlegroundNA; - friend class BattlegroundRL; - friend class BattlegroundRV; + friend class Arena; protected: - ArenaScore(uint64 playerGuid, uint32 team) : BattlegroundScore(playerGuid), TeamId(team == ALLIANCE ? 1 : 0) { } + ArenaScore(uint64 playerGuid, uint32 team) : BattlegroundScore(playerGuid), TeamId(team == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE) { } void AppendToPacket(WorldPacket& data) final { @@ -57,7 +53,52 @@ struct ArenaScore : public BattlegroundScore return stream.str(); } - uint8 TeamId; // bgTeamId + uint8 TeamId; // BattlegroundTeamId +}; + +struct ArenaTeamScore +{ + friend class Arena; + friend class Battleground; + + protected: + ArenaTeamScore() : RatingChange(0), MatchmakerRating(0) { } + + virtual ~ArenaTeamScore() { } + + void Reset() + { + RatingChange = 0; + MatchmakerRating = 0; + TeamName.clear(); + } + + void Assign(int32 ratingChange, uint32 matchMakerRating, std::string const& teamName) + { + RatingChange = ratingChange; + MatchmakerRating = matchMakerRating; + TeamName = teamName; + } + + void BuildRatingInfoBlock(WorldPacket& data) + { + uint32 ratingLost = std::abs(std::min(RatingChange, 0)); + uint32 ratingWon = std::max(RatingChange, 0); + + // should be old rating, new rating, and client will calculate rating change itself + data << uint32(ratingLost); + data << uint32(ratingWon); + data << uint32(MatchmakerRating); + } + + void BuildTeamInfoBlock(WorldPacket& data) + { + data << TeamName; + } + + int32 RatingChange; + uint32 MatchmakerRating; + std::string TeamName; }; #endif // TRINITY_ARENA_SCORE_H diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index a0d35d4c742..8aa210d99a3 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -17,8 +17,6 @@ */ #include "ArenaScore.h" -#include "ArenaTeam.h" -#include "ArenaTeamMgr.h" #include "Battleground.h" #include "BattlegroundMgr.h" #include "BattlegroundScore.h" @@ -36,7 +34,6 @@ #include "SpellAuraEffects.h" #include "SpellAuras.h" #include "Util.h" -#include "World.h" #include "WorldPacket.h" namespace Trinity @@ -249,8 +246,7 @@ void Battleground::Update(uint32 diff) { if (GetStartTime() >= 47 * MINUTE*IN_MILLISECONDS) { - UpdateArenaWorldState(); - CheckArenaAfterTimerConditions(); + EndBattleground(0); return; } } @@ -523,7 +519,7 @@ inline void Battleground::_ProcessJoin(uint32 diff) } } - CheckArenaWinConditions(); + CheckWinConditions(); } else { @@ -713,18 +709,6 @@ void Battleground::EndBattleground(uint32 winner) { RemoveFromBGFreeSlotQueue(); - 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) @@ -733,7 +717,7 @@ void Battleground::EndBattleground(uint32 winner) PlaySoundToAll(SOUND_ALLIANCE_WINS); // alliance wins sound - SetWinner(WINNER_ALLIANCE); + SetWinner(BG_TEAM_ALLIANCE); } else if (winner == HORDE) { @@ -741,7 +725,7 @@ void Battleground::EndBattleground(uint32 winner) PlaySoundToAll(SOUND_HORDE_WINS); // horde wins sound - SetWinner(WINNER_HORDE); + SetWinner(BG_TEAM_HORDE); } else { @@ -752,58 +736,6 @@ void Battleground::EndBattleground(uint32 winner) //we must set it this way, because end time is sent in packet! m_EndTime = TIME_TO_AUTOREMOVE; - // arena rating calculation - if (isArena() && isRated()) - { - winnerArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(winner)); - loserArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(winner))); - - if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) - { - loserTeamRating = loserArenaTeam->GetRating(); - loserMatchmakerRating = GetArenaMatchmakerRating(GetOtherTeam(winner)); - winnerTeamRating = winnerArenaTeam->GetRating(); - winnerMatchmakerRating = GetArenaMatchmakerRating(winner); - - if (winner != WINNER_NONE) - { - winnerMatchmakerChange = winnerArenaTeam->WonAgainst(winnerMatchmakerRating, loserMatchmakerRating, winnerChange); - loserMatchmakerChange = loserArenaTeam->LostAgainst(loserMatchmakerRating, winnerMatchmakerRating, loserChange); - 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, - winnerMatchmakerChange, loserTeamRating, loserChange, loserMatchmakerRating, loserMatchmakerChange); - SetArenaMatchmakerRating(winner, winnerMatchmakerRating + winnerMatchmakerChange); - SetArenaMatchmakerRating(GetOtherTeam(winner), loserMatchmakerRating + loserMatchmakerChange); - - // bg team that the client expects is different to TeamId - // alliance 1, horde 0 - uint8 winnerTeam = winner == ALLIANCE ? WINNER_ALLIANCE : WINNER_HORDE; - uint8 loserTeam = winner == ALLIANCE ? WINNER_HORDE : WINNER_ALLIANCE; - - _arenaTeamScores[winnerTeam].Assign(winnerChange, winnerMatchmakerRating, winnerArenaTeam->GetName()); - _arenaTeamScores[loserTeam].Assign(loserChange, loserMatchmakerRating, loserArenaTeam->GetName()); - - 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); - if (sWorld->getBoolConfig(CONFIG_ARENA_LOG_EXTENDED_INFO)) - for (auto const& score : PlayerScores) - if (Player* player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(score.first, 0, HIGHGUID_PLAYER))) - { - TC_LOG_DEBUG("bg.arena", "Statistics match Type: %u for %s (GUID: %u, Team: %d, IP: %s): %s", - m_ArenaType, player->GetName().c_str(), score.first, player->GetArenaTeamId(m_ArenaType == 5 ? 2 : m_ArenaType == 3), - player->GetSession()->GetRemoteAddress().c_str(), score.second->ToString().c_str()); - } - } - // Deduct 16 points from each teams arena-rating if there are no winners after 45+2 minutes - else - { - _arenaTeamScores[WINNER_ALLIANCE].Assign(ARENA_TIMELIMIT_POINTS_LOSS, winnerMatchmakerRating, winnerArenaTeam->GetName()); - _arenaTeamScores[WINNER_HORDE].Assign(ARENA_TIMELIMIT_POINTS_LOSS, loserMatchmakerRating, loserArenaTeam->GetName()); - - winnerArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS); - loserArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS); - } - } - } - WorldPacket pvpLogData; BuildPvPLogDataPacket(pvpLogData); @@ -814,19 +746,6 @@ void Battleground::EndBattleground(uint32 winner) { uint32 team = itr->second.Team; - if (itr->second.OfflineRemoveTime) - { - //if rated arena match - make member lost! - if (isArena() && isRated() && winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) - { - if (team == winner) - winnerArenaTeam->OfflineMemberLost(itr->first, loserMatchmakerRating, winnerMatchmakerChange); - else - loserArenaTeam->OfflineMemberLost(itr->first, winnerMatchmakerRating, loserMatchmakerChange); - } - continue; - } - Player* player = _GetPlayer(itr, "EndBattleground"); if (!player) continue; @@ -835,10 +754,6 @@ void Battleground::EndBattleground(uint32 winner) if (player->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) player->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT); - // Last standing - Rated 5v5 arena & be solely alive player - if (team == winner && isArena() && isRated() && GetArenaType() == ARENA_TYPE_5v5 && aliveWinners == 1 && player->IsAlive()) - player->CastSpell(player, SPELL_THE_LAST_STANDING, true); - if (!player->IsAlive()) { player->ResurrectPlayer(1.0f); @@ -851,27 +766,6 @@ void Battleground::EndBattleground(uint32 winner) player->getHostileRefManager().deleteReferences(); } - // per player calculation - if (isArena() && isRated() && winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) - { - if (team == winner) - { - // update achievement BEFORE personal rating update - uint32 rating = player->GetArenaPersonalRating(winnerArenaTeam->GetSlot()); - player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1); - player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA, GetMapId()); - - winnerArenaTeam->MemberWon(player, loserMatchmakerRating, winnerMatchmakerChange); - } - else - { - 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); - } - } - uint32 winner_kills = player->GetRandomWinner() ? sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_HONOR_LAST) : sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_HONOR_FIRST); uint32 loser_kills = player->GetRandomWinner() ? sWorld->getIntConfig(CONFIG_BG_REWARD_LOSER_HONOR_LAST) : sWorld->getIntConfig(CONFIG_BG_REWARD_LOSER_HONOR_FIRST); uint32 winner_arena = player->GetRandomWinner() ? sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_ARENA_LAST) : sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_ARENA_FIRST); @@ -909,17 +803,6 @@ void Battleground::EndBattleground(uint32 winner) player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1); } - if (isArena() && isRated() && winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) - { - // save the stat changes - 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 - winnerArenaTeam->NotifyStatsChanged(); - loserArenaTeam->NotifyStatsChanged(); - } - if (winmsg_id) SendMessageToAll(winmsg_id, CHAT_MSG_BG_SYSTEM_NEUTRAL); } @@ -986,26 +869,16 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac { player->ClearAfkReports(); - if (!team) team = player->GetTeam(); - // if arena, remove the specific arena auras if (isArena()) { - bgTypeId=BATTLEGROUND_AA; // set the bg type to all arenas (it will be used for queue refreshing) + bgTypeId = BATTLEGROUND_AA; // set the bg type to all arenas (it will be used for queue refreshing) // unsummon current and summon old pet if there was one and there isn't a current pet player->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT); player->ResummonPetTemporaryUnSummonedIfAny(); - - if (isRated() && GetStatus() == STATUS_IN_PROGRESS) - { - //left a rated match while the encounter was in progress, consider as loser - 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) { WorldPacket data; @@ -1016,26 +889,12 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac // this call is important, because player, when joins to battleground, this method is not called, so it must be called when leaving bg player->RemoveBattlegroundQueueId(bgQueueTypeId); } - else - // removing offline participant - { - if (isRated() && GetStatus() == STATUS_IN_PROGRESS) - { - //left a rated match while the encounter was in progress, consider as loser - ArenaTeam* others_arena_team = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(team))); - ArenaTeam* players_arena_team = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(team)); - if (others_arena_team && players_arena_team) - players_arena_team->OfflineMemberLost(guid, GetArenaMatchmakerRating(GetOtherTeam(team))); - } - } // remove from raid group if player is member if (Group* group = GetBgRaid(team)) { if (!group->RemoveMember(guid)) // group was disbanded - { SetBgRaid(team, NULL); - } } DecreaseInvitedCount(team); //we should update battleground queue, but only if bg isn't ending @@ -1070,7 +929,7 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac // this method is called when no players remains in battleground void Battleground::Reset() { - SetWinner(WINNER_NONE); + SetWinner(0); SetStatus(STATUS_WAIT_QUEUE); SetStartTime(0); SetEndTime(0); @@ -1143,21 +1002,6 @@ void Battleground::AddPlayer(Player* player) if (isArena()) { player->RemoveArenaEnchantments(TEMP_ENCHANTMENT_SLOT); - if (team == ALLIANCE) // gold - { - if (player->GetTeam() == HORDE) - player->CastSpell(player, SPELL_HORDE_GOLD_FLAG, true); - else - player->CastSpell(player, SPELL_ALLIANCE_GOLD_FLAG, true); - } - else // green - { - if (player->GetTeam() == HORDE) - player->CastSpell(player, SPELL_HORDE_GREEN_FLAG, true); - else - player->CastSpell(player, SPELL_ALLIANCE_GREEN_FLAG, true); - } - player->DestroyConjuredItems(true); player->UnsummonPetTemporaryIfAny(); @@ -1379,10 +1223,10 @@ bool Battleground::UpdatePlayerScore(Player* player, uint32 type, uint32 value, if (itr == PlayerScores.end()) // player not found... return false; - itr->second->UpdateScore(type, value); - if (type == SCORE_BONUS_HONOR && doAddHonor && isBattleground()) player->RewardHonor(NULL, 1, value); // RewardHonor calls UpdatePlayerScore with doAddHonor = false + else + itr->second->UpdateScore(type, value); return true; } @@ -1900,27 +1744,6 @@ int32 Battleground::GetObjectType(uint64 guid) return -1; } -void Battleground::HandleKillUnit(Creature* /*victim*/, Player* /*killer*/) { } - -void Battleground::CheckArenaAfterTimerConditions() -{ - EndBattleground(WINNER_NONE); -} - -void Battleground::CheckArenaWinConditions() -{ - if (!GetAlivePlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE)) - EndBattleground(HORDE); - else if (GetPlayersCountByTeam(ALLIANCE) && !GetAlivePlayersCountByTeam(HORDE)) - EndBattleground(ALLIANCE); -} - -void Battleground::UpdateArenaWorldState() -{ - UpdateWorldState(0xe10, GetAlivePlayersCountByTeam(HORDE)); - UpdateWorldState(0xe11, GetAlivePlayersCountByTeam(ALLIANCE)); -} - void Battleground::SetBgRaid(uint32 TeamID, Group* bg_raid) { Group*& old_raid = TeamID == ALLIANCE ? m_BgRaids[TEAM_ALLIANCE] : m_BgRaids[TEAM_HORDE]; diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index 468b73c51ab..635ad1b28d3 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -19,6 +19,7 @@ #ifndef __BATTLEGROUND_H #define __BATTLEGROUND_H +#include "ArenaScore.h" #include "Common.h" #include "SharedDefines.h" #include "DBCEnums.h" @@ -34,7 +35,6 @@ class WorldObject; class WorldPacket; class BattlegroundMap; -struct BattlegroundScore; struct PvPDifficultyEntry; struct WorldSafeLocsEntry; @@ -104,17 +104,12 @@ enum BattlegroundSpells SPELL_SPIRIT_HEAL = 22012, // Spirit Heal SPELL_RESURRECTION_VISUAL = 24171, // Resurrection Impact Visual SPELL_ARENA_PREPARATION = 32727, // use this one, 32728 not correct - SPELL_ALLIANCE_GOLD_FLAG = 32724, - SPELL_ALLIANCE_GREEN_FLAG = 32725, - SPELL_HORDE_GOLD_FLAG = 35774, - SPELL_HORDE_GREEN_FLAG = 35775, SPELL_PREPARATION = 44521, // Preparation SPELL_SPIRIT_HEAL_MANA = 44535, // Spirit Heal SPELL_RECENTLY_DROPPED_FLAG = 42792, // Recently Dropped Flag SPELL_AURA_PLAYER_INACTIVE = 43681, // Inactive SPELL_HONORABLE_DEFENDER_25Y = 68652, // +50% honor when standing at a capture point that you control, 25yards radius (added in 3.2) - SPELL_HONORABLE_DEFENDER_60Y = 66157, // +50% honor when standing at a capture point that you control, 60yards radius (added in 3.2), probably for 40+ player battlegrounds - SPELL_THE_LAST_STANDING = 26549 // Arena achievement related + SPELL_HONORABLE_DEFENDER_60Y = 66157 // +50% honor when standing at a capture point that you control, 60yards radius (added in 3.2), probably for 40+ player battlegrounds }; enum BattlegroundTimeIntervals @@ -180,21 +175,6 @@ enum ArenaType ARENA_TYPE_5v5 = 5 }; -enum BattlegroundType -{ - TYPE_BATTLEGROUND = 3, - TYPE_ARENA = 4 -}; - -enum BattlegroundWinner -{ - WINNER_HORDE = 0, - WINNER_ALLIANCE = 1, - WINNER_NONE = 2 -}; - -#define BG_TEAMS_COUNT 2 - enum BattlegroundStartingEvents { BG_STARTING_EVENT_NONE = 0x00, @@ -378,7 +358,7 @@ class Battleground void RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID); void UpdateWorldState(uint32 Field, uint32 Value); void UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player* player); - void EndBattleground(uint32 winner); + virtual void EndBattleground(uint32 winner); void BlockMovement(Player* player); void SendWarningToAll(int32 entry, ...); @@ -406,22 +386,21 @@ class Battleground ++m_PlayersCount[GetTeamIndexByTeamId(Team)]; } + virtual void CheckWinConditions() { } + // used for rated arena battles void SetArenaTeamIdForTeam(uint32 Team, uint32 ArenaTeamId) { m_ArenaTeamIds[GetTeamIndexByTeamId(Team)] = ArenaTeamId; } uint32 GetArenaTeamIdForTeam(uint32 Team) const { return m_ArenaTeamIds[GetTeamIndexByTeamId(Team)]; } uint32 GetArenaTeamIdByIndex(uint32 index) const { return m_ArenaTeamIds[index]; } void SetArenaMatchmakerRating(uint32 Team, uint32 MMR){ m_ArenaTeamMMR[GetTeamIndexByTeamId(Team)] = MMR; } uint32 GetArenaMatchmakerRating(uint32 Team) const { return m_ArenaTeamMMR[GetTeamIndexByTeamId(Team)]; } - void CheckArenaAfterTimerConditions(); - void CheckArenaWinConditions(); - void UpdateArenaWorldState(); // Triggers handle // must be implemented in BG subclass virtual void HandleAreaTrigger(Player* /*player*/, uint32 /*Trigger*/); // must be implemented in BG subclass if need AND call base class generic code virtual void HandleKillPlayer(Player* player, Player* killer); - virtual void HandleKillUnit(Creature* /*unit*/, Player* /*killer*/); + virtual void HandleKillUnit(Creature* /*creature*/, Player* /*killer*/) { } // Battleground events virtual void EventPlayerDroppedFlag(Player* /*player*/) { } @@ -530,6 +509,8 @@ class Battleground BGHonorMode m_HonorMode; int32 m_TeamScores[BG_TEAMS_COUNT]; + ArenaTeamScore _arenaTeamScores[BG_TEAMS_COUNT]; + private: // Battleground BattlegroundTypeId m_TypeID; @@ -605,52 +586,6 @@ class Battleground uint32 m_ArenaTeamMMR[BG_TEAMS_COUNT]; - struct ArenaTeamScore - { - friend class Battleground; - - protected: - ArenaTeamScore() : RatingChange(0), MatchmakerRating(0) { } - - virtual ~ArenaTeamScore() { } - - void Assign(int32 ratingChange, uint32 matchMakerRating, std::string const& teamName) - { - RatingChange = ratingChange; - MatchmakerRating = matchMakerRating; - TeamName = teamName; - } - - void BuildRatingInfoBlock(WorldPacket& data) - { - uint32 ratingLost = std::abs(std::min(RatingChange, 0)); - uint32 ratingWon = std::max(RatingChange, 0); - - // should be old rating, new rating, and client will calculate rating change itself - data << uint32(ratingLost); - data << uint32(ratingWon); - data << uint32(MatchmakerRating); - } - - void BuildTeamInfoBlock(WorldPacket& data) - { - data << TeamName; - } - - void Reset() - { - RatingChange = 0; - MatchmakerRating = 0; - TeamName.clear(); - } - - int32 RatingChange; - uint32 MatchmakerRating; - std::string TeamName; - }; - - ArenaTeamScore _arenaTeamScores[BG_TEAMS_COUNT]; - // Limits uint32 m_LevelMin; uint32 m_LevelMax; diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index 615bbc12199..b5b0d04a069 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -977,7 +977,7 @@ BattlegroundTypeId BattlegroundMgr::GetRandomBG(BattlegroundTypeId bgTypeId) // there is only one bg to select if (selectionWeights.size() == 1) - return bgTypeId; + return selectionWeights.begin()->first; if (weight) { diff --git a/src/server/game/Battlegrounds/BattlegroundScore.h b/src/server/game/Battlegrounds/BattlegroundScore.h index 95d1db2c337..81aca355be8 100644 --- a/src/server/game/Battlegrounds/BattlegroundScore.h +++ b/src/server/game/Battlegrounds/BattlegroundScore.h @@ -51,6 +51,7 @@ enum ScoreType struct BattlegroundScore { + friend class Arena; friend class Battleground; protected: diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp index 548e0bf463b..916531e3947 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp @@ -16,32 +16,13 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ArenaScore.h" #include "BattlegroundBE.h" -#include "Language.h" -#include "Object.h" -#include "ObjectMgr.h" #include "Player.h" #include "WorldPacket.h" BattlegroundBE::BattlegroundBE() { BgObjects.resize(BG_BE_OBJECT_MAX); - - StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; - StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S; - StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S; - StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE; - //we must set messageIds - StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE; - StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS; - StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS; - StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN; -} - -BattlegroundBE::~BattlegroundBE() -{ - } void BattlegroundBE::StartingEventCloseDoors() @@ -62,39 +43,6 @@ void BattlegroundBE::StartingEventOpenDoors() SpawnBGObject(i, 60); } -void BattlegroundBE::AddPlayer(Player* player) -{ - Battleground::AddPlayer(player); - PlayerScores[player->GetGUIDLow()] = new ArenaScore(player->GetGUID(), player->GetBGTeam()); - UpdateArenaWorldState(); -} - -void BattlegroundBE::RemovePlayer(Player* /*player*/, uint64 /*guid*/, uint32 /*team*/) -{ - if (GetStatus() == STATUS_WAIT_LEAVE) - return; - - UpdateArenaWorldState(); - CheckArenaWinConditions(); -} - -void BattlegroundBE::HandleKillPlayer(Player* player, Player* killer) -{ - if (GetStatus() != STATUS_IN_PROGRESS) - return; - - if (!killer) - { - TC_LOG_ERROR("bg.battleground", "Killer player not found"); - return; - } - - Battleground::HandleKillPlayer(player, killer); - - UpdateArenaWorldState(); - CheckArenaWinConditions(); -} - void BattlegroundBE::HandleAreaTrigger(Player* player, uint32 trigger) { if (GetStatus() != STATUS_IN_PROGRESS) @@ -111,16 +59,10 @@ void BattlegroundBE::HandleAreaTrigger(Player* player, uint32 trigger) } } -void BattlegroundBE::FillInitialWorldStates(WorldPacket &data) -{ - data << uint32(0x9f3) << uint32(1); // 9 - UpdateArenaWorldState(); -} - -void BattlegroundBE::Reset() +void BattlegroundBE::FillInitialWorldStates(WorldPacket& data) { - //call parent's class reset - Battleground::Reset(); + data << uint32(0x9f3) << uint32(1); // 9 show + Arena::FillInitialWorldStates(data); } bool BattlegroundBE::SetupBattleground() diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundBE.h b/src/server/game/Battlegrounds/Zones/BattlegroundBE.h index 6fd4dc37fc8..f391edbf747 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundBE.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundBE.h @@ -19,7 +19,7 @@ #ifndef __BATTLEGROUNDBE_H #define __BATTLEGROUNDBE_H -#include "Battleground.h" +#include "Arena.h" enum BattlegroundBEObjectTypes { @@ -32,7 +32,7 @@ enum BattlegroundBEObjectTypes BG_BE_OBJECT_MAX = 6 }; -enum BattlegroundBEObjects +enum BattlegroundBEGameObjects { BG_BE_OBJECT_TYPE_DOOR_1 = 183971, BG_BE_OBJECT_TYPE_DOOR_2 = 183973, @@ -42,22 +42,17 @@ enum BattlegroundBEObjects BG_BE_OBJECT_TYPE_BUFF_2 = 184664 }; -class BattlegroundBE : public Battleground +class BattlegroundBE : public Arena { public: BattlegroundBE(); - ~BattlegroundBE(); /* inherited from BattlegroundClass */ - void AddPlayer(Player* player); void StartingEventCloseDoors(); void StartingEventOpenDoors(); - void RemovePlayer(Player* player, uint64 guid, uint32 team); void HandleAreaTrigger(Player* Source, uint32 Trigger); bool SetupBattleground(); - void Reset(); void FillInitialWorldStates(WorldPacket &d); - void HandleKillPlayer(Player* player, Player* killer); }; #endif diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp index 1d6970f8317..864faa30916 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp @@ -16,12 +16,9 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ArenaScore.h" #include "BattlegroundDS.h" #include "Creature.h" #include "GameObject.h" -#include "Language.h" -#include "ObjectAccessor.h" #include "Player.h" #include "WorldPacket.h" @@ -30,25 +27,8 @@ BattlegroundDS::BattlegroundDS() BgObjects.resize(BG_DS_OBJECT_MAX); BgCreatures.resize(BG_DS_NPC_MAX); - _waterfallTimer = 0; - _waterfallStatus = 0; - _waterfallKnockbackTimer = 0; _pipeKnockBackTimer = 0; _pipeKnockBackCount = 0; - - StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; - StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S; - StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S; - StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE; - StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE; - StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS; - StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS; - StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN; -} - -BattlegroundDS::~BattlegroundDS() -{ - } void BattlegroundDS::PostUpdateImpl(uint32 diff) @@ -56,64 +36,58 @@ void BattlegroundDS::PostUpdateImpl(uint32 diff) if (GetStatus() != STATUS_IN_PROGRESS) return; - if (getPipeKnockBackCount() < BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT) - { - if (getPipeKnockBackTimer() < diff) - { - for (uint32 i = BG_DS_NPC_PIPE_KNOCKBACK_1; i <= BG_DS_NPC_PIPE_KNOCKBACK_2; ++i) - if (Creature* waterSpout = GetBgMap()->GetCreature(BgCreatures[i])) - waterSpout->CastSpell(waterSpout, BG_DS_SPELL_FLUSH, true); - - setPipeKnockBackCount(getPipeKnockBackCount() + 1); - setPipeKnockBackTimer(BG_DS_PIPE_KNOCKBACK_DELAY); - } - else - setPipeKnockBackTimer(getPipeKnockBackTimer() - diff); - } + _events.Update(diff); - if (getWaterFallStatus() == BG_DS_WATERFALL_STATUS_ON) // Repeat knockback while the waterfall still active + while (uint32 eventId = _events.ExecuteEvent()) { - if (getWaterFallKnockbackTimer() < diff) + switch (eventId) { - if (Creature* waterSpout = GetBgMap()->GetCreature(BgCreatures[BG_DS_NPC_WATERFALL_KNOCKBACK])) - waterSpout->CastSpell(waterSpout, BG_DS_SPELL_WATER_SPOUT, true); - - setWaterFallKnockbackTimer(BG_DS_WATERFALL_KNOCKBACK_TIMER); + case BG_DS_EVENT_WATERFALL_WARNING: + // Add the water + DoorClose(BG_DS_OBJECT_WATER_2); + _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_ON, BG_DS_WATERFALL_WARNING_DURATION); + break; + case BG_DS_EVENT_WATERFALL_ON: + // Active collision and start knockback timer + DoorClose(BG_DS_OBJECT_WATER_1); + _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_OFF, BG_DS_WATERFALL_DURATION); + _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_KNOCKBACK, BG_DS_WATERFALL_KNOCKBACK_TIMER); + break; + case BG_DS_EVENT_WATERFALL_OFF: + // Remove collision and water + DoorOpen(BG_DS_OBJECT_WATER_1); + DoorOpen(BG_DS_OBJECT_WATER_2); + _events.CancelEvent(BG_DS_EVENT_WATERFALL_KNOCKBACK); + _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_WARNING, urand(BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX)); + break; + case BG_DS_EVENT_WATERFALL_KNOCKBACK: + // Repeat knockback while the waterfall still active + if (Creature* waterSpout = GetBGCreature(BG_DS_NPC_WATERFALL_KNOCKBACK)) + waterSpout->CastSpell(waterSpout, BG_DS_SPELL_WATER_SPOUT, true); + _events.ScheduleEvent(eventId, BG_DS_WATERFALL_KNOCKBACK_TIMER); + break; + case BG_DS_EVENT_PIPE_KNOCKBACK: + for (uint32 i = BG_DS_NPC_PIPE_KNOCKBACK_1; i <= BG_DS_NPC_PIPE_KNOCKBACK_2; ++i) + if (Creature* waterSpout = GetBGCreature(i)) + waterSpout->CastSpell(waterSpout, BG_DS_SPELL_FLUSH, true); + break; } - else - setWaterFallKnockbackTimer(getWaterFallKnockbackTimer() - diff); } - if (getWaterFallTimer() < diff) + if (_pipeKnockBackCount < BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT) { - if (getWaterFallStatus() == BG_DS_WATERFALL_STATUS_OFF) // Add the water - { - DoorClose(BG_DS_OBJECT_WATER_2); - setWaterFallTimer(BG_DS_WATERFALL_WARNING_DURATION); - setWaterFallStatus(BG_DS_WATERFALL_STATUS_WARNING); - } - else if (getWaterFallStatus() == BG_DS_WATERFALL_STATUS_WARNING) // Active collision and start knockback timer - { - if (GameObject* gob = GetBgMap()->GetGameObject(BgObjects[BG_DS_OBJECT_WATER_1])) - gob->SetGoState(GO_STATE_READY); - - setWaterFallTimer(BG_DS_WATERFALL_DURATION); - setWaterFallStatus(BG_DS_WATERFALL_STATUS_ON); - setWaterFallKnockbackTimer(BG_DS_WATERFALL_KNOCKBACK_TIMER); - } - else //if (getWaterFallStatus() == BG_DS_WATERFALL_STATUS_ON) // Remove collision and water + if (_pipeKnockBackTimer < diff) { - // turn off collision - if (GameObject* gob = GetBgMap()->GetGameObject(BgObjects[BG_DS_OBJECT_WATER_1])) - gob->SetGoState(GO_STATE_ACTIVE); + for (uint32 i = BG_DS_NPC_PIPE_KNOCKBACK_1; i <= BG_DS_NPC_PIPE_KNOCKBACK_2; ++i) + if (Creature* waterSpout = GetBGCreature(i)) + waterSpout->CastSpell(waterSpout, BG_DS_SPELL_FLUSH, true); - DoorOpen(BG_DS_OBJECT_WATER_2); - setWaterFallTimer(urand(BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX)); - setWaterFallStatus(BG_DS_WATERFALL_STATUS_OFF); + ++_pipeKnockBackCount; + _pipeKnockBackTimer = BG_DS_PIPE_KNOCKBACK_DELAY; } + else + _pipeKnockBackTimer -= diff; } - else - setWaterFallTimer(getWaterFallTimer() - diff); } void BattlegroundDS::StartingEventCloseDoors() @@ -130,57 +104,22 @@ void BattlegroundDS::StartingEventOpenDoors() for (uint32 i = BG_DS_OBJECT_BUFF_1; i <= BG_DS_OBJECT_BUFF_2; ++i) SpawnBGObject(i, 60); - setWaterFallTimer(urand(BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX)); - setWaterFallStatus(BG_DS_WATERFALL_STATUS_OFF); + _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_WARNING, urand(BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX)); + //for (uint8 i = 0; i < BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT; ++i) + // _events.ScheduleEvent(BG_DS_EVENT_PIPE_KNOCKBACK, BG_DS_PIPE_KNOCKBACK_FIRST_DELAY + i * BG_DS_PIPE_KNOCKBACK_DELAY); - setPipeKnockBackTimer(BG_DS_PIPE_KNOCKBACK_FIRST_DELAY); - setPipeKnockBackCount(0); + _pipeKnockBackCount = 0; + _pipeKnockBackTimer = BG_DS_PIPE_KNOCKBACK_FIRST_DELAY; SpawnBGObject(BG_DS_OBJECT_WATER_2, RESPAWN_IMMEDIATELY); - DoorOpen(BG_DS_OBJECT_WATER_2); - // Turn off collision - if (GameObject* gob = GetBgMap()->GetGameObject(BgObjects[BG_DS_OBJECT_WATER_1])) - gob->SetGoState(GO_STATE_ACTIVE); + DoorOpen(BG_DS_OBJECT_WATER_1); // Turn off collision + DoorOpen(BG_DS_OBJECT_WATER_2); // Remove effects of Demonic Circle Summon for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) - if (Player* player = ObjectAccessor::FindPlayer(itr->first)) - if (player->HasAura(48018)) - player->RemoveAurasDueToSpell(48018); -} - -void BattlegroundDS::AddPlayer(Player* player) -{ - Battleground::AddPlayer(player); - PlayerScores[player->GetGUIDLow()] = new ArenaScore(player->GetGUID(), player->GetBGTeam()); - UpdateArenaWorldState(); -} - -void BattlegroundDS::RemovePlayer(Player* /*player*/, uint64 /*guid*/, uint32 /*team*/) -{ - if (GetStatus() == STATUS_WAIT_LEAVE) - return; - - UpdateArenaWorldState(); - CheckArenaWinConditions(); -} - -void BattlegroundDS::HandleKillPlayer(Player* player, Player* killer) -{ - if (GetStatus() != STATUS_IN_PROGRESS) - return; - - if (!killer) - { - TC_LOG_ERROR("bg.battleground", "BattlegroundDS: Killer player not found"); - return; - } - - Battleground::HandleKillPlayer(player, killer); - - UpdateArenaWorldState(); - CheckArenaWinConditions(); + if (Player* player = _GetPlayer(itr, "BattlegroundDS::StartingEventOpenDoors")) + player->RemoveAurasDueToSpell(SPELL_WARL_DEMONIC_CIRCLE); } void BattlegroundDS::HandleAreaTrigger(Player* player, uint32 trigger) @@ -193,13 +132,12 @@ void BattlegroundDS::HandleAreaTrigger(Player* player, uint32 trigger) case 5347: case 5348: // Remove effects of Demonic Circle Summon - if (player->HasAura(48018)) - player->RemoveAurasDueToSpell(48018); + player->RemoveAurasDueToSpell(SPELL_WARL_DEMONIC_CIRCLE); // Someone has get back into the pipes and the knockback has already been performed, // so we reset the knockback count for kicking the player again into the arena. - if (getPipeKnockBackCount() >= BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT) - setPipeKnockBackCount(0); + if (_pipeKnockBackCount >= BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT) + _pipeKnockBackCount = 0; break; default: Battleground::HandleAreaTrigger(player, trigger); @@ -207,16 +145,10 @@ void BattlegroundDS::HandleAreaTrigger(Player* player, uint32 trigger) } } -void BattlegroundDS::FillInitialWorldStates(WorldPacket &data) -{ - data << uint32(3610) << uint32(1); // 9 show - UpdateArenaWorldState(); -} - -void BattlegroundDS::Reset() +void BattlegroundDS::FillInitialWorldStates(WorldPacket& data) { - //call parent's class reset - Battleground::Reset(); + data << uint32(3610) << uint32(1); // 9 show + Arena::FillInitialWorldStates(data); } bool BattlegroundDS::SetupBattleground() diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundDS.h b/src/server/game/Battlegrounds/Zones/BattlegroundDS.h index cb71300dc5d..4c763316d83 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundDS.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundDS.h @@ -19,7 +19,7 @@ #ifndef __BATTLEGROUNDDS_H #define __BATTLEGROUNDDS_H -#include "Battleground.h" +#include "Arena.h" enum BattlegroundDSObjectTypes { @@ -32,7 +32,7 @@ enum BattlegroundDSObjectTypes BG_DS_OBJECT_MAX = 6 }; -enum BattlegroundDSObjects +enum BattlegroundDSGameObjects { BG_DS_OBJECT_TYPE_DOOR_1 = 192642, BG_DS_OBJECT_TYPE_DOOR_2 = 192643, @@ -59,61 +59,54 @@ enum BattlegroundDSSpells { BG_DS_SPELL_FLUSH = 57405, // Visual and target selector for the starting knockback from the pipe BG_DS_SPELL_FLUSH_KNOCKBACK = 61698, // Knockback effect for previous spell (triggered, not needed to be cast) - BG_DS_SPELL_WATER_SPOUT = 58873 // Knockback effect of the central waterfall + BG_DS_SPELL_WATER_SPOUT = 58873, // Knockback effect of the central waterfall + + SPELL_WARL_DEMONIC_CIRCLE = 48018 // Demonic Circle Summon }; enum BattlegroundDSData -{ // These values are NOT blizzlike... need the correct data! - BG_DS_WATERFALL_TIMER_MIN = 30000, - BG_DS_WATERFALL_TIMER_MAX = 60000, - BG_DS_WATERFALL_WARNING_DURATION = 5000, - BG_DS_WATERFALL_DURATION = 30000, - BG_DS_WATERFALL_KNOCKBACK_TIMER = 1500, - - BG_DS_PIPE_KNOCKBACK_FIRST_DELAY = 5000, - BG_DS_PIPE_KNOCKBACK_DELAY = 3000, - BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT = 2, - - BG_DS_WATERFALL_STATUS_WARNING = 1, // Water starting to fall, but no LoS Blocking nor movement blocking - BG_DS_WATERFALL_STATUS_ON = 2, // LoS and Movement blocking active - BG_DS_WATERFALL_STATUS_OFF = 3 +{ + // These values are NOT blizzlike... need the correct data! + BG_DS_WATERFALL_TIMER_MIN = 30000, + BG_DS_WATERFALL_TIMER_MAX = 60000, + BG_DS_WATERFALL_WARNING_DURATION = 5000, + BG_DS_WATERFALL_DURATION = 30000, + BG_DS_WATERFALL_KNOCKBACK_TIMER = 1500, + + BG_DS_PIPE_KNOCKBACK_FIRST_DELAY = 5000, + BG_DS_PIPE_KNOCKBACK_DELAY = 3000, + BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT = 2, +}; + +enum BattlegroundDSEvents +{ + BG_DS_EVENT_WATERFALL_WARNING = 1, // Water starting to fall, but no LoS Blocking nor movement blocking + BG_DS_EVENT_WATERFALL_ON = 2, // LoS and Movement blocking active + BG_DS_EVENT_WATERFALL_OFF = 3, + BG_DS_EVENT_WATERFALL_KNOCKBACK = 4, + + BG_DS_EVENT_PIPE_KNOCKBACK = 5 }; -class BattlegroundDS : public Battleground +class BattlegroundDS : public Arena { public: BattlegroundDS(); - ~BattlegroundDS(); /* inherited from BattlegroundClass */ - void AddPlayer(Player* player); void StartingEventCloseDoors(); void StartingEventOpenDoors(); - void RemovePlayer(Player* player, uint64 guid, uint32 team); void HandleAreaTrigger(Player* Source, uint32 Trigger); bool SetupBattleground(); - void Reset(); void FillInitialWorldStates(WorldPacket &d); - void HandleKillPlayer(Player* player, Player* killer); + private: - uint32 _waterfallTimer; - uint8 _waterfallStatus; - uint32 _waterfallKnockbackTimer; + void PostUpdateImpl(uint32 diff); + + EventMap _events; + uint32 _pipeKnockBackTimer; uint8 _pipeKnockBackCount; - - void PostUpdateImpl(uint32 diff); - protected: - uint32 getWaterFallStatus() { return _waterfallStatus; } - void setWaterFallStatus(uint8 status) { _waterfallStatus = status; } - uint32 getWaterFallTimer() { return _waterfallTimer; } - void setWaterFallTimer(uint32 timer) { _waterfallTimer = timer; } - uint32 getWaterFallKnockbackTimer() { return _waterfallKnockbackTimer; } - void setWaterFallKnockbackTimer(uint32 timer) { _waterfallKnockbackTimer = timer; } - uint8 getPipeKnockBackCount() { return _pipeKnockBackCount; } - void setPipeKnockBackCount(uint8 count) { _pipeKnockBackCount = count; } - uint32 getPipeKnockBackTimer() { return _pipeKnockBackTimer; } - void setPipeKnockBackTimer(uint32 timer) { _pipeKnockBackTimer = timer; } }; #endif diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp index 1685f06f92d..41a37a8962f 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp @@ -500,7 +500,7 @@ void BattlegroundIC::EventPlayerClickedOnFlag(Player* player, GameObject* target if (!AddObject(nodePoint[i].gameobject_type, nodePoint[i].gameobject_entry, cords[0], cords[1], cords[2], cords[3], 0, 0, 0, 0, RESPAWN_ONE_DAY)) { TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning a banner (type: %u, entry: %u). Isle of Conquest BG cancelled.", nodePoint[i].gameobject_type, nodePoint[i].gameobject_entry); - Battleground::EndBattleground(WINNER_NONE); + EndBattleground(0); } GetBGObject(nodePoint[i].gameobject_type)->SetUInt32Value(GAMEOBJECT_FACTION, nodePoint[i].faction == TEAM_ALLIANCE ? BG_IC_Factions[1] : BG_IC_Factions[0]); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp index 82fcb2f6f91..46128c44d69 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp @@ -16,32 +16,13 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ArenaScore.h" #include "BattlegroundNA.h" -#include "Language.h" -#include "Object.h" -#include "ObjectMgr.h" #include "Player.h" #include "WorldPacket.h" BattlegroundNA::BattlegroundNA() { BgObjects.resize(BG_NA_OBJECT_MAX); - - StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; - StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S; - StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S; - StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE; - //we must set messageIds - StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE; - StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS; - StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS; - StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN; -} - -BattlegroundNA::~BattlegroundNA() -{ - } void BattlegroundNA::StartingEventCloseDoors() @@ -59,39 +40,6 @@ void BattlegroundNA::StartingEventOpenDoors() SpawnBGObject(i, 60); } -void BattlegroundNA::AddPlayer(Player* player) -{ - Battleground::AddPlayer(player); - PlayerScores[player->GetGUIDLow()] = new ArenaScore(player->GetGUID(), player->GetBGTeam()); - UpdateArenaWorldState(); -} - -void BattlegroundNA::RemovePlayer(Player* /*player*/, uint64 /*guid*/, uint32 /*team*/) -{ - if (GetStatus() == STATUS_WAIT_LEAVE) - return; - - UpdateArenaWorldState(); - CheckArenaWinConditions(); -} - -void BattlegroundNA::HandleKillPlayer(Player* player, Player* killer) -{ - if (GetStatus() != STATUS_IN_PROGRESS) - return; - - if (!killer) - { - TC_LOG_ERROR("bg.battleground", "BattlegroundNA: Killer player not found"); - return; - } - - Battleground::HandleKillPlayer(player, killer); - - UpdateArenaWorldState(); - CheckArenaWinConditions(); -} - void BattlegroundNA::HandleAreaTrigger(Player* player, uint32 trigger) { if (GetStatus() != STATUS_IN_PROGRESS) @@ -108,16 +56,10 @@ void BattlegroundNA::HandleAreaTrigger(Player* player, uint32 trigger) } } -void BattlegroundNA::FillInitialWorldStates(WorldPacket &data) -{ - data << uint32(0xa11) << uint32(1); // 9 - UpdateArenaWorldState(); -} - -void BattlegroundNA::Reset() +void BattlegroundNA::FillInitialWorldStates(WorldPacket& data) { - //call parent's class reset - Battleground::Reset(); + data << uint32(0xa11) << uint32(1); // 9 show + Arena::FillInitialWorldStates(data); } bool BattlegroundNA::SetupBattleground() diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundNA.h b/src/server/game/Battlegrounds/Zones/BattlegroundNA.h index dd21e44f593..2fa93a07651 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundNA.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundNA.h @@ -18,7 +18,7 @@ #ifndef __BATTLEGROUNDNA_H #define __BATTLEGROUNDNA_H -#include "Battleground.h" +#include "Arena.h" enum BattlegroundNAObjectTypes { @@ -31,7 +31,7 @@ enum BattlegroundNAObjectTypes BG_NA_OBJECT_MAX = 6 }; -enum BattlegroundNAObjects +enum BattlegroundNAGameObjects { BG_NA_OBJECT_TYPE_DOOR_1 = 183978, BG_NA_OBJECT_TYPE_DOOR_2 = 183980, @@ -41,22 +41,17 @@ enum BattlegroundNAObjects BG_NA_OBJECT_TYPE_BUFF_2 = 184664 }; -class BattlegroundNA : public Battleground +class BattlegroundNA : public Arena { public: BattlegroundNA(); - ~BattlegroundNA(); /* inherited from BattlegroundClass */ - void AddPlayer(Player* player); void StartingEventCloseDoors(); void StartingEventOpenDoors(); - void RemovePlayer(Player* player, uint64 guid, uint32 team); void HandleAreaTrigger(Player* Source, uint32 Trigger); bool SetupBattleground(); - void Reset(); void FillInitialWorldStates(WorldPacket &d); - void HandleKillPlayer(Player* player, Player* killer); }; #endif diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp index 712d9a6e296..f474946e069 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp @@ -16,32 +16,13 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ArenaScore.h" #include "BattlegroundRL.h" -#include "Language.h" -#include "Object.h" -#include "ObjectMgr.h" #include "Player.h" #include "WorldPacket.h" BattlegroundRL::BattlegroundRL() { BgObjects.resize(BG_RL_OBJECT_MAX); - - StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; - StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S; - StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S; - StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE; - //we must set messageIds - StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE; - StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS; - StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS; - StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN; -} - -BattlegroundRL::~BattlegroundRL() -{ - } void BattlegroundRL::StartingEventCloseDoors() @@ -59,39 +40,6 @@ void BattlegroundRL::StartingEventOpenDoors() SpawnBGObject(i, 60); } -void BattlegroundRL::AddPlayer(Player* player) -{ - Battleground::AddPlayer(player); - PlayerScores[player->GetGUIDLow()] = new ArenaScore(player->GetGUID(), player->GetBGTeam()); - UpdateArenaWorldState(); -} - -void BattlegroundRL::RemovePlayer(Player* /*player*/, uint64 /*guid*/, uint32 /*team*/) -{ - if (GetStatus() == STATUS_WAIT_LEAVE) - return; - - UpdateArenaWorldState(); - CheckArenaWinConditions(); -} - -void BattlegroundRL::HandleKillPlayer(Player* player, Player* killer) -{ - if (GetStatus() != STATUS_IN_PROGRESS) - return; - - if (!killer) - { - TC_LOG_ERROR("bg.battleground", "Killer player not found"); - return; - } - - Battleground::HandleKillPlayer(player, killer); - - UpdateArenaWorldState(); - CheckArenaWinConditions(); -} - void BattlegroundRL::HandleAreaTrigger(Player* player, uint32 trigger) { if (GetStatus() != STATUS_IN_PROGRESS) @@ -108,16 +56,10 @@ void BattlegroundRL::HandleAreaTrigger(Player* player, uint32 trigger) } } -void BattlegroundRL::FillInitialWorldStates(WorldPacket &data) -{ - data << uint32(0xbba) << uint32(1); // 9 - UpdateArenaWorldState(); -} - -void BattlegroundRL::Reset() +void BattlegroundRL::FillInitialWorldStates(WorldPacket& data) { - //call parent's reset - Battleground::Reset(); + data << uint32(0xbba) << uint32(1); // 9 show + Arena::FillInitialWorldStates(data); } bool BattlegroundRL::SetupBattleground() diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRL.h b/src/server/game/Battlegrounds/Zones/BattlegroundRL.h index 27974108168..ad4fe18a3c7 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundRL.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundRL.h @@ -18,7 +18,7 @@ #ifndef __BATTLEGROUNDRL_H #define __BATTLEGROUNDRL_H -#include "Battleground.h" +#include "Arena.h" enum BattlegroundRLObjectTypes { @@ -29,7 +29,7 @@ enum BattlegroundRLObjectTypes BG_RL_OBJECT_MAX = 4 }; -enum BattlegroundRLObjects +enum BattlegroundRLGameObjects { BG_RL_OBJECT_TYPE_DOOR_1 = 185918, BG_RL_OBJECT_TYPE_DOOR_2 = 185917, @@ -37,22 +37,17 @@ enum BattlegroundRLObjects BG_RL_OBJECT_TYPE_BUFF_2 = 184664 }; -class BattlegroundRL : public Battleground +class BattlegroundRL : public Arena { public: BattlegroundRL(); - ~BattlegroundRL(); /* inherited from BattlegroundClass */ - void AddPlayer(Player* player); - void Reset(); void FillInitialWorldStates(WorldPacket &d); void StartingEventCloseDoors(); void StartingEventOpenDoors(); - void RemovePlayer(Player* player, uint64 guid, uint32 team); void HandleAreaTrigger(Player* Source, uint32 Trigger); bool SetupBattleground(); - void HandleKillPlayer(Player* player, Player* killer); }; #endif diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp index 1059124d041..9609009d610 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp @@ -16,70 +16,54 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ArenaScore.h" -#include "Battleground.h" #include "BattlegroundRV.h" +#include "GameObject.h" #include "ObjectAccessor.h" -#include "Language.h" #include "Player.h" #include "WorldPacket.h" -#include "GameObject.h" BattlegroundRV::BattlegroundRV() { BgObjects.resize(BG_RV_OBJECT_MAX); - Timer = 0; - State = 0; - PillarCollision = false; - - StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; - StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S; - StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S; - StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE; - StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE; - StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS; - StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS; - StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN; + _timer = 0; + _state = 0; + _pillarCollision = false; } -BattlegroundRV::~BattlegroundRV() { } - void BattlegroundRV::PostUpdateImpl(uint32 diff) { if (GetStatus() != STATUS_IN_PROGRESS) return; - if (getTimer() < diff) + if (_timer < diff) { - switch (getState()) + switch (_state) { case BG_RV_STATE_OPEN_FENCES: // Open fire (only at game start) for (uint8 i = BG_RV_OBJECT_FIRE_1; i <= BG_RV_OBJECT_FIREDOOR_2; ++i) DoorOpen(i); - setTimer(BG_RV_CLOSE_FIRE_TIMER); - setState(BG_RV_STATE_CLOSE_FIRE); + _timer = BG_RV_CLOSE_FIRE_TIMER; + _state = BG_RV_STATE_CLOSE_FIRE; break; case BG_RV_STATE_CLOSE_FIRE: for (uint8 i = BG_RV_OBJECT_FIRE_1; i <= BG_RV_OBJECT_FIREDOOR_2; ++i) DoorClose(i); // Fire got closed after five seconds, leaves twenty seconds before toggling pillars - setTimer(BG_RV_FIRE_TO_PILLAR_TIMER); - setState(BG_RV_STATE_SWITCH_PILLARS); + _timer = BG_RV_FIRE_TO_PILLAR_TIMER; + _state = BG_RV_STATE_SWITCH_PILLARS; break; case BG_RV_STATE_SWITCH_PILLARS: TogglePillarCollision(); - setTimer(BG_RV_PILLAR_SWITCH_TIMER); + _timer = BG_RV_PILLAR_SWITCH_TIMER; break; } } else - setTimer(getTimer() - diff); + _timer -= diff; } -void BattlegroundRV::StartingEventCloseDoors() { } - void BattlegroundRV::StartingEventOpenDoors() { // Buff respawn @@ -89,53 +73,14 @@ void BattlegroundRV::StartingEventOpenDoors() DoorOpen(BG_RV_OBJECT_ELEVATOR_1); DoorOpen(BG_RV_OBJECT_ELEVATOR_2); - setState(BG_RV_STATE_OPEN_FENCES); - setTimer(BG_RV_FIRST_TIMER); + _state = BG_RV_STATE_OPEN_FENCES; + _timer = BG_RV_FIRST_TIMER; // Should be false at first, TogglePillarCollision will do it. - SetPillarCollision(true); + _pillarCollision = true; TogglePillarCollision(); } -void BattlegroundRV::AddPlayer(Player* player) -{ - Battleground::AddPlayer(player); - PlayerScores[player->GetGUIDLow()] = new ArenaScore(player->GetGUID(), player->GetBGTeam()); - - UpdateWorldState(BG_RV_WORLD_STATE_A, GetAlivePlayersCountByTeam(ALLIANCE)); - UpdateWorldState(BG_RV_WORLD_STATE_H, GetAlivePlayersCountByTeam(HORDE)); -} - -void BattlegroundRV::RemovePlayer(Player* /*player*/, uint64 /*guid*/, uint32 /*team*/) -{ - if (GetStatus() == STATUS_WAIT_LEAVE) - return; - - UpdateWorldState(BG_RV_WORLD_STATE_A, GetAlivePlayersCountByTeam(ALLIANCE)); - UpdateWorldState(BG_RV_WORLD_STATE_H, GetAlivePlayersCountByTeam(HORDE)); - - CheckArenaWinConditions(); -} - -void BattlegroundRV::HandleKillPlayer(Player* player, Player* killer) -{ - if (GetStatus() != STATUS_IN_PROGRESS) - return; - - if (!killer) - { - TC_LOG_ERROR("bg.battleground", "BattlegroundRV: Killer player not found"); - return; - } - - Battleground::HandleKillPlayer(player, killer); - - UpdateWorldState(BG_RV_WORLD_STATE_A, GetAlivePlayersCountByTeam(ALLIANCE)); - UpdateWorldState(BG_RV_WORLD_STATE_H, GetAlivePlayersCountByTeam(HORDE)); - - CheckArenaWinConditions(); -} - void BattlegroundRV::HandleAreaTrigger(Player* player, uint32 trigger) { if (GetStatus() != STATUS_IN_PROGRESS) @@ -155,17 +100,10 @@ void BattlegroundRV::HandleAreaTrigger(Player* player, uint32 trigger) } } -void BattlegroundRV::FillInitialWorldStates(WorldPacket &data) +void BattlegroundRV::FillInitialWorldStates(WorldPacket& data) { - data << uint32(BG_RV_WORLD_STATE_A) << uint32(GetAlivePlayersCountByTeam(ALLIANCE)); - data << uint32(BG_RV_WORLD_STATE_H) << uint32(GetAlivePlayersCountByTeam(HORDE)); data << uint32(BG_RV_WORLD_STATE) << uint32(1); -} - -void BattlegroundRV::Reset() -{ - //call parent's class reset - Battleground::Reset(); + Arena::FillInitialWorldStates(data); } bool BattlegroundRV::SetupBattleground() @@ -197,9 +135,7 @@ bool BattlegroundRV::SetupBattleground() || !AddObject(BG_RV_OBJECT_PILAR_COLLISION_1, BG_RV_OBJECT_TYPE_PILAR_COLLISION_1, 763.632385f, -306.162384f, 30.639660f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY) || !AddObject(BG_RV_OBJECT_PILAR_COLLISION_2, BG_RV_OBJECT_TYPE_PILAR_COLLISION_2, 723.644287f, -284.493256f, 32.382710f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY) || !AddObject(BG_RV_OBJECT_PILAR_COLLISION_3, BG_RV_OBJECT_TYPE_PILAR_COLLISION_3, 763.611145f, -261.856750f, 30.639660f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY) - || !AddObject(BG_RV_OBJECT_PILAR_COLLISION_4, BG_RV_OBJECT_TYPE_PILAR_COLLISION_4, 802.211609f, -284.493256f, 32.382710f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY) - -) + || !AddObject(BG_RV_OBJECT_PILAR_COLLISION_4, BG_RV_OBJECT_TYPE_PILAR_COLLISION_4, 802.211609f, -284.493256f, 32.382710f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)) { TC_LOG_ERROR("sql.sql", "BatteGroundRV: Failed to spawn some object!"); return false; @@ -207,38 +143,30 @@ bool BattlegroundRV::SetupBattleground() return true; } - void BattlegroundRV::TogglePillarCollision() { - bool apply = GetPillarCollision(); - // Toggle visual pillars, pulley, gear, and collision based on previous state for (uint8 i = BG_RV_OBJECT_PILAR_1; i <= BG_RV_OBJECT_GEAR_2; ++i) - apply ? DoorOpen(i) : DoorClose(i); + _pillarCollision ? DoorOpen(i) : DoorClose(i); for (uint8 i = BG_RV_OBJECT_PILAR_2; i <= BG_RV_OBJECT_PULLEY_2; ++i) - apply ? DoorClose(i) : DoorOpen(i); + _pillarCollision ? DoorClose(i) : DoorOpen(i); for (uint8 i = BG_RV_OBJECT_PILAR_1; i <= BG_RV_OBJECT_PILAR_COLLISION_4; ++i) { - if (GameObject* gob = GetBgMap()->GetGameObject(BgObjects[i])) + if (GameObject* go = GetBGObject(i)) { if (i >= BG_RV_OBJECT_PILAR_COLLISION_1) { - uint32 _state = GO_STATE_READY; - if (gob->GetGOInfo()->door.startOpen) - _state = GO_STATE_ACTIVE; - gob->SetGoState(apply ? (GOState)_state : (GOState)(!_state)); - - if (gob->GetGOInfo()->door.startOpen) - gob->EnableCollision(!apply); // Forced collision toggle + GOState state = (bool(go->GetGOInfo()->door.startOpen) == _pillarCollision) ? GO_STATE_ACTIVE : GO_STATE_READY; + go->SetGoState(state); } - for (BattlegroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) - if (Player* player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER))) - gob->SendUpdateToPlayer(player); + for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) + if (Player* player = ObjectAccessor::FindPlayer(itr->first)) + go->SendUpdateToPlayer(player); } } - SetPillarCollision(!apply); + _pillarCollision = !_pillarCollision; } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRV.h b/src/server/game/Battlegrounds/Zones/BattlegroundRV.h index 454ea723f8b..d23f6757b83 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundRV.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundRV.h @@ -18,7 +18,7 @@ #ifndef __BATTLEGROUNDRV_H #define __BATTLEGROUNDRV_H -#include "Battleground.h" +#include "Arena.h" enum BattlegroundRVObjectTypes { @@ -49,7 +49,7 @@ enum BattlegroundRVObjectTypes BG_RV_OBJECT_MAX }; -enum BattlegroundRVObjects +enum BattlegroundRVGameObjects { BG_RV_OBJECT_TYPE_BUFF_1 = 184663, BG_RV_OBJECT_TYPE_BUFF_2 = 184664, @@ -86,44 +86,29 @@ enum BattlegroundRVData BG_RV_FIRE_TO_PILLAR_TIMER = 20000, BG_RV_CLOSE_FIRE_TIMER = 5000, BG_RV_FIRST_TIMER = 20133, - BG_RV_WORLD_STATE_A = 0xe10, - BG_RV_WORLD_STATE_H = 0xe11, + BG_RV_WORLD_STATE = 0xe1a }; -class BattlegroundRV : public Battleground +class BattlegroundRV : public Arena { public: BattlegroundRV(); - ~BattlegroundRV(); /* inherited from BattlegroundClass */ - void AddPlayer(Player* player); - void StartingEventCloseDoors(); void StartingEventOpenDoors(); - void Reset(); void FillInitialWorldStates(WorldPacket &d); - void RemovePlayer(Player* player, uint64 guid, uint32 team); void HandleAreaTrigger(Player* Source, uint32 Trigger); bool SetupBattleground(); - void HandleKillPlayer(Player* player, Player* killer); private: - uint32 Timer; - uint32 State; - bool PillarCollision; - void PostUpdateImpl(uint32 diff); - protected: - uint32 getTimer() { return Timer; } - void setTimer(uint32 timer) { Timer = timer; } - - uint32 getState() { return State; } - void setState(uint32 state) { State = state; } void TogglePillarCollision(); - bool GetPillarCollision() { return PillarCollision; } - void SetPillarCollision(bool apply) { PillarCollision = apply; } + + uint32 _timer; + uint32 _state; + bool _pillarCollision; }; #endif diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp index 1faa3361975..c50669b137e 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp @@ -82,7 +82,7 @@ void BattlegroundWS::PostUpdateImpl(uint32 diff) if (GetTeamScore(TEAM_ALLIANCE) == 0) { if (GetTeamScore(TEAM_HORDE) == 0) // No one scored - result is tie - EndBattleground(WINNER_NONE); + EndBattleground(0); else // Horde has more points and thus wins EndBattleground(HORDE); } diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 946cbc42f25..24b2dbb05f8 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -623,7 +623,7 @@ struct BattlemasterListEntry { uint32 id; // 0 int32 mapid[8]; // 1-8 mapid - uint32 type; // 9 (3 - BG, 4 - arena) + uint32 type; // 9 map type (3 - BG, 4 - arena) //uint32 canJoinAsGroup; // 10 (0 or 1) char* name[16]; // 11-26 //uint32 nameFlags // 27 string flag, unused diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index cc199969174..d41878bed3b 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -525,7 +525,7 @@ void Pet::setDeathState(DeathState s) // overwrite virtual //lose happiness when died and not in BG/Arena MapEntry const* mapEntry = sMapStore.LookupEntry(GetMapId()); - if (!mapEntry || (mapEntry->map_type != MAP_ARENA && mapEntry->map_type != MAP_BATTLEGROUND)) + if (!GetMap()->IsBattlegroundOrArena()) ModifyPower(POWER_HAPPINESS, -HAPPINESS_LEVEL_SIZE); //SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); |