root/trunk/src/arcemu-world/BattlegroundMgr.h @ 2860

Revision 2860, 13.9 kB (checked in by Vlack, 12 months ago)

Notice: Trunk is now 3.2.0

FIXED: Mail sending (by providing a missing item for the world database, this item is necessary for the client - for the item, thanks goes to Darkgrööm)
FIXED: Battleground selection crash (now the server will queue you on Isle of Conquest - note: this does not mean you can play on it, but it solves the instant crash when players selected it)
FIXED: Glyphs (till we properly implement dual spec)
FIXED: A9 target GUID sending (on flags & UPDATEFLAG_HAS_TARGET - thanks Alleycat)
FIXED: Re-enabled ground targeted spells (on m_targetMask & TARGET_FLAG_DEST_LOCATION - if a spell where you can select the area of its effect crashes the client in the future, we'll revise this part)
FIXED: A9 (actually just moved the already existing code pieces up/down to better suit the required format, but to know the format right, I had looked into Mangos code too, as I haven't got months to figure out the right structure)
FIXED: TaxiMgr::GetGlobalTaxiNodeMask? (index check, as with the new DBCs we have a "to" with value "-1", and when that's used as an uint, it'll result in an index of 255, while the structure is from 0 to 11).
ADDED: Override support (this extends the core with special features for special gameobjects, like what's required for trams and transports, which include features as: "override update fields", "never despawn on same map", "announce on greater range" and "push to player on map entry").
FIXED: static map object pushing (repaired the buffer handling error which duplicated buffer content in a pretty unique way).
ADDED: SQL fixes for Deeprun and Ulduar Trams (retail data, but it works right only with the override system).
UPDATED: UpdateFields?.h
UPDATED: DBCs (thanks Xuni)
UPDATED: Error codes (thanks Hopla)
FIXED: various packets, especially the following ones: character enumeration, mail list, group details (raid difficulty), movement-related packets
FIXED: The display of quest rewards the player can choose from on the quest page before accepting it.
FIXED: A nasty bug when un-equipping an item to a bag and not to the backpack. The problem was that I have missed 2 for loops where the visible items get nulled out on unequip, it erased 17 fields instead of just 2, so it made the character pretty much naked.

  • Property svn:eol-style set to native
  • Property ff set to
    *.cpp = svn:eol-style=native
    Makefile = svn:eol-style=native
    README = svn:eol-style=native
    CHANGELOG = svn:eol-style=native
    LICENSE = svn:eol-style=native
Line 
1/*
2 * ArcEmu MMORPG Server
3 * Copyright (C) 2005-2007 Ascent Team <http://www.ascentemu.com/>
4 * Copyright (C) 2008-2009 <http://www.ArcEmu.org/>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * 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 Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#ifndef __BATTLEGROUNDMGR_H
22#define __BATTLEGROUNDMGR_H
23
24#define ANTI_CHEAT
25
26class CBattleground;
27class MapMgr;
28class Player;
29class Map;
30class Group;
31// AV - Corpse
32class Corpse;
33
34
35enum BattlegroundDbcIndex
36{
37        BGDBC_ALTERAC_VALLEY                    = 1,
38        BGDBC_WARSONG_GULCH                     = 2,
39        BGDBC_ARATHI_BASIN                      = 3,
40        BGDBC_ARENA_NAGRAND                     = 4,
41        BGDBC_ARENA_BLADES_EDGE                 = 5,
42        BGDBC_ARENA_ALLMAPS                     = 6,
43        BGDBC_EYE_OF_THE_STORM                  = 7,
44        BGDBC_RUINS_OF_LORDAERON                = 8,
45        BGDBC_STRAND_OF_THE_ANCIENT             = 9,
46        BGDBC_DALARAN_SEWERS                    = 10,
47        BGDBC_RING_OF_VALOR                     = 11,
48        BGDBC_ROWS                              = 11,
49};
50
51enum BattleGroundTypes
52{
53        BATTLEGROUND_ALTERAC_VALLEY             = 1,
54        BATTLEGROUND_WARSONG_GULCH              = 2,
55        BATTLEGROUND_ARATHI_BASIN               = 3,
56        BATTLEGROUND_ARENA_2V2                  = 4,
57        BATTLEGROUND_ARENA_3V3                  = 5,
58        BATTLEGROUND_ARENA_5V5                  = 6,
59        BATTLEGROUND_EYE_OF_THE_STORM           = 7,
60        BATTLEGROUND_STRAND_OF_THE_ANCIENT      = 9,
61        BATTLEGROUND_NUM_TYPES                  = 33, //Based on BattlemasterList.dbc, make the storage arrays big enough! On 3.1.3 the last one was 11 The Ring of Valor, so 12 was enough here, but on 3.2.0 there is 32 All Battlegrounds!
62};
63
64struct BGScore
65{
66        uint32 KillingBlows;
67        uint32 HonorableKills;
68        uint32 Deaths;
69        uint32 BonusHonor;
70        uint32 DamageDone;
71        uint32 HealingDone;
72        uint32 MiscData[5];
73};
74
75#define BG_SCORE_AB_BASES_ASSAULTED 0
76#define BG_SCORE_AB_BASES_CAPTURED 1
77#define BG_SCORE_AV_GRAVEYARDS_ASSAULTED 0
78#define BG_SCORE_AV_GRAVEYARDS_DEFENDED 1
79#define BG_SCORE_AV_TOWERS_ASSAULTED 2
80#define BG_SCORE_AV_TOWERS_DEFENDED 3
81#define BG_SCORE_AV_MINES_CAPTURES 4
82#define BG_SCORE_EOTS_FLAGS_CAPTURED 0
83#define BG_SCORE_WSG_FLAGS_CAPTURED 0
84#define BG_SCORE_WSG_FLAGS_RETURNED 1
85#define BG_SCORE_SOTA_DEMOLISHERS_DESTROYED 0
86#define BG_SCORE_SOTA_GATES_DESTROYED 1
87
88#define SOUND_BATTLEGROUND_BEGIN                        0xD6F
89#define SOUND_HORDE_SCORES                              8213
90#define SOUND_ALLIANCE_SCORES                           8173
91#define SOUND_ALLIANCE_CAPTURE                          8174
92#define SOUND_HORDE_CAPTURE                             8212
93#define SOUND_ALLIANCE_RETURNED                         8192
94#define SOUND_HORDE_RETURNED                            8192    // huh?
95#define SOUND_HORDEWINS                                 8454
96#define SOUND_ALLIANCEWINS                              8455
97#define SOUND_HORDE_BGALMOSTEND                         0x2108
98#define SOUND_ALLIANCE_BGALMOSTEND                      0x2109
99
100#define AB_ALLIANCE_RESOURCES                           0x6F0
101#define AB_HORDE_RESOURCES                              0x6F1
102#define AB_HORDE_CAPTUREBASE                            0x6F2
103#define AB_ALLIANCE_CAPTUREBASE                         0x6F3
104#define AB_MAX_SCORE                                    0x6F4
105
106#define BG_PREPARATION                                  44521
107#define BG_REVIVE_PREPARATION                           44535
108#define RESURRECT_SPELL                                 21074   // Spirit Healer Res
109#define BG_DESERTER                                     26013
110
111// WSG define's
112#define WSG_ALLIANCE_FLAG_CAPTURED                      0x922
113#define WSG_HORDE_FLAG_CAPTURED                         0x923
114#define WSG_CURRENT_HORDE_SCORE                         0x62E
115#define WSG_CURRENT_ALLIANCE_SCORE                      0x62D
116#define WSG_MAX_SCORE                                   0x641
117
118// AV define's
119#define AV_UNCONTROLED_SNOWFALL_GRAVE                   0x7AE //1 -> show uncontrolled
120
121#define AV_CONTROLED_ICEBLOOD_TOWER_HORDE               0x569 //1 -> horde controlled
122#define AV_CONTROLED_TOWER_POINT_HORDE                  0x568 //1 -> horde controlled
123#define AV_CONTROLED_FROSTWOLF_RELIFHUNT_HORDE          0x532 //1 -> horde controlled
124#define AV_CONTROLED_EAST_FROSTWOLF_TOWER_HORDE         0x567 //1 -> horde controlled
125#define AV_CONTROLED_WEST_FROSTWOLF_TOWER_HORDE         0x566 //1 -> horde controlled
126#define AV_CONTROLED_ICEBLOOD_GRAVE_HORDE               0x543 //1 -> horde controlled
127#define AV_CONTROLED_FROSTWOLF_GRAVE_HORDE              0x53A //1 -> horde controlled
128
129#define AV_CONTROLED_IRONDEEP_MINE_TROGG                0x550 //1 -> trogg controlled
130#define AV_CONTROLED_COLDTHOOT_MINE_KOBOLT              0x54D //1 -> kobolt controlled
131
132#define AV_CONTROLED_STORMPIKE_GRAVE_ALLIANCE           0x535 //1 -> alliance controlled
133#define AV_CONTROLED_STONEHEART_BUNKER_ALLIANCE         0x554 //1 -> alliance controlled
134#define AV_CONTROLED_ICEWING_BUNKER_ALLIANCE            0x553 //1 -> alliance controlled
135#define AV_CONTROLED_DUBALDER_NORTH_BUNKER_ALLIANCE     0x552 //1 -> alliance controlled
136#define AV_CONTROLED_DUBALDER_SOUTH_BUNKER_ALLIANCE     0x551 //1 -> alliance controlled
137#define AV_CONTROLED_STORMPIKE_AID_STATION_ALLIANCE     0x52D //1 -> alliance controlled
138#define AV_CONTROLED_STONEHEART_GRAVE_ALLIANCE          0x516 //1 -> alliance controlled
139
140/* get level grouping for player */
141static inline uint32 GetLevelGrouping(uint32 level)
142{
143        if(level < 10)
144                return 0;
145        else if(level < 20)
146                return 1;
147        else if(level < 30)
148                return 2;
149        else if(level < 40)
150                return 3;
151        else if(level < 50)
152                return 4;
153        else if(level < 60)
154                return 5;
155        else if(level < 70)
156                return 6;
157        else if(level < 80)
158                return 7;
159        else
160                return 8;
161}
162
163static inline uint32 GetFieldCount(uint32 BGType)
164{
165        switch( BGType )
166        {
167        case BATTLEGROUND_ALTERAC_VALLEY:
168                return 5;
169        case BATTLEGROUND_ARATHI_BASIN:
170        case BATTLEGROUND_WARSONG_GULCH:
171        case BATTLEGROUND_STRAND_OF_THE_ANCIENT:
172                return 2;
173        case BATTLEGROUND_EYE_OF_THE_STORM:
174                return 1;
175        default:
176                return 0;
177        }
178}
179
180#define MAX_LEVEL_GROUP 9
181#define MINIMUM_PLAYERS_ON_EACH_SIDE_FOR_BG 1
182#define MAXIMUM_BATTLEGROUNDS_PER_LEVEL_GROUP 50
183#define LEVEL_GROUP_70 8
184
185
186class CBattlegroundManager : public Singleton<CBattlegroundManager>, public EventableObject
187{
188        /* Battleground Instance Map */
189        map<uint32, CBattleground*> m_instances[BATTLEGROUND_NUM_TYPES];
190        Mutex m_instanceLock;
191
192        /* Max Id */
193        uint32 m_maxBattlegroundId[BATTLEGROUND_NUM_TYPES];
194       
195        /* Queue System */
196        // Instance Id -> list<Player guid> [ BattlegroundType ] (instance 0 - first available)
197        list<uint32> m_queuedPlayers[BATTLEGROUND_NUM_TYPES][MAX_LEVEL_GROUP];
198
199        // Instance Id -> list<Group id> [BattlegroundType][LevelGroup]
200        list<uint32> m_queuedGroups[BATTLEGROUND_NUM_TYPES];
201
202        Mutex m_queueLock;
203
204public:
205        CBattlegroundManager();
206        ~CBattlegroundManager();
207
208        /* Get the Config */
209        void LoadBGSetFromConfig();
210
211        /* Packet Handlers */
212        void HandleBattlegroundListPacket(WorldSession * m_session, uint32 BattlegroundType, uint8 from=0);
213        void HandleArenaJoin(WorldSession * m_session, uint32 BattlegroundType, uint8 as_group, uint8 rated_match);
214
215        /* Player Logout Handler */
216        void OnPlayerLogout(Player * plr);
217
218        /* Handler On Update Event */
219        void EventQueueUpdate();
220        void EventQueueUpdate(bool forceStart);
221
222        /* Handle GetBattlegroundQueue Command */
223        void HandleGetBattlegroundQueueCommand(WorldSession * m_session);
224
225        /* Handle Battleground Join */
226        void HandleBattlegroundJoin(WorldSession * m_session, WorldPacket & pck);
227
228        /* Remove Player From All Queues */
229        void RemovePlayerFromQueues(Player * plr);
230        void RemoveGroupFromQueues(Group * grp);
231
232        /* Create a battleground instance of type x */
233        CBattleground * CreateInstance(uint32 Type, uint32 LevelGroup);
234
235        /* Can we create a new instance of type x level group y? (NO LOCK!) */
236        bool CanCreateInstance(uint32 Type, uint32 LevelGroup);
237
238        /* Deletes a battleground (called from MapMgr) */
239        void DeleteBattleground(CBattleground * bg);
240
241        /* Build SMSG_BATTLEFIELD_STATUS */
242        void SendBattlefieldStatus(Player * plr, uint32 Status, uint32 Type, uint32 InstanceID, uint32 Time, uint32 MapId, uint8 RatedMatch);
243
244        /* Gets ArenaTeam info from group */
245        uint32 GetArenaGroupQInfo(Group * group, int type, uint32 *avgRating);
246
247        /* Creates an arena with groups group1 and group2 */
248        int CreateArenaType(int type, Group * group1, Group * group2);
249
250        /* Add player to bg team */
251        void AddPlayerToBgTeam(CBattleground * bg, deque<uint32> *playerVec, uint32 i, uint32 j, int Team);
252
253        /* Add player to bg */
254        void AddPlayerToBg(CBattleground * bg, deque<uint32> *playerVec, uint32 i, uint32 j);
255
256        /* Add a group to an arena */
257        void AddGroupToArena(CBattleground * bg, Group * group, int nteam);
258
259        /* Returns the minimum number of players (Only valid for battlegrounds) */
260        uint32 GetMinimumPlayers(uint32 dbcIndex);
261
262        /* Returns the maximum number of players (Only valid for battlegrounds) */
263        uint32 GetMaximumPlayers(uint32 dbcIndex);
264};
265
266class CBattleground : public EventableObject
267{
268
269friend class AVNode;
270protected:
271        /* Groups */
272        Group * m_groups[2];
273
274        time_t m_nextPvPUpdateTime;
275        MapMgr * m_mapMgr;
276        uint32 m_id;
277        uint32 m_type;
278        uint32 m_levelGroup;
279        uint32 m_deltaRating[2];
280        uint32 m_invisGMs;
281        uint32 m_honorPerKill;
282
283public:
284        /* Team->Player Map */
285        set<Player*> m_players[2];
286        void Lock() { m_mainLock.Acquire(); }
287        void Unlock() { m_mainLock.Release(); }
288        void AddInvisGM() {Lock(); m_invisGMs++; Unlock();}
289        void RemoveInvisGM() {Lock(); m_invisGMs--; Unlock();}
290protected:
291        /* World States. This should be moved to mapmgr instead for world pvp :/ */
292        map<uint32, uint32> m_worldStates;
293
294        /* PvP Log Data Map */
295        map<uint32, BGScore> m_pvpData;
296
297        /* Lock for all player data */
298        Mutex m_mainLock;
299
300        /* Player count per team */
301        uint32 m_playerCountPerTeam;
302
303        /* "pending" players */
304        set<uint32> m_pendPlayers[2];
305
306        /* starting time */
307        uint32 m_startTime;
308        bool m_started;
309
310        /* countdown stuff */
311        uint32 m_countdownStage;
312
313        /* winner stuff */
314        bool m_ended;
315        uint8 m_winningteam;
316
317        /* resurrect queue */
318        map<Creature*, set<uint32> > m_resurrectMap;
319        uint32 m_lastResurrect;
320
321        bool m_isWeekend;
322
323public:
324
325        void SendChatMessage(uint32 Type, uint64 Guid, const char * Format, ...);
326
327        /* Hook Functions */
328        virtual void HookOnPlayerDeath(Player * plr) = 0;
329
330        /* Repopping - different battlegrounds have different ways of handling this */
331        virtual bool HookHandleRepop(Player * plr) = 0;
332
333        /* In CTF battlegrounds mounting will cause you to lose your flag. */
334        virtual void HookOnMount(Player * plr) = 0;
335
336        /* Only used in CTF (as far as I know) */
337        virtual void HookFlagDrop(Player * plr, GameObject * obj) = 0;
338        virtual void HookFlagStand(Player * plr, GameObject * obj) = 0;
339        virtual void HookOnFlagDrop(Player *plr) = 0;
340
341        /* Used when a player kills a player */
342        virtual void HookOnPlayerKill(Player * plr, Player * pVictim) = 0;
343        virtual void HookOnHK(Player * plr) = 0;
344
345        /* On Area Trigger */
346        virtual void HookOnAreaTrigger(Player * plr, uint32 id) = 0;
347
348        /* On Shadow Sight */
349        virtual void HookOnShadowSight() = 0;
350
351        /* On Loot Generating */
352        virtual void HookGenerateLoot(Player *plr, Object *pCorpse) = 0;
353
354        /* On Unit Killing */
355        virtual void HookOnUnitKill(Player * plr, Unit * pVictim) = 0;
356
357        /* Retrieval Functions */
358        ARCEMU_INLINE uint32 GetId() { return m_id; }
359        ARCEMU_INLINE uint32 GetLevelGroup() { return m_levelGroup; }
360        ARCEMU_INLINE MapMgr* GetMapMgr() { return m_mapMgr; }
361       
362        /* Creating a battleground requires a pre-existing map manager */
363        CBattleground(MapMgr * mgr, uint32 id, uint32 levelgroup, uint32 type);
364        virtual ~CBattleground();
365
366        /* Has it ended? */
367        ARCEMU_INLINE bool HasEnded() { return m_ended; }
368        /* Has it started? */
369        ARCEMU_INLINE bool HasStarted() { return m_started; }
370
371        /* Send our current world states to a player . */
372        void SendWorldStates(Player * plr);
373
374        /* Send the pvp log data of all players to this player. */
375        void SendPVPData(Player * plr);
376
377        /* Get the starting position for this team. */
378        virtual LocationVector GetStartingCoords(uint32 Team) = 0;
379
380        /* Send a packet to the entire battleground */
381        void DistributePacketToAll(WorldPacket * packet);
382
383        /* send a packet to only this team */
384        void DistributePacketToTeam(WorldPacket * packet, uint32 Team);
385
386        /* play sound to this team only */
387        void PlaySoundToTeam(uint32 Team, uint32 Sound);
388
389        /* play sound to all */
390        void PlaySoundToAll(uint32 Sound);
391
392        /* Full? */
393        ARCEMU_INLINE bool IsFull() { return !(HasFreeSlots(0,m_type) || HasFreeSlots(1,m_type)); }
394
395        /* Are we full? */
396        bool HasFreeSlots(uint32 Team, uint32 type);
397
398        /* Add Player */
399        void AddPlayer(Player * plr, uint32 team);
400        virtual void OnAddPlayer(Player * plr) = 0;
401
402        /* Remove Player */
403        void RemovePlayer(Player * plr, bool logout);
404        virtual void OnRemovePlayer(Player * plr) = 0;
405
406        /* Port Player */
407        void PortPlayer(Player * plr, bool skip_teleport = false);
408        virtual void OnCreate() = 0;
409
410        /* Remove pending player */
411        void RemovePendingPlayer(Player * plr);
412
413        /* Gets the number of free slots */
414        uint32 GetFreeSlots(uint32 t, uint32 type);
415
416        GameObject * SpawnGameObject(uint32 entry,uint32 MapId , float x, float y, float z, float o, uint32 flags, uint32 faction, float scale);
417        Creature * SpawnCreature(uint32 entry,float x, float y, float z, float o);
418        void UpdatePvPData();
419
420        ARCEMU_INLINE uint32 GetStartTime() { return m_startTime; }
421        ARCEMU_INLINE uint32 GetType() { return m_type; }
422
423        // events should execute in the correct context
424        int32 event_GetInstanceID();
425        void EventCreate();
426
427        virtual uint32 GetNameID() { return 34;}
428        void EventCountdown();
429
430        virtual void Start();
431        virtual void OnStart() {}
432        void Close();
433        virtual void OnClose() {}
434
435        void SetWorldState(uint32 Index, uint32 Value);
436        Creature * SpawnSpiritGuide(float x, float y, float z, float o, uint32 horde);
437
438        ARCEMU_INLINE uint32 GetLastResurrect() { return m_lastResurrect; }
439        void AddSpiritGuide(Creature * pCreature);
440        void RemoveSpiritGuide(Creature * pCreature);
441        void QueuePlayerForResurrect(Player * plr, Creature * spirit_healer);
442        void RemovePlayerFromResurrect(Player * plr, Creature * spirit_healer);
443        void EventResurrectPlayers();
444        virtual bool CanPlayerJoin(Player * plr,uint32 type);
445        virtual bool CreateCorpse(Player * plr) { return true; }
446        virtual bool HookSlowLockOpen(GameObject * pGo, Player * pPlayer, Spell * pSpell) { return false; }
447
448        void BuildPvPUpdateDataPacket(WorldPacket * data);
449        virtual uint8 Rated() { return 0; }
450        void OnPlayerPushed(Player* plr);
451
452        virtual void SetIsWeekend(bool isweekend) {}
453        void QueueAtNearestSpiritGuide(Player *plr, Creature *old);
454};
455
456#define BattlegroundManager CBattlegroundManager::getSingleton( )
457
458       
459#endif
Note: See TracBrowser for help on using the browser.