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"
22 #include "ObjectMgr.h"
25 #include "GameObject.h"
28 OutdoorPvPEP::OutdoorPvPEP() : OutdoorPvP(),
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
);
68 switch (player
->GetTeam())
71 if (m_towersAlliance
> 0)
72 player
->CastSpell(player
, plaguelandsTowerBuffs
[m_towersAlliance
- 1].spellIdAlliance
, true);
75 if (m_towersHorde
> 0)
76 player
->CastSpell(player
, plaguelandsTowerBuffs
[m_towersHorde
- 1].spellIdHorde
, true);
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);
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());
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
);
119 case GO_TOWER_BANNER_CROWNGUARD
:
120 InitBanner(go
, TOWER_ID_CROWNGUARD
);
122 case GO_TOWER_BANNER_EASTWALL
:
123 InitBanner(go
, TOWER_ID_EASTWALL
);
125 case GO_TOWER_BANNER_PLAGUEWOOD
:
126 InitBanner(go
, TOWER_ID_PLAGUEWOOD
);
128 case GO_TOWER_BANNER
:
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
);
139 case GO_LORDAERON_SHRINE_ALLIANCE
:
140 m_lordaeronShrineAlliance
= go
->GetObjectGuid();
142 case GO_LORDAERON_SHRINE_HORDE
:
143 m_lordaeronShrineHorde
= go
->GetObjectGuid();
148 void OutdoorPvPEP::HandleObjectiveComplete(uint32 eventId
, std::list
<Player
*> players
, Team team
)
154 case EVENT_CROWNGUARD_PROGRESS_ALLIANCE
:
155 case EVENT_CROWNGUARD_PROGRESS_HORDE
:
156 credit
= NPC_CROWNGUARD_TOWER_QUEST_DOODAD
;
158 case EVENT_EASTWALL_PROGRESS_ALLIANCE
:
159 case EVENT_EASTWALL_PROGRESS_HORDE
:
160 credit
= NPC_EASTWALL_TOWER_QUEST_DOODAD
;
162 case EVENT_NORTHPASS_PROGRESS_ALLIANCE
:
163 case EVENT_NORTHPASS_PROGRESS_HORDE
:
164 credit
= NPC_NORTHPASS_TOWER_QUEST_DOODAD
;
166 case EVENT_PLAGUEWOOD_PROGRESS_ALLIANCE
:
167 case EVENT_PLAGUEWOOD_PROGRESS_HORDE
:
168 credit
= NPC_PLAGUEWOOD_TOWER_QUEST_DOODAD
;
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
207 // no need to iterate other towers
215 bool OutdoorPvPEP::ProcessCaptureEvent(GameObject
* go
, uint32 towerId
, Team team
, uint32 newWorldState
)
217 if (team
== ALLIANCE
)
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
);
225 SendUpdateWorldState(WORLD_STATE_EP_TOWER_COUNT_ALLIANCE
, m_towersAlliance
);
228 BuffTeam(ALLIANCE
, plaguelandsTowerBuffs
[m_towersAlliance
- 1].spellIdAlliance
);
230 else if (team
== HORDE
)
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
);
238 SendUpdateWorldState(WORLD_STATE_EP_TOWER_COUNT_HORDE
, m_towersHorde
);
241 BuffTeam(HORDE
, plaguelandsTowerBuffs
[m_towersHorde
- 1].spellIdHorde
);
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
)
253 SendUpdateWorldState(WORLD_STATE_EP_TOWER_COUNT_ALLIANCE
, m_towersAlliance
);
255 if (m_towersAlliance
== 0)
256 BuffTeam(ALLIANCE
, plaguelandsTowerBuffs
[0].spellIdAlliance
, true);
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
279 case TOWER_ID_NORTHPASS
:
280 RespawnGO(go
, team
== ALLIANCE
? m_lordaeronShrineAlliance
: m_lordaeronShrineHorde
, true);
282 case TOWER_ID_CROWNGUARD
:
283 sObjectMgr
.SetGraveYardLinkTeam(GRAVEYARD_ID_EASTERN_PLAGUE
, GRAVEYARD_ZONE_EASTERN_PLAGUE
, team
);
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;
290 case TOWER_ID_PLAGUEWOOD
:
291 // Return false - allow the DB to handle summons
292 eventHandled
= false;
298 // remove rewards of changed tower
301 case TOWER_ID_NORTHPASS
:
302 RespawnGO(go
, m_towerOwner
[TOWER_ID_NORTHPASS
] == ALLIANCE
? m_lordaeronShrineAlliance
: m_lordaeronShrineHorde
, false);
304 case TOWER_ID_CROWNGUARD
:
305 sObjectMgr
.SetGraveYardLinkTeam(GRAVEYARD_ID_EASTERN_PLAGUE
, GRAVEYARD_ZONE_EASTERN_PLAGUE
, TEAM_INVALID
);
307 case TOWER_ID_EASTWALL
:
308 UnsummonSoldiers(go
);
310 case TOWER_ID_PLAGUEWOOD
:
311 UnsummonFlightMaster(go
);
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
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);
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();