2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #ifndef __BATTLEGROUND_H
20 #define __BATTLEGROUND_H
23 #include "WorldPacket.h"
24 #include "WorldSession.h"
26 #include "ObjectMgr.h"
27 #include "BattleGroundMgr.h"
28 #include "SharedDefines.h"
30 enum BattleGroundSounds
32 SOUND_HORDE_WINS
= 8454,
33 SOUND_ALLIANCE_WINS
= 8455,
37 enum BattleGroundQuests
39 SPELL_WS_QUEST_REWARD
= 43483,
40 SPELL_AB_QUEST_REWARD
= 43484,
41 SPELL_AV_QUEST_REWARD
= 43475,
42 SPELL_AV_QUEST_KILLED_BOSS
= 23658,
43 SPELL_EY_QUEST_REWARD
= 43477,
44 SPELL_AB_QUEST_REWARD_4_BASES
= 24061,
45 SPELL_AB_QUEST_REWARD_5_BASES
= 24064
48 enum BattleGroundMarks
50 SPELL_WS_MARK_LOSER
= 24950,
51 SPELL_WS_MARK_WINNER
= 24951,
52 SPELL_AB_MARK_LOSER
= 24952,
53 SPELL_AB_MARK_WINNER
= 24953,
54 SPELL_AV_MARK_LOSER
= 24954,
55 SPELL_AV_MARK_WINNER
= 24955,
56 ITEM_EY_MARK_OF_HONOR
= 29024
59 enum BattleGroundMarksCount
61 ITEM_WINNER_COUNT
= 3,
65 enum BattleGroundSpells
67 SPELL_WAITING_FOR_RESURRECT
= 2584, // Waiting to Resurrect
68 SPELL_SPIRIT_HEAL_CHANNEL
= 22011, // Spirit Heal Channel
69 SPELL_SPIRIT_HEAL
= 22012, // Spirit Heal
70 SPELL_RESURRECTION_VISUAL
= 24171, // Resurrection Impact Visual
71 SPELL_ARENA_PREPARATION
= 32727, // use this one, 32728 not correct
72 SPELL_ALLIANCE_GOLD_FLAG
= 32724,
73 SPELL_ALLIANCE_GREEN_FLAG
= 32725,
74 SPELL_HORDE_GOLD_FLAG
= 35774,
75 SPELL_HORDE_GREEN_FLAG
= 35775,
76 SPELL_PREPARATION
= 44521, // Preparation
77 SPELL_SPIRIT_HEAL_MANA
= 44535, // Spirit Heal
78 SPELL_RECENTLY_DROPPED_FLAG
= 42792, // Recently Dropped Flag
79 SPELL_AURA_PLAYER_INACTIVE
= 43681 // Inactive
82 enum BattleGroundTimeIntervals
84 RESURRECTION_INTERVAL
= 30000, // ms
85 REMIND_INTERVAL
= 30000, // ms
86 INVITE_ACCEPT_WAIT_TIME
= 80000, // ms
87 TIME_TO_AUTOREMOVE
= 120000, // ms
88 MAX_OFFLINE_TIME
= 300000, // ms
89 START_DELAY0
= 120000, // ms
90 START_DELAY1
= 60000, // ms
91 START_DELAY2
= 30000, // ms
92 START_DELAY3
= 15000, // ms used only in arena
93 RESPAWN_ONE_DAY
= 86400, // secs
94 RESPAWN_IMMEDIATELY
= 0, // secs
95 BUFF_RESPAWN_TIME
= 180, // secs
96 BG_HONOR_SCORE_TICKS
= 330 // points
99 enum BattleGroundBuffObjects
101 BG_OBJECTID_SPEEDBUFF_ENTRY
= 179871,
102 BG_OBJECTID_REGENBUFF_ENTRY
= 179904,
103 BG_OBJECTID_BERSERKERBUFF_ENTRY
= 179905
106 const uint32 Buff_Entries
[3] = { BG_OBJECTID_SPEEDBUFF_ENTRY
, BG_OBJECTID_REGENBUFF_ENTRY
, BG_OBJECTID_BERSERKERBUFF_ENTRY
};
108 enum BattleGroundStatus
111 STATUS_WAIT_QUEUE
= 1,
112 STATUS_WAIT_JOIN
= 2,
113 STATUS_IN_PROGRESS
= 3,
114 STATUS_WAIT_LEAVE
= 4 // custom
117 struct BattleGroundPlayer
119 uint32 LastOnlineTime
; // for tracking and removing offline players from queue after 5 minutes
120 uint32 Team
; // Player's team
123 struct BattleGroundObjectInfo
125 BattleGroundObjectInfo() : object(NULL
), timer(0), spellid(0) {}
132 enum BattleGroundTypeId
143 BATTLEGROUND_DS
= 10,
147 // handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time
148 enum BattleGroundQueueTypeId
150 BATTLEGROUND_QUEUE_AV
= 1,
151 BATTLEGROUND_QUEUE_WS
= 2,
152 BATTLEGROUND_QUEUE_AB
= 3,
153 BATTLEGROUND_QUEUE_EY
= 4,
154 BATTLEGROUND_QUEUE_SA
= 5,
155 BATTLEGROUND_QUEUE_2v2
= 6,
156 BATTLEGROUND_QUEUE_3v3
= 7,
157 BATTLEGROUND_QUEUE_5v5
= 8,
162 SCORE_KILLING_BLOWS
= 1,
164 SCORE_HONORABLE_KILLS
= 3,
165 SCORE_BONUS_HONOR
= 4,
166 //EY, but in MSG_PVP_LOG_DATA opcode!
167 SCORE_DAMAGE_DONE
= 5,
168 SCORE_HEALING_DONE
= 6,
170 SCORE_FLAG_CAPTURES
= 7,
171 SCORE_FLAG_RETURNS
= 8,
173 SCORE_BASES_ASSAULTED
= 9,
174 SCORE_BASES_DEFENDED
= 10,
176 SCORE_GRAVEYARDS_ASSAULTED
= 11,
177 SCORE_GRAVEYARDS_DEFENDED
= 12,
178 SCORE_TOWERS_ASSAULTED
= 13,
179 SCORE_TOWERS_DEFENDED
= 14,
180 SCORE_MINES_CAPTURED
= 15,
181 SCORE_LEADERS_KILLED
= 16,
182 SCORE_SECONDARY_OBJECTIVES
= 17
183 // TODO : implement them
193 enum BattleGroundType
195 TYPE_BATTLEGROUND
= 3,
199 enum BattleGroundWinner
206 enum BattleGroundTeamId
208 BG_TEAM_ALLIANCE
= 0,
212 enum BattleGroundJoinError
215 BG_JOIN_ERR_OFFLINE_MEMBER
= 1,
216 BG_JOIN_ERR_GROUP_TOO_MANY
= 2,
217 BG_JOIN_ERR_MIXED_FACTION
= 3,
218 BG_JOIN_ERR_MIXED_LEVELS
= 4,
219 BG_JOIN_ERR_MIXED_ARENATEAM
= 5,
220 BG_JOIN_ERR_GROUP_MEMBER_ALREADY_IN_QUEUE
= 6,
221 BG_JOIN_ERR_GROUP_DESERTER
= 7,
222 BG_JOIN_ERR_ALL_QUEUES_USED
= 8,
223 BG_JOIN_ERR_GROUP_NOT_ENOUGH
= 9
226 class BattleGroundScore
229 BattleGroundScore() : KillingBlows(0), HonorableKills(0), Deaths(0), DamageDone(0), HealingDone(0), BonusHonor(0) {};
230 virtual ~BattleGroundScore() //virtual destructor is used when deleting score from scores map
235 uint32 HonorableKills
;
242 This class is used to:
243 1. Add player to battleground
244 2. Remove player from battleground
245 3. some certain cases, same for all battlegrounds
246 4. It has properties same for all battlegrounds
250 friend class BattleGroundMgr
;
255 /*BattleGround(const BattleGround& bg);*/
256 virtual ~BattleGround();
257 virtual void Update(uint32 diff
); // must be implemented in BG subclass of BG specific update code, but must in begginning call parent version
258 virtual bool SetupBattleGround() // must be implemented in BG subclass
262 void Reset(); // resets all common properties for battlegrounds
263 virtual void ResetBGSubclass() // must be implemented in BG subclass
269 char const* GetName() const { return m_Name
; }
270 uint32
GetTypeID() const { return m_TypeID
; }
271 uint32
GetQueueType() const { return m_Queue_type
; }
272 uint32
GetInstanceID() const { return m_InstanceID
; }
273 uint32
GetStatus() const { return m_Status
; }
274 uint32
GetStartTime() const { return m_StartTime
; }
275 uint32
GetEndTime() const { return m_EndTime
; }
276 uint32
GetLastResurrectTime() const { return m_LastResurrectTime
; }
277 uint32
GetMaxPlayers() const { return m_MaxPlayers
; }
278 uint32
GetMinPlayers() const { return m_MinPlayers
; }
280 uint32
GetMinLevel() const { return m_LevelMin
; }
281 uint32
GetMaxLevel() const { return m_LevelMax
; }
283 uint32
GetMaxPlayersPerTeam() const { return m_MaxPlayersPerTeam
; }
284 uint32
GetMinPlayersPerTeam() const { return m_MinPlayersPerTeam
; }
286 int GetStartDelayTime() const { return m_StartDelayTime
; }
287 uint8
GetArenaType() const { return m_ArenaType
; }
288 uint8
GetWinner() const { return m_Winner
; }
289 uint32
GetBattlemasterEntry() const;
292 void SetName(char const* Name
) { m_Name
= Name
; }
293 void SetTypeID(uint32 TypeID
) { m_TypeID
= TypeID
; }
294 void SetQueueType(uint32 ID
) { m_Queue_type
= ID
; }
295 void SetInstanceID(uint32 InstanceID
) { m_InstanceID
= InstanceID
; }
296 void SetStatus(uint32 Status
) { m_Status
= Status
; }
297 void SetStartTime(uint32 Time
) { m_StartTime
= Time
; }
298 void SetEndTime(uint32 Time
) { m_EndTime
= Time
; }
299 void SetLastResurrectTime(uint32 Time
) { m_LastResurrectTime
= Time
; }
300 void SetMaxPlayers(uint32 MaxPlayers
) { m_MaxPlayers
= MaxPlayers
; }
301 void SetMinPlayers(uint32 MinPlayers
) { m_MinPlayers
= MinPlayers
; }
302 void SetLevelRange(uint32 min
, uint32 max
) { m_LevelMin
= min
; m_LevelMax
= max
; }
303 void SetRated(bool state
) { m_IsRated
= state
; }
304 void SetArenaType(uint8 type
) { m_ArenaType
= type
; }
305 void SetArenaorBGType(bool _isArena
) { m_IsArena
= _isArena
; }
306 void SetWinner(uint8 winner
) { m_Winner
= winner
; }
308 void ModifyStartDelayTime(int diff
) { m_StartDelayTime
-= diff
; }
309 void SetStartDelayTime(int Time
) { m_StartDelayTime
= Time
; }
311 void SetMaxPlayersPerTeam(uint32 MaxPlayers
) { m_MaxPlayersPerTeam
= MaxPlayers
; }
312 void SetMinPlayersPerTeam(uint32 MinPlayers
) { m_MinPlayersPerTeam
= MinPlayers
; }
314 void AddToBGFreeSlotQueue(); //this queue will be useful when more battlegrounds instances will be available
315 void RemoveFromBGFreeSlotQueue(); //this method could delete whole BG instance, if another free is available
317 void DecreaseInvitedCount(uint32 team
) { (team
== ALLIANCE
) ? --m_InvitedAlliance
: --m_InvitedHorde
; }
318 void IncreaseInvitedCount(uint32 team
) { (team
== ALLIANCE
) ? ++m_InvitedAlliance
: ++m_InvitedHorde
; }
319 uint32
GetInvitedCount(uint32 team
) const
321 if( team
== ALLIANCE
)
322 return m_InvitedAlliance
;
324 return m_InvitedHorde
;
326 bool HasFreeSlotsForTeam(uint32 Team
) const;
327 bool HasFreeSlots() const;
328 uint32
GetFreeSlotsForTeam(uint32 Team
) const;
330 bool isArena() const { return m_IsArena
; }
331 bool isBattleGround() const { return !m_IsArena
; }
332 bool isRated() const { return m_IsRated
; }
334 typedef std::map
<uint64
, BattleGroundPlayer
> BattleGroundPlayerMap
;
335 BattleGroundPlayerMap
const& GetPlayers() const { return m_Players
; }
336 uint32
GetPlayersSize() const { return m_Players
.size(); }
337 uint32
GetRemovedPlayersSize() const { return m_RemovedPlayers
.size(); }
339 std::map
<uint64
, BattleGroundScore
*>::const_iterator
GetPlayerScoresBegin() const { return m_PlayerScores
.begin(); }
340 std::map
<uint64
, BattleGroundScore
*>::const_iterator
GetPlayerScoresEnd() const { return m_PlayerScores
.end(); }
341 uint32
GetPlayerScoresSize() const { return m_PlayerScores
.size(); }
343 uint32
GetReviveQueueSize() const { return m_ReviveQueue
.size(); }
345 void AddPlayerToResurrectQueue(uint64 npc_guid
, uint64 player_guid
);
346 void RemovePlayerFromResurrectQueue(uint64 player_guid
);
348 void StartBattleGround();
351 void SetMapId(uint32 MapID
) { m_MapId
= MapID
; }
352 uint32
GetMapId() const { return m_MapId
; }
354 void SetTeamStartLoc(uint32 TeamID
, float X
, float Y
, float Z
, float O
);
355 void GetTeamStartLoc(uint32 TeamID
, float &X
, float &Y
, float &Z
, float &O
) const
357 uint8 idx
= GetTeamIndexByTeamId(TeamID
);
358 X
= m_TeamStartLocX
[idx
];
359 Y
= m_TeamStartLocY
[idx
];
360 Z
= m_TeamStartLocZ
[idx
];
361 O
= m_TeamStartLocO
[idx
];
364 /* Packet Transfer */
365 // method that should fill worldpacket with actual world states (not yet implemented for all battlegrounds!)
366 virtual void FillInitialWorldStates(WorldPacket
& /*data*/) {}
367 void SendPacketToTeam(uint32 TeamID
, WorldPacket
*packet
, Player
*sender
= NULL
, bool self
= true);
368 void SendPacketToAll(WorldPacket
*packet
);
369 void PlaySoundToTeam(uint32 SoundID
, uint32 TeamID
);
370 void PlaySoundToAll(uint32 SoundID
);
371 void CastSpellOnTeam(uint32 SpellID
, uint32 TeamID
);
372 void RewardHonorToTeam(uint32 Honor
, uint32 TeamID
);
373 void RewardReputationToTeam(uint32 faction_id
, uint32 Reputation
, uint32 TeamID
);
374 void RewardMark(Player
*plr
,uint32 count
);
375 void SendRewardMarkByMail(Player
*plr
,uint32 mark
, uint32 count
);
376 void RewardQuest(Player
*plr
);
377 void UpdateWorldState(uint32 Field
, uint32 Value
);
378 void UpdateWorldStateForPlayer(uint32 Field
, uint32 Value
, Player
*Source
);
379 void EndBattleGround(uint32 winner
);
380 void BlockMovement(Player
*plr
);
382 void SendMessageToAll(char const* text
);
383 void SendMessageToAll(int32 entry
);
386 Group
*GetBgRaid(uint32 TeamID
) const { return TeamID
== ALLIANCE
? m_BgRaids
[BG_TEAM_ALLIANCE
] : m_BgRaids
[BG_TEAM_HORDE
]; }
387 void SetBgRaid(uint32 TeamID
, Group
*bg_raid
)
389 Group
* &old_raid
= TeamID
== ALLIANCE
? m_BgRaids
[BG_TEAM_ALLIANCE
] : m_BgRaids
[BG_TEAM_HORDE
];
390 if(old_raid
) old_raid
->SetBattlegroundGroup(NULL
);
391 if(bg_raid
) bg_raid
->SetBattlegroundGroup(this);
395 virtual void UpdatePlayerScore(Player
*Source
, uint32 type
, uint32 value
);
397 uint8
GetTeamIndexByTeamId(uint32 Team
) const { return Team
== ALLIANCE
? BG_TEAM_ALLIANCE
: BG_TEAM_HORDE
; }
398 uint32
GetPlayersCountByTeam(uint32 Team
) const { return m_PlayersCount
[GetTeamIndexByTeamId(Team
)]; }
399 uint32
GetAlivePlayersCountByTeam(uint32 Team
) const; // used in arenas to correctly handle death in spirit of redemption / last stand etc. (killer = killed) cases
400 void UpdatePlayersCountByTeam(uint32 Team
, bool remove
)
403 --m_PlayersCount
[GetTeamIndexByTeamId(Team
)];
405 ++m_PlayersCount
[GetTeamIndexByTeamId(Team
)];
408 // used for rated arena battles
409 void SetArenaTeamIdForTeam(uint32 Team
, uint32 ArenaTeamId
) { m_ArenaTeamIds
[GetTeamIndexByTeamId(Team
)] = ArenaTeamId
; }
410 uint32
GetArenaTeamIdForTeam(uint32 Team
) const { return m_ArenaTeamIds
[GetTeamIndexByTeamId(Team
)]; }
411 void SetArenaTeamRatingChangeForTeam(uint32 Team
, int32 RatingChange
) { m_ArenaTeamRatingChanges
[GetTeamIndexByTeamId(Team
)] = RatingChange
; }
412 int32
GetArenaTeamRatingChangeForTeam(uint32 Team
) const { return m_ArenaTeamRatingChanges
[GetTeamIndexByTeamId(Team
)]; }
414 /* Triggers handle */
415 // must be implemented in BG subclass
416 virtual void HandleAreaTrigger(Player
* /*Source*/, uint32
/*Trigger*/) {}
417 // must be implemented in BG subclass if need AND call base class generic code
418 virtual void HandleKillPlayer(Player
*player
, Player
*killer
);
420 /* Battleground events */
421 /* these functions will return true event is possible, but false if player is bugger */
422 virtual void EventPlayerDroppedFlag(Player
* /*player*/) {}
423 virtual void EventPlayerClickedOnFlag(Player
* /*player*/, GameObject
* /*target_obj*/) {}
424 virtual void EventPlayerCapturedFlag(Player
* /*player*/) {}
427 virtual WorldSafeLocsEntry
const* GetClosestGraveYard(float /*x*/, float /*y*/, float /*z*/, uint32
/*team*/) { return NULL
; }
429 virtual void AddPlayer(Player
*plr
); // must be implemented in BG subclass
431 virtual void RemovePlayerAtLeave(uint64 guid
, bool Transport
, bool SendPacket
);
432 // can be extended in in BG subclass
434 void HandleTriggerBuff(uint64
const& go_guid
);
436 // TODO: make this protected:
437 typedef std::vector
<uint64
> BGObjects
;
438 typedef std::vector
<uint64
> BGCreatures
;
439 BGObjects m_BgObjects
;
440 BGCreatures m_BgCreatures
;
441 void SpawnBGObject(uint32 type
, uint32 respawntime
);
442 bool AddObject(uint32 type
, uint32 entry
, float x
, float y
, float z
, float o
, float rotation0
, float rotation1
, float rotation2
, float rotation3
, uint32 respawnTime
= 0);
443 // void SpawnBGCreature(uint32 type, uint32 respawntime);
444 Creature
* AddCreature(uint32 entry
, uint32 type
, uint32 teamval
, float x
, float y
, float z
, float o
, uint32 respawntime
= 0);
445 bool DelCreature(uint32 type
);
446 bool DelObject(uint32 type
);
447 bool AddSpiritGuide(uint32 type
, float x
, float y
, float z
, float o
, uint32 team
);
449 void DoorOpen(uint32 type
);
450 void DoorClose(uint32 type
);
451 const char *GetMangosString(int32 entry
);
453 virtual bool HandlePlayerUnderMap(Player
* plr
) {return false;}
455 // since arenas can be AvA or Hvh, we have to get the "temporary" team of a player
456 uint32
GetPlayerTeam(uint64 guid
);
458 void SetDeleteThis() {m_SetDeleteThis
= true;}
461 //this method is called, when BG cannot spawn its own spirit guide, or something is wrong, It correctly ends BattleGround
466 std::map
<uint64
, BattleGroundScore
*> m_PlayerScores
;
467 // must be implemented in BG subclass
468 virtual void RemovePlayer(Player
* /*player*/, uint64
/*guid*/) {}
470 /* Player lists, those need to be accessible by inherited classes */
471 BattleGroundPlayerMap m_Players
;
472 // Spirit Guide guid + Player list GUIDS
473 std::map
<uint64
, std::vector
<uint64
> > m_ReviveQueue
;
476 this is important variable used for invitation messages
484 uint32 m_TypeID
; //Battleground type, defined in enum BattleGroundTypeId
485 uint32 m_InstanceID
; //BattleGround Instance's GUID!
489 uint32 m_LastResurrectTime
;
491 uint8 m_ArenaType
; // 2=2v2, 3=3v3, 5=5v5
492 bool m_InBGFreeSlotQueue
; // used to make sure that BG is only once inserted into the BattleGroundMgr.BGFreeSlotQueue[bgTypeId] deque
493 bool m_SetDeleteThis
; // used for safe deletion of the bg after end / all players leave
494 // this variable is not used .... it can be found in many other ways... but to store it in BG object instance is useless
495 //uint8 m_BattleGroundType; // 3=BG, 4=arena
496 //instead of uint8 (in previous line) is bool used
498 uint8 m_Winner
; // 0=alliance, 1=horde, 2=none
499 int32 m_StartDelayTime
;
500 bool m_IsRated
; // is this battle rated?
501 bool m_PrematureCountDown
;
502 uint32 m_PrematureCountDownTimer
;
506 std::vector
<uint64
> m_ResurrectQueue
; // Player GUID
507 std::map
<uint64
, uint8
> m_RemovedPlayers
; // uint8 is remove type (0 - bgqueue, 1 - bg, 2 - resurrect queue)
509 /* Invited counters are useful for player invitation to BG - do not allow, if BG is started to one faction to have 2 more players than another faction */
510 /* Invited counters will be changed only when removing already invited player from queue, removing player from battleground and inviting player to BG */
511 /* Invited players counters*/
512 uint32 m_InvitedAlliance
;
513 uint32 m_InvitedHorde
;
516 Group
*m_BgRaids
[2]; // 0 - alliance, 1 - horde
518 /* Players count by team */
519 uint32 m_PlayersCount
[2];
521 /* Arena team ids by team */
522 uint32 m_ArenaTeamIds
[2];
524 int32 m_ArenaTeamRatingChanges
[2];
529 uint32 m_MaxPlayersPerTeam
;
531 uint32 m_MinPlayersPerTeam
;
536 float m_TeamStartLocX
[2];
537 float m_TeamStartLocY
[2];
538 float m_TeamStartLocZ
[2];
539 float m_TeamStartLocO
[2];