[10041] Use for spell 49145 and ranks for decrease SPELL_DIRECT_DAMAGE damage.
[getmangos.git] / src / game / BattleGroundEY.cpp
blobea8e4667784d508847d4987ff77534cdc21c260d
1 /*
2 * Copyright (C) 2005-2010 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 "Object.h"
20 #include "Player.h"
21 #include "BattleGround.h"
22 #include "BattleGroundEY.h"
23 #include "Creature.h"
24 #include "ObjectMgr.h"
25 #include "BattleGroundMgr.h"
26 #include "Language.h"
27 #include "WorldPacket.h"
28 #include "Util.h"
29 #include "MapManager.h"
31 BattleGroundEY::BattleGroundEY()
33 m_BuffChange = true;
34 m_BgObjects.resize(BG_EY_OBJECT_MAX);
36 m_Points_Trigger[BG_EY_NODE_FEL_REAVER] = TR_FEL_REAVER_BUFF;
37 m_Points_Trigger[BG_EY_NODE_BLOOD_ELF] = TR_BLOOD_ELF_BUFF;
38 m_Points_Trigger[BG_EY_NODE_DRAENEI_RUINS] = TR_DRAENEI_RUINS_BUFF;
39 m_Points_Trigger[BG_EY_NODE_MAGE_TOWER] = TR_MAGE_TOWER_BUFF;
41 m_StartMessageIds[BG_STARTING_EVENT_FIRST] = 0;
42 m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_EY_START_ONE_MINUTE;
43 m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_EY_START_HALF_MINUTE;
44 m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_EY_HAS_BEGUN;
47 BattleGroundEY::~BattleGroundEY()
51 void BattleGroundEY::Update(uint32 diff)
53 BattleGround::Update(diff);
55 if (GetStatus() == STATUS_IN_PROGRESS)
57 m_PointAddingTimer -= diff;
58 if (m_PointAddingTimer <= 0)
60 m_PointAddingTimer = BG_EY_FPOINTS_TICK_TIME;
61 if (m_TeamPointsCount[BG_TEAM_ALLIANCE] > 0)
62 AddPoints(ALLIANCE, BG_EY_TickPoints[m_TeamPointsCount[BG_TEAM_ALLIANCE] - 1]);
63 if (m_TeamPointsCount[BG_TEAM_HORDE] > 0)
64 AddPoints(HORDE, BG_EY_TickPoints[m_TeamPointsCount[BG_TEAM_HORDE] - 1]);
67 if (m_FlagState == BG_EY_FLAG_STATE_WAIT_RESPAWN || m_FlagState == BG_EY_FLAG_STATE_ON_GROUND)
69 m_FlagsTimer -= diff;
71 if (m_FlagsTimer < 0)
73 m_FlagsTimer = 0;
74 if (m_FlagState == BG_EY_FLAG_STATE_WAIT_RESPAWN)
75 RespawnFlag(true);
76 else
77 RespawnFlagAfterDrop();
81 m_TowerCapCheckTimer -= diff;
82 if (m_TowerCapCheckTimer <= 0)
84 //check if player joined point
85 /*I used this order of calls, because although we will check if one player is in gameobject's distance 2 times
86 but we can count of players on current point in CheckSomeoneLeftPoint
88 CheckSomeoneJoinedPoint();
89 //check if player left point
90 CheckSomeoneLeftPoint();
91 UpdatePointStatuses();
92 m_TowerCapCheckTimer = BG_EY_FPOINTS_TICK_TIME;
97 void BattleGroundEY::StartingEventCloseDoors()
101 void BattleGroundEY::StartingEventOpenDoors()
103 // eye-doors are despawned, not opened
104 SpawnEvent(BG_EVENT_DOOR, 0, false);
106 for(uint32 i = 0; i < BG_EY_NODES_MAX; ++i)
108 //randomly spawn buff
109 uint8 buff = urand(0, 2);
110 SpawnBGObject(m_BgObjects[BG_EY_OBJECT_SPEEDBUFF_FEL_REAVER + buff + i * 3], RESPAWN_IMMEDIATELY);
114 void BattleGroundEY::AddPoints(uint32 Team, uint32 Points)
116 BattleGroundTeamId team_index = GetTeamIndexByTeamId(Team);
117 m_TeamScores[team_index] += Points;
118 m_HonorScoreTics[team_index] += Points;
119 if (m_HonorScoreTics[team_index] >= m_HonorTics )
121 RewardHonorToTeam(GetBonusHonorFromKill(1), Team);
122 m_HonorScoreTics[team_index] -= m_HonorTics;
124 UpdateTeamScore(Team);
127 void BattleGroundEY::CheckSomeoneJoinedPoint()
129 for (uint8 i = 0; i < BG_EY_NODES_MAX; ++i)
131 uint8 j = 0;
132 while (j < m_PlayersNearPoint[BG_EY_PLAYERS_OUT_OF_POINTS].size())
134 Player *plr = sObjectMgr.GetPlayer(m_PlayersNearPoint[BG_EY_PLAYERS_OUT_OF_POINTS][j]);
135 if (!plr)
137 sLog.outError("BattleGroundEY:CheckSomeoneJoinedPoint: Player (GUID: %u) not found!", GUID_LOPART(m_PlayersNearPoint[BG_EY_PLAYERS_OUT_OF_POINTS][j]));
138 ++j;
139 continue;
141 if (plr->CanCaptureTowerPoint() &&
142 plr->IsWithinDist3d(BG_EY_NodePositions[i][0], BG_EY_NodePositions[i][1], BG_EY_NodePositions[i][2], BG_EY_POINT_RADIUS))
144 //player joined point!
145 //show progress bar
146 UpdateWorldStateForPlayer(PROGRESS_BAR_PERCENT_GREY, BG_EY_PROGRESS_BAR_PERCENT_GREY, plr);
147 UpdateWorldStateForPlayer(PROGRESS_BAR_STATUS, m_PointBarStatus[i], plr);
148 UpdateWorldStateForPlayer(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_SHOW, plr);
149 //add player to point
150 m_PlayersNearPoint[i].push_back(m_PlayersNearPoint[BG_EY_PLAYERS_OUT_OF_POINTS][j]);
151 //remove player from "free space"
152 m_PlayersNearPoint[BG_EY_PLAYERS_OUT_OF_POINTS].erase(m_PlayersNearPoint[BG_EY_PLAYERS_OUT_OF_POINTS].begin() + j);
154 else
155 ++j;
160 void BattleGroundEY::CheckSomeoneLeftPoint()
162 //reset current point counts
163 for (uint8 i = 0; i < 2*BG_EY_NODES_MAX; ++i)
164 m_CurrentPointPlayersCount[i] = 0;
165 for(uint8 i = 0; i < BG_EY_NODES_MAX; ++i)
167 uint8 j = 0;
168 while (j < m_PlayersNearPoint[i].size())
170 Player *plr = sObjectMgr.GetPlayer(m_PlayersNearPoint[i][j]);
171 if (!plr)
173 sLog.outError("BattleGroundEY:CheckSomeoneLeftPoint Player (GUID: %u) not found!", GUID_LOPART(m_PlayersNearPoint[i][j]));
174 //move not existed player to "free space" - this will cause many error showing in log, but it is a very important bug
175 m_PlayersNearPoint[BG_EY_PLAYERS_OUT_OF_POINTS].push_back(m_PlayersNearPoint[i][j]);
176 m_PlayersNearPoint[i].erase(m_PlayersNearPoint[i].begin() + j);
177 ++j;
178 continue;
180 if (!plr->CanCaptureTowerPoint() ||
181 !plr->IsWithinDist3d(BG_EY_NodePositions[i][0], BG_EY_NodePositions[i][1], BG_EY_NodePositions[i][2], BG_EY_POINT_RADIUS))
182 //move player out of point (add him to players that are out of points
184 m_PlayersNearPoint[BG_EY_PLAYERS_OUT_OF_POINTS].push_back(m_PlayersNearPoint[i][j]);
185 m_PlayersNearPoint[i].erase(m_PlayersNearPoint[i].begin() + j);
186 UpdateWorldStateForPlayer(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_DONT_SHOW, plr);
188 else
190 //player is neat flag, so update count:
191 m_CurrentPointPlayersCount[2 * i + GetTeamIndexByTeamId(plr->GetTeam())]++;
192 ++j;
198 void BattleGroundEY::UpdatePointStatuses()
200 for(uint8 point = 0; point < BG_EY_NODES_MAX; ++point)
202 if (m_PlayersNearPoint[point].empty())
203 continue;
204 //count new point bar status:
205 m_PointBarStatus[point] += (m_CurrentPointPlayersCount[2 * point] - m_CurrentPointPlayersCount[2 * point + 1] < BG_EY_POINT_MAX_CAPTURERS_COUNT) ? m_CurrentPointPlayersCount[2 * point] - m_CurrentPointPlayersCount[2 * point + 1] : BG_EY_POINT_MAX_CAPTURERS_COUNT;
207 if (m_PointBarStatus[point] > BG_EY_PROGRESS_BAR_ALI_CONTROLLED)
208 //point is fully alliance's
209 m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_ALI_CONTROLLED;
210 if (m_PointBarStatus[point] < BG_EY_PROGRESS_BAR_HORDE_CONTROLLED)
211 //point is fully horde's
212 m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_HORDE_CONTROLLED;
214 uint32 pointOwnerTeamId = 0;
215 //find which team should own this point
216 if (m_PointBarStatus[point] <= BG_EY_PROGRESS_BAR_NEUTRAL_LOW)
217 pointOwnerTeamId = HORDE;
218 else if (m_PointBarStatus[point] >= BG_EY_PROGRESS_BAR_NEUTRAL_HIGH)
219 pointOwnerTeamId = ALLIANCE;
220 else
221 pointOwnerTeamId = EY_POINT_NO_OWNER;
223 for (uint8 i = 0; i < m_PlayersNearPoint[point].size(); ++i)
225 Player *plr = sObjectMgr.GetPlayer(m_PlayersNearPoint[point][i]);
226 if (plr)
228 UpdateWorldStateForPlayer(PROGRESS_BAR_STATUS, m_PointBarStatus[point], plr);
229 //if point owner changed we must evoke event!
230 if (pointOwnerTeamId != m_PointOwnedByTeam[point])
232 //point was uncontrolled and player is from team which captured point
233 if (m_PointState[point] == EY_POINT_STATE_UNCONTROLLED && plr->GetTeam() == pointOwnerTeamId)
234 EventTeamCapturedPoint(plr, point);
236 //point was under control and player isn't from team which controlled it
237 if (m_PointState[point] == EY_POINT_UNDER_CONTROL && plr->GetTeam() != m_PointOwnedByTeam[point])
238 EventTeamLostPoint(plr, point);
245 void BattleGroundEY::UpdateTeamScore(uint32 Team)
247 uint32 score = GetTeamScore(Team);
249 if (score >= BG_EY_MAX_TEAM_SCORE)
251 score = BG_EY_MAX_TEAM_SCORE;
252 EndBattleGround(Team);
255 if (Team == ALLIANCE)
256 UpdateWorldState(EY_ALLIANCE_RESOURCES, score);
257 else
258 UpdateWorldState(EY_HORDE_RESOURCES, score);
261 void BattleGroundEY::EndBattleGround(uint32 winner)
263 //win reward
264 if (winner == ALLIANCE)
265 RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
266 if (winner == HORDE)
267 RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
268 //complete map reward
269 RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
270 RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
272 BattleGround::EndBattleGround(winner);
275 void BattleGroundEY::UpdatePointsCount(uint32 Team)
277 if (Team == ALLIANCE)
278 UpdateWorldState(EY_ALLIANCE_BASE, m_TeamPointsCount[BG_TEAM_ALLIANCE]);
279 else
280 UpdateWorldState(EY_HORDE_BASE, m_TeamPointsCount[BG_TEAM_HORDE]);
283 void BattleGroundEY::UpdatePointsIcons(uint32 Team, uint32 Point)
285 //we MUST firstly send 0, after that we can send 1!!!
286 if (m_PointState[Point] == EY_POINT_UNDER_CONTROL)
288 UpdateWorldState(PointsIconStruct[Point].WorldStateControlIndex, 0);
289 if (Team == ALLIANCE)
290 UpdateWorldState(PointsIconStruct[Point].WorldStateAllianceControlledIndex, 1);
291 else
292 UpdateWorldState(PointsIconStruct[Point].WorldStateHordeControlledIndex, 1);
294 else
296 if (Team == ALLIANCE)
297 UpdateWorldState(PointsIconStruct[Point].WorldStateAllianceControlledIndex, 0);
298 else
299 UpdateWorldState(PointsIconStruct[Point].WorldStateHordeControlledIndex, 0);
300 UpdateWorldState(PointsIconStruct[Point].WorldStateControlIndex, 1);
304 void BattleGroundEY::AddPlayer(Player *plr)
306 BattleGround::AddPlayer(plr);
307 //create score and add it to map
308 BattleGroundEYScore* sc = new BattleGroundEYScore;
310 m_PlayersNearPoint[BG_EY_PLAYERS_OUT_OF_POINTS].push_back(plr->GetGUID());
312 m_PlayerScores[plr->GetGUID()] = sc;
315 void BattleGroundEY::RemovePlayer(Player *plr, uint64 guid)
317 // sometimes flag aura not removed :(
318 for (int j = BG_EY_NODES_MAX; j >= 0; --j)
320 for(size_t i = 0; i < m_PlayersNearPoint[j].size(); ++i)
321 if (m_PlayersNearPoint[j][i] == guid)
322 m_PlayersNearPoint[j].erase(m_PlayersNearPoint[j].begin() + i);
324 if (IsFlagPickedup())
326 if (m_FlagKeeper == guid)
328 if (plr)
329 EventPlayerDroppedFlag(plr);
330 else
332 SetFlagPicker(0);
333 RespawnFlag(true);
339 void BattleGroundEY::HandleAreaTrigger(Player *Source, uint32 Trigger)
341 if (GetStatus() != STATUS_IN_PROGRESS)
342 return;
344 if(!Source->isAlive()) //hack code, must be removed later
345 return;
347 switch(Trigger)
349 case TR_BLOOD_ELF_POINT:
350 if (m_PointState[BG_EY_NODE_BLOOD_ELF] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[BG_EY_NODE_BLOOD_ELF] == Source->GetTeam())
351 if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
352 EventPlayerCapturedFlag(Source, BG_EY_NODE_BLOOD_ELF);
353 break;
354 case TR_FEL_REAVER_POINT:
355 if (m_PointState[BG_EY_NODE_FEL_REAVER] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[BG_EY_NODE_FEL_REAVER] == Source->GetTeam())
356 if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
357 EventPlayerCapturedFlag(Source, BG_EY_NODE_FEL_REAVER);
358 break;
359 case TR_MAGE_TOWER_POINT:
360 if (m_PointState[BG_EY_NODE_MAGE_TOWER] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[BG_EY_NODE_MAGE_TOWER] == Source->GetTeam())
361 if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
362 EventPlayerCapturedFlag(Source, BG_EY_NODE_MAGE_TOWER);
363 break;
364 case TR_DRAENEI_RUINS_POINT:
365 if (m_PointState[BG_EY_NODE_DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[BG_EY_NODE_DRAENEI_RUINS] == Source->GetTeam())
366 if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
367 EventPlayerCapturedFlag(Source, BG_EY_NODE_DRAENEI_RUINS);
368 break;
369 case 4512:
370 case 4515:
371 case 4517:
372 case 4519:
373 case 4530:
374 case 4531:
375 case 4568:
376 case 4569:
377 case 4570:
378 case 4571:
379 case 5866:
380 break;
381 default:
382 sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger);
383 Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
384 break;
388 bool BattleGroundEY::SetupBattleGround()
390 //buffs
391 for (int i = 0; i < BG_EY_NODES_MAX; ++i)
393 AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(m_Points_Trigger[i]);
394 if (!at)
396 sLog.outError("BattleGroundEY: Unknown trigger: %u", m_Points_Trigger[i]);
397 continue;
399 if (!AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REAVER + i * 3, Buff_Entries[0], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY)
400 || !AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REAVER + i * 3 + 1, Buff_Entries[1], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY)
401 || !AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REAVER + i * 3 + 2, Buff_Entries[2], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY)
403 sLog.outError("BattleGroundEY: Cannot spawn buff");
406 return true;
409 void BattleGroundEY::Reset()
411 //call parent's class reset
412 BattleGround::Reset();
414 m_TeamScores[BG_TEAM_ALLIANCE] = 0;
415 m_TeamScores[BG_TEAM_HORDE] = 0;
416 m_TeamPointsCount[BG_TEAM_ALLIANCE] = 0;
417 m_TeamPointsCount[BG_TEAM_HORDE] = 0;
418 m_HonorScoreTics[BG_TEAM_ALLIANCE] = 0;
419 m_HonorScoreTics[BG_TEAM_HORDE] = 0;
420 m_FlagState = BG_EY_FLAG_STATE_ON_BASE;
421 m_FlagKeeper = 0;
422 m_DroppedFlagGUID = 0;
423 m_PointAddingTimer = 0;
424 m_TowerCapCheckTimer = 0;
425 bool isBGWeekend = BattleGroundMgr::IsBGWeekend(GetTypeID());
426 m_HonorTics = (isBGWeekend) ? BG_EY_EYWeekendHonorTicks : BG_EY_NotEYWeekendHonorTicks;
428 for(uint8 i = 0; i < BG_EY_NODES_MAX; ++i)
430 m_PointOwnedByTeam[i] = EY_POINT_NO_OWNER;
431 m_PointState[i] = EY_POINT_STATE_UNCONTROLLED;
432 m_PointBarStatus[i] = BG_EY_PROGRESS_BAR_STATE_MIDDLE;
433 m_PlayersNearPoint[i].clear();
434 m_PlayersNearPoint[i].reserve(15); //tip size
435 m_ActiveEvents[i] = BG_EYE_NEUTRAL_TEAM; // neutral team owns every node
437 // the flag in the middle is spawned at beginning
438 m_ActiveEvents[BG_EY_EVENT_CAPTURE_FLAG] = BG_EY_EVENT2_FLAG_CENTER;
440 m_PlayersNearPoint[BG_EY_PLAYERS_OUT_OF_POINTS].clear();
441 m_PlayersNearPoint[BG_EY_PLAYERS_OUT_OF_POINTS].reserve(30);
444 void BattleGroundEY::RespawnFlag(bool send_message)
446 m_FlagState = BG_EY_FLAG_STATE_ON_BASE;
447 // will despawn captured flags at the node and spawn in center
448 SpawnEvent(BG_EY_EVENT_CAPTURE_FLAG, BG_EY_EVENT2_FLAG_CENTER, true);
450 if (send_message)
452 SendMessageToAll(LANG_BG_EY_RESETED_FLAG, CHAT_MSG_BG_SYSTEM_NEUTRAL);
453 PlaySoundToAll(BG_EY_SOUND_FLAG_RESET); // flags respawned sound...
456 UpdateWorldState(NETHERSTORM_FLAG, 1);
459 void BattleGroundEY::RespawnFlagAfterDrop()
461 RespawnFlag(true);
463 GameObject *obj = GetBgMap()->GetGameObject(GetDroppedFlagGUID());
464 if (obj)
465 obj->Delete();
466 else
467 sLog.outError("BattleGroundEY: Unknown dropped flag guid: %u",GUID_LOPART(GetDroppedFlagGUID()));
469 SetDroppedFlagGUID(0);
472 void BattleGroundEY::HandleKillPlayer(Player *player, Player *killer)
474 if (GetStatus() != STATUS_IN_PROGRESS)
475 return;
477 BattleGround::HandleKillPlayer(player, killer);
478 EventPlayerDroppedFlag(player);
481 void BattleGroundEY::EventPlayerDroppedFlag(Player *Source)
483 if (GetStatus() != STATUS_IN_PROGRESS)
485 // if not running, do not cast things at the dropper player, neither send unnecessary messages
486 // just take off the aura
487 if (IsFlagPickedup() && GetFlagPickerGUID() == Source->GetGUID())
489 SetFlagPicker(0);
490 Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
492 return;
495 if (!IsFlagPickedup())
496 return;
498 if (GetFlagPickerGUID() != Source->GetGUID())
499 return;
501 SetFlagPicker(0);
502 Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
503 m_FlagState = BG_EY_FLAG_STATE_ON_GROUND;
504 m_FlagsTimer = BG_EY_FLAG_RESPAWN_TIME;
505 Source->CastSpell(Source, SPELL_RECENTLY_DROPPED_FLAG, true);
506 Source->CastSpell(Source, BG_EY_PLAYER_DROPPED_FLAG_SPELL, true);
507 //this does not work correctly :( (it should remove flag carrier name)
508 UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
509 UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
511 if (Source->GetTeam() == ALLIANCE)
512 SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL);
513 else
514 SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, NULL);
517 void BattleGroundEY::EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj)
519 if (GetStatus() != STATUS_IN_PROGRESS || IsFlagPickedup() || !Source->IsWithinDistInMap(target_obj, 10))
520 return;
522 if (Source->GetTeam() == ALLIANCE)
524 UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_ON_PLAYER);
525 PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE);
527 else
529 UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_ON_PLAYER);
530 PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_HORDE);
533 if (m_FlagState == BG_EY_FLAG_STATE_ON_BASE)
534 UpdateWorldState(NETHERSTORM_FLAG, 0);
535 m_FlagState = BG_EY_FLAG_STATE_ON_PLAYER;
537 // despawn center-flag
538 SpawnEvent(BG_EY_EVENT_CAPTURE_FLAG, BG_EY_EVENT2_FLAG_CENTER, false);
540 SetFlagPicker(Source->GetGUID());
541 //get flag aura on player
542 Source->CastSpell(Source, BG_EY_NETHERSTORM_FLAG_SPELL, true);
543 Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
545 if (Source->GetTeam() == ALLIANCE)
546 PSendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL, Source->GetName());
547 else
548 PSendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, NULL, Source->GetName());
551 void BattleGroundEY::EventTeamLostPoint(Player *Source, uint32 Point)
553 if (GetStatus() != STATUS_IN_PROGRESS)
554 return;
556 // neutral node
557 uint32 Team = m_PointOwnedByTeam[Point];
559 if (!Team)
560 return;
562 if (Team == ALLIANCE)
563 m_TeamPointsCount[BG_TEAM_ALLIANCE]--;
564 else
565 m_TeamPointsCount[BG_TEAM_HORDE]--;
567 // it's important to set the OwnedBy before despawning spiritguides, else
568 // player won't get teleported away
569 m_PointOwnedByTeam[Point] = EY_POINT_NO_OWNER;
570 m_PointState[Point] = EY_POINT_NO_OWNER;
572 SpawnEvent(Point, BG_EYE_NEUTRAL_TEAM, true); // will despawn alliance/horde
574 //buff isn't despawned
576 if (Team == ALLIANCE)
577 SendMessageToAll(LoosingPointTypes[Point].MessageIdAlliance,CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
578 else
579 SendMessageToAll(LoosingPointTypes[Point].MessageIdHorde,CHAT_MSG_BG_SYSTEM_HORDE, Source);
581 UpdatePointsIcons(Team, Point);
582 UpdatePointsCount(Team);
585 void BattleGroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point)
587 if (GetStatus() != STATUS_IN_PROGRESS)
588 return;
590 uint32 Team = Source->GetTeam();
592 m_TeamPointsCount[GetTeamIndexByTeamId(Team)]++;
593 SpawnEvent(Point, GetTeamIndexByTeamId(Team), true);
595 //buff isn't respawned
597 m_PointOwnedByTeam[Point] = Team;
598 m_PointState[Point] = EY_POINT_UNDER_CONTROL;
600 if (Team == ALLIANCE)
601 SendMessageToAll(CapturingPointTypes[Point].MessageIdAlliance,CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
602 else
603 SendMessageToAll(CapturingPointTypes[Point].MessageIdHorde,CHAT_MSG_BG_SYSTEM_HORDE, Source);
605 UpdatePointsIcons(Team, Point);
606 UpdatePointsCount(Team);
609 void BattleGroundEY::EventPlayerCapturedFlag(Player *Source, BG_EY_Nodes node)
611 if (GetStatus() != STATUS_IN_PROGRESS || GetFlagPickerGUID() != Source->GetGUID())
612 return;
614 SetFlagPicker(0);
615 m_FlagState = BG_EY_FLAG_STATE_WAIT_RESPAWN;
616 Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
618 Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
620 if (Source->GetTeam() == ALLIANCE)
621 PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE);
622 else
623 PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_HORDE);
625 SpawnEvent(BG_EY_EVENT_CAPTURE_FLAG, node, true);
627 m_FlagsTimer = BG_EY_FLAG_RESPAWN_TIME;
629 uint8 team_id = 0;
630 if (Source->GetTeam() == ALLIANCE)
632 team_id = BG_TEAM_ALLIANCE;
633 SendMessageToAll(LANG_BG_EY_CAPTURED_FLAG_A, CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
635 else
637 team_id = BG_TEAM_HORDE;
638 SendMessageToAll(LANG_BG_EY_CAPTURED_FLAG_H, CHAT_MSG_BG_SYSTEM_HORDE, Source);
641 if (m_TeamPointsCount[team_id] > 0)
642 AddPoints(Source->GetTeam(), BG_EY_FlagPoints[m_TeamPointsCount[team_id] - 1]);
644 UpdatePlayerScore(Source, SCORE_FLAG_CAPTURES, 1);
647 void BattleGroundEY::UpdatePlayerScore(Player *Source, uint32 type, uint32 value)
649 BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
650 if(itr == m_PlayerScores.end()) // player not found
651 return;
653 switch(type)
655 case SCORE_FLAG_CAPTURES: // flags captured
656 ((BattleGroundEYScore*)itr->second)->FlagCaptures += value;
657 break;
658 default:
659 BattleGround::UpdatePlayerScore(Source, type, value);
660 break;
664 void BattleGroundEY::FillInitialWorldStates(WorldPacket& data, uint32& count)
666 FillInitialWorldState(data, count, EY_HORDE_BASE, m_TeamPointsCount[BG_TEAM_HORDE]);
667 FillInitialWorldState(data, count, EY_ALLIANCE_BASE, m_TeamPointsCount[BG_TEAM_ALLIANCE]);
668 FillInitialWorldState(data, count, 0xab6, 0x0);
669 FillInitialWorldState(data, count, 0xab5, 0x0);
670 FillInitialWorldState(data, count, 0xab4, 0x0);
671 FillInitialWorldState(data, count, 0xab3, 0x0);
672 FillInitialWorldState(data, count, 0xab2, 0x0);
673 FillInitialWorldState(data, count, 0xab1, 0x0);
674 FillInitialWorldState(data, count, 0xab0, 0x0);
675 FillInitialWorldState(data, count, 0xaaf, 0x0);
677 FillInitialWorldState(data, count, DRAENEI_RUINS_HORDE_CONTROL, m_PointOwnedByTeam[BG_EY_NODE_DRAENEI_RUINS] == HORDE && m_PointState[BG_EY_NODE_DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL);
678 FillInitialWorldState(data, count, DRAENEI_RUINS_ALLIANCE_CONTROL, m_PointOwnedByTeam[BG_EY_NODE_DRAENEI_RUINS] == ALLIANCE && m_PointState[BG_EY_NODE_DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL);
679 FillInitialWorldState(data, count, DRAENEI_RUINS_UNCONTROL, m_PointState[BG_EY_NODE_DRAENEI_RUINS] != EY_POINT_UNDER_CONTROL);
680 FillInitialWorldState(data, count, MAGE_TOWER_ALLIANCE_CONTROL, m_PointOwnedByTeam[BG_EY_NODE_MAGE_TOWER] == ALLIANCE && m_PointState[BG_EY_NODE_MAGE_TOWER] == EY_POINT_UNDER_CONTROL);
681 FillInitialWorldState(data, count, MAGE_TOWER_HORDE_CONTROL, m_PointOwnedByTeam[BG_EY_NODE_MAGE_TOWER] == HORDE && m_PointState[BG_EY_NODE_MAGE_TOWER] == EY_POINT_UNDER_CONTROL);
682 FillInitialWorldState(data, count, MAGE_TOWER_UNCONTROL, m_PointState[BG_EY_NODE_MAGE_TOWER] != EY_POINT_UNDER_CONTROL);
683 FillInitialWorldState(data, count, FEL_REAVER_HORDE_CONTROL, m_PointOwnedByTeam[BG_EY_NODE_FEL_REAVER] == HORDE && m_PointState[BG_EY_NODE_FEL_REAVER] == EY_POINT_UNDER_CONTROL);
684 FillInitialWorldState(data, count, FEL_REAVER_ALLIANCE_CONTROL, m_PointOwnedByTeam[BG_EY_NODE_FEL_REAVER] == ALLIANCE && m_PointState[BG_EY_NODE_FEL_REAVER] == EY_POINT_UNDER_CONTROL);
685 FillInitialWorldState(data, count, FEL_REAVER_UNCONTROL, m_PointState[BG_EY_NODE_FEL_REAVER] != EY_POINT_UNDER_CONTROL);
686 FillInitialWorldState(data, count, BLOOD_ELF_HORDE_CONTROL, m_PointOwnedByTeam[BG_EY_NODE_BLOOD_ELF] == HORDE && m_PointState[BG_EY_NODE_BLOOD_ELF] == EY_POINT_UNDER_CONTROL);
687 FillInitialWorldState(data, count, BLOOD_ELF_ALLIANCE_CONTROL, m_PointOwnedByTeam[BG_EY_NODE_BLOOD_ELF] == ALLIANCE && m_PointState[BG_EY_NODE_BLOOD_ELF] == EY_POINT_UNDER_CONTROL);
688 FillInitialWorldState(data, count, BLOOD_ELF_UNCONTROL, m_PointState[BG_EY_NODE_BLOOD_ELF] != EY_POINT_UNDER_CONTROL);
689 FillInitialWorldState(data, count, NETHERSTORM_FLAG, m_FlagState == BG_EY_FLAG_STATE_ON_BASE);
690 FillInitialWorldState(data, count, 0xad2, 0x1);
691 FillInitialWorldState(data, count, 0xad1, 0x1);
692 FillInitialWorldState(data, count, 0xabe, GetTeamScore(HORDE));
693 FillInitialWorldState(data, count, 0xabd, GetTeamScore(ALLIANCE));
694 FillInitialWorldState(data, count, 0xa05, 0x8e);
695 FillInitialWorldState(data, count, 0xaa0, 0x0);
696 FillInitialWorldState(data, count, 0xa9f, 0x0);
697 FillInitialWorldState(data, count, 0xa9e, 0x0);
698 FillInitialWorldState(data, count, 0xc0d, 0x17b);
701 WorldSafeLocsEntry const *BattleGroundEY::GetClosestGraveYard(Player* player)
703 uint32 g_id = 0;
705 switch(player->GetTeam())
707 case ALLIANCE: g_id = EY_GRAVEYARD_MAIN_ALLIANCE; break;
708 case HORDE: g_id = EY_GRAVEYARD_MAIN_HORDE; break;
709 default: return NULL;
712 float distance, nearestDistance;
714 WorldSafeLocsEntry const* entry = NULL;
715 WorldSafeLocsEntry const* nearestEntry = NULL;
716 entry = sWorldSafeLocsStore.LookupEntry(g_id);
717 nearestEntry = entry;
719 if (!entry)
721 sLog.outError("BattleGroundEY: Not found the main team graveyard. Graveyard system isn't working!");
722 return NULL;
725 float plr_x = player->GetPositionX();
726 float plr_y = player->GetPositionY();
727 float plr_z = player->GetPositionZ();
730 distance = (entry->x - plr_x)*(entry->x - plr_x) + (entry->y - plr_y)*(entry->y - plr_y) + (entry->z - plr_z)*(entry->z - plr_z);
731 nearestDistance = distance;
733 for(uint8 i = 0; i < BG_EY_NODES_MAX; ++i)
735 if (m_PointOwnedByTeam[i]==player->GetTeam() && m_PointState[i]==EY_POINT_UNDER_CONTROL)
737 entry = sWorldSafeLocsStore.LookupEntry(CapturingPointTypes[i].GraveYardId);
738 if (!entry)
739 sLog.outError("BattleGroundEY: Not found graveyard: %u",CapturingPointTypes[i].GraveYardId);
740 else
742 distance = (entry->x - plr_x)*(entry->x - plr_x) + (entry->y - plr_y)*(entry->y - plr_y) + (entry->z - plr_z)*(entry->z - plr_z);
743 if (distance < nearestDistance)
745 nearestDistance = distance;
746 nearestEntry = entry;
752 return nearestEntry;
755 bool BattleGroundEY::IsAllNodesConrolledByTeam(uint32 team) const
757 for(int i = 0; i < BG_EY_NODES_MAX; ++i)
758 if (m_PointState[i] != EY_POINT_UNDER_CONTROL || m_PointOwnedByTeam[i] != team)
759 return false;
761 return true;