diff --git a/src/game/OutdoorPvP/OutdoorPvPEP.cpp b/src/game/OutdoorPvP/OutdoorPvPEP.cpp index b166faf81..e6b4c46e2 100644 --- a/src/game/OutdoorPvP/OutdoorPvPEP.cpp +++ b/src/game/OutdoorPvP/OutdoorPvPEP.cpp @@ -15,3 +15,344 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include "OutdoorPvPEP.h" +#include "WorldPacket.h" +#include "../World.h" +#include "../ObjectMgr.h" +#include "../Object.h" +#include "../Creature.h" +#include "../GameObject.h" +#include "../Player.h" + +OutdoorPvPEP::OutdoorPvPEP() : OutdoorPvP(), + m_towersAlliance(0), + m_towersHorde(0) +{ + m_towerWorldState[0] = WORLD_STATE_EP_NORTHPASS_NEUTRAL; + m_towerWorldState[1] = WORLD_STATE_EP_CROWNGUARD_NEUTRAL; + m_towerWorldState[2] = WORLD_STATE_EP_EASTWALL_NEUTRAL; + m_towerWorldState[3] = WORLD_STATE_EP_PLAGUEWOOD_NEUTRAL; + + for (uint8 i = 0; i < MAX_EP_TOWERS; ++i) + m_towerOwner[i] = TEAM_NONE; + + // initially set graveyard owner to neither faction + sObjectMgr.SetGraveYardLinkTeam(GRAVEYARD_ID_EASTERN_PLAGUE, GRAVEYARD_ZONE_EASTERN_PLAGUE, TEAM_INVALID); +} + +void OutdoorPvPEP::FillInitialWorldStates(WorldPacket& data, uint32& count) +{ + FillInitialWorldState(data, count, WORLD_STATE_EP_TOWER_COUNT_ALLIANCE, m_towersAlliance); + FillInitialWorldState(data, count, WORLD_STATE_EP_TOWER_COUNT_HORDE, m_towersHorde); + + for (uint8 i = 0; i < MAX_EP_TOWERS; ++i) + FillInitialWorldState(data, count, m_towerWorldState[i], WORLD_STATE_ADD); +} + +void OutdoorPvPEP::SendRemoveWorldStates(Player* player) +{ + for (uint8 i = 0; i < MAX_EP_TOWERS; ++i) + player->SendUpdateWorldState(m_towerWorldState[i], WORLD_STATE_REMOVE); +} + +void OutdoorPvPEP::HandlePlayerEnterZone(Player* player, bool isMainZone) +{ + OutdoorPvP::HandlePlayerEnterZone(player, isMainZone); + + // remove the buff from the player first; Sometimes on relog players still have the aura + for (uint8 i = 0; i < MAX_EP_TOWERS; ++i) + player->RemoveAurasDueToSpell(player->GetTeam() == ALLIANCE ? plaguelandsTowerBuffs[i].spellIdAlliance : plaguelandsTowerBuffs[i].spellIdHorde); + + // buff the player + switch (player->GetTeam()) + { + case ALLIANCE: + if (m_towersAlliance > 0) + player->CastSpell(player, plaguelandsTowerBuffs[m_towersAlliance - 1].spellIdAlliance, true); + break; + case HORDE: + if (m_towersHorde > 0) + player->CastSpell(player, plaguelandsTowerBuffs[m_towersHorde - 1].spellIdHorde, true); + break; + default: + break; + } +} + +void OutdoorPvPEP::HandlePlayerLeaveZone(Player* player, bool isMainZone) +{ + // remove the buff from the player + for (uint8 i = 0; i < MAX_EP_TOWERS; ++i) + player->RemoveAurasDueToSpell(player->GetTeam() == ALLIANCE ? plaguelandsTowerBuffs[i].spellIdAlliance : plaguelandsTowerBuffs[i].spellIdHorde); + + OutdoorPvP::HandlePlayerLeaveZone(player, isMainZone); +} + +void OutdoorPvPEP::HandleCreatureCreate(Creature* creature) +{ + switch (creature->GetEntry()) + { + case NPC_SPECTRAL_FLIGHT_MASTER: + m_flightMaster = creature->GetObjectGuid(); + creature->setFaction(m_towerOwner[TOWER_ID_PLAGUEWOOD] == ALLIANCE ? FACTION_FLIGHT_MASTER_ALLIANCE : FACTION_FLIGHT_MASTER_HORDE); + creature->CastSpell(creature, m_towerOwner[TOWER_ID_PLAGUEWOOD] == ALLIANCE ? SPELL_SPIRIT_PARTICLES_BLUE : SPELL_SPIRIT_PARTICLES_RED, true); + break; + case NPC_LORDAERON_COMMANDER: + case NPC_LORDAERON_SOLDIER: + case NPC_LORDAERON_VETERAN: + case NPC_LORDAERON_FIGHTER: + m_soldiers.push_back(creature->GetObjectGuid()); + break; + } +} + +void OutdoorPvPEP::HandleGameObjectCreate(GameObject* go) +{ + switch (go->GetEntry()) + { + case GO_TOWER_BANNER_NORTHPASS: + InitBanner(go, TOWER_ID_NORTHPASS); + break; + case GO_TOWER_BANNER_CROWNGUARD: + InitBanner(go, TOWER_ID_CROWNGUARD); + break; + case GO_TOWER_BANNER_EASTWALL: + InitBanner(go, TOWER_ID_EASTWALL); + break; + case GO_TOWER_BANNER_PLAGUEWOOD: + InitBanner(go, TOWER_ID_PLAGUEWOOD); + break; + case GO_TOWER_BANNER: + // sort banners + if (go->IsWithinDist2d(plaguelandsTowerLocations[TOWER_ID_NORTHPASS][0], plaguelandsTowerLocations[TOWER_ID_NORTHPASS][1], 50.0f)) + InitBanner(go, TOWER_ID_NORTHPASS); + else if (go->IsWithinDist2d(plaguelandsTowerLocations[TOWER_ID_CROWNGUARD][0], plaguelandsTowerLocations[TOWER_ID_CROWNGUARD][1], 50.0f)) + InitBanner(go, TOWER_ID_CROWNGUARD); + else if (go->IsWithinDist2d(plaguelandsTowerLocations[TOWER_ID_EASTWALL][0], plaguelandsTowerLocations[TOWER_ID_EASTWALL][1], 50.0f)) + InitBanner(go, TOWER_ID_EASTWALL); + else if (go->IsWithinDist2d(plaguelandsTowerLocations[TOWER_ID_PLAGUEWOOD][0], plaguelandsTowerLocations[TOWER_ID_PLAGUEWOOD][1], 50.0f)) + InitBanner(go, TOWER_ID_PLAGUEWOOD); + break; + case GO_LORDAERON_SHRINE_ALLIANCE: + m_lordaeronShrineAlliance = go->GetObjectGuid(); + break; + case GO_LORDAERON_SHRINE_HORDE: + m_lordaeronShrineHorde = go->GetObjectGuid(); + break; + } +} + +void OutdoorPvPEP::HandleObjectiveComplete(uint32 eventId, std::list players, Team team) +{ + uint32 credit = 0; + + switch (eventId) + { + case EVENT_CROWNGUARD_PROGRESS_ALLIANCE: + case EVENT_CROWNGUARD_PROGRESS_HORDE: + credit = NPC_CROWNGUARD_TOWER_QUEST_DOODAD; + break; + case EVENT_EASTWALL_PROGRESS_ALLIANCE: + case EVENT_EASTWALL_PROGRESS_HORDE: + credit = NPC_EASTWALL_TOWER_QUEST_DOODAD; + break; + case EVENT_NORTHPASS_PROGRESS_ALLIANCE: + case EVENT_NORTHPASS_PROGRESS_HORDE: + credit = NPC_NORTHPASS_TOWER_QUEST_DOODAD; + break; + case EVENT_PLAGUEWOOD_PROGRESS_ALLIANCE: + case EVENT_PLAGUEWOOD_PROGRESS_HORDE: + credit = NPC_PLAGUEWOOD_TOWER_QUEST_DOODAD; + break; + default: + return; + } + + for (std::list::iterator itr = players.begin(); itr != players.end(); ++itr) + { + if ((*itr) && (*itr)->GetTeam() == team) + { + (*itr)->KilledMonsterCredit(credit); + (*itr)->RewardHonor(NULL, 1, HONOR_REWARD_PLAGUELANDS); + } + } +} + +// process the capture events +bool OutdoorPvPEP::HandleEvent(uint32 eventId, GameObject* go) +{ + for (uint8 i = 0; i < MAX_EP_TOWERS; ++i) + { + if (plaguelandsBanners[i] == go->GetEntry()) + { + for (uint8 j = 0; j < 4; ++j) + { + if (plaguelandsTowerEvents[i][j].eventEntry == eventId) + { + // prevent processing if the owner did not change (happens if progress event is called after contest event) + if (plaguelandsTowerEvents[i][j].team != m_towerOwner[i]) + { + if (plaguelandsTowerEvents[i][j].defenseMessage) + sWorld.SendDefenseMessage(ZONE_ID_EASTERN_PLAGUELANDS, plaguelandsTowerEvents[i][j].defenseMessage); + + return ProcessCaptureEvent(go, i, plaguelandsTowerEvents[i][j].team, plaguelandsTowerEvents[i][j].worldState); + } + // no need to iterate other events or towers + return false; + } + } + // no need to iterate other towers + return false; + } + } + + return false; +} + +bool OutdoorPvPEP::ProcessCaptureEvent(GameObject* go, uint32 towerId, Team team, uint32 newWorldState) +{ + if (team == ALLIANCE) + { + // update banner + for (GuidList::const_iterator itr = m_towerBanners[towerId].begin(); itr != m_towerBanners[towerId].end(); ++itr) + SetBannerVisual(go, (*itr), CAPTURE_ARTKIT_ALLIANCE, CAPTURE_ANIM_ALLIANCE); + + // update counter + ++m_towersAlliance; + SendUpdateWorldState(WORLD_STATE_EP_TOWER_COUNT_ALLIANCE, m_towersAlliance); + + // buff players + BuffTeam(ALLIANCE, plaguelandsTowerBuffs[m_towersAlliance - 1].spellIdAlliance); + } + else if (team == HORDE) + { + // update banner + for (GuidList::const_iterator itr = m_towerBanners[towerId].begin(); itr != m_towerBanners[towerId].end(); ++itr) + SetBannerVisual(go, (*itr), CAPTURE_ARTKIT_HORDE, CAPTURE_ANIM_HORDE); + + // update counter + ++m_towersHorde; + SendUpdateWorldState(WORLD_STATE_EP_TOWER_COUNT_HORDE, m_towersHorde); + + // buff players + BuffTeam(HORDE, plaguelandsTowerBuffs[m_towersHorde - 1].spellIdHorde); + } + else + { + // update banner + for (GuidList::const_iterator itr = m_towerBanners[towerId].begin(); itr != m_towerBanners[towerId].end(); ++itr) + SetBannerVisual(go, (*itr), CAPTURE_ARTKIT_NEUTRAL, CAPTURE_ANIM_NEUTRAL); + + if (m_towerOwner[towerId] == ALLIANCE) + { + // update counter + --m_towersAlliance; + SendUpdateWorldState(WORLD_STATE_EP_TOWER_COUNT_ALLIANCE, m_towersAlliance); + + if (m_towersAlliance == 0) + BuffTeam(ALLIANCE, plaguelandsTowerBuffs[0].spellIdAlliance, true); + } + else + { + // update counter + --m_towersHorde; + SendUpdateWorldState(WORLD_STATE_EP_TOWER_COUNT_HORDE, m_towersHorde); + + if (m_towersHorde == 0) + BuffTeam(HORDE, plaguelandsTowerBuffs[0].spellIdHorde, true); + } + } + + bool eventHandled = true; + + if (team != TEAM_NONE) + { + // update capture point owner before rewards are applied + m_towerOwner[towerId] = team; + + // apply rewards of changed tower + switch (towerId) + { + case TOWER_ID_NORTHPASS: + RespawnGO(go, team == ALLIANCE ? m_lordaeronShrineAlliance : m_lordaeronShrineHorde, true); + break; + case TOWER_ID_CROWNGUARD: + sObjectMgr.SetGraveYardLinkTeam(GRAVEYARD_ID_EASTERN_PLAGUE, GRAVEYARD_ZONE_EASTERN_PLAGUE, team); + break; + case TOWER_ID_EASTWALL: + // Return false - allow the DB to handle summons + if (m_towerOwner[TOWER_ID_NORTHPASS] != team) + eventHandled = false; + break; + case TOWER_ID_PLAGUEWOOD: + // Return false - allow the DB to handle summons + eventHandled = false; + break; + } + } + else + { + // remove rewards of changed tower + switch (towerId) + { + case TOWER_ID_NORTHPASS: + RespawnGO(go, m_towerOwner[TOWER_ID_NORTHPASS] == ALLIANCE ? m_lordaeronShrineAlliance : m_lordaeronShrineHorde, false); + break; + case TOWER_ID_CROWNGUARD: + sObjectMgr.SetGraveYardLinkTeam(GRAVEYARD_ID_EASTERN_PLAGUE, GRAVEYARD_ZONE_EASTERN_PLAGUE, TEAM_INVALID); + break; + case TOWER_ID_EASTWALL: + UnsummonSoldiers(go); + break; + case TOWER_ID_PLAGUEWOOD: + UnsummonFlightMaster(go); + break; + } + + // update capture point owner after rewards have been removed + m_towerOwner[towerId] = team; + } + + // update tower state + SendUpdateWorldState(m_towerWorldState[towerId], WORLD_STATE_REMOVE); + m_towerWorldState[towerId] = newWorldState; + SendUpdateWorldState(m_towerWorldState[towerId], WORLD_STATE_ADD); + + // there are some events which required further DB script + return eventHandled; +} + +bool OutdoorPvPEP::HandleGameObjectUse(Player* /*player*/, GameObject* go) +{ + // prevent despawning after go use + if (go->GetEntry() == GO_LORDAERON_SHRINE_ALLIANCE || go->GetEntry() == GO_LORDAERON_SHRINE_HORDE) + go->SetRespawnTime(0); + + return false; +} + +void OutdoorPvPEP::InitBanner(GameObject* go, uint32 towerId) +{ + m_towerBanners[towerId].push_back(go->GetObjectGuid()); + go->SetGoArtKit(GetBannerArtKit(m_towerOwner[towerId])); +} + +// Handle the unsummon of the spectral flight master when the Plaguewood tower is lost +void OutdoorPvPEP::UnsummonFlightMaster(const WorldObject* objRef) +{ + if (Creature* flightMaster = objRef->GetMap()->GetCreature(m_flightMaster)) + flightMaster->ForcedDespawn(); +} + +// Handle the unsummon of the soldiers when the Eastwall tower is lost +void OutdoorPvPEP::UnsummonSoldiers(const WorldObject* objRef) +{ + for (GuidList::const_iterator itr = m_soldiers.begin(); itr != m_soldiers.end(); ++itr) + { + if (Creature* soldier = objRef->GetMap()->GetCreature(*itr)) + soldier->ForcedDespawn(); + } + + m_soldiers.clear(); +} \ No newline at end of file diff --git a/src/game/OutdoorPvP/OutdoorPvPEP.h b/src/game/OutdoorPvP/OutdoorPvPEP.h index f054100a4..9a692b85e 100644 --- a/src/game/OutdoorPvP/OutdoorPvPEP.h +++ b/src/game/OutdoorPvP/OutdoorPvPEP.h @@ -19,4 +19,251 @@ #ifndef WORLD_PVP_EP #define WORLD_PVP_EP -#endif +#include "Common.h" +#include "OutdoorPvP.h" +#include "../Language.h" + +enum +{ + TOWER_ID_NORTHPASS = 0, + TOWER_ID_CROWNGUARD = 1, + TOWER_ID_EASTWALL = 2, + TOWER_ID_PLAGUEWOOD = 3, + MAX_EP_TOWERS = 4, + + // spells + SPELL_ECHOES_OF_LORDAERON_ALLIANCE_1 = 11413, + SPELL_ECHOES_OF_LORDAERON_ALLIANCE_2 = 11414, + SPELL_ECHOES_OF_LORDAERON_ALLIANCE_3 = 11415, + SPELL_ECHOES_OF_LORDAERON_ALLIANCE_4 = 1386, + + SPELL_ECHOES_OF_LORDAERON_HORDE_1 = 30880, + SPELL_ECHOES_OF_LORDAERON_HORDE_2 = 30683, + SPELL_ECHOES_OF_LORDAERON_HORDE_3 = 30682, + SPELL_ECHOES_OF_LORDAERON_HORDE_4 = 29520, + + // graveyards + GRAVEYARD_ZONE_EASTERN_PLAGUE = 139, + GRAVEYARD_ID_EASTERN_PLAGUE = 927, + + // misc + HONOR_REWARD_PLAGUELANDS = 18, + + // npcs + NPC_SPECTRAL_FLIGHT_MASTER = 17209, + + // flight master factions + FACTION_FLIGHT_MASTER_ALLIANCE = 774, + FACTION_FLIGHT_MASTER_HORDE = 775, + + SPELL_SPIRIT_PARTICLES_BLUE = 17327, + SPELL_SPIRIT_PARTICLES_RED = 31309, + + // quest + NPC_CROWNGUARD_TOWER_QUEST_DOODAD = 17689, + NPC_EASTWALL_TOWER_QUEST_DOODAD = 17690, + NPC_NORTHPASS_TOWER_QUEST_DOODAD = 17696, + NPC_PLAGUEWOOD_TOWER_QUEST_DOODAD = 17698, + + // alliance + NPC_LORDAERON_COMMANDER = 17635, + NPC_LORDAERON_SOLDIER = 17647, + + // horde + NPC_LORDAERON_VETERAN = 17995, + NPC_LORDAERON_FIGHTER = 17996, + + // gameobjects + GO_LORDAERON_SHRINE_ALLIANCE = 181682, + GO_LORDAERON_SHRINE_HORDE = 181955, + GO_TOWER_FLAG = 182106, + + // possible shrine auras - not used + //GO_ALLIANCE_BANNER_AURA = 180100, + //GO_HORDE_BANNER_AURA = 180101, + + // capture points + GO_TOWER_BANNER_NORTHPASS = 181899, + GO_TOWER_BANNER_CROWNGUARD = 182096, + GO_TOWER_BANNER_EASTWALL = 182097, + GO_TOWER_BANNER_PLAGUEWOOD = 182098, + + GO_TOWER_BANNER = 182106, // tower banners around + + // events + //EVENT_NORTHPASS_WIN_ALLIANCE = 10568, + //EVENT_NORTHPASS_WIN_HORDE = 10556, + //EVENT_NORTHPASS_CONTEST_ALLIANCE = 10697, + //EVENT_NORTHPASS_CONTEST_HORDE = 10696, + EVENT_NORTHPASS_PROGRESS_ALLIANCE = 10699, + EVENT_NORTHPASS_PROGRESS_HORDE = 10698, + EVENT_NORTHPASS_NEUTRAL_ALLIANCE = 11151, + EVENT_NORTHPASS_NEUTRAL_HORDE = 11150, + + //EVENT_CROWNGUARD_WIN_ALLIANCE = 10570, + //EVENT_CROWNGUARD_WIN_HORDE = 10566, + //EVENT_CROWNGUARD_CONTEST_ALLIANCE = 10703, + //EVENT_CROWNGUARD_CONTEST_HORDE = 10702, + EVENT_CROWNGUARD_PROGRESS_ALLIANCE = 10705, + EVENT_CROWNGUARD_PROGRESS_HORDE = 10704, + EVENT_CROWNGUARD_NEUTRAL_ALLIANCE = 11155, + EVENT_CROWNGUARD_NEUTRAL_HORDE = 11154, + + //EVENT_EASTWALL_WIN_ALLIANCE = 10569, + //EVENT_EASTWALL_WIN_HORDE = 10565, + //EVENT_EASTWALL_CONTEST_ALLIANCE = 10689, + //EVENT_EASTWALL_CONTEST_HORDE = 10690, + EVENT_EASTWALL_PROGRESS_ALLIANCE = 10691, + EVENT_EASTWALL_PROGRESS_HORDE = 10692, + EVENT_EASTWALL_NEUTRAL_ALLIANCE = 11149, + EVENT_EASTWALL_NEUTRAL_HORDE = 11148, + + //EVENT_PLAGUEWOOD_WIN_ALLIANCE = 10567, + //EVENT_PLAGUEWOOD_WIN_HORDE = 10564, + //EVENT_PLAGUEWOOD_CONTEST_ALLIANCE = 10687, + //EVENT_PLAGUEWOOD_CONTEST_HORDE = 10688, + EVENT_PLAGUEWOOD_PROGRESS_ALLIANCE = 10701, + EVENT_PLAGUEWOOD_PROGRESS_HORDE = 10700, + EVENT_PLAGUEWOOD_NEUTRAL_ALLIANCE = 11153, + EVENT_PLAGUEWOOD_NEUTRAL_HORDE = 11152, + + // world states + WORLD_STATE_EP_TOWER_COUNT_ALLIANCE = 2327, + WORLD_STATE_EP_TOWER_COUNT_HORDE = 2328, + + //WORLD_STATE_EP_PLAGUEWOOD_CONTEST_ALLIANCE = 2366, + //WORLD_STATE_EP_PLAGUEWOOD_CONTEST_HORDE = 2367, + //WORLD_STATE_EP_PLAGUEWOOD_PROGRESS_ALLIANCE = 2368, + //WORLD_STATE_EP_PLAGUEWOOD_PROGRESS_HORDE = 2369, + WORLD_STATE_EP_PLAGUEWOOD_ALLIANCE = 2370, + WORLD_STATE_EP_PLAGUEWOOD_HORDE = 2371, + WORLD_STATE_EP_PLAGUEWOOD_NEUTRAL = 2353, + + //WORLD_STATE_EP_NORTHPASS_CONTEST_ALLIANCE = 2362, + //WORLD_STATE_EP_NORTHPASS_CONTEST_HORDE = 2363, + //WORLD_STATE_EP_NORTHPASS_PROGRESS_ALLIANCE = 2364, + //WORLD_STATE_EP_NORTHPASS_PROGRESS_HORDE = 2365, + WORLD_STATE_EP_NORTHPASS_ALLIANCE = 2372, + WORLD_STATE_EP_NORTHPASS_HORDE = 2373, + WORLD_STATE_EP_NORTHPASS_NEUTRAL = 2352, + + //WORLD_STATE_EP_EASTWALL_CONTEST_ALLIANCE = 2359, + //WORLD_STATE_EP_EASTWALL_CONTEST_HORDE = 2360, + //WORLD_STATE_EP_EASTWALL_PROGRESS_ALLIANCE = 2357, + //WORLD_STATE_EP_EASTWALL_PROGRESS_HORDE = 2358, + WORLD_STATE_EP_EASTWALL_ALLIANCE = 2354, + WORLD_STATE_EP_EASTWALL_HORDE = 2356, + WORLD_STATE_EP_EASTWALL_NEUTRAL = 2361, + + //WORLD_STATE_EP_CROWNGUARD_CONTEST_ALLIANCE = 2374, + //WORLD_STATE_EP_CROWNGUARD_CONTEST_HORDE = 2375, + //WORLD_STATE_EP_CROWNGUARD_PROGRESS_ALLIANCE = 2376, + //WORLD_STATE_EP_CROWNGUARD_PROGRESS_HORDE = 2377, + WORLD_STATE_EP_CROWNGUARD_ALLIANCE = 2378, + WORLD_STATE_EP_CROWNGUARD_HORDE = 2379, + WORLD_STATE_EP_CROWNGUARD_NEUTRAL = 2355 +}; + +struct PlaguelandsTowerBuff +{ + uint32 spellIdAlliance, spellIdHorde; +}; + +static const PlaguelandsTowerBuff plaguelandsTowerBuffs[MAX_EP_TOWERS] = +{ + {SPELL_ECHOES_OF_LORDAERON_ALLIANCE_1, SPELL_ECHOES_OF_LORDAERON_HORDE_1}, + {SPELL_ECHOES_OF_LORDAERON_ALLIANCE_2, SPELL_ECHOES_OF_LORDAERON_HORDE_2}, + {SPELL_ECHOES_OF_LORDAERON_ALLIANCE_3, SPELL_ECHOES_OF_LORDAERON_HORDE_3}, + {SPELL_ECHOES_OF_LORDAERON_ALLIANCE_4, SPELL_ECHOES_OF_LORDAERON_HORDE_4} +}; + +// capture points coordinates to sort the banners +static const float plaguelandsTowerLocations[MAX_EP_TOWERS][2] = +{ + {3181.08f, -4379.36f}, // Northpass + {1860.85f, -3731.23f}, // Crownguard + {2574.51f, -4794.89f}, // Eastwall + {2962.71f, -3042.31f} // Plaguewood +}; + +struct PlaguelandsTowerEvent +{ + uint32 eventEntry; + Team team; + uint32 defenseMessage; + uint32 worldState; +}; + +static const PlaguelandsTowerEvent plaguelandsTowerEvents[MAX_EP_TOWERS][4] = +{ + { + {EVENT_NORTHPASS_PROGRESS_ALLIANCE, ALLIANCE, LANG_OPVP_EP_CAPTURE_NPT_A, WORLD_STATE_EP_NORTHPASS_ALLIANCE}, + {EVENT_NORTHPASS_PROGRESS_HORDE, HORDE, LANG_OPVP_EP_CAPTURE_NPT_H, WORLD_STATE_EP_NORTHPASS_HORDE}, + {EVENT_NORTHPASS_NEUTRAL_HORDE, TEAM_NONE, 0, WORLD_STATE_EP_NORTHPASS_NEUTRAL}, + {EVENT_NORTHPASS_NEUTRAL_ALLIANCE, TEAM_NONE, 0, WORLD_STATE_EP_NORTHPASS_NEUTRAL}, + }, + { + {EVENT_CROWNGUARD_PROGRESS_ALLIANCE, ALLIANCE, LANG_OPVP_EP_CAPTURE_CGT_A, WORLD_STATE_EP_CROWNGUARD_ALLIANCE}, + {EVENT_CROWNGUARD_PROGRESS_HORDE, HORDE, LANG_OPVP_EP_CAPTURE_CGT_H, WORLD_STATE_EP_CROWNGUARD_HORDE}, + {EVENT_CROWNGUARD_NEUTRAL_HORDE, TEAM_NONE, 0, WORLD_STATE_EP_CROWNGUARD_NEUTRAL}, + {EVENT_CROWNGUARD_NEUTRAL_ALLIANCE, TEAM_NONE, 0, WORLD_STATE_EP_CROWNGUARD_NEUTRAL}, + }, + { + {EVENT_EASTWALL_PROGRESS_ALLIANCE, ALLIANCE, LANG_OPVP_EP_CAPTURE_EWT_A, WORLD_STATE_EP_EASTWALL_ALLIANCE}, + {EVENT_EASTWALL_PROGRESS_HORDE, HORDE, LANG_OPVP_EP_CAPTURE_EWT_H, WORLD_STATE_EP_EASTWALL_HORDE}, + {EVENT_EASTWALL_NEUTRAL_HORDE, TEAM_NONE, 0, WORLD_STATE_EP_EASTWALL_NEUTRAL}, + {EVENT_EASTWALL_NEUTRAL_ALLIANCE, TEAM_NONE, 0, WORLD_STATE_EP_EASTWALL_NEUTRAL}, + }, + { + {EVENT_PLAGUEWOOD_PROGRESS_ALLIANCE, ALLIANCE, LANG_OPVP_EP_CAPTURE_PWT_A, WORLD_STATE_EP_PLAGUEWOOD_ALLIANCE}, + {EVENT_PLAGUEWOOD_PROGRESS_HORDE, HORDE, LANG_OPVP_EP_CAPTURE_PWT_H, WORLD_STATE_EP_PLAGUEWOOD_HORDE}, + {EVENT_PLAGUEWOOD_NEUTRAL_HORDE, TEAM_NONE, 0, WORLD_STATE_EP_PLAGUEWOOD_NEUTRAL}, + {EVENT_PLAGUEWOOD_NEUTRAL_ALLIANCE, TEAM_NONE, 0, WORLD_STATE_EP_PLAGUEWOOD_NEUTRAL}, + }, +}; + +static const uint32 plaguelandsBanners[MAX_EP_TOWERS] = {GO_TOWER_BANNER_NORTHPASS, GO_TOWER_BANNER_CROWNGUARD, GO_TOWER_BANNER_EASTWALL, GO_TOWER_BANNER_PLAGUEWOOD}; + +class OutdoorPvPEP : public OutdoorPvP +{ + public: + OutdoorPvPEP(); + + 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 HandleCreatureCreate(Creature* creature) override; + void HandleGameObjectCreate(GameObject* go) override; + bool HandleGameObjectUse(Player* player, GameObject* go) override; + + private: + // process capture events + bool ProcessCaptureEvent(GameObject* go, uint32 towerId, Team team, uint32 newWorldState); + + void InitBanner(GameObject* go, uint32 towerId); + + // Plaguewood bonus - flight master + void UnsummonFlightMaster(const WorldObject* objRef); + // Eastwall bonus - soldiers + void UnsummonSoldiers(const WorldObject* objRef); + + Team m_towerOwner[MAX_EP_TOWERS]; + uint32 m_towerWorldState[MAX_EP_TOWERS]; + uint8 m_towersAlliance; + uint8 m_towersHorde; + + ObjectGuid m_flightMaster; + ObjectGuid m_lordaeronShrineAlliance; + ObjectGuid m_lordaeronShrineHorde; + + GuidList m_soldiers; + + GuidList m_towerBanners[MAX_EP_TOWERS]; +}; + +#endif \ No newline at end of file diff --git a/src/game/OutdoorPvP/OutdoorPvPMgr.cpp b/src/game/OutdoorPvP/OutdoorPvPMgr.cpp index 6319f38a1..d2479df9c 100644 --- a/src/game/OutdoorPvP/OutdoorPvPMgr.cpp +++ b/src/game/OutdoorPvP/OutdoorPvPMgr.cpp @@ -50,6 +50,7 @@ OutdoorPvPMgr::~OutdoorPvPMgr() void OutdoorPvPMgr::InitOutdoorPvP() { m_scripts[OPVP_ID_SI] = new OutdoorPvPSI(); + m_scripts[OPVP_ID_EP] = new OutdoorPvPEP(); sLog.outString(); sLog.outString(">> Loaded %u Outdoor PvP zones", MAX_OPVP_ID);