From f32d6d31c91e9933babd2c17e2bc18caf98f0a4d Mon Sep 17 00:00:00 2001 From: Xfurry Date: Fri, 17 Aug 2012 18:53:13 +0200 Subject: [PATCH] Implement Terokkar Forest Outdoor PvP script --- src/game/OutdoorPvP/OutdoorPvPMgr.cpp | 1 + src/game/OutdoorPvP/OutdoorPvPTF.cpp | 350 ++++++++++++++++++++++++++ src/game/OutdoorPvP/OutdoorPvPTF.h | 179 +++++++++++++ 3 files changed, 530 insertions(+) diff --git a/src/game/OutdoorPvP/OutdoorPvPMgr.cpp b/src/game/OutdoorPvP/OutdoorPvPMgr.cpp index ee5a7fa65..1bfab9945 100644 --- a/src/game/OutdoorPvP/OutdoorPvPMgr.cpp +++ b/src/game/OutdoorPvP/OutdoorPvPMgr.cpp @@ -53,6 +53,7 @@ void OutdoorPvPMgr::InitOutdoorPvP() m_scripts[OPVP_ID_EP] = new OutdoorPvPEP(); m_scripts[OPVP_ID_HP] = new OutdoorPvPHP(); m_scripts[OPVP_ID_ZM] = new OutdoorPvPZM(); + m_scripts[OPVP_ID_TF] = new OutdoorPvPTF(); sLog.outString(); sLog.outString(">> Loaded %u Outdoor PvP zones", MAX_OPVP_ID); diff --git a/src/game/OutdoorPvP/OutdoorPvPTF.cpp b/src/game/OutdoorPvP/OutdoorPvPTF.cpp index b166faf81..d28e490cf 100644 --- a/src/game/OutdoorPvP/OutdoorPvPTF.cpp +++ b/src/game/OutdoorPvP/OutdoorPvPTF.cpp @@ -15,3 +15,353 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include "OutdoorPvPTF.h" +#include "WorldPacket.h" +#include "../World.h" +#include "../ObjectMgr.h" +#include "../Object.h" +#include "../Creature.h" +#include "../GameObject.h" +#include "../Player.h" + +OutdoorPvPTF::OutdoorPvPTF() : OutdoorPvP(), + m_zoneWorldState(WORLD_STATE_TF_TOWERS_CONTROLLED), + m_zoneOwner(TEAM_NONE), + //m_zoneUpdateTimer(TIMER_TF_UPDATE_TIME), + m_zoneLockTimer(0), + m_towersAlliance(0), + m_towersHorde(0) +{ + m_towerWorldState[0] = WORLD_STATE_TF_WEST_TOWER_NEUTRAL; + m_towerWorldState[1] = WORLD_STATE_TF_NORTH_TOWER_NEUTRAL; + m_towerWorldState[2] = WORLD_STATE_TF_EAST_TOWER_NEUTRAL; + m_towerWorldState[3] = WORLD_STATE_TF_SOUTH_EAST_TOWER_NEUTRAL; + m_towerWorldState[4] = WORLD_STATE_TF_SOUTH_TOWER_NEUTRAL; + + for (uint8 i = 0; i < MAX_TF_TOWERS; ++i) + m_towerOwner[i] = TEAM_NONE; +} + +void OutdoorPvPTF::FillInitialWorldStates(WorldPacket& data, uint32& count) +{ + FillInitialWorldState(data, count, m_zoneWorldState, WORLD_STATE_ADD); + if (m_zoneWorldState == WORLD_STATE_TF_TOWERS_CONTROLLED) + { + FillInitialWorldState(data, count, WORLD_STATE_TF_TOWER_COUNT_H, m_towersHorde); + FillInitialWorldState(data, count, WORLD_STATE_TF_TOWER_COUNT_A, m_towersAlliance); + + for (uint8 i = 0; i < MAX_TF_TOWERS; ++i) + FillInitialWorldState(data, count, m_towerWorldState[i], WORLD_STATE_ADD); + } + else + UpdateTimerWorldState(); +} + +void OutdoorPvPTF::SendRemoveWorldStates(Player* player) +{ + player->SendUpdateWorldState(m_zoneWorldState, WORLD_STATE_REMOVE); + + for (uint8 i = 0; i < MAX_TF_TOWERS; ++i) + player->SendUpdateWorldState(m_towerWorldState[i], WORLD_STATE_REMOVE); +} + +void OutdoorPvPTF::HandlePlayerEnterZone(Player* player, bool isMainZone) +{ + OutdoorPvP::HandlePlayerEnterZone(player, isMainZone); + + // remove the buff from the player first because there are some issues at relog + player->RemoveAurasDueToSpell(SPELL_AUCHINDOUN_BLESSING); + + // Handle the buffs + if (player->GetTeam() == m_zoneOwner) + player->CastSpell(player, SPELL_AUCHINDOUN_BLESSING, true); +} + +void OutdoorPvPTF::HandlePlayerLeaveZone(Player* player, bool isMainZone) +{ + // remove the buff from the player + player->RemoveAurasDueToSpell(SPELL_AUCHINDOUN_BLESSING); + + OutdoorPvP::HandlePlayerLeaveZone(player, isMainZone); +} + +void OutdoorPvPTF::HandleGameObjectCreate(GameObject* go) +{ + switch (go->GetEntry()) + { + case GO_TOWER_BANNER_WEST: + m_towerBanners[0] = go->GetObjectGuid(); + go->SetGoArtKit(GetBannerArtKit(m_towerOwner[0])); + break; + case GO_TOWER_BANNER_NORTH: + m_towerBanners[1] = go->GetObjectGuid(); + go->SetGoArtKit(GetBannerArtKit(m_towerOwner[1])); + break; + case GO_TOWER_BANNER_EAST: + m_towerBanners[2] = go->GetObjectGuid(); + go->SetGoArtKit(GetBannerArtKit(m_towerOwner[2])); + break; + case GO_TOWER_BANNER_SOUTH_EAST: + m_towerBanners[3] = go->GetObjectGuid(); + go->SetGoArtKit(GetBannerArtKit(m_towerOwner[3])); + break; + case GO_TOWER_BANNER_SOUTH: + m_towerBanners[4] = go->GetObjectGuid(); + go->SetGoArtKit(GetBannerArtKit(m_towerOwner[4])); + break; + } +} + +void OutdoorPvPTF::HandleObjectiveComplete(uint32 eventId, std::list players, Team team) +{ + for (uint8 i = 0; i < MAX_TF_TOWERS; ++i) + { + for (uint8 j = 0; j < 4; ++j) + { + if (terokkarTowerEvents[i][j].eventEntry == eventId) + { + for (std::list::iterator itr = players.begin(); itr != players.end(); ++itr) + { + if ((*itr) && (*itr)->GetTeam() == team) + (*itr)->AreaExploredOrEventHappens(team == ALLIANCE ? QUEST_SPIRITS_OF_AUCHINDOUM_ALLIANCE : QUEST_SPIRITS_OF_AUCHINDOUM_HORDE); + } + return; + } + } + } +} + +// process the capture events +bool OutdoorPvPTF::HandleEvent(uint32 eventId, GameObject* go) +{ + for (uint8 i = 0; i < MAX_TF_TOWERS; ++i) + { + if (terokkarTowers[i] == go->GetEntry()) + { + for (uint8 j = 0; j < 4; ++j) + { + if (terokkarTowerEvents[i][j].eventEntry == eventId) + { + // prevent processing if the owner did not change (happens if progress event is called after contest event) + if (terokkarTowerEvents[i][j].team != m_towerOwner[i]) + { + sWorld.SendDefenseMessage(ZONE_ID_TEROKKAR_FOREST, terokkarTowerEvents[i][j].defenseMessage); + + return ProcessCaptureEvent(go, i, terokkarTowerEvents[i][j].team, terokkarTowerEvents[i][j].worldState); + } + // no need to iterate other events or towers + return false; + } + } + // no need to iterate other towers + return false; + } + } + + return false; +} + +bool OutdoorPvPTF::ProcessCaptureEvent(GameObject* go, uint32 towerId, Team team, uint32 newWorldState) +{ + if (team == ALLIANCE) + { + // update banner + SetBannerVisual(go, CAPTURE_ARTKIT_ALLIANCE, CAPTURE_ANIM_ALLIANCE); + + // update tower count + ++m_towersAlliance; + + // if all towers are captured then process event + if (m_towersAlliance == MAX_TF_TOWERS) + { + LockZone(go, towerId, team, newWorldState); + return true; + } + + // update tower count world state + SendUpdateWorldState(WORLD_STATE_TF_TOWER_COUNT_A, m_towersAlliance); + } + else if (team == HORDE) + { + // update banner + SetBannerVisual(go, CAPTURE_ARTKIT_HORDE, CAPTURE_ANIM_HORDE); + + // update tower count + ++m_towersHorde; + + // if all towers are captured then process event + if (m_towersHorde == MAX_TF_TOWERS) + { + LockZone(go, towerId, team, newWorldState); + return true; + } + + // update tower count world state + SendUpdateWorldState(WORLD_STATE_TF_TOWER_COUNT_H, m_towersHorde); + } + else + { + // update banner + SetBannerVisual(go, CAPTURE_ARTKIT_NEUTRAL, CAPTURE_ANIM_NEUTRAL); + + // update tower count + if (m_towerOwner[towerId] == ALLIANCE) + { + --m_towersAlliance; + SendUpdateWorldState(WORLD_STATE_TF_TOWER_COUNT_A, m_towersAlliance); + } + else + { + --m_towersHorde; + SendUpdateWorldState(WORLD_STATE_TF_TOWER_COUNT_H, m_towersHorde); + } + } + + // update tower state + SendUpdateWorldState(m_towerWorldState[towerId], WORLD_STATE_REMOVE); + m_towerWorldState[towerId] = newWorldState; + SendUpdateWorldState(m_towerWorldState[towerId], WORLD_STATE_ADD); + + // update capture point owner + m_towerOwner[towerId] = team; + + // the are no DB exceptions in this case + return true; +} + +// Handle the zone lock when the timer is activated +void OutdoorPvPTF::LockZone(GameObject* go, uint32 towerId, Team team, uint32 newWorldState) +{ + SendUpdateWorldState(m_zoneWorldState, WORLD_STATE_REMOVE); + m_zoneWorldState = team == ALLIANCE ? WORLD_STATE_TF_LOCKED_ALLIANCE : WORLD_STATE_TF_LOCKED_HORDE; + SendUpdateWorldState(m_zoneWorldState, WORLD_STATE_ADD); + + m_zoneLockTimer = TIMER_TF_LOCK_TIME; + UpdateTimerWorldState(); + + m_zoneOwner = team; + BuffTeam(team, SPELL_AUCHINDOUN_BLESSING); + + // lock the towers + LockTowers(go); + + sWorld.SendDefenseMessage(ZONE_ID_TEROKKAR_FOREST, team == ALLIANCE ? LANG_OPVP_TF_CAPTURE_ALL_TOWERS_A : LANG_OPVP_TF_CAPTURE_ALL_TOWERS_H); + + // remove tower states when zone has been captured and locked + for (uint8 i = 0; i < MAX_TF_TOWERS; ++i) + SendUpdateWorldState(m_towerWorldState[i], WORLD_STATE_REMOVE); + + m_towerWorldState[towerId] = newWorldState; +} + +// Handle the zone reset when the timer expires +void OutdoorPvPTF::UnlockZone() +{ + // remove buffs + BuffTeam(m_zoneOwner, SPELL_AUCHINDOUN_BLESSING, true); + + m_zoneOwner = TEAM_NONE; + + // reset world states and towers + SendUpdateWorldState(m_zoneWorldState, WORLD_STATE_REMOVE); + m_zoneWorldState = WORLD_STATE_TF_TOWERS_CONTROLLED; + SendUpdateWorldState(m_zoneWorldState, WORLD_STATE_ADD); + + // reset tower states + m_towerWorldState[0] = WORLD_STATE_TF_WEST_TOWER_NEUTRAL; + m_towerWorldState[1] = WORLD_STATE_TF_NORTH_TOWER_NEUTRAL; + m_towerWorldState[2] = WORLD_STATE_TF_EAST_TOWER_NEUTRAL; + m_towerWorldState[3] = WORLD_STATE_TF_SOUTH_EAST_TOWER_NEUTRAL; + m_towerWorldState[4] = WORLD_STATE_TF_SOUTH_TOWER_NEUTRAL; + for (uint8 i = 0; i < MAX_TF_TOWERS; ++i) + SendUpdateWorldState(m_towerWorldState[i], WORLD_STATE_ADD); + + // update tower count + m_towersAlliance = 0; + m_towersHorde = 0; + SendUpdateWorldState(WORLD_STATE_TF_TOWER_COUNT_A, m_towersAlliance); + SendUpdateWorldState(WORLD_STATE_TF_TOWER_COUNT_H, m_towersHorde); + + for (GuidZoneMap::iterator itr = m_zonePlayers.begin(); itr != m_zonePlayers.end(); ++itr) + { + // Find player who is in main zone (Terokkar Forest) to get correct map reference + if (!itr->second) + continue; + + if (Player* player = sObjectMgr.GetPlayer(itr->first)) + { + ResetTowers(player); + break; + } + } +} + +void OutdoorPvPTF::Update(uint32 diff) +{ + if (m_zoneLockTimer) + { + if (m_zoneLockTimer < diff) + { + UnlockZone(); + m_zoneLockTimer = 0; + } + else + { + // update timer - if OutdoorPvPMgr update timer interval needs to be lowered replace this line with the commented-out ones below + UpdateTimerWorldState(); + + /*if (m_zoneUpdateTimer < diff) + { + // update timer + UpdateTimerWorldState(); + m_zoneUpdateTimer = TIMER_TF_UPDATE_TIME; + } + else + m_zoneUpdateTimer -= diff;*/ + + m_zoneLockTimer -= diff; + } + } +} + +void OutdoorPvPTF::UpdateTimerWorldState() +{ + // Calculate time + uint32 minutesLeft = m_zoneLockTimer / 60000; + uint32 hoursLeft = minutesLeft / 60; + minutesLeft -= hoursLeft * 60; + uint32 firstDigit = minutesLeft / 10; + + SendUpdateWorldState(WORLD_STATE_TF_TIME_MIN_FIRST_DIGIT, firstDigit); + SendUpdateWorldState(WORLD_STATE_TF_TIME_MIN_SECOND_DIGIT, minutesLeft - firstDigit * 10); + SendUpdateWorldState(WORLD_STATE_TF_TIME_HOURS, hoursLeft); +} + +// Handle the Terokkar towers lock during the update timer +void OutdoorPvPTF::LockTowers(const WorldObject* objRef) +{ + for (uint8 i = 0; i < MAX_TF_TOWERS; ++i) + { + if (GameObject* go = objRef->GetMap()->GetGameObject(m_towerBanners[i])) + go->SetLootState(GO_JUST_DEACTIVATED); + + sOutdoorPvPMgr.SetCapturePointSlider(terokkarTowers[i], m_zoneOwner == ALLIANCE ? CAPTURE_SLIDER_ALLIANCE_LOCKED : CAPTURE_SLIDER_HORDE_LOCKED); + } +} + +// Handle towers reset when the timer expires +void OutdoorPvPTF::ResetTowers(const WorldObject* objRef) +{ + for (uint8 i = 0; i < MAX_TF_TOWERS; ++i) + { + if (GameObject* go = objRef->GetMap()->GetGameObject(m_towerBanners[i])) + { + go->SetCapturePointSlider(CAPTURE_SLIDER_NEUTRAL); + SetBannerVisual(go, CAPTURE_ARTKIT_NEUTRAL, CAPTURE_ANIM_NEUTRAL); + } + else + // if grid is unloaded, resetting the slider value is enough + sOutdoorPvPMgr.SetCapturePointSlider(terokkarTowers[i], CAPTURE_SLIDER_NEUTRAL); + } +} diff --git a/src/game/OutdoorPvP/OutdoorPvPTF.h b/src/game/OutdoorPvP/OutdoorPvPTF.h index db3b482a9..164b36e23 100644 --- a/src/game/OutdoorPvP/OutdoorPvPTF.h +++ b/src/game/OutdoorPvP/OutdoorPvPTF.h @@ -19,4 +19,183 @@ #ifndef WORLD_PVP_TF #define WORLD_PVP_TF +#include "Common.h" +#include "OutdoorPvP.h" +#include "../Language.h" + +enum +{ + MAX_TF_TOWERS = 5, + + // gameobjects + GO_TOWER_BANNER_WEST = 183104, + GO_TOWER_BANNER_NORTH = 183411, + GO_TOWER_BANNER_EAST = 183412, + GO_TOWER_BANNER_SOUTH_EAST = 183413, + GO_TOWER_BANNER_SOUTH = 183414, + + // spells + SPELL_AUCHINDOUN_BLESSING = 33377, + + // timers + TIMER_TF_LOCK_TIME = 6 * HOUR * IN_MILLISECONDS, + //TIMER_TF_UPDATE_TIME = MINUTE * IN_MILLISECONDS, + + // quests + QUEST_SPIRITS_OF_AUCHINDOUM_ALLIANCE = 11505, + QUEST_SPIRITS_OF_AUCHINDOUM_HORDE = 11506, + + // events + EVENT_WEST_TOWER_PROGRESS_ALLIANCE = 12226, + EVENT_WEST_TOWER_PROGRESS_HORDE = 12225, + EVENT_WEST_TOWER_NEUTRAL_ALLIANCE = 12228, + EVENT_WEST_TOWER_NEUTRAL_HORDE = 12227, + + EVENT_NORTH_TOWER_PROGRESS_ALLIANCE = 12497, + EVENT_NORTH_TOWER_PROGRESS_HORDE = 12496, + EVENT_NORTH_TOWER_NEUTRAL_ALLIANCE = 12490, + EVENT_NORTH_TOWER_NEUTRAL_HORDE = 12491, + + EVENT_EAST_TOWER_PROGRESS_ALLIANCE = 12486, + EVENT_EAST_TOWER_PROGRESS_HORDE = 12487, + EVENT_EAST_TOWER_NEUTRAL_ALLIANCE = 12488, + EVENT_EAST_TOWER_NEUTRAL_HORDE = 12489, + + EVENT_SOUTH_EAST_TOWER_PROGRESS_ALLIANCE = 12499, + EVENT_SOUTH_EAST_TOWER_PROGRESS_HORDE = 12498, + EVENT_SOUTH_EAST_TOWER_NEUTRAL_ALLIANCE = 12492, + EVENT_SOUTH_EAST_TOWER_NEUTRAL_HORDE = 12493, + + EVENT_SOUTH_TOWER_PROGRESS_ALLIANCE = 12501, + EVENT_SOUTH_TOWER_PROGRESS_HORDE = 12500, + EVENT_SOUTH_TOWER_NEUTRAL_ALLIANCE = 12494, + EVENT_SOUTH_TOWER_NEUTRAL_HORDE = 12495, + + // world states + // tower counter before the lock event + WORLD_STATE_TF_TOWER_COUNT_H = 2622, + WORLD_STATE_TF_TOWER_COUNT_A = 2621, + WORLD_STATE_TF_TOWERS_CONTROLLED = 2620, + + // timer for the lock event + WORLD_STATE_TF_TIME_MIN_FIRST_DIGIT = 2512, + WORLD_STATE_TF_TIME_MIN_SECOND_DIGIT = 2510, + WORLD_STATE_TF_TIME_HOURS = 2509, + + // lock period - factions + WORLD_STATE_TF_LOCKED_NEUTRAL = 2508, + WORLD_STATE_TF_LOCKED_HORDE = 2768, + WORLD_STATE_TF_LOCKED_ALLIANCE = 2767, + + // tower world states + WORLD_STATE_TF_WEST_TOWER_ALLIANCE = 2683, + WORLD_STATE_TF_WEST_TOWER_HORDE = 2682, + WORLD_STATE_TF_WEST_TOWER_NEUTRAL = 2681, + + WORLD_STATE_TF_NORTH_TOWER_ALLIANCE = 2684, + WORLD_STATE_TF_NORTH_TOWER_HORDE = 2685, + WORLD_STATE_TF_NORTH_TOWER_NEUTRAL = 2686, + + WORLD_STATE_TF_EAST_TOWER_ALLIANCE = 2688, + WORLD_STATE_TF_EAST_TOWER_HORDE = 2689, + WORLD_STATE_TF_EAST_TOWER_NEUTRAL = 2690, + + WORLD_STATE_TF_SOUTH_EAST_TOWER_ALLIANCE = 2694, + WORLD_STATE_TF_SOUTH_EAST_TOWER_HORDE = 2695, + WORLD_STATE_TF_SOUTH_EAST_TOWER_NEUTRAL = 2696, + + WORLD_STATE_TF_SOUTH_TOWER_ALLIANCE = 2691, + WORLD_STATE_TF_SOUTH_TOWER_HORDE = 2692, + WORLD_STATE_TF_SOUTH_TOWER_NEUTRAL = 2693 +}; + +struct TerokkarTowerEvent +{ + uint32 eventEntry; + Team team; + uint32 defenseMessage; + uint32 worldState; +}; + +static const TerokkarTowerEvent terokkarTowerEvents[MAX_TF_TOWERS][4] = +{ + { + {EVENT_WEST_TOWER_PROGRESS_ALLIANCE, ALLIANCE, LANG_OPVP_TF_CAPTURE_TOWER_A, WORLD_STATE_TF_WEST_TOWER_ALLIANCE}, + {EVENT_WEST_TOWER_PROGRESS_HORDE, HORDE, LANG_OPVP_TF_CAPTURE_TOWER_H, WORLD_STATE_TF_WEST_TOWER_HORDE}, + {EVENT_WEST_TOWER_NEUTRAL_HORDE, TEAM_NONE, LANG_OPVP_TF_LOSE_TOWER_A, WORLD_STATE_TF_WEST_TOWER_NEUTRAL}, + {EVENT_WEST_TOWER_NEUTRAL_ALLIANCE, TEAM_NONE, LANG_OPVP_TF_LOSE_TOWER_H, WORLD_STATE_TF_WEST_TOWER_NEUTRAL}, + }, + { + {EVENT_NORTH_TOWER_PROGRESS_ALLIANCE, ALLIANCE, LANG_OPVP_TF_CAPTURE_TOWER_A, WORLD_STATE_TF_NORTH_TOWER_ALLIANCE}, + {EVENT_NORTH_TOWER_PROGRESS_HORDE, HORDE, LANG_OPVP_TF_CAPTURE_TOWER_H, WORLD_STATE_TF_NORTH_TOWER_HORDE}, + {EVENT_NORTH_TOWER_NEUTRAL_HORDE, TEAM_NONE, LANG_OPVP_TF_LOSE_TOWER_A, WORLD_STATE_TF_NORTH_TOWER_NEUTRAL}, + {EVENT_NORTH_TOWER_NEUTRAL_ALLIANCE, TEAM_NONE, LANG_OPVP_TF_LOSE_TOWER_H, WORLD_STATE_TF_NORTH_TOWER_NEUTRAL}, + }, + { + {EVENT_EAST_TOWER_PROGRESS_ALLIANCE, ALLIANCE, LANG_OPVP_TF_CAPTURE_TOWER_A, WORLD_STATE_TF_EAST_TOWER_ALLIANCE}, + {EVENT_EAST_TOWER_PROGRESS_HORDE, HORDE, LANG_OPVP_TF_CAPTURE_TOWER_H, WORLD_STATE_TF_EAST_TOWER_HORDE}, + {EVENT_EAST_TOWER_NEUTRAL_HORDE, TEAM_NONE, LANG_OPVP_TF_LOSE_TOWER_A, WORLD_STATE_TF_EAST_TOWER_NEUTRAL}, + {EVENT_EAST_TOWER_NEUTRAL_ALLIANCE, TEAM_NONE, LANG_OPVP_TF_LOSE_TOWER_H, WORLD_STATE_TF_EAST_TOWER_NEUTRAL}, + }, + { + {EVENT_SOUTH_EAST_TOWER_PROGRESS_ALLIANCE, ALLIANCE, LANG_OPVP_TF_CAPTURE_TOWER_A, WORLD_STATE_TF_SOUTH_EAST_TOWER_ALLIANCE}, + {EVENT_SOUTH_EAST_TOWER_PROGRESS_HORDE, HORDE, LANG_OPVP_TF_CAPTURE_TOWER_H, WORLD_STATE_TF_SOUTH_EAST_TOWER_HORDE}, + {EVENT_SOUTH_EAST_TOWER_NEUTRAL_HORDE, TEAM_NONE, LANG_OPVP_TF_LOSE_TOWER_A, WORLD_STATE_TF_SOUTH_EAST_TOWER_NEUTRAL}, + {EVENT_SOUTH_EAST_TOWER_NEUTRAL_ALLIANCE, TEAM_NONE, LANG_OPVP_TF_LOSE_TOWER_H, WORLD_STATE_TF_SOUTH_EAST_TOWER_NEUTRAL}, + }, + { + {EVENT_SOUTH_TOWER_PROGRESS_ALLIANCE, ALLIANCE, LANG_OPVP_TF_CAPTURE_TOWER_A, WORLD_STATE_TF_SOUTH_TOWER_ALLIANCE}, + {EVENT_SOUTH_TOWER_PROGRESS_HORDE, HORDE, LANG_OPVP_TF_CAPTURE_TOWER_H, WORLD_STATE_TF_SOUTH_TOWER_HORDE}, + {EVENT_SOUTH_TOWER_NEUTRAL_HORDE, TEAM_NONE, LANG_OPVP_TF_LOSE_TOWER_A, WORLD_STATE_TF_SOUTH_TOWER_NEUTRAL}, + {EVENT_SOUTH_TOWER_NEUTRAL_ALLIANCE, TEAM_NONE, LANG_OPVP_TF_LOSE_TOWER_H, WORLD_STATE_TF_SOUTH_TOWER_NEUTRAL}, + }, +}; + +static const uint32 terokkarTowers[MAX_TF_TOWERS] = {GO_TOWER_BANNER_WEST, GO_TOWER_BANNER_NORTH, GO_TOWER_BANNER_EAST, GO_TOWER_BANNER_SOUTH_EAST, GO_TOWER_BANNER_SOUTH}; + +class OutdoorPvPTF : public OutdoorPvP +{ + friend class OutdoorPvPMgr; + + public: + OutdoorPvPTF(); + + void HandlePlayerEnterZone(Player* player, bool isMainZone) override; + void HandlePlayerLeaveZone(Player* player, bool isMainZone) override; + void FillInitialWorldStates(WorldPacket& data, uint32& count) override; + void SendRemoveWorldStates(Player* player) override; + + bool HandleEvent(uint32 eventId, GameObject* go) override; + void HandleObjectiveComplete(uint32 eventId, std::list players, Team team) override; + + void HandleGameObjectCreate(GameObject* go) override; + void Update(uint32 diff) override; + + private: + void UpdateTimerWorldState(); + + // process capture events + bool ProcessCaptureEvent(GameObject* go, uint32 towerId, Team team, uint32 newWorldState); + + void LockZone(GameObject* go, uint32 towerId, Team team, uint32 newWorldState); + void UnlockZone(); + + void LockTowers(const WorldObject* objRef); + void ResetTowers(const WorldObject* objRef); + + uint32 m_towerWorldState[MAX_TF_TOWERS]; + uint32 m_zoneWorldState; + + Team m_towerOwner[MAX_TF_TOWERS]; + Team m_zoneOwner; + + uint32 m_zoneLockTimer; + //uint32 m_zoneUpdateTimer; + + uint8 m_towersAlliance; + uint8 m_towersHorde; + + ObjectGuid m_towerBanners[MAX_TF_TOWERS]; +}; + #endif