Updated Copyright year to 2013
[getmangos.git] / src / game / OutdoorPvP / OutdoorPvPEP.cpp
blob66f32bbdecbf89426a137b6aafce6803c548e1f4
1 /*
2 * Copyright (C) 2005-2013 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "OutdoorPvPEP.h"
20 #include "WorldPacket.h"
21 #include "World.h"
22 #include "ObjectMgr.h"
23 #include "Object.h"
24 #include "Creature.h"
25 #include "GameObject.h"
26 #include "Player.h"
28 OutdoorPvPEP::OutdoorPvPEP() : OutdoorPvP(),
29 m_towersAlliance(0),
30 m_towersHorde(0)
32 m_towerWorldState[0] = WORLD_STATE_EP_NORTHPASS_NEUTRAL;
33 m_towerWorldState[1] = WORLD_STATE_EP_CROWNGUARD_NEUTRAL;
34 m_towerWorldState[2] = WORLD_STATE_EP_EASTWALL_NEUTRAL;
35 m_towerWorldState[3] = WORLD_STATE_EP_PLAGUEWOOD_NEUTRAL;
37 for (uint8 i = 0; i < MAX_EP_TOWERS; ++i)
38 m_towerOwner[i] = TEAM_NONE;
40 // initially set graveyard owner to neither faction
41 sObjectMgr.SetGraveYardLinkTeam(GRAVEYARD_ID_EASTERN_PLAGUE, GRAVEYARD_ZONE_EASTERN_PLAGUE, TEAM_INVALID);
44 void OutdoorPvPEP::FillInitialWorldStates(WorldPacket& data, uint32& count)
46 FillInitialWorldState(data, count, WORLD_STATE_EP_TOWER_COUNT_ALLIANCE, m_towersAlliance);
47 FillInitialWorldState(data, count, WORLD_STATE_EP_TOWER_COUNT_HORDE, m_towersHorde);
49 for (uint8 i = 0; i < MAX_EP_TOWERS; ++i)
50 FillInitialWorldState(data, count, m_towerWorldState[i], WORLD_STATE_ADD);
53 void OutdoorPvPEP::SendRemoveWorldStates(Player* player)
55 for (uint8 i = 0; i < MAX_EP_TOWERS; ++i)
56 player->SendUpdateWorldState(m_towerWorldState[i], WORLD_STATE_REMOVE);
59 void OutdoorPvPEP::HandlePlayerEnterZone(Player* player, bool isMainZone)
61 OutdoorPvP::HandlePlayerEnterZone(player, isMainZone);
63 // remove the buff from the player first; Sometimes on relog players still have the aura
64 for (uint8 i = 0; i < MAX_EP_TOWERS; ++i)
65 player->RemoveAurasDueToSpell(player->GetTeam() == ALLIANCE ? plaguelandsTowerBuffs[i].spellIdAlliance : plaguelandsTowerBuffs[i].spellIdHorde);
67 // buff the player
68 switch (player->GetTeam())
70 case ALLIANCE:
71 if (m_towersAlliance > 0)
72 player->CastSpell(player, plaguelandsTowerBuffs[m_towersAlliance - 1].spellIdAlliance, true);
73 break;
74 case HORDE:
75 if (m_towersHorde > 0)
76 player->CastSpell(player, plaguelandsTowerBuffs[m_towersHorde - 1].spellIdHorde, true);
77 break;
78 default:
79 break;
83 void OutdoorPvPEP::HandlePlayerLeaveZone(Player* player, bool isMainZone)
85 // remove the buff from the player
86 for (uint8 i = 0; i < MAX_EP_TOWERS; ++i)
87 player->RemoveAurasDueToSpell(player->GetTeam() == ALLIANCE ? plaguelandsTowerBuffs[i].spellIdAlliance : plaguelandsTowerBuffs[i].spellIdHorde);
89 OutdoorPvP::HandlePlayerLeaveZone(player, isMainZone);
92 void OutdoorPvPEP::HandleCreatureCreate(Creature* creature)
94 switch (creature->GetEntry())
96 case NPC_SPECTRAL_FLIGHT_MASTER:
97 m_flightMaster = creature->GetObjectGuid();
98 creature->setFaction(m_towerOwner[TOWER_ID_PLAGUEWOOD] == ALLIANCE ? FACTION_FLIGHT_MASTER_ALLIANCE : FACTION_FLIGHT_MASTER_HORDE);
99 creature->CastSpell(creature, m_towerOwner[TOWER_ID_PLAGUEWOOD] == ALLIANCE ? SPELL_SPIRIT_PARTICLES_BLUE : SPELL_SPIRIT_PARTICLES_RED, true);
100 break;
101 case NPC_LORDAERON_COMMANDER:
102 case NPC_LORDAERON_SOLDIER:
103 case NPC_LORDAERON_VETERAN:
104 case NPC_LORDAERON_FIGHTER:
105 m_soldiers.push_back(creature->GetObjectGuid());
106 break;
110 void OutdoorPvPEP::HandleGameObjectCreate(GameObject* go)
112 OutdoorPvP::HandleGameObjectCreate(go);
114 switch (go->GetEntry())
116 case GO_TOWER_BANNER_NORTHPASS:
117 InitBanner(go, TOWER_ID_NORTHPASS);
118 break;
119 case GO_TOWER_BANNER_CROWNGUARD:
120 InitBanner(go, TOWER_ID_CROWNGUARD);
121 break;
122 case GO_TOWER_BANNER_EASTWALL:
123 InitBanner(go, TOWER_ID_EASTWALL);
124 break;
125 case GO_TOWER_BANNER_PLAGUEWOOD:
126 InitBanner(go, TOWER_ID_PLAGUEWOOD);
127 break;
128 case GO_TOWER_BANNER:
129 // sort banners
130 if (go->IsWithinDist2d(plaguelandsTowerLocations[TOWER_ID_NORTHPASS][0], plaguelandsTowerLocations[TOWER_ID_NORTHPASS][1], 50.0f))
131 InitBanner(go, TOWER_ID_NORTHPASS);
132 else if (go->IsWithinDist2d(plaguelandsTowerLocations[TOWER_ID_CROWNGUARD][0], plaguelandsTowerLocations[TOWER_ID_CROWNGUARD][1], 50.0f))
133 InitBanner(go, TOWER_ID_CROWNGUARD);
134 else if (go->IsWithinDist2d(plaguelandsTowerLocations[TOWER_ID_EASTWALL][0], plaguelandsTowerLocations[TOWER_ID_EASTWALL][1], 50.0f))
135 InitBanner(go, TOWER_ID_EASTWALL);
136 else if (go->IsWithinDist2d(plaguelandsTowerLocations[TOWER_ID_PLAGUEWOOD][0], plaguelandsTowerLocations[TOWER_ID_PLAGUEWOOD][1], 50.0f))
137 InitBanner(go, TOWER_ID_PLAGUEWOOD);
138 break;
139 case GO_LORDAERON_SHRINE_ALLIANCE:
140 m_lordaeronShrineAlliance = go->GetObjectGuid();
141 break;
142 case GO_LORDAERON_SHRINE_HORDE:
143 m_lordaeronShrineHorde = go->GetObjectGuid();
144 break;
148 void OutdoorPvPEP::HandleObjectiveComplete(uint32 eventId, std::list<Player*> players, Team team)
150 uint32 credit = 0;
152 switch (eventId)
154 case EVENT_CROWNGUARD_PROGRESS_ALLIANCE:
155 case EVENT_CROWNGUARD_PROGRESS_HORDE:
156 credit = NPC_CROWNGUARD_TOWER_QUEST_DOODAD;
157 break;
158 case EVENT_EASTWALL_PROGRESS_ALLIANCE:
159 case EVENT_EASTWALL_PROGRESS_HORDE:
160 credit = NPC_EASTWALL_TOWER_QUEST_DOODAD;
161 break;
162 case EVENT_NORTHPASS_PROGRESS_ALLIANCE:
163 case EVENT_NORTHPASS_PROGRESS_HORDE:
164 credit = NPC_NORTHPASS_TOWER_QUEST_DOODAD;
165 break;
166 case EVENT_PLAGUEWOOD_PROGRESS_ALLIANCE:
167 case EVENT_PLAGUEWOOD_PROGRESS_HORDE:
168 credit = NPC_PLAGUEWOOD_TOWER_QUEST_DOODAD;
169 break;
170 default:
171 return;
174 for (std::list<Player*>::iterator itr = players.begin(); itr != players.end(); ++itr)
176 if ((*itr) && (*itr)->GetTeam() == team)
178 (*itr)->KilledMonsterCredit(credit);
179 (*itr)->RewardHonor(NULL, 1, HONOR_REWARD_PLAGUELANDS);
184 // process the capture events
185 bool OutdoorPvPEP::HandleEvent(uint32 eventId, GameObject* go)
187 for (uint8 i = 0; i < MAX_EP_TOWERS; ++i)
189 if (plaguelandsBanners[i] == go->GetEntry())
191 for (uint8 j = 0; j < 4; ++j)
193 if (plaguelandsTowerEvents[i][j].eventEntry == eventId)
195 // prevent processing if the owner did not change (happens if progress event is called after contest event)
196 if (plaguelandsTowerEvents[i][j].team != m_towerOwner[i])
198 if (plaguelandsTowerEvents[i][j].defenseMessage)
199 sWorld.SendDefenseMessage(ZONE_ID_EASTERN_PLAGUELANDS, plaguelandsTowerEvents[i][j].defenseMessage);
201 return ProcessCaptureEvent(go, i, plaguelandsTowerEvents[i][j].team, plaguelandsTowerEvents[i][j].worldState);
203 // no need to iterate other events or towers
204 return false;
207 // no need to iterate other towers
208 return false;
212 return false;
215 bool OutdoorPvPEP::ProcessCaptureEvent(GameObject* go, uint32 towerId, Team team, uint32 newWorldState)
217 if (team == ALLIANCE)
219 // update banner
220 for (GuidList::const_iterator itr = m_towerBanners[towerId].begin(); itr != m_towerBanners[towerId].end(); ++itr)
221 SetBannerVisual(go, (*itr), CAPTURE_ARTKIT_ALLIANCE, CAPTURE_ANIM_ALLIANCE);
223 // update counter
224 ++m_towersAlliance;
225 SendUpdateWorldState(WORLD_STATE_EP_TOWER_COUNT_ALLIANCE, m_towersAlliance);
227 // buff players
228 BuffTeam(ALLIANCE, plaguelandsTowerBuffs[m_towersAlliance - 1].spellIdAlliance);
230 else if (team == HORDE)
232 // update banner
233 for (GuidList::const_iterator itr = m_towerBanners[towerId].begin(); itr != m_towerBanners[towerId].end(); ++itr)
234 SetBannerVisual(go, (*itr), CAPTURE_ARTKIT_HORDE, CAPTURE_ANIM_HORDE);
236 // update counter
237 ++m_towersHorde;
238 SendUpdateWorldState(WORLD_STATE_EP_TOWER_COUNT_HORDE, m_towersHorde);
240 // buff players
241 BuffTeam(HORDE, plaguelandsTowerBuffs[m_towersHorde - 1].spellIdHorde);
243 else
245 // update banner
246 for (GuidList::const_iterator itr = m_towerBanners[towerId].begin(); itr != m_towerBanners[towerId].end(); ++itr)
247 SetBannerVisual(go, (*itr), CAPTURE_ARTKIT_NEUTRAL, CAPTURE_ANIM_NEUTRAL);
249 if (m_towerOwner[towerId] == ALLIANCE)
251 // update counter
252 --m_towersAlliance;
253 SendUpdateWorldState(WORLD_STATE_EP_TOWER_COUNT_ALLIANCE, m_towersAlliance);
255 if (m_towersAlliance == 0)
256 BuffTeam(ALLIANCE, plaguelandsTowerBuffs[0].spellIdAlliance, true);
258 else
260 // update counter
261 --m_towersHorde;
262 SendUpdateWorldState(WORLD_STATE_EP_TOWER_COUNT_HORDE, m_towersHorde);
264 if (m_towersHorde == 0)
265 BuffTeam(HORDE, plaguelandsTowerBuffs[0].spellIdHorde, true);
269 bool eventHandled = true;
271 if (team != TEAM_NONE)
273 // update capture point owner before rewards are applied
274 m_towerOwner[towerId] = team;
276 // apply rewards of changed tower
277 switch (towerId)
279 case TOWER_ID_NORTHPASS:
280 RespawnGO(go, team == ALLIANCE ? m_lordaeronShrineAlliance : m_lordaeronShrineHorde, true);
281 break;
282 case TOWER_ID_CROWNGUARD:
283 sObjectMgr.SetGraveYardLinkTeam(GRAVEYARD_ID_EASTERN_PLAGUE, GRAVEYARD_ZONE_EASTERN_PLAGUE, team);
284 break;
285 case TOWER_ID_EASTWALL:
286 // Return false - allow the DB to handle summons
287 if (m_towerOwner[TOWER_ID_NORTHPASS] != team)
288 eventHandled = false;
289 break;
290 case TOWER_ID_PLAGUEWOOD:
291 // Return false - allow the DB to handle summons
292 eventHandled = false;
293 break;
296 else
298 // remove rewards of changed tower
299 switch (towerId)
301 case TOWER_ID_NORTHPASS:
302 RespawnGO(go, m_towerOwner[TOWER_ID_NORTHPASS] == ALLIANCE ? m_lordaeronShrineAlliance : m_lordaeronShrineHorde, false);
303 break;
304 case TOWER_ID_CROWNGUARD:
305 sObjectMgr.SetGraveYardLinkTeam(GRAVEYARD_ID_EASTERN_PLAGUE, GRAVEYARD_ZONE_EASTERN_PLAGUE, TEAM_INVALID);
306 break;
307 case TOWER_ID_EASTWALL:
308 UnsummonSoldiers(go);
309 break;
310 case TOWER_ID_PLAGUEWOOD:
311 UnsummonFlightMaster(go);
312 break;
315 // update capture point owner after rewards have been removed
316 m_towerOwner[towerId] = team;
319 // update tower state
320 SendUpdateWorldState(m_towerWorldState[towerId], WORLD_STATE_REMOVE);
321 m_towerWorldState[towerId] = newWorldState;
322 SendUpdateWorldState(m_towerWorldState[towerId], WORLD_STATE_ADD);
324 // there are some events which required further DB script
325 return eventHandled;
328 bool OutdoorPvPEP::HandleGameObjectUse(Player* /*player*/, GameObject* go)
330 // prevent despawning after go use
331 if (go->GetEntry() == GO_LORDAERON_SHRINE_ALLIANCE || go->GetEntry() == GO_LORDAERON_SHRINE_HORDE)
332 go->SetRespawnTime(0);
334 return false;
337 void OutdoorPvPEP::InitBanner(GameObject* go, uint32 towerId)
339 m_towerBanners[towerId].push_back(go->GetObjectGuid());
340 go->SetGoArtKit(GetBannerArtKit(m_towerOwner[towerId]));
343 // Handle the unsummon of the spectral flight master when the Plaguewood tower is lost
344 void OutdoorPvPEP::UnsummonFlightMaster(const WorldObject* objRef)
346 if (Creature* flightMaster = objRef->GetMap()->GetCreature(m_flightMaster))
347 flightMaster->ForcedDespawn();
350 // Handle the unsummon of the soldiers when the Eastwall tower is lost
351 void OutdoorPvPEP::UnsummonSoldiers(const WorldObject* objRef)
353 for (GuidList::const_iterator itr = m_soldiers.begin(); itr != m_soldiers.end(); ++itr)
355 if (Creature* soldier = objRef->GetMap()->GetCreature(*itr))
356 soldier->ForcedDespawn();
359 m_soldiers.clear();