root/trunk/src/game/BattleGroundEY.cpp @ 9

Revision 9, 40.8 kB (checked in by yumileroy, 17 years ago)

[svn] -enabled instantiated battlegrounds
-enabled arena matches
-rewritten battleground queuing to support joining as group
-removed queue announcements

Original author: w12x
Date: 2008-10-05 08:48:32-05:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
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.
8 *
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.
13 *
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
17 */
18
19#include "Object.h"
20#include "Player.h"
21#include "BattleGround.h"
22#include "BattleGroundEY.h"
23#include "Creature.h"
24#include "Chat.h"
25#include "ObjectMgr.h"
26#include "MapManager.h"
27#include "Language.h"
28#include "Util.h"
29
30BattleGroundEY::BattleGroundEY()
31{
32    m_BuffChange = true;
33    m_BgObjects.resize(BG_EY_OBJECT_MAX);
34    m_BgCreatures.resize(BG_EY_CREATURES_MAX);
35    m_Points_Trigger[FEL_REALVER] = TR_FEL_REALVER_BUFF;
36    m_Points_Trigger[BLOOD_ELF] = TR_BLOOD_ELF_BUFF;
37    m_Points_Trigger[DRAENEI_RUINS] = TR_DRAENEI_RUINS_BUFF;
38    m_Points_Trigger[MAGE_TOWER] = TR_MAGE_TOWER_BUFF;
39}
40
41BattleGroundEY::~BattleGroundEY()
42{
43}
44
45void BattleGroundEY::Update(time_t diff)
46{
47    BattleGround::Update(diff);
48    // after bg start we get there (once)
49    if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize())
50    {
51        ModifyStartDelayTime(diff);
52
53        if(!(m_Events & 0x01))
54        {
55            m_Events |= 0x01;
56
57            // setup here, only when at least one player has ported to the map
58            if(!SetupBattleGround())
59            {
60                EndNow();
61                return;
62            }
63
64            SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_IMMEDIATELY);
65            SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_IMMEDIATELY);
66
67            for(uint32 i = BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER; i < BG_EY_OBJECT_MAX; ++i)
68                SpawnBGObject(i, RESPAWN_ONE_DAY);
69
70            SetStartDelayTime(START_DELAY0);
71        }
72        // After 1 minute, warning is signalled
73        else if(GetStartDelayTime() <= START_DELAY1 && !(m_Events & 0x04))
74        {
75            m_Events |= 0x04;
76            SendMessageToAll(GetMangosString(LANG_BG_EY_ONE_MINUTE));
77        }
78        // After 1,5 minute, warning is signalled
79        else if(GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x08))
80        {
81            m_Events |= 0x08;
82            SendMessageToAll(GetMangosString(LANG_BG_EY_HALF_MINUTE));
83        }
84        // After 2 minutes, gates OPEN ! x)
85        else if(GetStartDelayTime() < 0 && !(m_Events & 0x10))
86        {
87            m_Events |= 0x10;
88            SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_ONE_DAY);
89            SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_ONE_DAY);
90
91            for(uint32 i = BG_EY_OBJECT_N_BANNER_FEL_REALVER_CENTER; i <= BG_EY_OBJECT_FLAG_NETHERSTORM; ++i)
92                SpawnBGObject(i, RESPAWN_IMMEDIATELY);
93            for(uint32 i = 0; i < EY_POINTS_MAX; ++i)
94            {
95                //randomly spawn buff
96                uint8 buff = urand(0, 2);
97                SpawnBGObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + buff + i * 3, RESPAWN_IMMEDIATELY);
98            }
99
100            SendMessageToAll(GetMangosString(LANG_BG_EY_BEGIN));
101
102            PlaySoundToAll(SOUND_BG_START);
103            SetStatus(STATUS_IN_PROGRESS);
104
105            for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
106                if(Player *plr = objmgr.GetPlayer(itr->first))
107                    plr->RemoveAurasDueToSpell(SPELL_PREPARATION);
108        }
109    }
110    else if(GetStatus() == STATUS_IN_PROGRESS)
111    {
112        m_PointAddingTimer -= diff;
113        if(m_PointAddingTimer <= 0)
114        {
115            m_PointAddingTimer = BG_EY_FPOINTS_TICK_TIME;
116            if (m_TeamPointsCount[BG_TEAM_ALLIANCE] > 0)
117                AddPoints(ALLIANCE, BG_EY_TickPoints[m_TeamPointsCount[BG_TEAM_ALLIANCE] - 1]);
118            if (m_TeamPointsCount[BG_TEAM_HORDE] > 0)
119                AddPoints(HORDE, BG_EY_TickPoints[m_TeamPointsCount[BG_TEAM_HORDE] - 1]);
120        }
121
122        if(m_FlagState == BG_EY_FLAG_STATE_WAIT_RESPAWN || m_FlagState == BG_EY_FLAG_STATE_ON_GROUND)
123        {
124            m_FlagsTimer -= diff;
125
126            if(m_FlagsTimer < 0)
127            {
128                m_FlagsTimer = 0;
129                if (m_FlagState == BG_EY_FLAG_STATE_WAIT_RESPAWN)
130                    RespawnFlag(true);
131                else
132                    RespawnFlagAfterDrop();
133            }
134        }
135
136        m_TowerCapCheckTimer -= diff;
137        if(m_TowerCapCheckTimer <= 0)
138        {
139            //check if player joined point
140            /*I used this order of calls, because although we will check if one player is in gameobject's distance 2 times
141              but we can count of players on current point in CheckSomeoneLeftPoint
142            */
143            this->CheckSomeoneJoinedPoint();
144            //check if player left point
145            this->CheckSomeoneLeftPoint();
146            this->UpdatePointStatuses();
147            m_TowerCapCheckTimer = BG_EY_FPOINTS_TICK_TIME;
148        }
149    }
150}
151
152void BattleGroundEY::AddPoints(uint32 Team, uint32 Points)
153{
154    uint8 team_index = GetTeamIndexByTeamId(Team);
155    m_TeamScores[team_index] += Points;
156    m_HonorScoreTics[team_index] += Points;
157    if (m_HonorScoreTics[team_index] >= BG_HONOR_SCORE_TICKS)
158    {
159        RewardHonorToTeam(20, Team);
160        m_HonorScoreTics[team_index] -= BG_HONOR_SCORE_TICKS;
161    }
162    UpdateTeamScore(Team);
163}
164
165void BattleGroundEY::CheckSomeoneJoinedPoint()
166{
167    GameObject *obj = NULL;
168    for (uint8 i = 0; i < EY_POINTS_MAX; ++i)
169    {
170        obj = HashMapHolder<GameObject>::Find(m_BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REALVER + i]);
171        if (obj)
172        {
173            uint8 j = 0;
174            while (j < m_PlayersNearPoint[EY_POINTS_MAX].size())
175            {
176                Player *plr = objmgr.GetPlayer(m_PlayersNearPoint[EY_POINTS_MAX][j]);
177                if(!plr)
178                {
179                    sLog.outError("BattleGroundEY: Player " I64FMTD " not found!", m_PlayersNearPoint[EY_POINTS_MAX][j]);
180                    ++j;
181                    continue;
182                }
183                if (plr->isAlive() && plr->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS))
184                {
185                    //player joined point!
186                    //show progress bar
187                    UpdateWorldStateForPlayer(PROGRESS_BAR_PERCENT_GREY, BG_EY_PROGRESS_BAR_PERCENT_GREY, plr);
188                    UpdateWorldStateForPlayer(PROGRESS_BAR_STATUS, m_PointBarStatus[i], plr);
189                    UpdateWorldStateForPlayer(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_SHOW, plr);
190                    //add player to point
191                    m_PlayersNearPoint[i].push_back(m_PlayersNearPoint[EY_POINTS_MAX][j]);
192                    //remove player from "free space"
193                    m_PlayersNearPoint[EY_POINTS_MAX].erase(m_PlayersNearPoint[EY_POINTS_MAX].begin() + j);
194                }
195                else
196                    ++j;
197            }
198        }
199    }
200}
201
202void BattleGroundEY::CheckSomeoneLeftPoint()
203{
204    //reset current point counts
205    for (uint8 i = 0; i < 2*EY_POINTS_MAX; ++i)
206        m_CurrentPointPlayersCount[i] = 0;
207    GameObject *obj = NULL;
208    for(uint8 i = 0; i < EY_POINTS_MAX; ++i)
209    {
210        obj = HashMapHolder<GameObject>::Find(m_BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REALVER + i]);
211        if(obj)
212        {
213            uint8 j = 0;
214            while (j < m_PlayersNearPoint[i].size())
215            {
216                Player *plr = objmgr.GetPlayer(m_PlayersNearPoint[i][j]);
217                if (!plr)
218                {
219                    sLog.outError("BattleGroundEY: Player " I64FMTD " not found!", m_PlayersNearPoint[i][j]);
220                    //move not existed player to "free space" - this will cause many error showing in log, but it is a very important bug
221                    m_PlayersNearPoint[EY_POINTS_MAX].push_back(m_PlayersNearPoint[i][j]);
222                    m_PlayersNearPoint[i].erase(m_PlayersNearPoint[i].begin() + j);
223                    ++j;
224                    continue;
225                }
226                if (!plr->isAlive() || !plr->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS))
227                    //move player out of point (add him to players that are out of points
228                {
229                    m_PlayersNearPoint[EY_POINTS_MAX].push_back(m_PlayersNearPoint[i][j]);
230                    m_PlayersNearPoint[i].erase(m_PlayersNearPoint[i].begin() + j);
231                    this->UpdateWorldStateForPlayer(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_DONT_SHOW, plr);
232                }
233                else
234                {
235                    //player is neat flag, so update count:
236                    m_CurrentPointPlayersCount[2 * i + GetTeamIndexByTeamId(plr->GetTeam())]++;
237                    ++j;
238                }
239            }
240        }
241    }
242}
243
244void BattleGroundEY::UpdatePointStatuses()
245{
246    for(uint8 point = 0; point < EY_POINTS_MAX; ++point)
247    {
248        if (m_PlayersNearPoint[point].empty())
249            continue;
250        //count new point bar status:
251        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;
252
253        if (m_PointBarStatus[point] > BG_EY_PROGRESS_BAR_ALI_CONTROLLED)
254            //point is fully alliance's
255            m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_ALI_CONTROLLED;
256        if (m_PointBarStatus[point] < BG_EY_PROGRESS_BAR_HORDE_CONTROLLED)
257            //point is fully horde's
258            m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_HORDE_CONTROLLED;
259
260        uint32 pointOwnerTeamId = 0;
261        //find which team should own this point
262        if (m_PointBarStatus[point] <= BG_EY_PROGRESS_BAR_NEUTRAL_LOW)
263            pointOwnerTeamId = HORDE;
264        else if (m_PointBarStatus[point] >= BG_EY_PROGRESS_BAR_NEUTRAL_HIGH)
265            pointOwnerTeamId = ALLIANCE;
266        else
267            pointOwnerTeamId = EY_POINT_NO_OWNER;
268
269        for (uint8 i = 0; i < m_PlayersNearPoint[point].size(); ++i)
270        {
271            Player *plr = objmgr.GetPlayer(m_PlayersNearPoint[point][i]);
272            if (plr)
273            {
274                this->UpdateWorldStateForPlayer(PROGRESS_BAR_STATUS, m_PointBarStatus[point], plr);
275                                                            //if point owner changed we must evoke event!
276                if (pointOwnerTeamId != m_PointOwnedByTeam[point])
277                {
278                    //point was uncontrolled and player is from team which captured point
279                    if (m_PointState[point] == EY_POINT_STATE_UNCONTROLLED && plr->GetTeam() == pointOwnerTeamId)
280                        this->EventTeamCapturedPoint(plr, point);
281
282                    //point was under control and player isn't from team which controlled it
283                    if (m_PointState[point] == EY_POINT_UNDER_CONTROL && plr->GetTeam() != m_PointOwnedByTeam[point])
284                        this->EventTeamLostPoint(plr, point);
285                }
286            }
287        }
288    }
289}
290
291void BattleGroundEY::UpdateTeamScore(uint32 Team)
292{
293    uint32 score = GetTeamScore(Team);
294    if(score >= EY_MAX_TEAM_SCORE)
295    {
296        score = EY_MAX_TEAM_SCORE;
297        EndBattleGround(Team);
298    }
299
300    if(Team == ALLIANCE)
301        UpdateWorldState(EY_ALLIANCE_RESOURCES, score);
302    else
303        UpdateWorldState(EY_HORDE_RESOURCES, score);
304}
305
306void BattleGroundEY::UpdatePointsCount(uint32 Team)
307{
308    if(Team == ALLIANCE)
309        UpdateWorldState(EY_ALLIANCE_BASE, m_TeamPointsCount[BG_TEAM_ALLIANCE]);
310    else
311        UpdateWorldState(EY_HORDE_BASE, m_TeamPointsCount[BG_TEAM_HORDE]);
312}
313
314void BattleGroundEY::UpdatePointsIcons(uint32 Team, uint32 Point)
315{
316    //we MUST firstly send 0, after that we can send 1!!!
317    if (m_PointState[Point] == EY_POINT_UNDER_CONTROL)
318    {
319        UpdateWorldState(m_PointsIconStruct[Point].WorldStateControlIndex, 0);
320        if(Team == ALLIANCE)
321            UpdateWorldState(m_PointsIconStruct[Point].WorldStateAllianceControlledIndex, 1);
322        else
323            UpdateWorldState(m_PointsIconStruct[Point].WorldStateHordeControlledIndex, 1);
324    }
325    else
326    {
327        if(Team == ALLIANCE)
328            UpdateWorldState(m_PointsIconStruct[Point].WorldStateAllianceControlledIndex, 0);
329        else
330            UpdateWorldState(m_PointsIconStruct[Point].WorldStateHordeControlledIndex, 0);
331        UpdateWorldState(m_PointsIconStruct[Point].WorldStateControlIndex, 1);
332    }
333}
334
335void BattleGroundEY::AddPlayer(Player *plr)
336{
337    BattleGround::AddPlayer(plr);
338    //create score and add it to map
339    BattleGroundEYScore* sc = new BattleGroundEYScore;
340
341    m_PlayersNearPoint[EY_POINTS_MAX].push_back(plr->GetGUID());
342
343    m_PlayerScores[plr->GetGUID()] = sc;
344}
345
346void BattleGroundEY::RemovePlayer(Player *plr, uint64 guid)
347{
348    // sometimes flag aura not removed :(
349    for (int j = EY_POINTS_MAX; j >= 0; --j)
350    {
351        for(int i = 0; i < m_PlayersNearPoint[j].size(); ++i)
352            if(m_PlayersNearPoint[j][i] == guid)
353                m_PlayersNearPoint[j].erase(m_PlayersNearPoint[j].begin() + i);
354    }
355    if(IsFlagPickedup())
356    {
357        if(m_FlagKeeper == guid)
358        {
359            if(plr)
360                this->EventPlayerDroppedFlag(plr);
361            else
362            {
363                SetFlagPicker(0);
364                RespawnFlag(true);
365            }
366        }
367    }
368}
369
370void BattleGroundEY::HandleAreaTrigger(Player *Source, uint32 Trigger)
371{
372    if(GetStatus() != STATUS_IN_PROGRESS)
373        return;
374
375    if(!Source->isAlive())                                  //hack code, must be removed later
376        return;
377
378    switch(Trigger)
379    {
380        case TR_BLOOD_ELF_POINT:
381            if(m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[BLOOD_ELF] == Source->GetTeam())
382                if(m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
383                    EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_BLOOD_ELF);
384            break;
385        case TR_FEL_REALVER_POINT:
386            if(m_PointState[FEL_REALVER] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[FEL_REALVER] == Source->GetTeam())
387                if(m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
388                    EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_FEL_REALVER);
389            break;
390        case TR_MAGE_TOWER_POINT:
391            if(m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[MAGE_TOWER] == Source->GetTeam())
392                if(m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
393                    EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_MAGE_TOWER);
394            break;
395        case TR_DRAENEI_RUINS_POINT:
396            if(m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[DRAENEI_RUINS] == Source->GetTeam())
397                if(m_FlagState && GetFlagPickerGUID() == Source->GetGUID())
398                    EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_DRAENEI_RUINS);
399            break;
400        case 4512:
401        case 4515:
402        case 4517:
403        case 4519:
404        case 4530:
405        case 4531:
406        case 4568:
407        case 4569:
408        case 4570:
409        case 4571:
410            break;
411        default:
412            sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger);
413            Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
414            break;
415    }
416}
417
418bool BattleGroundEY::SetupBattleGround()
419{
420        // doors
421    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)
422        || !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)
423        // banners (alliance)
424        || !AddObject(BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER, BG_OBJECT_A_BANNER_EY_ENTRY, 2057.46f, 1735.07f, 1187.91f, -0.925024f, 0, 0, 0.446198f, -0.894934f, RESPAWN_ONE_DAY)
425        || !AddObject(BG_EY_OBJECT_A_BANNER_FEL_REALVER_LEFT, BG_OBJECT_A_BANNER_EY_ENTRY, 2032.25f, 1729.53f, 1190.33f, 1.8675f, 0, 0, 0.803857f, 0.594823f, RESPAWN_ONE_DAY)
426        || !AddObject(BG_EY_OBJECT_A_BANNER_FEL_REALVER_RIGHT, BG_OBJECT_A_BANNER_EY_ENTRY, 2092.35f, 1775.46f, 1187.08f, -0.401426f, 0, 0, 0.199368f, -0.979925f, RESPAWN_ONE_DAY)
427        || !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)
428        || !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)
429        || !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)
430        || !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)
431        || !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)
432        || !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)
433        || !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)
434        || !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)
435        || !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)
436        // banners (horde)
437        || !AddObject(BG_EY_OBJECT_H_BANNER_FEL_REALVER_CENTER, BG_OBJECT_H_BANNER_EY_ENTRY, 2057.46f, 1735.07f, 1187.91f, -0.925024f, 0, 0, 0.446198f, -0.894934f, RESPAWN_ONE_DAY)
438        || !AddObject(BG_EY_OBJECT_H_BANNER_FEL_REALVER_LEFT, BG_OBJECT_H_BANNER_EY_ENTRY, 2032.25f, 1729.53f, 1190.33f, 1.8675f, 0, 0, 0.803857f, 0.594823f, RESPAWN_ONE_DAY)
439        || !AddObject(BG_EY_OBJECT_H_BANNER_FEL_REALVER_RIGHT, BG_OBJECT_H_BANNER_EY_ENTRY, 2092.35f, 1775.46f, 1187.08f, -0.401426f, 0, 0, 0.199368f, -0.979925f, RESPAWN_ONE_DAY)
440        || !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)
441        || !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)
442        || !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)
443        || !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)
444        || !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)
445        || !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)
446        || !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)
447        || !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)
448        || !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)
449        // banners (natural)
450        || !AddObject(BG_EY_OBJECT_N_BANNER_FEL_REALVER_CENTER, BG_OBJECT_N_BANNER_EY_ENTRY, 2057.46f, 1735.07f, 1187.91f, -0.925024f, 0, 0, 0.446198f, -0.894934f, RESPAWN_ONE_DAY)
451        || !AddObject(BG_EY_OBJECT_N_BANNER_FEL_REALVER_LEFT, BG_OBJECT_N_BANNER_EY_ENTRY, 2032.25f, 1729.53f, 1190.33f, 1.8675f, 0, 0, 0.803857f, 0.594823f, RESPAWN_ONE_DAY)
452        || !AddObject(BG_EY_OBJECT_N_BANNER_FEL_REALVER_RIGHT, BG_OBJECT_N_BANNER_EY_ENTRY, 2092.35f, 1775.46f, 1187.08f, -0.401426f, 0, 0, 0.199368f, -0.979925f, RESPAWN_ONE_DAY)
453        || !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)
454        || !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)
455        || !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)
456        || !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)
457        || !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)
458        || !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)
459        || !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)
460        || !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)
461        || !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)
462        // flags
463        || !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)
464        || !AddObject(BG_EY_OBJECT_FLAG_FEL_REALVER, BG_OBJECT_FLAG1_EY_ENTRY, 2044.28f, 1729.68f, 1189.96f, -0.017453f, 0, 0, 0.008727f, -0.999962f, RESPAWN_ONE_DAY)
465        || !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)
466        || !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)
467        || !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)
468        // tower cap
469        || !AddObject(BG_EY_OBJECT_TOWER_CAP_FEL_REALVER, BG_OBJECT_FR_TOWER_CAP_EY_ENTRY, 2024.600708f, 1742.819580f, 1195.157715f, 2.443461f, 0, 0, 0.939693f, 0.342020f, RESPAWN_ONE_DAY)
470        || !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)
471        || !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)
472        || !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)
473        )
474    {
475        sLog.outErrorDb("BatteGroundEY: Failed to spawn some object BattleGround not created!");
476        return false;
477    }
478
479    //buffs
480    for (int i = 0; i < EY_POINTS_MAX; ++i)
481    {
482        AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(m_Points_Trigger[i]);
483        if( !at )
484        {
485            sLog.outError("BattleGroundEY: Unknown trigger: %u", m_Points_Trigger[i]);
486            continue;
487        }
488        if (   !AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + i * 3, Buff_Entries[0], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY)
489            || !AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + i * 3 + 1, Buff_Entries[1], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY)
490            || !AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + i * 3 + 2, Buff_Entries[2], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY)
491            )
492            sLog.outError("BattleGroundEY: Cannot spawn buff");
493    }
494
495    WorldSafeLocsEntry const *sg = NULL;
496    sg = sWorldSafeLocsStore.LookupEntry(EY_GRAVEYARD_MAIN_ALLIANCE);
497    if( !sg || !AddSpiritGuide(EY_SPIRIT_MAIN_ALLIANCE, sg->x, sg->y, sg->z, 3.124139f, ALLIANCE) )
498    {
499        sLog.outErrorDb("BatteGroundEY: Failed to spawn spirit guide! BattleGround not created!");
500        return false;
501    }
502
503    sg = sWorldSafeLocsStore.LookupEntry(EY_GRAVEYARD_MAIN_HORDE);
504    if( !sg || !AddSpiritGuide(EY_SPIRIT_MAIN_HORDE, sg->x, sg->y, sg->z, 3.193953f, HORDE) )
505    {
506        sLog.outErrorDb("BatteGroundEY: Failed to spawn spirit guide! BattleGround not created!");
507        return false;
508    }
509
510    return true;
511}
512
513void BattleGroundEY::ResetBGSubclass()
514{
515    m_TeamScores[BG_TEAM_ALLIANCE] = 0;
516    m_TeamScores[BG_TEAM_HORDE] = 0;
517    m_TeamPointsCount[BG_TEAM_ALLIANCE] = 0;
518    m_TeamPointsCount[BG_TEAM_HORDE] = 0;
519    m_HonorScoreTics[BG_TEAM_ALLIANCE] = 0;
520    m_HonorScoreTics[BG_TEAM_HORDE] = 0;
521    m_FlagState = BG_EY_FLAG_STATE_ON_BASE;
522    m_FlagCapturedBgObjectType = 0;
523    m_FlagKeeper = 0;
524    m_DroppedFlagGUID = 0;
525    m_PointAddingTimer = 0;
526    m_TowerCapCheckTimer = 0;
527
528    for(uint8 i = 0; i < EY_POINTS_MAX; ++i)
529    {
530        m_PointOwnedByTeam[i] = EY_POINT_NO_OWNER;
531        m_PointState[i] = EY_POINT_STATE_UNCONTROLLED;
532        m_PointBarStatus[i] = BG_EY_PROGRESS_BAR_STATE_MIDDLE;
533        m_PlayersNearPoint[i].clear();
534        m_PlayersNearPoint[i].reserve(15);                  //tip size
535    }
536    m_PlayersNearPoint[EY_PLAYERS_OUT_OF_POINTS].clear();
537    m_PlayersNearPoint[EY_PLAYERS_OUT_OF_POINTS].reserve(30);
538}
539
540void BattleGroundEY::RespawnFlag(bool send_message)
541{
542    if (m_FlagCapturedBgObjectType > 0)
543        SpawnBGObject(m_FlagCapturedBgObjectType, RESPAWN_ONE_DAY);
544
545    m_FlagCapturedBgObjectType = 0;
546    m_FlagState = BG_EY_FLAG_STATE_ON_BASE;
547    SpawnBGObject(BG_EY_OBJECT_FLAG_NETHERSTORM, RESPAWN_IMMEDIATELY);
548
549    if(send_message)
550    {
551        SendMessageToAll(GetMangosString(LANG_BG_EY_RESETED_FLAG));
552        PlaySoundToAll(BG_EY_SOUND_FLAG_RESET);             // flags respawned sound...
553    }
554
555    UpdateWorldState(NETHERSTORM_FLAG, 1);
556}
557
558void BattleGroundEY::RespawnFlagAfterDrop()
559{
560    RespawnFlag(true);
561
562    GameObject *obj = HashMapHolder<GameObject>::Find(GetDroppedFlagGUID());
563    if(obj)
564        obj->Delete();
565    else
566        sLog.outError("BattleGroundEY: Unknown dropped flag guid: %u",GetDroppedFlagGUID());
567
568    SetDroppedFlagGUID(0);
569}
570
571void BattleGroundEY::HandleKillPlayer(Player *player, Player *killer)
572{
573    if(GetStatus() != STATUS_IN_PROGRESS)
574        return;
575
576    BattleGround::HandleKillPlayer(player, killer);
577    EventPlayerDroppedFlag(player);
578}
579
580void BattleGroundEY::EventPlayerDroppedFlag(Player *Source)
581{
582    if(GetStatus() != STATUS_IN_PROGRESS)
583    {
584        // if not running, do not cast things at the dropper player, neither send unnecessary messages
585        // just take off the aura
586        if(IsFlagPickedup() && GetFlagPickerGUID() == Source->GetGUID())
587        {
588            SetFlagPicker(0);
589            Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
590        }
591        return;
592    }
593
594    if(!IsFlagPickedup())
595        return;
596
597    if(GetFlagPickerGUID() != Source->GetGUID())
598        return;
599
600    const char *message = "";
601    uint8 type = 0;
602
603    SetFlagPicker(0);
604    Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
605    m_FlagState = BG_EY_FLAG_STATE_ON_GROUND;
606    m_FlagsTimer = BG_EY_FLAG_RESPAWN_TIME;
607    Source->CastSpell(Source, SPELL_RECENTLY_DROPPED_FLAG, true);
608    Source->CastSpell(Source, BG_EY_PLAYER_DROPPED_FLAG_SPELL, true);
609    if(Source->GetTeam() == ALLIANCE)
610    {
611        message = GetMangosString(LANG_BG_EY_DROPPED_FLAG);
612        type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
613    }
614    else
615    {
616        message = GetMangosString(LANG_BG_EY_DROPPED_FLAG);
617        type = CHAT_MSG_BG_SYSTEM_HORDE;
618    }
619    //this does not work correctly :( (it should remove flag carrier name)
620    UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
621    UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
622
623    WorldPacket data;
624    ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
625    SendPacketToAll(&data);
626}
627
628void BattleGroundEY::EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj)
629{
630    if(GetStatus() != STATUS_IN_PROGRESS || this->IsFlagPickedup() || !Source->IsWithinDistInMap(target_obj, 10))
631        return;
632
633    const char *message;
634    uint8 type = 0;
635    message = GetMangosString(LANG_BG_EY_HAS_TAKEN_FLAG);
636
637    if(Source->GetTeam() == ALLIANCE)
638    {
639        UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_ON_PLAYER);
640        type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
641        PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE);
642    }
643    else
644    {
645        UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_ON_PLAYER);
646        type = CHAT_MSG_BG_SYSTEM_HORDE;
647        PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_HORDE);
648    }
649
650    if (m_FlagState == BG_EY_FLAG_STATE_ON_BASE)
651        UpdateWorldState(NETHERSTORM_FLAG, 0);
652    m_FlagState = BG_EY_FLAG_STATE_ON_PLAYER;
653
654    SpawnBGObject(BG_EY_OBJECT_FLAG_NETHERSTORM, RESPAWN_ONE_DAY);
655    SetFlagPicker(Source->GetGUID());
656    //get flag aura on player
657    Source->CastSpell(Source, BG_EY_NETHERSTORM_FLAG_SPELL, true);
658    Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
659
660    WorldPacket data;
661    ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
662    SendPacketToAll(&data);
663}
664
665void BattleGroundEY::EventTeamLostPoint(Player *Source, uint32 Point)
666{
667    if(GetStatus() != STATUS_IN_PROGRESS)
668        return;
669
670    //Natural point
671    uint8 message_type = 0;
672    const char *message = "";
673    uint32 Team = m_PointOwnedByTeam[Point];
674
675    if(!Team)
676        return;
677
678    if (Team == ALLIANCE)
679    {
680        m_TeamPointsCount[BG_TEAM_ALLIANCE]--;
681        message_type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
682        message = GetMangosString(m_LoosingPointTypes[Point].MessageIdAlliance);
683        SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeAlliance, RESPAWN_ONE_DAY);
684        SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeAlliance + 1, RESPAWN_ONE_DAY);
685        SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeAlliance + 2, RESPAWN_ONE_DAY);
686    }
687    else
688    {
689        m_TeamPointsCount[BG_TEAM_HORDE]--;
690        message_type = CHAT_MSG_BG_SYSTEM_HORDE;
691        message = GetMangosString(m_LoosingPointTypes[Point].MessageIdHorde);
692        SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde, RESPAWN_ONE_DAY);
693        SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde + 1, RESPAWN_ONE_DAY);
694        SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde + 2, RESPAWN_ONE_DAY);
695    }
696
697    SpawnBGObject(m_LoosingPointTypes[Point].SpawnNeutralObjectType, RESPAWN_IMMEDIATELY);
698    SpawnBGObject(m_LoosingPointTypes[Point].SpawnNeutralObjectType + 1, RESPAWN_IMMEDIATELY);
699    SpawnBGObject(m_LoosingPointTypes[Point].SpawnNeutralObjectType + 2, RESPAWN_IMMEDIATELY);
700
701    //buff isn't despawned
702
703    m_PointOwnedByTeam[Point] = EY_POINT_NO_OWNER;
704    m_PointState[Point] = EY_POINT_NO_OWNER;
705
706    WorldPacket data;
707    ChatHandler::FillMessageData(&data, Source->GetSession(), message_type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
708    SendPacketToAll(&data);
709
710    UpdatePointsIcons(Team, Point);
711    UpdatePointsCount(Team);
712}
713
714void BattleGroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point)
715{
716    if(GetStatus() != STATUS_IN_PROGRESS)
717        return;
718
719    uint8 type = 0;
720    const char *message = "";
721    uint32 Team = Source->GetTeam();
722
723    SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType, RESPAWN_ONE_DAY);
724    SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType + 1, RESPAWN_ONE_DAY);
725    SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType + 2, RESPAWN_ONE_DAY);
726
727    if (Team == ALLIANCE)
728    {
729        m_TeamPointsCount[BG_TEAM_ALLIANCE]++;
730        type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
731        message = GetMangosString(m_CapturingPointTypes[Point].MessageIdAlliance);
732        SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance, RESPAWN_IMMEDIATELY);
733        SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance + 1, RESPAWN_IMMEDIATELY);
734        SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance + 2, RESPAWN_IMMEDIATELY);
735    }
736    else
737    {
738        m_TeamPointsCount[BG_TEAM_HORDE]++;
739        type = CHAT_MSG_BG_SYSTEM_HORDE;
740        message = GetMangosString(m_CapturingPointTypes[Point].MessageIdHorde);
741        SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde, RESPAWN_IMMEDIATELY);
742        SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde + 1, RESPAWN_IMMEDIATELY);
743        SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde + 2, RESPAWN_IMMEDIATELY);
744    }
745
746    //buff isn't respawned
747
748    m_PointOwnedByTeam[Point] = Team;
749    m_PointState[Point] = EY_POINT_UNDER_CONTROL;
750
751    WorldPacket data;
752    ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
753    SendPacketToAll(&data);
754
755    if(m_BgCreatures[Point])
756        DelCreature(Point);
757
758    WorldSafeLocsEntry const *sg = NULL;
759    sg = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[Point].GraveYardId);
760    if(!sg || !AddSpiritGuide(Point, sg->x, sg->y, sg->z, 3.124139f, Team))
761        sLog.outError("BatteGroundEY: Failed to spawn spirit guide! point: %u, team: u, graveyard_id: %u", Point, Team, m_CapturingPointTypes[Point].GraveYardId);
762
763    UpdatePointsIcons(Team, Point);
764    UpdatePointsCount(Team);
765}
766
767void BattleGroundEY::EventPlayerCapturedFlag(Player *Source, uint32 BgObjectType)
768{
769    if(GetStatus() != STATUS_IN_PROGRESS || this->GetFlagPickerGUID() != Source->GetGUID())
770        return;
771
772    uint8 type = 0;
773    uint8 team_id = 0;
774    const char *message = "";
775
776    SetFlagPicker(0);
777    m_FlagState = BG_EY_FLAG_STATE_WAIT_RESPAWN;
778    Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
779
780    Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
781    if(Source->GetTeam() == ALLIANCE)
782    {
783        PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE);
784        team_id = BG_TEAM_ALLIANCE;
785        message = GetMangosString(LANG_BG_EY_CAPTURED_FLAG_A);
786        type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
787    }
788    else
789    {
790        PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_HORDE);
791        team_id = BG_TEAM_HORDE;
792        message = GetMangosString(LANG_BG_EY_CAPTURED_FLAG_H);
793        type = CHAT_MSG_BG_SYSTEM_HORDE;
794    }
795
796    SpawnBGObject(BgObjectType, RESPAWN_IMMEDIATELY);
797
798    m_FlagsTimer = BG_EY_FLAG_RESPAWN_TIME;
799    m_FlagCapturedBgObjectType = BgObjectType;
800
801    WorldPacket data;
802    ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
803    SendPacketToAll(&data);
804
805    if(m_TeamPointsCount[team_id] > 0)
806        AddPoints(Source->GetTeam(), BG_EY_FlagPoints[m_TeamPointsCount[team_id] - 1]);
807
808    UpdatePlayerScore(Source, SCORE_FLAG_CAPTURES, 1);
809}
810
811void BattleGroundEY::UpdatePlayerScore(Player *Source, uint32 type, uint32 value)
812{
813    std::map<uint64, BattleGroundScore*>::iterator itr = m_PlayerScores.find(Source->GetGUID());
814
815    if(itr == m_PlayerScores.end())                         // player not found
816        return;
817
818    switch(type)
819    {
820        case SCORE_FLAG_CAPTURES:                           // flags captured
821            ((BattleGroundEYScore*)itr->second)->FlagCaptures += value;
822            break;
823        default:
824            BattleGround::UpdatePlayerScore(Source, type, value);
825            break;
826    }
827}
828
829void BattleGroundEY::FillInitialWorldStates(WorldPacket& data)
830{
831    data << uint32(EY_HORDE_BASE) << uint32(m_TeamPointsCount[BG_TEAM_HORDE]);
832    data << uint32(EY_ALLIANCE_BASE) << uint32(m_TeamPointsCount[BG_TEAM_ALLIANCE]);
833    data << uint32(0xab6) << uint32(0x0);
834    data << uint32(0xab5) << uint32(0x0);
835    data << uint32(0xab4) << uint32(0x0);
836    data << uint32(0xab3) << uint32(0x0);
837    data << uint32(0xab2) << uint32(0x0);
838    data << uint32(0xab1) << uint32(0x0);
839    data << uint32(0xab0) << uint32(0x0);
840    data << uint32(0xaaf) << uint32(0x0);
841
842    data << uint32(DRAENEI_RUINS_HORDE_CONTROL)     << uint32(m_PointOwnedByTeam[DRAENEI_RUINS] == HORDE && m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL);
843
844    data << uint32(DRAENEI_RUINS_ALLIANCE_CONTROL)  << uint32(m_PointOwnedByTeam[DRAENEI_RUINS] == ALLIANCE && m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL);
845
846    data << uint32(DRAENEI_RUINS_UNCONTROL)         << uint32(m_PointState[DRAENEI_RUINS] != EY_POINT_UNDER_CONTROL);
847
848    data << uint32(MAGE_TOWER_ALLIANCE_CONTROL)     << uint32(m_PointOwnedByTeam[MAGE_TOWER] == ALLIANCE && m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL);
849
850    data << uint32(MAGE_TOWER_HORDE_CONTROL)        << uint32(m_PointOwnedByTeam[MAGE_TOWER] == HORDE && m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL);
851
852    data << uint32(MAGE_TOWER_UNCONTROL)            << uint32(m_PointState[MAGE_TOWER] != EY_POINT_UNDER_CONTROL);
853
854    data << uint32(FEL_REAVER_HORDE_CONTROL)        << uint32(m_PointOwnedByTeam[FEL_REALVER] == HORDE && m_PointState[FEL_REALVER] == EY_POINT_UNDER_CONTROL);
855
856    data << uint32(FEL_REAVER_ALLIANCE_CONTROL)     << uint32(m_PointOwnedByTeam[FEL_REALVER] == ALLIANCE && m_PointState[FEL_REALVER] == EY_POINT_UNDER_CONTROL);
857
858    data << uint32(FEL_REAVER_UNCONTROL)            << uint32(m_PointState[FEL_REALVER] != EY_POINT_UNDER_CONTROL);
859
860    data << uint32(BLOOD_ELF_HORDE_CONTROL)         << uint32(m_PointOwnedByTeam[BLOOD_ELF] == HORDE && m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL);
861
862    data << uint32(BLOOD_ELF_ALLIANCE_CONTROL)      << uint32(m_PointOwnedByTeam[BLOOD_ELF] == ALLIANCE && m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL);
863
864    data << uint32(BLOOD_ELF_UNCONTROL)             << uint32(m_PointState[BLOOD_ELF] != EY_POINT_UNDER_CONTROL);
865
866    data << uint32(NETHERSTORM_FLAG)                << uint32(m_FlagState == BG_EY_FLAG_STATE_ON_BASE);
867
868    data << uint32(0xad2) << uint32(0x1);
869    data << uint32(0xad1) << uint32(0x1);
870    data << uint32(0xabe) << uint32(GetTeamScore(HORDE));
871    data << uint32(0xabd) << uint32(GetTeamScore(ALLIANCE));
872    data << uint32(0xa05) << uint32(0x8e);
873    data << uint32(0xaa0) << uint32(0x0);
874    data << uint32(0xa9f) << uint32(0x0);
875    data << uint32(0xa9e) << uint32(0x0);
876    data << uint32(0xc0d) << uint32(0x17b);
877}
878
879WorldSafeLocsEntry const *BattleGroundEY::GetClosestGraveYard(float x, float y, float z, uint32 team)
880{
881    uint32 g_id = 0;
882
883    if(team == ALLIANCE)
884        g_id = EY_GRAVEYARD_MAIN_ALLIANCE;
885    else if(team == HORDE)
886        g_id = EY_GRAVEYARD_MAIN_HORDE;
887    else
888        return NULL;
889
890    float distance, nearestDistance;
891
892    WorldSafeLocsEntry const* entry = NULL;
893    WorldSafeLocsEntry const* nearestEntry = NULL;
894    entry = sWorldSafeLocsStore.LookupEntry(g_id);
895    nearestEntry = entry;
896
897    if(!entry)
898    {
899        sLog.outError("BattleGroundEY: Not found the main team graveyard. Graveyard system isn't working!");
900        return NULL;
901    }
902
903    distance = (entry->x - x)*(entry->x - x) + (entry->y - y)*(entry->y - y) + (entry->z - z)*(entry->z - z);
904    nearestDistance = distance;
905
906    for(uint8 i = 0; i < EY_POINTS_MAX; ++i)
907    {
908        if(m_PointOwnedByTeam[i]==team && m_PointState[i]==EY_POINT_UNDER_CONTROL)
909        {
910            entry = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[i].GraveYardId);
911            if(!entry)
912                sLog.outError("BattleGroundEY: Not found graveyard: %u",m_CapturingPointTypes[i].GraveYardId);
913            else
914            {
915                distance = (entry->x - x)*(entry->x - x) + (entry->y - y)*(entry->y - y) + (entry->z - z)*(entry->z - z);
916                if(distance < nearestDistance)
917                {
918                    nearestDistance = distance;
919                    nearestEntry = entry;
920                }
921            }
922        }
923    }
924
925    return nearestEntry;
926}
Note: See TracBrowser for help on using the browser.