text: /*
   * Copyright (C) 2005 - 2012 MaNGOS <http://www.getmangos.com/>
   *
   * Copyright (C) 2008 - 2012 Trinity <http://www.trinitycore.org/>
   *
   * Copyright (C) 2010 - 2012 ProjectSkyfire <http://www.projectskyfire.org/>
   * 
   * Copyright (C) 2011 - 2012 ArkCORE <http://www.arkania.net/>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
   */
  
  #include "gamePCH.h"
  #include "ObjectMgr.h"
  #include "World.h"
  #include "WorldPacket.h"
  #include "BattlegroundMgr.h"
  #include "Battleground.h"
  #include "BattlegroundEY.h"
  #include "Creature.h"
  #include "Language.h"
  #include "Object.h"
  #include "Player.h"
  #include "Util.h"
  
  // these variables aren't used outside of this file, so declare them only here
  uint32 BG_EY_HonorScoreTicks[BG_HONOR_MODE_NUM] = {
      330, // normal honor
      200  // holiday
  };
  
  BattlegroundEY::BattlegroundEY()
  {
      m_BuffChange = true;
      m_BgObjects.resize(BG_EY_OBJECT_MAX);
      m_BgCreatures.resize(BG_EY_CREATURES_MAX);
      m_Points_Trigger[FEL_REAVER] = TR_FEL_REAVER_BUFF;
      m_Points_Trigger[BLOOD_ELF] = TR_BLOOD_ELF_BUFF;
      m_Points_Trigger[DRAENEI_RUINS] = TR_DRAENEI_RUINS_BUFF;
      m_Points_Trigger[MAGE_TOWER] = TR_MAGE_TOWER_BUFF;
  
      m_StartMessageIds[BG_STARTING_EVENT_FIRST]  = LANG_BG_EY_START_TWO_MINUTES;
      m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_EY_START_ONE_MINUTE;
      m_StartMessageIds[BG_STARTING_EVENT_THIRD]  = LANG_BG_EY_START_HALF_MINUTE;
      m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_EY_HAS_BEGUN;
  }
  
  BattlegroundEY::~BattlegroundEY()
  {
  }
  
  void BattlegroundEY::Update(uint32 diff)
  {
      Battleground::Update(diff);
  
      if (GetStatus() == STATUS_IN_PROGRESS)
      {
          m_PointAddingTimer -= diff;
          if (m_PointAddingTimer <= 0)
          {
              m_PointAddingTimer = BG_EY_FPOINTS_TICK_TIME;
              if (m_TeamPointsCount[BG_TEAM_ALLIANCE] > 0)
                  AddPoints(ALLIANCE, BG_EY_TickPoints[m_TeamPointsCount[BG_TEAM_ALLIANCE] - 1]);
              if (m_TeamPointsCount[BG_TEAM_HORDE] > 0)
                  AddPoints(HORDE, BG_EY_TickPoints[m_TeamPointsCount[BG_TEAM_HORDE] - 1]);
          }
  
          if (m_FlagState == BG_EY_FLAG_STATE_WAIT_RESPAWN || m_FlagState == BG_EY_FLAG_STATE_ON_GROUND)
          {
              m_FlagsTimer -= diff;
  
              if (m_FlagsTimer < 0)
              {
                  m_FlagsTimer = 0;
                  if (m_FlagState == BG_EY_FLAG_STATE_WAIT_RESPAWN)
                      RespawnFlag(true);
                  else
                      RespawnFlagAfterDrop();
              }
          }
  
          m_TowerCapCheckTimer -= diff;
          if (m_TowerCapCheckTimer <= 0)
          {
              //check if player joined point
              /*I used this order of calls, because although we will check if one player is in gameobject's distance 2 times
                but we can count of players on current point in CheckSomeoneLeftPoint
              */
              this->CheckSomeoneJoinedPoint();
              //check if player left point
              this->CheckSomeoneLeftPoint();
              this->UpdatePointStatuses();
              m_TowerCapCheckTimer = BG_EY_FPOINTS_TICK_TIME;
          }
      }
  }
  
  void BattlegroundEY::StartingEventCloseDoors()
  {
      SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_IMMEDIATELY);
      SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_IMMEDIATELY);
  
      for (uint32 i = BG_EY_OBJECT_A_BANNER_FEL_REAVER_CENTER; i < BG_EY_OBJECT_MAX; ++i)
          SpawnBGObject(i, RESPAWN_ONE_DAY);
  }
  
  void BattlegroundEY::StartingEventOpenDoors()
  {
      SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_ONE_DAY);
      SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_ONE_DAY);
  
      for (uint32 i = BG_EY_OBJECT_N_BANNER_FEL_REAVER_CENTER; i <= BG_EY_OBJECT_FLAG_NETHERSTORM; ++i)
          SpawnBGObject(i, RESPAWN_IMMEDIATELY);
      for (uint32 i = 0; i < EY_POINTS_MAX; ++i)
      {
          //randomly spawn buff
          uint8 buff = urand(0, 2);
          SpawnBGObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REAVER + buff + i * 3, RESPAWN_IMMEDIATELY);
      }
  }
  
  void BattlegroundEY::AddPoints(uint32 Team, uint32 Points)
  {
      BattlegroundTeamId team_index = GetTeamIndexByTeamId(Team);
      m_TeamScores[team_index] += Points;
      m_HonorScoreTics[team_index] += Points;
      if (m_HonorScoreTics[team_index] >= m_HonorTics)
      {
          RewardHonorToTeam(GetBonusHonorFromKill(1), Team);
          m_HonorScoreTics[team_index] -= m_HonorTics;
      }
      UpdateTeamScore(Team);
  }
  
  void BattlegroundEY::CheckSomeoneJoinedPoint()
  {
      GameObject *obj = NULL;
      for (uint8 i = 0; i < EY_POINTS_MAX; ++i)
      {
          obj = HashMapHolder<GameObject>::Find(m_BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REAVER + i]);
          if (obj)
          {
              uint8 j = 0;
              while (j < m_PlayersNearPoint[EY_POINTS_MAX].size())
              {
                  Player *plr = sObjectMgr->GetPlayer(m_PlayersNearPoint[EY_POINTS_MAX][j]);
                  if (!plr)
                  {
                      sLog->outError("BattlegroundEY:CheckSomeoneJoinedPoint: Player (GUID: %u) not found!", GUID_LOPART(m_PlayersNearPoint[EY_POINTS_MAX][j]));
                      ++j;
                      continue;
                  }
                  if (plr->CanCaptureTowerPoint() && plr->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS))
                  {
                      //player joined point!
                      //show progress bar
                      UpdateWorldStateForPlayer(PROGRESS_BAR_PERCENT_GREY, BG_EY_PROGRESS_BAR_PERCENT_GREY, plr);
                      UpdateWorldStateForPlayer(PROGRESS_BAR_STATUS, m_PointBarStatus[i], plr);
                      UpdateWorldStateForPlayer(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_SHOW, plr);
                      //add player to point
                      m_PlayersNearPoint[i].push_back(m_PlayersNearPoint[EY_POINTS_MAX][j]);
                      //remove player from "free space"
                      m_PlayersNearPoint[EY_POINTS_MAX].erase(m_PlayersNearPoint[EY_POINTS_MAX].begin() + j);
                  }
                  else
                      ++j;
              }
          }
      }
  }
  
  void BattlegroundEY::CheckSomeoneLeftPoint()
  {
      //reset current point counts
      for (uint8 i = 0; i < 2*EY_POINTS_MAX; ++i)
          m_CurrentPointPlayersCount[i] = 0;
      GameObject *obj = NULL;
      for (uint8 i = 0; i < EY_POINTS_MAX; ++i)
      {
          obj = HashMapHolder<GameObject>::Find(m_BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REAVER + i]);
          if (obj)
          {
              uint8 j = 0;
              while (j < m_PlayersNearPoint[i].size())
              {
                  Player *plr = sObjectMgr->GetPlayer(m_PlayersNearPoint[i][j]);
                  if (!plr)
                  {
                      sLog->outError("BattlegroundEY:CheckSomeoneLeftPoint Player (GUID: %u) not found!", GUID_LOPART(m_PlayersNearPoint[i][j]));
                      //move not existed player to "free space" - this will cause many error showing in log, but it is a very important bug
                      m_PlayersNearPoint[EY_POINTS_MAX].push_back(m_PlayersNearPoint[i][j]);
                      m_PlayersNearPoint[i].erase(m_PlayersNearPoint[i].begin() + j);
                      ++j;
                      continue;
                  }
                  if (!plr->CanCaptureTowerPoint() || !plr->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS))
                      //move player out of point (add him to players that are out of points
                  {
                      m_PlayersNearPoint[EY_POINTS_MAX].push_back(m_PlayersNearPoint[i][j]);
                      m_PlayersNearPoint[i].erase(m_PlayersNearPoint[i].begin() + j);
                      this->UpdateWorldStateForPlayer(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_DONT_SHOW, plr);
                  }
                  else
                  {
                      //player is neat flag, so update count:
                      m_CurrentPointPlayersCount[2 * i + GetTeamIndexByTeamId(plr->GetTeam())]++;
                      ++j;
                  }
              }
          }
      }
  }
  
  void BattlegroundEY::UpdatePointStatuses()
  {
      for (uint8 point = 0; point < EY_POINTS_MAX; ++point)
      {
          if (m_PlayersNearPoint[point].empty())
              continue;
          //count new point bar status:
          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;
  
          if (m_PointBarStatus[point] > BG_EY_PROGRESS_BAR_ALI_CONTROLLED)
              //point is fully alliance's
              m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_ALI_CONTROLLED;
          if (m_PointBarStatus[point] < BG_EY_PROGRESS_BAR_HORDE_CONTROLLED)
              //point is fully horde's
              m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_HORDE_CONTROLLED;
  
          uint32 pointOwnerTeamId = 0;
          //find which team should own this point
          if (m_PointBarStatus[point] <= BG_EY_PROGRESS_BAR_NEUTRAL_LOW)
              pointOwnerTeamId = HORDE;
          else if (m_PointBarStatus[point] >= BG_EY_PROGRESS_BAR_NEUTRAL_HIGH)
              pointOwnerTeamId = ALLIANCE;
          else
              pointOwnerTeamId = EY_POINT_NO_OWNER;
  
          for (uint8 i = 0; i < m_PlayersNearPoint[point].size(); ++i)
          {
              Player *plr = sObjectMgr->GetPlayer(m_PlayersNearPoint[point][i]);
              if (plr)
              {
                  this->UpdateWorldStateForPlayer(PROGRESS_BAR_STATUS, m_PointBarStatus[point], plr);
                                                              //if point owner changed we must evoke event!
                  if (pointOwnerTeamId != m_PointOwnedByTeam[point])
                  {
                      //point was uncontrolled and player is from team which captured point
                      if (m_PointState[point] == EY_POINT_STATE_UNCONTROLLED && plr->GetTeam() == pointOwnerTeamId)
                          this->EventTeamCapturedPoint(plr, point);
  
                      //point was under control and player isn't from team which controlled it
                      if (m_PointState[point] == EY_POINT_UNDER_CONTROL && plr->GetTeam() != m_PointOwnedByTeam[point])
                          this->EventTeamLostPoint(plr, point);
                  }
              }
          }
      }
  }
  
  void BattlegroundEY::UpdateTeamScore(uint32 Team)
  {
      uint32 score = GetTeamScore(Team);
      //TODO there should be some sound played when one team is near victory!! - and define variables
      /*if (!m_IsInformedNearVictory && score >= BG_EY_WARNING_NEAR_VICTORY_SCORE)
      {
          if (Team == ALLIANCE)
              SendMessageToAll(LANG_BG_EY_A_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
          else
              SendMessageToAll(LANG_BG_EY_H_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
          PlaySoundToAll(BG_EY_SOUND_NEAR_VICTORY);
          m_IsInformedNearVictory = true;
      }*/
  
      if (score >= BG_EY_MAX_TEAM_SCORE)
      {
          score = BG_EY_MAX_TEAM_SCORE;
          EndBattleground(Team);
      }
  
      if (Team == ALLIANCE)
          UpdateWorldState(EY_ALLIANCE_RESOURCES, score);
      else
          UpdateWorldState(EY_HORDE_RESOURCES, score);
  }
  
  void BattlegroundEY::EndBattleground(uint32 winner)
  {
      //win reward
      if (winner == ALLIANCE)
          RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
      if (winner == HORDE)
          RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
      //complete map reward
      RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
      RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
  
      Battleground::EndBattleground(winner);
  }
  
  void BattlegroundEY::UpdatePointsCount(uint32 Team)
  {
      if (Team == ALLIANCE)
          UpdateWorldState(EY_ALLIANCE_BASE, m_TeamPointsCount[BG_TEAM_ALLIANCE]);
      else
          UpdateWorldState(EY_HORDE_BASE, m_TeamPointsCount[BG_TEAM_HORDE]);
  }
  
  void BattlegroundEY::UpdatePointsIcons(uint32 Team, uint32 Point)
  {
      //we MUST firstly send 0, after that we can send 1!!!
      if (m_PointState[Point] == EY_POINT_UNDER_CONTROL)
      {
          UpdateWorldState(m_PointsIconStruct[Point].WorldStateControlIndex, 0);
          if (Team == ALLIANCE)
              UpdateWorldState(m_PointsIconStruct[Point].WorldStateAllianceControlledIndex, 1);
          else
              UpdateWorldState(m_PointsIconStruct[Point].WorldStateHordeControlledIndex, 1);
      }
      else
      {
          if (Team == ALLIANCE)
              UpdateWorldState(m_PointsIconStruct[Point].WorldStateAllianceControlledIndex, 0);
          else
              UpdateWorldState(m_PointsIconStruct[Point].WorldStateHordeControlledIndex, 0);
          UpdateWorldState(m_PointsIconStruct[Point].WorldStateControlIndex, 1);
      }
  }
  
  void BattlegroundEY::AddPlayer(Player *plr)
  {
      Battleground::AddPlayer(plr);
      //create score and add it to map
      BattlegroundEYScore* sc = new BattlegroundEYScore;
  
      m_PlayersNearPoint[EY_POINTS_MAX].push_back(plr->GetGUID());
  
      m_PlayerScores[plr->GetGUID()] = sc;
  }
  
  void BattlegroundEY::RemovePlayer(Player *plr, uint64 guid)
  {
      // sometimes flag aura not removed :(
      for (int j = EY_POINTS_MAX; j >= 0; --j)
      {
          for (size_t i = 0; i < m_PlayersNearPoint[j].size(); ++i)
              if (m_PlayersNearPoint[j][i] == guid)
                  m_PlayersNearPoint[j].erase(m_PlayersNearPoint[j].begin() + i);
      }
      if (IsFlagPickedup())
      {
          if (m_FlagKeeper == guid)
          {
              if (plr)
                  EventPlayerDroppedFlag(plr);
              else
              {
                  SetFlagPicker(0);
                  RespawnFlag(true);
              }
          }
      }
  }
  
  void BattlegroundEY::HandleAreaTrigger(Player *Source, uint32 Trigger)
  {
      if (GetStatus() != STATUS_IN_PROGRESS)
          return;
  
      if (!Source->isAlive())                                  //hack code, must be removed later
          return;
  
      switch(Trigger)
      {
          case TR_BLOOD_ELF_POINT:
              if (m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[BLOOD_ELF] == Source->GetTeam())
                  if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
                      EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_BLOOD_ELF);
              break;
          case TR_FEL_REAVER_POINT:
              if (m_PointState[FEL_REAVER] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[FEL_REAVER] == Source->GetTeam())
                  if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
                      EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_FEL_REAVER);
              break;
          case TR_MAGE_TOWER_POINT:
              if (m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[MAGE_TOWER] == Source->GetTeam())
                  if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
                      EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_MAGE_TOWER);
              break;
          case TR_DRAENEI_RUINS_POINT:
              if (m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[DRAENEI_RUINS] == Source->GetTeam())
                  if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
                      EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_DRAENEI_RUINS);
              break;
          case 4512:
          case 4515:
          case 4517:
          case 4519:
          case 4530:
          case 4531:
          case 4568:
          case 4569:
          case 4570:
          case 4571:
          case 5866:
              break;
          default:
              sLog->outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger);
              Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
              break;
      }
  }
  
  bool BattlegroundEY::SetupBattleground()
  {
          // doors
      if (!AddObject(BG_EY_OBJECT_DOOR_A, BG_OBJECT_A_DOOR_EY_ENTRY, 2527.6f, 1596.91f, 1262.13f, -3.12414f, -0.173642f, -0.001515f, 0.98477f, -0.008594f, RESPAWN_IMMEDIATELY)
          || !AddObject(BG_EY_OBJECT_DOOR_H, BG_OBJECT_H_DOOR_EY_ENTRY, 1803.21f, 1539.49f, 1261.09f, 3.14159f, 0.173648f, 0, 0.984808f, 0, RESPAWN_IMMEDIATELY)
          // banners (alliance)
          || !AddObject(BG_EY_OBJECT_A_BANNER_FEL_REAVER_CENTER, BG_OBJECT_A_BANNER_EY_ENTRY, 2057.46f, 1735.07f, 1187.91f, -0.925024f, 0, 0, 0.446198f, -0.894934f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_A_BANNER_FEL_REAVER_LEFT, BG_OBJECT_A_BANNER_EY_ENTRY, 2032.25f, 1729.53f, 1190.33f, 1.8675f, 0, 0, 0.803857f, 0.594823f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_A_BANNER_FEL_REAVER_RIGHT, BG_OBJECT_A_BANNER_EY_ENTRY, 2092.35f, 1775.46f, 1187.08f, -0.401426f, 0, 0, 0.199368f, -0.979925f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_A_BANNER_BLOOD_ELF_CENTER, BG_OBJECT_A_BANNER_EY_ENTRY, 2047.19f, 1349.19f, 1189.0f, -1.62316f, 0, 0, 0.725374f, -0.688354f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_A_BANNER_BLOOD_ELF_LEFT, BG_OBJECT_A_BANNER_EY_ENTRY, 2074.32f, 1385.78f, 1194.72f, 0.488692f, 0, 0, 0.241922f, 0.970296f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_A_BANNER_BLOOD_ELF_RIGHT, BG_OBJECT_A_BANNER_EY_ENTRY, 2025.13f, 1386.12f, 1192.74f, 2.3911f, 0, 0, 0.930418f, 0.366501f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_CENTER, BG_OBJECT_A_BANNER_EY_ENTRY, 2276.8f, 1400.41f, 1196.33f, 2.44346f, 0, 0, 0.939693f, 0.34202f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_LEFT, BG_OBJECT_A_BANNER_EY_ENTRY, 2305.78f, 1404.56f, 1199.38f, 1.74533f, 0, 0, 0.766044f, 0.642788f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_RIGHT, BG_OBJECT_A_BANNER_EY_ENTRY, 2245.4f, 1366.41f, 1195.28f, 2.21657f, 0, 0, 0.894934f, 0.446198f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_A_BANNER_MAGE_TOWER_CENTER, BG_OBJECT_A_BANNER_EY_ENTRY, 2270.84f, 1784.08f, 1186.76f, 2.42601f, 0, 0, 0.936672f, 0.350207f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_A_BANNER_MAGE_TOWER_LEFT, BG_OBJECT_A_BANNER_EY_ENTRY, 2269.13f, 1737.7f, 1186.66f, 0.994838f, 0, 0, 0.477159f, 0.878817f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_A_BANNER_MAGE_TOWER_RIGHT, BG_OBJECT_A_BANNER_EY_ENTRY, 2300.86f, 1741.25f, 1187.7f, -0.785398f, 0, 0, 0.382683f, -0.92388f, RESPAWN_ONE_DAY)
          // banners (horde)
          || !AddObject(BG_EY_OBJECT_H_BANNER_FEL_REAVER_CENTER, BG_OBJECT_H_BANNER_EY_ENTRY, 2057.46f, 1735.07f, 1187.91f, -0.925024f, 0, 0, 0.446198f, -0.894934f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_H_BANNER_FEL_REAVER_LEFT, BG_OBJECT_H_BANNER_EY_ENTRY, 2032.25f, 1729.53f, 1190.33f, 1.8675f, 0, 0, 0.803857f, 0.594823f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_H_BANNER_FEL_REAVER_RIGHT, BG_OBJECT_H_BANNER_EY_ENTRY, 2092.35f, 1775.46f, 1187.08f, -0.401426f, 0, 0, 0.199368f, -0.979925f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_H_BANNER_BLOOD_ELF_CENTER, BG_OBJECT_H_BANNER_EY_ENTRY, 2047.19f, 1349.19f, 1189.0f, -1.62316f, 0, 0, 0.725374f, -0.688354f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_H_BANNER_BLOOD_ELF_LEFT, BG_OBJECT_H_BANNER_EY_ENTRY, 2074.32f, 1385.78f, 1194.72f, 0.488692f, 0, 0, 0.241922f, 0.970296f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_H_BANNER_BLOOD_ELF_RIGHT, BG_OBJECT_H_BANNER_EY_ENTRY, 2025.13f, 1386.12f, 1192.74f, 2.3911f, 0, 0, 0.930418f, 0.366501f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_CENTER, BG_OBJECT_H_BANNER_EY_ENTRY, 2276.8f, 1400.41f, 1196.33f, 2.44346f, 0, 0, 0.939693f, 0.34202f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_LEFT, BG_OBJECT_H_BANNER_EY_ENTRY, 2305.78f, 1404.56f, 1199.38f, 1.74533f, 0, 0, 0.766044f, 0.642788f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_RIGHT, BG_OBJECT_H_BANNER_EY_ENTRY, 2245.4f, 1366.41f, 1195.28f, 2.21657f, 0, 0, 0.894934f, 0.446198f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_H_BANNER_MAGE_TOWER_CENTER, BG_OBJECT_H_BANNER_EY_ENTRY, 2270.84f, 1784.08f, 1186.76f, 2.42601f, 0, 0, 0.936672f, 0.350207f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_H_BANNER_MAGE_TOWER_LEFT, BG_OBJECT_H_BANNER_EY_ENTRY, 2269.13f, 1737.7f, 1186.66f, 0.994838f, 0, 0, 0.477159f, 0.878817f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_H_BANNER_MAGE_TOWER_RIGHT, BG_OBJECT_H_BANNER_EY_ENTRY, 2300.86f, 1741.25f, 1187.7f, -0.785398f, 0, 0, 0.382683f, -0.92388f, RESPAWN_ONE_DAY)
          // banners (natural)
          || !AddObject(BG_EY_OBJECT_N_BANNER_FEL_REAVER_CENTER, BG_OBJECT_N_BANNER_EY_ENTRY, 2057.46f, 1735.07f, 1187.91f, -0.925024f, 0, 0, 0.446198f, -0.894934f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_N_BANNER_FEL_REAVER_LEFT, BG_OBJECT_N_BANNER_EY_ENTRY, 2032.25f, 1729.53f, 1190.33f, 1.8675f, 0, 0, 0.803857f, 0.594823f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_N_BANNER_FEL_REAVER_RIGHT, BG_OBJECT_N_BANNER_EY_ENTRY, 2092.35f, 1775.46f, 1187.08f, -0.401426f, 0, 0, 0.199368f, -0.979925f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_N_BANNER_BLOOD_ELF_CENTER, BG_OBJECT_N_BANNER_EY_ENTRY, 2047.19f, 1349.19f, 1189.0f, -1.62316f, 0, 0, 0.725374f, -0.688354f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_N_BANNER_BLOOD_ELF_LEFT, BG_OBJECT_N_BANNER_EY_ENTRY, 2074.32f, 1385.78f, 1194.72f, 0.488692f, 0, 0, 0.241922f, 0.970296f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_N_BANNER_BLOOD_ELF_RIGHT, BG_OBJECT_N_BANNER_EY_ENTRY, 2025.13f, 1386.12f, 1192.74f, 2.3911f, 0, 0, 0.930418f, 0.366501f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_CENTER, BG_OBJECT_N_BANNER_EY_ENTRY, 2276.8f, 1400.41f, 1196.33f, 2.44346f, 0, 0, 0.939693f, 0.34202f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_LEFT, BG_OBJECT_N_BANNER_EY_ENTRY, 2305.78f, 1404.56f, 1199.38f, 1.74533f, 0, 0, 0.766044f, 0.642788f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_RIGHT, BG_OBJECT_N_BANNER_EY_ENTRY, 2245.4f, 1366.41f, 1195.28f, 2.21657f, 0, 0, 0.894934f, 0.446198f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_CENTER, BG_OBJECT_N_BANNER_EY_ENTRY, 2270.84f, 1784.08f, 1186.76f, 2.42601f, 0, 0, 0.936672f, 0.350207f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_LEFT, BG_OBJECT_N_BANNER_EY_ENTRY, 2269.13f, 1737.7f, 1186.66f, 0.994838f, 0, 0, 0.477159f, 0.878817f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_RIGHT, BG_OBJECT_N_BANNER_EY_ENTRY, 2300.86f, 1741.25f, 1187.7f, -0.785398f, 0, 0, 0.382683f, -0.92388f, RESPAWN_ONE_DAY)
          // flags
          || !AddObject(BG_EY_OBJECT_FLAG_NETHERSTORM, BG_OBJECT_FLAG2_EY_ENTRY, 2174.782227f, 1569.054688f, 1160.361938f, -1.448624f, 0, 0, 0.662620f, -0.748956f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_FLAG_FEL_REAVER, BG_OBJECT_FLAG1_EY_ENTRY, 2044.28f, 1729.68f, 1189.96f, -0.017453f, 0, 0, 0.008727f, -0.999962f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_FLAG_BLOOD_ELF, BG_OBJECT_FLAG1_EY_ENTRY, 2048.83f, 1393.65f, 1194.49f, 0.20944f, 0, 0, 0.104528f, 0.994522f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_FLAG_DRAENEI_RUINS, BG_OBJECT_FLAG1_EY_ENTRY, 2286.56f, 1402.36f, 1197.11f, 3.72381f, 0, 0, 0.957926f, -0.287016f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_FLAG_MAGE_TOWER, BG_OBJECT_FLAG1_EY_ENTRY, 2284.48f, 1731.23f, 1189.99f, 2.89725f, 0, 0, 0.992546f, 0.121869f, RESPAWN_ONE_DAY)
          // tower cap
          || !AddObject(BG_EY_OBJECT_TOWER_CAP_FEL_REAVER, BG_OBJECT_FR_TOWER_CAP_EY_ENTRY, 2024.600708f, 1742.819580f, 1195.157715f, 2.443461f, 0, 0, 0.939693f, 0.342020f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_TOWER_CAP_BLOOD_ELF, BG_OBJECT_BE_TOWER_CAP_EY_ENTRY, 2050.493164f, 1372.235962f, 1194.563477f, 1.710423f, 0, 0, 0.754710f, 0.656059f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_TOWER_CAP_DRAENEI_RUINS, BG_OBJECT_DR_TOWER_CAP_EY_ENTRY, 2301.010498f, 1386.931641f, 1197.183472f, 1.570796f, 0, 0, 0.707107f, 0.707107f, RESPAWN_ONE_DAY)
          || !AddObject(BG_EY_OBJECT_TOWER_CAP_MAGE_TOWER, BG_OBJECT_HU_TOWER_CAP_EY_ENTRY, 2282.121582f, 1760.006958f, 1189.707153f, 1.919862f, 0, 0, 0.819152f, 0.573576f, RESPAWN_ONE_DAY)
  )
      {
          sLog->outErrorDb("BatteGroundEY: Failed to spawn some object Battleground not created!");
          return false;
      }
  
      //buffs
      for (int i = 0; i < EY_POINTS_MAX; ++i)
      {
          AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(m_Points_Trigger[i]);
          if (!at)
          {
              sLog->outError("BattlegroundEY: Unknown trigger: %u", m_Points_Trigger[i]);
              continue;
          }
          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)
              || !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)
              || !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)
  )
              sLog->outError("BattlegroundEY: Cannot spawn buff");
      }
  
      WorldSafeLocsEntry const *sg = NULL;
      sg = sWorldSafeLocsStore.LookupEntry(EY_GRAVEYARD_MAIN_ALLIANCE);
      if (!sg || !AddSpiritGuide(EY_SPIRIT_MAIN_ALLIANCE, sg->x, sg->y, sg->z, 3.124139f, ALLIANCE))
      {
          sLog->outErrorDb("BatteGroundEY: Failed to spawn spirit guide! Battleground not created!");
          return false;
      }
  
      sg = sWorldSafeLocsStore.LookupEntry(EY_GRAVEYARD_MAIN_HORDE);
      if (!sg || !AddSpiritGuide(EY_SPIRIT_MAIN_HORDE, sg->x, sg->y, sg->z, 3.193953f, HORDE))
      {
          sLog->outErrorDb("BatteGroundEY: Failed to spawn spirit guide! Battleground not created!");
          return false;
      }
  
      return true;
  }
  
  void BattlegroundEY::Reset()
  {
      //call parent's class reset
      Battleground::Reset();
  
      m_TeamScores[BG_TEAM_ALLIANCE] = 0;
      m_TeamScores[BG_TEAM_HORDE] = 0;
      m_TeamPointsCount[BG_TEAM_ALLIANCE] = 0;
      m_TeamPointsCount[BG_TEAM_HORDE] = 0;
      m_HonorScoreTics[BG_TEAM_ALLIANCE] = 0;
      m_HonorScoreTics[BG_TEAM_HORDE] = 0;
      m_FlagState = BG_EY_FLAG_STATE_ON_BASE;
      m_FlagCapturedBgObjectType = 0;
      m_FlagKeeper = 0;
      m_DroppedFlagGUID = 0;
      m_PointAddingTimer = 0;
      m_TowerCapCheckTimer = 0;
      bool isBGWeekend = sBattlegroundMgr->IsBGWeekend(GetTypeID());
      m_HonorTics = (isBGWeekend) ? BG_EY_EYWeekendHonorTicks : BG_EY_NotEYWeekendHonorTicks;
  
      for (uint8 i = 0; i < EY_POINTS_MAX; ++i)
      {
          m_PointOwnedByTeam[i] = EY_POINT_NO_OWNER;
          m_PointState[i] = EY_POINT_STATE_UNCONTROLLED;
          m_PointBarStatus[i] = BG_EY_PROGRESS_BAR_STATE_MIDDLE;
          m_PlayersNearPoint[i].clear();
          m_PlayersNearPoint[i].reserve(15);                  //tip size
      }
      m_PlayersNearPoint[EY_PLAYERS_OUT_OF_POINTS].clear();
      m_PlayersNearPoint[EY_PLAYERS_OUT_OF_POINTS].reserve(30);
  }
  
  void BattlegroundEY::RespawnFlag(bool send_message)
  {
      if (m_FlagCapturedBgObjectType > 0)
          SpawnBGObject(m_FlagCapturedBgObjectType, RESPAWN_ONE_DAY);
  
      m_FlagCapturedBgObjectType = 0;
      m_FlagState = BG_EY_FLAG_STATE_ON_BASE;
      SpawnBGObject(BG_EY_OBJECT_FLAG_NETHERSTORM, RESPAWN_IMMEDIATELY);
  
      if (send_message)
      {
          SendMessageToAll(LANG_BG_EY_RESETED_FLAG, CHAT_MSG_BG_SYSTEM_NEUTRAL);
          PlaySoundToAll(BG_EY_SOUND_FLAG_RESET);             // flags respawned sound...
      }
  
      UpdateWorldState(NETHERSTORM_FLAG, 1);
  }
  
  void BattlegroundEY::RespawnFlagAfterDrop()
  {
      RespawnFlag(true);
  
      GameObject *obj = HashMapHolder<GameObject>::Find(GetDroppedFlagGUID());
      if (obj)
          obj->Delete();
      else
          sLog->outError("BattlegroundEY: Unknown dropped flag guid: %u", GUID_LOPART(GetDroppedFlagGUID()));
  
      SetDroppedFlagGUID(0);
  }
  
  void BattlegroundEY::HandleKillPlayer(Player *player, Player *killer)
  {
      if (GetStatus() != STATUS_IN_PROGRESS)
          return;
  
      Battleground::HandleKillPlayer(player, killer);
      EventPlayerDroppedFlag(player);
  }
  
  void BattlegroundEY::EventPlayerDroppedFlag(Player *Source)
  {
      if (GetStatus() != STATUS_IN_PROGRESS)
      {
          // if not running, do not cast things at the dropper player, neither send unnecessary messages
          // just take off the aura
          if (IsFlagPickedup() && GetFlagPickerGUID() == Source->GetGUID())
          {
              SetFlagPicker(0);
              Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
          }
          return;
      }
  
      if (!IsFlagPickedup())
          return;
  
      if (GetFlagPickerGUID() != Source->GetGUID())
          return;
  
      SetFlagPicker(0);
      Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
      m_FlagState = BG_EY_FLAG_STATE_ON_GROUND;
      m_FlagsTimer = BG_EY_FLAG_RESPAWN_TIME;
      Source->CastSpell(Source, SPELL_RECENTLY_DROPPED_FLAG, true);
      Source->CastSpell(Source, BG_EY_PLAYER_DROPPED_FLAG_SPELL, true);
      //this does not work correctly :((it should remove flag carrier name)
      UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
      UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
  
      if (Source->GetTeam() == ALLIANCE)
          SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL);
      else
          SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, NULL);
  }
  
  void BattlegroundEY::EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj)
  {
      if (GetStatus() != STATUS_IN_PROGRESS || IsFlagPickedup() || !Source->IsWithinDistInMap(target_obj, 10))
          return;
  
      if (Source->GetTeam() == ALLIANCE)
      {
          UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_ON_PLAYER);
          PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE);
      }
      else
      {
          UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_ON_PLAYER);
          PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_HORDE);
      }
  
      if (m_FlagState == BG_EY_FLAG_STATE_ON_BASE)
          UpdateWorldState(NETHERSTORM_FLAG, 0);
      m_FlagState = BG_EY_FLAG_STATE_ON_PLAYER;
  
      SpawnBGObject(BG_EY_OBJECT_FLAG_NETHERSTORM, RESPAWN_ONE_DAY);
      SetFlagPicker(Source->GetGUID());
      //get flag aura on player
      Source->CastSpell(Source, BG_EY_NETHERSTORM_FLAG_SPELL, true);
      Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
  
      if (Source->GetTeam() == ALLIANCE)
          PSendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL, Source->GetName());
      else
          PSendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, NULL, Source->GetName());
  }
  
  void BattlegroundEY::EventTeamLostPoint(Player *Source, uint32 Point)
  {
      if (GetStatus() != STATUS_IN_PROGRESS)
          return;
  
      //Natural point
      uint32 Team = m_PointOwnedByTeam[Point];
  
      if (!Team)
          return;
  
      if (Team == ALLIANCE)
      {
          m_TeamPointsCount[BG_TEAM_ALLIANCE]--;
          SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeAlliance, RESPAWN_ONE_DAY);
          SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeAlliance + 1, RESPAWN_ONE_DAY);
          SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeAlliance + 2, RESPAWN_ONE_DAY);
      }
      else
      {
          m_TeamPointsCount[BG_TEAM_HORDE]--;
          SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde, RESPAWN_ONE_DAY);
          SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde + 1, RESPAWN_ONE_DAY);
          SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde + 2, RESPAWN_ONE_DAY);
      }
  
      SpawnBGObject(m_LoosingPointTypes[Point].SpawnNeutralObjectType, RESPAWN_IMMEDIATELY);
      SpawnBGObject(m_LoosingPointTypes[Point].SpawnNeutralObjectType + 1, RESPAWN_IMMEDIATELY);
      SpawnBGObject(m_LoosingPointTypes[Point].SpawnNeutralObjectType + 2, RESPAWN_IMMEDIATELY);
  
      //buff isn't despawned
  
      m_PointOwnedByTeam[Point] = EY_POINT_NO_OWNER;
      m_PointState[Point] = EY_POINT_NO_OWNER;
  
      if (Team == ALLIANCE)
          SendMessageToAll(m_LoosingPointTypes[Point].MessageIdAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
      else
          SendMessageToAll(m_LoosingPointTypes[Point].MessageIdHorde, CHAT_MSG_BG_SYSTEM_HORDE, Source);
  
      UpdatePointsIcons(Team, Point);
      UpdatePointsCount(Team);
  
      //remove bonus honor aura trigger creature when node is lost
       if (Point < EY_POINTS_MAX)
           DelCreature(Point + 6);//NULL checks are in DelCreature! 0-5 spirit guides
  }
  
  void BattlegroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point)
  {
      if (GetStatus() != STATUS_IN_PROGRESS)
          return;
  
      uint32 Team = Source->GetTeam();
  
      SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType, RESPAWN_ONE_DAY);
      SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType + 1, RESPAWN_ONE_DAY);
      SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType + 2, RESPAWN_ONE_DAY);
  
      if (Team == ALLIANCE)
      {
          m_TeamPointsCount[BG_TEAM_ALLIANCE]++;
          SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance, RESPAWN_IMMEDIATELY);
          SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance + 1, RESPAWN_IMMEDIATELY);
          SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance + 2, RESPAWN_IMMEDIATELY);
      }
      else
      {
          m_TeamPointsCount[BG_TEAM_HORDE]++;
          SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde, RESPAWN_IMMEDIATELY);
          SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde + 1, RESPAWN_IMMEDIATELY);
          SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde + 2, RESPAWN_IMMEDIATELY);
      }
  
      //buff isn't respawned
  
      m_PointOwnedByTeam[Point] = Team;
      m_PointState[Point] = EY_POINT_UNDER_CONTROL;
  
      if (Team == ALLIANCE)
          SendMessageToAll(m_CapturingPointTypes[Point].MessageIdAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
      else
          SendMessageToAll(m_CapturingPointTypes[Point].MessageIdHorde, CHAT_MSG_BG_SYSTEM_HORDE, Source);
  
      if (m_BgCreatures[Point])
          DelCreature(Point);
  
      WorldSafeLocsEntry const *sg = NULL;
      sg = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[Point].GraveYardId);
      if (!sg || !AddSpiritGuide(Point, sg->x, sg->y, sg->z, 3.124139f, Team))
          sLog->outError("BatteGroundEY: Failed to spawn spirit guide! point: %u, team: %u, graveyard_id: %u",
              Point, Team, m_CapturingPointTypes[Point].GraveYardId);
  
  //    SpawnBGCreature(Point, RESPAWN_IMMEDIATELY);
  
      UpdatePointsIcons(Team, Point);
      UpdatePointsCount(Team);
  
      if (Point >= EY_POINTS_MAX)
          return;
  
      Creature* trigger = GetBGCreature(Point + 6);//0-5 spirit guides
      if (!trigger)
         trigger = AddCreature(WORLD_TRIGGER, Point+6, Team, BG_EY_TriggerPositions[Point][0], BG_EY_TriggerPositions[Point][1], BG_EY_TriggerPositions[Point][2], BG_EY_TriggerPositions[Point][3]);
  
      //add bonus honor aura trigger creature when node is accupied
      //cast bonus aura (+50% honor in 25yards)
      //aura should only apply to players who have accupied the node, set correct faction for trigger
      if (trigger)
      {
          trigger->setFaction(Team == ALLIANCE ? 84 : 83);
          trigger->CastSpell(trigger, SPELL_HONORABLE_DEFENDER_25Y, false);
      }
  }
  
  void BattlegroundEY::EventPlayerCapturedFlag(Player *Source, uint32 BgObjectType)
  {
      if (GetStatus() != STATUS_IN_PROGRESS || GetFlagPickerGUID() != Source->GetGUID())
          return;
  
      SetFlagPicker(0);
      m_FlagState = BG_EY_FLAG_STATE_WAIT_RESPAWN;
      Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
  
      Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
  
      if (Source->GetTeam() == ALLIANCE)
          PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE);
      else
          PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_HORDE);
  
      SpawnBGObject(BgObjectType, RESPAWN_IMMEDIATELY);
  
      m_FlagsTimer = BG_EY_FLAG_RESPAWN_TIME;
      m_FlagCapturedBgObjectType = BgObjectType;
  
      uint8 team_id = 0;
      if (Source->GetTeam() == ALLIANCE)
      {
          team_id = BG_TEAM_ALLIANCE;
          SendMessageToAll(LANG_BG_EY_CAPTURED_FLAG_A, CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
      }
      else
      {
          team_id = BG_TEAM_HORDE;
          SendMessageToAll(LANG_BG_EY_CAPTURED_FLAG_H, CHAT_MSG_BG_SYSTEM_HORDE, Source);
      }
  
      if (m_TeamPointsCount[team_id] > 0)
          AddPoints(Source->GetTeam(), BG_EY_FlagPoints[m_TeamPointsCount[team_id] - 1]);
  
      UpdatePlayerScore(Source, SCORE_FLAG_CAPTURES, 1);
  }
  
  void BattlegroundEY::UpdatePlayerScore(Player *Source, uint32 type, uint32 value, bool doAddHonor)
  {
      BattlegroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
      if (itr == m_PlayerScores.end())                         // player not found
          return;
  
      switch(type)
      {
          case SCORE_FLAG_CAPTURES:                           // flags captured
              ((BattlegroundEYScore*)itr->second)->FlagCaptures += value;
              Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, EY_OBJECTIVE_CAPTURE_FLAG);
              break;
          default:
              Battleground::UpdatePlayerScore(Source, type, value, doAddHonor);
              break;
      }
  }
  
  void BattlegroundEY::FillInitialWorldStates(WorldPacket& data)
  {
      data << uint32(EY_HORDE_BASE) << uint32(m_TeamPointsCount[BG_TEAM_HORDE]);
      data << uint32(EY_ALLIANCE_BASE) << uint32(m_TeamPointsCount[BG_TEAM_ALLIANCE]);
      data << uint32(0xab6) << uint32(0x0);
      data << uint32(0xab5) << uint32(0x0);
      data << uint32(0xab4) << uint32(0x0);
      data << uint32(0xab3) << uint32(0x0);
      data << uint32(0xab2) << uint32(0x0);
      data << uint32(0xab1) << uint32(0x0);
      data << uint32(0xab0) << uint32(0x0);
      data << uint32(0xaaf) << uint32(0x0);
  
      data << uint32(DRAENEI_RUINS_HORDE_CONTROL)     << uint32(m_PointOwnedByTeam[DRAENEI_RUINS] == HORDE && m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL);
  
      data << uint32(DRAENEI_RUINS_ALLIANCE_CONTROL)  << uint32(m_PointOwnedByTeam[DRAENEI_RUINS] == ALLIANCE && m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL);
  
      data << uint32(DRAENEI_RUINS_UNCONTROL)         << uint32(m_PointState[DRAENEI_RUINS] != EY_POINT_UNDER_CONTROL);
  
      data << uint32(MAGE_TOWER_ALLIANCE_CONTROL)     << uint32(m_PointOwnedByTeam[MAGE_TOWER] == ALLIANCE && m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL);
  
      data << uint32(MAGE_TOWER_HORDE_CONTROL)        << uint32(m_PointOwnedByTeam[MAGE_TOWER] == HORDE && m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL);
  
      data << uint32(MAGE_TOWER_UNCONTROL)            << uint32(m_PointState[MAGE_TOWER] != EY_POINT_UNDER_CONTROL);
  
      data << uint32(FEL_REAVER_HORDE_CONTROL)        << uint32(m_PointOwnedByTeam[FEL_REAVER] == HORDE && m_PointState[FEL_REAVER] == EY_POINT_UNDER_CONTROL);
  
      data << uint32(FEL_REAVER_ALLIANCE_CONTROL)     << uint32(m_PointOwnedByTeam[FEL_REAVER] == ALLIANCE && m_PointState[FEL_REAVER] == EY_POINT_UNDER_CONTROL);
  
      data << uint32(FEL_REAVER_UNCONTROL)            << uint32(m_PointState[FEL_REAVER] != EY_POINT_UNDER_CONTROL);
  
      data << uint32(BLOOD_ELF_HORDE_CONTROL)         << uint32(m_PointOwnedByTeam[BLOOD_ELF] == HORDE && m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL);
  
      data << uint32(BLOOD_ELF_ALLIANCE_CONTROL)      << uint32(m_PointOwnedByTeam[BLOOD_ELF] == ALLIANCE && m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL);
  
      data << uint32(BLOOD_ELF_UNCONTROL)             << uint32(m_PointState[BLOOD_ELF] != EY_POINT_UNDER_CONTROL);
  
      data << uint32(NETHERSTORM_FLAG)                << uint32(m_FlagState == BG_EY_FLAG_STATE_ON_BASE);
  
      data << uint32(0xad2) << uint32(0x1);
      data << uint32(0xad1) << uint32(0x1);
      data << uint32(0xabe) << uint32(GetTeamScore(HORDE));
      data << uint32(0xabd) << uint32(GetTeamScore(ALLIANCE));
      data << uint32(0xa05) << uint32(0x8e);
      data << uint32(0xaa0) << uint32(0x0);
      data << uint32(0xa9f) << uint32(0x0);
      data << uint32(0xa9e) << uint32(0x0);
      data << uint32(0xc0d) << uint32(0x17b);
  }
  
  WorldSafeLocsEntry const *BattlegroundEY::GetClosestGraveYard(Player* player)
  {
      uint32 g_id = 0;
  
      switch(player->GetTeam())
      {
          case ALLIANCE: g_id = EY_GRAVEYARD_MAIN_ALLIANCE; break;
          case HORDE:    g_id = EY_GRAVEYARD_MAIN_HORDE;    break;
          default:       return NULL;
      }
  
      float distance, nearestDistance;
  
      WorldSafeLocsEntry const* entry = NULL;
      WorldSafeLocsEntry const* nearestEntry = NULL;
      entry = sWorldSafeLocsStore.LookupEntry(g_id);
      nearestEntry = entry;
  
      if (!entry)
      {
          sLog->outError("BattlegroundEY: Not found the main team graveyard. Graveyard system isn't working!");
          return NULL;
      }
  
      float plr_x = player->GetPositionX();
      float plr_y = player->GetPositionY();
      float plr_z = player->GetPositionZ();
  
      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);
      nearestDistance = distance;
  
      for (uint8 i = 0; i < EY_POINTS_MAX; ++i)
      {
          if (m_PointOwnedByTeam[i] == player->GetTeam() && m_PointState[i] == EY_POINT_UNDER_CONTROL)
          {
              entry = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[i].GraveYardId);
              if (!entry)
                  sLog->outError("BattlegroundEY: Not found graveyard: %u", m_CapturingPointTypes[i].GraveYardId);
              else
              {
                  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);
                  if (distance < nearestDistance)
                  {
                      nearestDistance = distance;
                      nearestEntry = entry;
                  }
              }
          }
      }
  
      return nearestEntry;
  }
  
  bool BattlegroundEY::IsAllNodesConrolledByTeam(uint32 team) const
  {
      uint32 count = 0;
      for (int i = 0; i < EY_POINTS_MAX; ++i)
          if (m_PointOwnedByTeam[i] == team && m_PointState[i] == EY_POINT_UNDER_CONTROL)
              ++count;
  
      return count == EY_POINTS_MAX;
  }