root/trunk/src/game/BattleGroundWS.cpp @ 230

Revision 230, 29.4 kB (checked in by yumileroy, 17 years ago)

[svn] *** Source: MaNGOS ***
* Implement localization of creature/gameobject name that say/yell. Author: evilstar (rewrited by: Vladimir)
* Fix auth login queue. Author: Derex
* Allowed switching INVTYPE_HOLDABLE items during combat, used correct spells for triggering global cooldown at weapon switch. Author: mobel/simak
* Fixed some format arg type/value pairs. Other warnings. Author: Vladimir
* [238_world.sql] Allow have team dependent graveyards at entrance map for instances. Author: Vladimir

NOTE:
Entrance map graveyards selected by same way as local (by distance from entrance) Until DB support will work in old way base at current DB data.

Original author: visagalis
Date: 2008-11-14 17:03:03-06:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
4 * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "Object.h"
22#include "Player.h"
23#include "BattleGround.h"
24#include "BattleGroundWS.h"
25#include "Creature.h"
26#include "GameObject.h"
27#include "Chat.h"
28#include "MapManager.h"
29#include "Language.h"
30#include "World.h"
31
32// these variables aren't used outside of this file, so declare them only here
33enum BG_WSG_Rewards
34{
35    BG_WSG_WIN = 0,
36    BG_WSG_FLAG_CAP,
37    BG_WSG_MAP_COMPLETE,
38    BG_WSG_REWARD_NUM
39};
40
41uint32 BG_WSG_Honor[BG_HONOR_MODE_NUM][BG_WSG_REWARD_NUM] = {
42    {20,40,40}, // normal honor
43    {60,40,80}  // holiday
44};
45
46uint32 BG_WSG_Reputation[BG_HONOR_MODE_NUM][BG_WSG_REWARD_NUM] = {
47    {0,35,0}, // normal honor
48    {0,45,0}  // holiday
49};
50
51BattleGroundWS::BattleGroundWS()
52{
53    m_BgObjects.resize(BG_WS_OBJECT_MAX);
54    m_BgCreatures.resize(BG_CREATURES_MAX_WS);
55}
56
57BattleGroundWS::~BattleGroundWS()
58{
59}
60
61void BattleGroundWS::Update(time_t diff)
62{
63    BattleGround::Update(diff);
64
65    // after bg start we get there (once)
66    if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize())
67    {
68        ModifyStartDelayTime(diff);
69
70        if(!(m_Events & 0x01))
71        {
72            m_Events |= 0x01;
73
74            // setup here, only when at least one player has ported to the map
75            if(!SetupBattleGround())
76            {
77                EndNow();
78                return;
79            }
80
81            for(uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_H_4; i++)
82            {
83                SpawnBGObject(i, RESPAWN_IMMEDIATELY);
84                DoorClose(i);
85            }
86            for(uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; i++)
87                SpawnBGObject(i, RESPAWN_ONE_DAY);
88
89            SetStartDelayTime(START_DELAY0);
90        }
91        // After 1 minute, warning is signalled
92        else if(GetStartDelayTime() <= START_DELAY1 && !(m_Events & 0x04))
93        {
94            m_Events |= 0x04;
95            SendMessageToAll(GetTrinityString(LANG_BG_WS_ONE_MINUTE));
96        }
97        // After 1,5 minute, warning is signalled
98        else if(GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x08))
99        {
100            m_Events |= 0x08;
101            SendMessageToAll(GetTrinityString(LANG_BG_WS_HALF_MINUTE));
102        }
103        // After 2 minutes, gates OPEN ! x)
104        else if(GetStartDelayTime() < 0 && !(m_Events & 0x10))
105        {
106            m_Events |= 0x10;
107            for(uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_A_4; i++)
108                DoorOpen(i);
109            for(uint32 i = BG_WS_OBJECT_DOOR_H_1; i <= BG_WS_OBJECT_DOOR_H_2; i++)
110                DoorOpen(i);
111
112            SpawnBGObject(BG_WS_OBJECT_DOOR_A_5, RESPAWN_ONE_DAY);
113            SpawnBGObject(BG_WS_OBJECT_DOOR_A_6, RESPAWN_ONE_DAY);
114            SpawnBGObject(BG_WS_OBJECT_DOOR_H_3, RESPAWN_ONE_DAY);
115            SpawnBGObject(BG_WS_OBJECT_DOOR_H_4, RESPAWN_ONE_DAY);
116
117            for(uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; i++)
118                SpawnBGObject(i, RESPAWN_IMMEDIATELY);
119
120            SendMessageToAll(GetTrinityString(LANG_BG_WS_BEGIN));
121
122            PlaySoundToAll(SOUND_BG_START);
123            if(sWorld.getConfig(CONFIG_BG_START_MUSIC))
124                PlaySoundToAll(SOUND_BG_START_L70ETC); //MUSIC - Custom config
125            SetStatus(STATUS_IN_PROGRESS);
126
127            for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
128                if(Player* plr = objmgr.GetPlayer(itr->first))
129                    plr->RemoveAurasDueToSpell(SPELL_PREPARATION);
130        }
131    }
132    else if(GetStatus() == STATUS_IN_PROGRESS)
133    {
134        if(m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
135        {
136            m_FlagsTimer[BG_TEAM_ALLIANCE] -= diff;
137
138            if(m_FlagsTimer[BG_TEAM_ALLIANCE] < 0)
139            {
140                m_FlagsTimer[BG_TEAM_ALLIANCE] = 0;
141                RespawnFlag(ALLIANCE, true);
142            }
143        }
144        if(m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND)
145        {
146            m_FlagsDropTimer[BG_TEAM_ALLIANCE] -= diff;
147
148            if(m_FlagsDropTimer[BG_TEAM_ALLIANCE] < 0)
149            {
150                m_FlagsDropTimer[BG_TEAM_ALLIANCE] = 0;
151                RespawnFlagAfterDrop(ALLIANCE);
152            }
153        }
154        if(m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
155        {
156            m_FlagsTimer[BG_TEAM_HORDE] -= diff;
157
158            if(m_FlagsTimer[BG_TEAM_HORDE] < 0)
159            {
160                m_FlagsTimer[BG_TEAM_HORDE] = 0;
161                RespawnFlag(HORDE, true);
162            }
163        }
164        if(m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND)
165        {
166            m_FlagsDropTimer[BG_TEAM_HORDE] -= diff;
167
168            if(m_FlagsDropTimer[BG_TEAM_HORDE] < 0)
169            {
170                m_FlagsDropTimer[BG_TEAM_HORDE] = 0;
171                RespawnFlagAfterDrop(HORDE);
172            }
173        }
174    }
175}
176
177void BattleGroundWS::AddPlayer(Player *plr)
178{
179    BattleGround::AddPlayer(plr);
180    //create score and add it to map, default values are set in constructor
181    BattleGroundWGScore* sc = new BattleGroundWGScore;
182
183    m_PlayerScores[plr->GetGUID()] = sc;
184}
185
186void BattleGroundWS::RespawnFlag(uint32 Team, bool captured)
187{
188    if(Team == ALLIANCE)
189    {
190        sLog.outDebug("Respawn Alliance flag");
191        m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_BASE;
192    }
193    else
194    {
195        sLog.outDebug("Respawn Horde flag");
196        m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE;
197    }
198
199    if(captured)
200    {
201        //when map_update will be allowed for battlegrounds this code will be useless
202        SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
203        SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
204        SendMessageToAll(GetTrinityString(LANG_BG_WS_F_PLACED));
205        PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED);        // flag respawned sound...
206    }
207}
208
209void BattleGroundWS::RespawnFlagAfterDrop(uint32 team)
210{
211    if(GetStatus() != STATUS_IN_PROGRESS)
212        return;
213
214    RespawnFlag(team,false);
215    if(team == ALLIANCE)
216    {
217        SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
218        SendMessageToAll(GetTrinityString(LANG_BG_WS_ALLIANCE_FLAG_RESPAWNED));
219    }
220    else
221    {
222        SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
223        SendMessageToAll(GetTrinityString(LANG_BG_WS_HORDE_FLAG_RESPAWNED));
224    }
225
226    PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED);
227
228    GameObject *obj = HashMapHolder<GameObject>::Find(GetDroppedFlagGUID(team));
229    if(obj)
230        obj->Delete();
231    else
232        sLog.outError("unknown droped flag bg, guid: %u",GUID_LOPART(GetDroppedFlagGUID(team)));
233
234    SetDroppedFlagGUID(0,team);
235}
236
237void BattleGroundWS::EventPlayerCapturedFlag(Player *Source)
238{
239    if(GetStatus() != STATUS_IN_PROGRESS)
240        return;
241
242    uint8 type = 0;
243    uint32 winner = 0;
244    const char *message = "";
245
246    //TODO FIX reputation and honor gains for low level players!
247
248    Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
249    if(Source->GetTeam() == ALLIANCE)
250    {
251        if (!this->IsHordeFlagPickedup())
252            return;
253        SetHordeFlagPicker(0);                              // must be before aura remove to prevent 2 events (drop+capture) at the same time
254                                                            // horde flag in base (but not respawned yet)
255        m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_WAIT_RESPAWN;
256                                                            // Drop Horde Flag from Player
257        Source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
258        message = GetTrinityString(LANG_BG_WS_CAPTURED_HF);
259        type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
260        if(GetTeamScore(ALLIANCE) < BG_WS_MAX_TEAM_SCORE)
261            AddPoint(ALLIANCE, 1);
262        PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE);
263        RewardReputationToTeam(890, BG_WSG_Reputation[m_HonorMode][BG_WSG_FLAG_CAP], ALLIANCE);          // +35 reputation
264        RewardHonorToTeam(BG_WSG_Honor[m_HonorMode][BG_WSG_FLAG_CAP], ALLIANCE);                    // +40 bonushonor
265    }
266    else
267    {
268        if (!this->IsAllianceFlagPickedup())
269            return;
270        SetAllianceFlagPicker(0);                           // must be before aura remove to prevent 2 events (drop+capture) at the same time
271                                                            // alliance flag in base (but not respawned yet)
272        m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_WAIT_RESPAWN;
273                                                            // Drop Alliance Flag from Player
274        Source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
275        message = GetTrinityString(LANG_BG_WS_CAPTURED_AF);
276        type = CHAT_MSG_BG_SYSTEM_HORDE;
277        if(GetTeamScore(HORDE) < BG_WS_MAX_TEAM_SCORE)
278            AddPoint(HORDE, 1);
279        PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE);
280        RewardReputationToTeam(889, BG_WSG_Reputation[m_HonorMode][BG_WSG_FLAG_CAP], HORDE);             // +35 reputation
281        RewardHonorToTeam(BG_WSG_Honor[m_HonorMode][BG_WSG_FLAG_CAP], HORDE);                       // +40 bonushonor
282    }
283
284    SpawnBGObject(BG_WS_OBJECT_H_FLAG, BG_WS_FLAG_RESPAWN_TIME);
285    SpawnBGObject(BG_WS_OBJECT_A_FLAG, BG_WS_FLAG_RESPAWN_TIME);
286
287    WorldPacket data;
288    ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
289    SendPacketToAll(&data);
290
291    UpdateFlagState(Source->GetTeam(), 1);                  // flag state none
292    UpdateTeamScore(Source->GetTeam());
293    // only flag capture should be updated
294    UpdatePlayerScore(Source, SCORE_FLAG_CAPTURES, 1);      // +1 flag captures...
295
296    if(GetTeamScore(ALLIANCE) == BG_WS_MAX_TEAM_SCORE)
297        winner = ALLIANCE;
298
299    if(GetTeamScore(HORDE) == BG_WS_MAX_TEAM_SCORE)
300        winner = HORDE;
301
302    if(winner)
303    {
304        UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 0);
305        UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 0);
306        UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, 1);
307        UpdateWorldState(BG_WS_FLAG_STATE_HORDE, 1);
308
309        RewardHonorToTeam(BG_WSG_Honor[m_HonorMode][BG_WSG_WIN], winner);
310        EndBattleGround(winner);
311    }
312    else
313    {
314        m_FlagsTimer[GetTeamIndexByTeamId(Source->GetTeam()) ? 0 : 1] = BG_WS_FLAG_RESPAWN_TIME;
315    }
316}
317
318void BattleGroundWS::EventPlayerDroppedFlag(Player *Source)
319{
320    if(GetStatus() != STATUS_IN_PROGRESS)
321    {
322        // if not running, do not cast things at the dropper player (prevent spawning the "dropped" flag), neither send unnecessary messages
323        // just take off the aura
324        if(Source->GetTeam() == ALLIANCE)
325        {
326            if(!this->IsHordeFlagPickedup())
327                return;
328            if(GetHordeFlagPickerGUID() == Source->GetGUID())
329            {
330                SetHordeFlagPicker(0);
331                Source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
332            }
333        }
334        else
335        {
336            if(!this->IsAllianceFlagPickedup())
337                return;
338            if(GetAllianceFlagPickerGUID() == Source->GetGUID())
339            {
340                SetAllianceFlagPicker(0);
341                Source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
342            }
343        }
344        return;
345    }
346
347    const char *message = "";
348    uint8 type = 0;
349    bool set = false;
350
351    if(Source->GetTeam() == ALLIANCE)
352    {
353        if(!this->IsHordeFlagPickedup())
354            return;
355        if(GetHordeFlagPickerGUID() == Source->GetGUID())
356        {
357            SetHordeFlagPicker(0);
358            Source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
359            m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_GROUND;
360            message = GetTrinityString(LANG_BG_WS_DROPPED_HF);
361            type = CHAT_MSG_BG_SYSTEM_HORDE;
362            Source->CastSpell(Source, BG_WS_SPELL_WARSONG_FLAG_DROPPED, true);
363            set = true;
364        }
365    }
366    else
367    {
368        if(!this->IsAllianceFlagPickedup())
369            return;
370        if(GetAllianceFlagPickerGUID() == Source->GetGUID())
371        {
372            SetAllianceFlagPicker(0);
373            Source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
374            m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_GROUND;
375            message = GetTrinityString(LANG_BG_WS_DROPPED_AF);
376            type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
377            Source->CastSpell(Source, BG_WS_SPELL_SILVERWING_FLAG_DROPPED, true);
378            set = true;
379        }
380    }
381
382    if (set)
383    {
384        Source->CastSpell(Source, SPELL_RECENTLY_DROPPED_FLAG, true);
385        UpdateFlagState(Source->GetTeam(), 1);
386
387        WorldPacket data;
388        ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
389        SendPacketToAll(&data);
390
391        if(Source->GetTeam() == ALLIANCE)
392            UpdateWorldState(BG_WS_FLAG_UNK_HORDE, uint32(-1));
393        else
394            UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, uint32(-1));
395
396        m_FlagsDropTimer[GetTeamIndexByTeamId(Source->GetTeam()) ? 0 : 1] = BG_WS_FLAG_DROP_TIME;
397    }
398}
399
400void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj)
401{
402    if(GetStatus() != STATUS_IN_PROGRESS)
403        return;
404
405    const char *message;
406    uint8 type = 0;
407
408    //alliance flag picked up from base
409    if(Source->GetTeam() == HORDE && this->GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_BASE
410        && this->m_BgObjects[BG_WS_OBJECT_A_FLAG] == target_obj->GetGUID())
411    {
412        message = GetTrinityString(LANG_BG_WS_PICKEDUP_AF);
413        type = CHAT_MSG_BG_SYSTEM_HORDE;
414        PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
415        SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_ONE_DAY);
416        SetAllianceFlagPicker(Source->GetGUID());
417        m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_PLAYER;
418        //update world state to show correct flag carrier
419        UpdateFlagState(HORDE, BG_WS_FLAG_STATE_ON_PLAYER);
420        UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 1);
421        Source->CastSpell(Source, BG_WS_SPELL_SILVERWING_FLAG, true);
422    }
423
424    //horde flag picked up from base
425    if (Source->GetTeam() == ALLIANCE && this->GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_BASE
426        && this->m_BgObjects[BG_WS_OBJECT_H_FLAG] == target_obj->GetGUID())
427    {
428        message = GetTrinityString(LANG_BG_WS_PICKEDUP_HF);
429        type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
430        PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
431        SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_ONE_DAY);
432        SetHordeFlagPicker(Source->GetGUID());
433        m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_PLAYER;
434        //update world state to show correct flag carrier
435        UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER);
436        UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 1);
437        Source->CastSpell(Source, BG_WS_SPELL_WARSONG_FLAG, true);
438    }
439
440    //Alliance flag on ground(not in base) (returned or picked up again from ground!)
441    if(this->GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10))
442    {
443        if(Source->GetTeam() == ALLIANCE)
444        {
445            message = GetTrinityString(LANG_BG_WS_RETURNED_AF);
446            type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
447            UpdateFlagState(HORDE, BG_WS_FLAG_STATE_WAIT_RESPAWN);
448            RespawnFlag(ALLIANCE, false);
449            SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
450            PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED);
451            UpdatePlayerScore(Source, SCORE_FLAG_RETURNS, 1);
452        }
453        else
454        {
455            message = GetTrinityString(LANG_BG_WS_PICKEDUP_AF);
456            type = CHAT_MSG_BG_SYSTEM_HORDE;
457            PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
458            SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_ONE_DAY);
459            SetAllianceFlagPicker(Source->GetGUID());
460            Source->CastSpell(Source, BG_WS_SPELL_SILVERWING_FLAG, true);
461            m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_PLAYER;
462            UpdateFlagState(HORDE, BG_WS_FLAG_STATE_ON_PLAYER);
463            UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 1);
464        }
465        //called in HandleGameObjectUseOpcode:
466        //target_obj->Delete();
467    }
468
469    //Horde flag on ground(not in base) (returned or picked up again)
470    if(this->GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10))
471    {
472        if(Source->GetTeam() == HORDE)
473        {
474            message = GetTrinityString(LANG_BG_WS_RETURNED_HF);
475            type = CHAT_MSG_BG_SYSTEM_HORDE;
476            UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_WAIT_RESPAWN);
477            RespawnFlag(HORDE, false);
478            SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
479            PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED);
480            UpdatePlayerScore(Source, SCORE_FLAG_RETURNS, 1);
481        }
482        else
483        {
484            message = GetTrinityString(LANG_BG_WS_PICKEDUP_HF);
485            type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
486            PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
487            SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_ONE_DAY);
488            SetHordeFlagPicker(Source->GetGUID());
489            Source->CastSpell(Source, BG_WS_SPELL_WARSONG_FLAG, true);
490            m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_PLAYER;
491            UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER);
492            UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 1);
493        }
494        //called in HandleGameObjectUseOpcode:
495        //target_obj->Delete();
496    }
497
498    if (!type)
499        return;
500
501    WorldPacket data;
502    ChatHandler::FillMessageData(&data, Source->GetSession(), type, LANG_UNIVERSAL, NULL, Source->GetGUID(), message, NULL);
503    SendPacketToAll(&data);
504    Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
505}
506
507void BattleGroundWS::RemovePlayer(Player *plr, uint64 guid)
508{
509    // sometimes flag aura not removed :(
510    if(IsAllianceFlagPickedup() && m_FlagKeepers[BG_TEAM_ALLIANCE] == guid)
511    {
512        if(!plr)
513        {
514            sLog.outError("BattleGroundWS: Removing offline player who has the FLAG!!");
515            this->SetAllianceFlagPicker(0);
516            this->RespawnFlag(ALLIANCE, false);
517        }
518        else
519            this->EventPlayerDroppedFlag(plr);
520    }
521    if(IsHordeFlagPickedup() && m_FlagKeepers[BG_TEAM_HORDE] == guid)
522    {
523        if(!plr)
524        {
525            sLog.outError("BattleGroundWS: Removing offline player who has the FLAG!!");
526            this->SetHordeFlagPicker(0);
527            this->RespawnFlag(HORDE, false);
528        }
529        else
530            this->EventPlayerDroppedFlag(plr);
531    }
532}
533
534void BattleGroundWS::UpdateFlagState(uint32 team, uint32 value)
535{
536    if(team == ALLIANCE)
537        UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, value);
538    else
539        UpdateWorldState(BG_WS_FLAG_STATE_HORDE, value);
540}
541
542void BattleGroundWS::UpdateTeamScore(uint32 team)
543{
544    if(team == ALLIANCE)
545        UpdateWorldState(BG_WS_FLAG_CAPTURES_ALLIANCE, GetTeamScore(team));
546    else
547        UpdateWorldState(BG_WS_FLAG_CAPTURES_HORDE, GetTeamScore(team));
548}
549
550void BattleGroundWS::HandleAreaTrigger(Player *Source, uint32 Trigger)
551{
552    // this is wrong way to implement these things. On official it done by gameobject spell cast.
553    if(GetStatus() != STATUS_IN_PROGRESS)
554        return;
555
556    //uint32 SpellId = 0;
557    //uint64 buff_guid = 0;
558    switch(Trigger)
559    {
560        case 3686:                                          // Alliance elixir of speed spawn. Trigger not working, because located inside other areatrigger, can be replaced by IsWithinDist(object, dist) in BattleGround::Update().
561            //buff_guid = m_BgObjects[BG_WS_OBJECT_SPEEDBUFF_1];
562            break;
563        case 3687:                                          // Horde elixir of speed spawn. Trigger not working, because located inside other areatrigger, can be replaced by IsWithinDist(object, dist) in BattleGround::Update().
564            //buff_guid = m_BgObjects[BG_WS_OBJECT_SPEEDBUFF_2];
565            break;
566        case 3706:                                          // Alliance elixir of regeneration spawn
567            //buff_guid = m_BgObjects[BG_WS_OBJECT_REGENBUFF_1];
568            break;
569        case 3708:                                          // Horde elixir of regeneration spawn
570            //buff_guid = m_BgObjects[BG_WS_OBJECT_REGENBUFF_2];
571            break;
572        case 3707:                                          // Alliance elixir of berserk spawn
573            //buff_guid = m_BgObjects[BG_WS_OBJECT_BERSERKBUFF_1];
574            break;
575        case 3709:                                          // Horde elixir of berserk spawn
576            //buff_guid = m_BgObjects[BG_WS_OBJECT_BERSERKBUFF_2];
577            break;
578        case 3646:                                          // Alliance Flag spawn
579            if(m_FlagState[BG_TEAM_HORDE] && !m_FlagState[BG_TEAM_ALLIANCE])
580                if(GetHordeFlagPickerGUID() == Source->GetGUID())
581                    EventPlayerCapturedFlag(Source);
582            break;
583        case 3647:                                          // Horde Flag spawn
584            if(m_FlagState[BG_TEAM_ALLIANCE] && !m_FlagState[BG_TEAM_HORDE])
585                if(GetAllianceFlagPickerGUID() == Source->GetGUID())
586                    EventPlayerCapturedFlag(Source);
587            break;
588        case 3649:                                          // unk1
589        case 3688:                                          // unk2
590        case 4628:                                          // unk3
591        case 4629:                                          // unk4
592            break;
593        default:
594            sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger);
595            Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
596            break;
597    }
598
599    //if(buff_guid)
600    //    HandleTriggerBuff(buff_guid,Source);
601}
602
603bool BattleGroundWS::SetupBattleGround()
604{
605    // flags
606    if(    !AddObject(BG_WS_OBJECT_A_FLAG, BG_OBJECT_A_FLAG_WS_ENTRY, 1540.423f, 1481.325f, 351.8284f, 3.089233f, 0, 0, 0.9996573f, 0.02617699f, BG_WS_FLAG_RESPAWN_TIME/1000)
607        || !AddObject(BG_WS_OBJECT_H_FLAG, BG_OBJECT_H_FLAG_WS_ENTRY, 916.0226f, 1434.405f, 345.413f, 0.01745329f, 0, 0, 0.008726535f, 0.9999619f, BG_WS_FLAG_RESPAWN_TIME/1000)
608        // buffs
609        || !AddObject(BG_WS_OBJECT_SPEEDBUFF_1, BG_OBJECTID_SPEEDBUFF_ENTRY, 1449.93f, 1470.71f, 342.6346f, -1.64061f, 0, 0, 0.7313537f, -0.6819983f, BUFF_RESPAWN_TIME)
610        || !AddObject(BG_WS_OBJECT_SPEEDBUFF_2, BG_OBJECTID_SPEEDBUFF_ENTRY, 1005.171f, 1447.946f, 335.9032f, 1.64061f, 0, 0, 0.7313537f, 0.6819984f, BUFF_RESPAWN_TIME)
611        || !AddObject(BG_WS_OBJECT_REGENBUFF_1, BG_OBJECTID_REGENBUFF_ENTRY, 1317.506f, 1550.851f, 313.2344f, -0.2617996f, 0, 0, 0.1305263f, -0.9914448f, BUFF_RESPAWN_TIME)
612        || !AddObject(BG_WS_OBJECT_REGENBUFF_2, BG_OBJECTID_REGENBUFF_ENTRY, 1110.451f, 1353.656f, 316.5181f, -0.6806787f, 0, 0, 0.333807f, -0.9426414f, BUFF_RESPAWN_TIME)
613        || !AddObject(BG_WS_OBJECT_BERSERKBUFF_1, BG_OBJECTID_BERSERKERBUFF_ENTRY, 1320.09f, 1378.79f, 314.7532f, 1.186824f, 0, 0, 0.5591929f, 0.8290376f, BUFF_RESPAWN_TIME)
614        || !AddObject(BG_WS_OBJECT_BERSERKBUFF_2, BG_OBJECTID_BERSERKERBUFF_ENTRY, 1139.688f, 1560.288f, 306.8432f, -2.443461f, 0, 0, 0.9396926f, -0.3420201f, BUFF_RESPAWN_TIME)
615        // alliance gates
616        || !AddObject(BG_WS_OBJECT_DOOR_A_1, BG_OBJECT_DOOR_A_1_WS_ENTRY, 1503.335f, 1493.466f, 352.1888f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY)
617        || !AddObject(BG_WS_OBJECT_DOOR_A_2, BG_OBJECT_DOOR_A_2_WS_ENTRY, 1492.478f, 1457.912f, 342.9689f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY)
618        || !AddObject(BG_WS_OBJECT_DOOR_A_3, BG_OBJECT_DOOR_A_3_WS_ENTRY, 1468.503f, 1494.357f, 351.8618f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY)
619        || !AddObject(BG_WS_OBJECT_DOOR_A_4, BG_OBJECT_DOOR_A_4_WS_ENTRY, 1471.555f, 1458.778f, 362.6332f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY)
620        || !AddObject(BG_WS_OBJECT_DOOR_A_5, BG_OBJECT_DOOR_A_5_WS_ENTRY, 1492.347f, 1458.34f, 342.3712f, -0.03490669f, 0, 0, 0.01745246f, -0.9998477f, RESPAWN_IMMEDIATELY)
621        || !AddObject(BG_WS_OBJECT_DOOR_A_6, BG_OBJECT_DOOR_A_6_WS_ENTRY, 1503.466f, 1493.367f, 351.7352f, -0.03490669f, 0, 0, 0.01745246f, -0.9998477f, RESPAWN_IMMEDIATELY)
622        // horde gates
623        || !AddObject(BG_WS_OBJECT_DOOR_H_1, BG_OBJECT_DOOR_H_1_WS_ENTRY, 949.1663f, 1423.772f, 345.6241f, -0.5756807f, -0.01673368f, -0.004956111f, -0.2839723f, 0.9586737f, RESPAWN_IMMEDIATELY)
624        || !AddObject(BG_WS_OBJECT_DOOR_H_2, BG_OBJECT_DOOR_H_2_WS_ENTRY, 953.0507f, 1459.842f, 340.6526f, -1.99662f, -0.1971825f, 0.1575096f, -0.8239487f, 0.5073641f, RESPAWN_IMMEDIATELY)
625        || !AddObject(BG_WS_OBJECT_DOOR_H_3, BG_OBJECT_DOOR_H_3_WS_ENTRY, 949.9523f, 1422.751f, 344.9273f, 0.0f, 0, 0, 0, 1, RESPAWN_IMMEDIATELY)
626        || !AddObject(BG_WS_OBJECT_DOOR_H_4, BG_OBJECT_DOOR_H_4_WS_ENTRY, 950.7952f, 1459.583f, 342.1523f, 0.05235988f, 0, 0, 0.02617695f, 0.9996573f, RESPAWN_IMMEDIATELY)
627        )
628    {
629        sLog.outErrorDb("BatteGroundWS: Failed to spawn some object BattleGround not created!");
630        return false;
631    }
632
633    WorldSafeLocsEntry const *sg = sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_ALLIANCE);
634    if(!sg || !AddSpiritGuide(WS_SPIRIT_MAIN_ALLIANCE, sg->x, sg->y, sg->z, 3.124139f, ALLIANCE))
635    {
636        sLog.outErrorDb("BatteGroundWS: Failed to spawn Alliance spirit guide! BattleGround not created!");
637        return false;
638    }
639
640    sg = sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_HORDE);
641    if(!sg || !AddSpiritGuide(WS_SPIRIT_MAIN_HORDE, sg->x, sg->y, sg->z, 3.193953f, HORDE))
642    {
643        sLog.outErrorDb("BatteGroundWS: Failed to spawn Horde spirit guide! BattleGround not created!");
644        return false;
645    }
646
647    sLog.outDebug("BatteGroundWS: BG objects and spirit guides spawned");
648
649    return true;
650}
651
652void BattleGroundWS::ResetBGSubclass()
653{
654    m_FlagKeepers[BG_TEAM_ALLIANCE]     = 0;
655    m_FlagKeepers[BG_TEAM_HORDE]        = 0;
656    m_DroppedFlagGUID[BG_TEAM_ALLIANCE] = 0;
657    m_DroppedFlagGUID[BG_TEAM_HORDE]    = 0;
658    m_FlagState[BG_TEAM_ALLIANCE]       = BG_WS_FLAG_STATE_ON_BASE;
659    m_FlagState[BG_TEAM_HORDE]          = BG_WS_FLAG_STATE_ON_BASE;
660    m_TeamScores[BG_TEAM_ALLIANCE]      = 0;
661    m_TeamScores[BG_TEAM_HORDE]         = 0;
662
663    /* Spirit nodes is static at this BG and then not required deleting at BG reset.
664    if(m_BgCreatures[WS_SPIRIT_MAIN_ALLIANCE])
665        DelCreature(WS_SPIRIT_MAIN_ALLIANCE);
666
667    if(m_BgCreatures[WS_SPIRIT_MAIN_HORDE])
668        DelCreature(WS_SPIRIT_MAIN_HORDE);
669    */
670}
671
672void BattleGroundWS::HandleKillPlayer(Player *player, Player *killer)
673{
674    if(GetStatus() != STATUS_IN_PROGRESS)
675        return;
676
677    EventPlayerDroppedFlag(player);
678
679    BattleGround::HandleKillPlayer(player, killer);
680}
681
682void BattleGroundWS::UpdatePlayerScore(Player *Source, uint32 type, uint32 value)
683{
684
685    std::map<uint64, BattleGroundScore*>::iterator itr = m_PlayerScores.find(Source->GetGUID());
686
687    if(itr == m_PlayerScores.end())                         // player not found
688        return;
689
690    switch(type)
691    {
692        case SCORE_FLAG_CAPTURES:                           // flags captured
693            ((BattleGroundWGScore*)itr->second)->FlagCaptures += value;
694            break;
695        case SCORE_FLAG_RETURNS:                            // flags returned
696            ((BattleGroundWGScore*)itr->second)->FlagReturns += value;
697            break;
698        default:
699            BattleGround::UpdatePlayerScore(Source, type, value);
700            break;
701    }
702}
703
704void BattleGroundWS::FillInitialWorldStates(WorldPacket& data)
705{
706    data << uint32(BG_WS_FLAG_CAPTURES_ALLIANCE) << uint32(GetTeamScore(ALLIANCE));
707    data << uint32(BG_WS_FLAG_CAPTURES_HORDE) << uint32(GetTeamScore(HORDE));
708
709    if(m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND)
710        data << uint32(BG_WS_FLAG_UNK_ALLIANCE) << uint32(-1);
711    else if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_PLAYER)
712        data << uint32(BG_WS_FLAG_UNK_ALLIANCE) << uint32(1);
713    else
714        data << uint32(BG_WS_FLAG_UNK_ALLIANCE) << uint32(0);
715
716    if(m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND)
717        data << uint32(BG_WS_FLAG_UNK_HORDE) << uint32(-1);
718    else if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_PLAYER)
719        data << uint32(BG_WS_FLAG_UNK_HORDE) << uint32(1);
720    else
721        data << uint32(BG_WS_FLAG_UNK_HORDE) << uint32(0);
722
723    data << uint32(BG_WS_FLAG_CAPTURES_MAX) << uint32(BG_WS_MAX_TEAM_SCORE);
724
725    if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_PLAYER)
726        data << uint32(BG_WS_FLAG_STATE_ALLIANCE) << uint32(2);
727    else
728        data << uint32(BG_WS_FLAG_STATE_ALLIANCE) << uint32(1);
729
730    if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_PLAYER)
731        data << uint32(BG_WS_FLAG_STATE_HORDE) << uint32(2);
732    else
733        data << uint32(BG_WS_FLAG_STATE_HORDE) << uint32(1);
734
735}
Note: See TracBrowser for help on using the browser.