OregonCore  revision 3611e8a-git
Your Favourite TBC server
Battleground.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore Project. See AUTHORS file for Copyright information
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "Object.h"
19 #include "Player.h"
20 #include "Battleground.h"
21 #include "Creature.h"
22 #include "Language.h"
23 #include "Chat.h"
24 #include "ArenaTeam.h"
25 #include "World.h"
26 #include "Util.h"
27 #include "GridNotifiersImpl.h"
28 
29 namespace Oregon
30 {
32 {
33  public:
34  BattlegroundChatBuilder(ChatMsg msgtype, int32 textId, Player const* source, va_list* args = NULL)
35  : i_msgtype(msgtype), i_textId(textId), i_source(source), i_args(args) {}
36  void operator()(WorldPacket& data, int32 loc_idx)
37  {
38  char const* text = sObjectMgr.GetOregonString(i_textId, loc_idx);
39 
40  if (i_args)
41  {
42  // we need copy va_list before use or original va_list will corrupted
43  va_list ap;
44  va_copy(ap, *i_args);
45 
46  char str [2048];
47  vsnprintf(str, 2048, text, ap );
48  va_end(ap);
49 
50  do_helper(data, &str[0]);
51  }
52  else
53  do_helper(data, text);
54  }
55  private:
56  void do_helper(WorldPacket& data, char const* text)
57  {
58  uint64 target_guid = i_source ? i_source ->GetGUID() : 0;
59 
60  data << uint8(i_msgtype);
61  data << uint32(LANG_UNIVERSAL);
62  data << uint64(target_guid); // there 0 for BG messages
63  data << uint32(0); // can be chat msg group or something
64  data << uint64(target_guid);
65  data << uint32(strlen(text) + 1);
66  data << text;
67  data << uint8(i_source ? i_source->GetChatTag() : uint8(0));
68  }
69 
72  Player const* i_source;
73  va_list* i_args;
74 };
75 
77 {
78  public:
79  Battleground2ChatBuilder(ChatMsg msgtype, int32 textId, Player const* source, int32 arg1, int32 arg2)
80  : i_msgtype(msgtype), i_textId(textId), i_source(source), i_arg1(arg1), i_arg2(arg2) {}
81  void operator()(WorldPacket& data, int32 loc_idx)
82  {
83  char const* text = sObjectMgr.GetOregonString(i_textId, loc_idx);
84  char const* arg1str = i_arg1 ? sObjectMgr.GetOregonString(i_arg1, loc_idx) : "";
85  char const* arg2str = i_arg2 ? sObjectMgr.GetOregonString(i_arg2, loc_idx) : "";
86 
87  char str [2048];
88  snprintf(str, 2048, text, arg1str, arg2str );
89 
90  uint64 target_guid = i_source ? i_source ->GetGUID() : 0;
91 
92  data << uint8(i_msgtype);
93  data << uint32(LANG_UNIVERSAL);
94  data << uint64(target_guid); // there 0 for BG messages
95  data << uint32(0); // can be chat msg group or something
96  data << uint64(target_guid);
97  data << uint32(strlen(str) + 1);
98  data << str;
99  data << uint8(i_source ? i_source->GetChatTag() : uint8(0));
100  }
101  private:
102 
105  Player const* i_source;
108 };
109 } // namespace Oregon
110 
111 template<class Do>
113 {
114  for (std::map<uint64, BattlegroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
116  _do(plr);
117 }
118 
120 {
121  m_TypeID = 0;
122  m_InstanceID = 0;
123  m_Status = 0;
124  m_EndTime = 0;
125  m_LastResurrectTime = 0;
126  m_Queue_type = MAX_BATTLEGROUND_QUEUES;
127  m_InvitedAlliance = 0;
128  m_InvitedHorde = 0;
129  m_ArenaType = 0;
130  m_IsArena = false;
131  m_Winner = 2;
132  m_StartTime = 0;
133  m_ValidStartPositionTimer = 0;
134  m_Events = 0;
135  m_StartDelayTime = 0;
136  m_IsRated = false;
137  m_BuffChange = false;
138  m_Name = "";
139  m_LevelMin = 0;
140  m_LevelMax = 0;
141  m_InBGFreeSlotQueue = false;
142  m_SetDeleteThis = false;
143 
144  m_MaxPlayersPerTeam = 0;
145  m_MaxPlayers = 0;
146  m_MinPlayersPerTeam = 0;
147  m_MinPlayers = 0;
148 
149  m_MapId = 0;
150  m_Map = NULL;
151  m_StartMaxDist = 0.0f;
152 
153  m_TeamStartLocX[BG_TEAM_ALLIANCE] = 0;
154  m_TeamStartLocX[BG_TEAM_HORDE] = 0;
155 
156  m_TeamStartLocY[BG_TEAM_ALLIANCE] = 0;
157  m_TeamStartLocY[BG_TEAM_HORDE] = 0;
158 
159  m_TeamStartLocZ[BG_TEAM_ALLIANCE] = 0;
160  m_TeamStartLocZ[BG_TEAM_HORDE] = 0;
161 
162  m_TeamStartLocO[BG_TEAM_ALLIANCE] = 0;
163  m_TeamStartLocO[BG_TEAM_HORDE] = 0;
164 
165  m_ArenaTeamIds[BG_TEAM_ALLIANCE] = 0;
166  m_ArenaTeamIds[BG_TEAM_HORDE] = 0;
167 
168  m_ArenaTeamRatingChanges[BG_TEAM_ALLIANCE] = 0;
169  m_ArenaTeamRatingChanges[BG_TEAM_HORDE] = 0;
170 
171  m_BgRaids[BG_TEAM_ALLIANCE] = NULL;
172  m_BgRaids[BG_TEAM_HORDE] = NULL;
173 
174  m_PlayersCount[BG_TEAM_ALLIANCE] = 0;
175  m_PlayersCount[BG_TEAM_HORDE] = 0;
176 
177  m_TeamScores[BG_TEAM_ALLIANCE] = 0;
178  m_TeamScores[BG_TEAM_HORDE] = 0;
179 
180  m_score[BG_TEAM_ALLIANCE] = m_TeamScores[BG_TEAM_ALLIANCE];
181  m_score[BG_TEAM_HORDE] = m_TeamScores[BG_TEAM_HORDE];
182 
183  m_PrematureCountDown = false;
184  m_PrematureCountDownTimer = 0;
185 
186  m_HonorMode = BG_NORMAL;
187 
188  m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_2M;
189  m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_1M;
190  m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_30S;
191  m_StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
192  //we must set to some default existing values
196  m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN;
197 }
198 
200 {
201  // remove objects and creatures
202  // (this is done automatically in mapmanager update, when the instance is reset after the reset time)
203  int size = m_BgCreatures.size();
204  for (int i = 0; i < size; ++i)
205  DelCreature(i);
206 
207  size = m_BgObjects.size();
208  for (int i = 0; i < size; ++i)
209  DelObject(i);
210 
211  if (GetInstanceID()) // not spam by useless queries in case BG templates
212  {
213  // delete creature and go respawn times
214  WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE instance = '%u'", GetInstanceID());
215  WorldDatabase.PExecute("DELETE FROM gameobject_respawn WHERE instance = '%u'", GetInstanceID());
216  // delete instance from db
217  CharacterDatabase.PExecute("DELETE FROM instance WHERE id = '%u'", GetInstanceID());
218  // remove from battlegrounds
219  }
220 
221  sBattlegroundMgr.RemoveBattleground(GetInstanceID());
222  // unload map
223  if (m_Map)
224  m_Map->SetUnload();
225  // remove from bg free slot queue
226  this->RemoveFromBGFreeSlotQueue();
227 
228  for (BattlegroundScoreMap::const_iterator itr = m_PlayerScores.begin(); itr != m_PlayerScores.end(); ++itr)
229  delete itr->second;
230 }
231 
233 {
234  if (!GetPlayersSize() && !GetRemovedPlayersSize() && !GetReviveQueueSize())
235  //BG is empty
236  return;
237 
238  m_StartTime += diff;
239 
240  // WorldPacket data;
241 
242  if (GetRemovedPlayersSize())
243  {
244  for (std::map<uint64, uint8>::iterator itr = m_RemovedPlayers.begin(); itr != m_RemovedPlayers.end(); ++itr)
245  {
246  Player* plr = sObjectMgr.GetPlayer(itr->first);
247  switch (itr->second)
248  {
249  //following code is handled by event:
250  /*case 0:
251  sBattlegroundMgr.m_BattlegroundQueues[GetTypeID()].RemovePlayer(itr->first);
252  //RemovePlayerFromQueue(itr->first);
253  if (plr)
254  {
255  sBattlegroundMgr.BuildBattlegroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattlegroundQueueIndex(m_TypeID), STATUS_NONE, 0, 0);
256  plr->GetSession()->SendPacket(&data);
257  }
258  break;*/
259  case 1: // currently in bg and was removed from bg
260  if (plr)
261  RemovePlayerAtLeave(itr->first, true, true);
262  else
263  RemovePlayerAtLeave(itr->first, false, false);
264  break;
265  case 2: // revive queue
266  RemovePlayerFromResurrectQueue(itr->first);
267  break;
268  default:
269  sLog.outError("Battleground: Unknown remove player case!");
270  }
271  }
272  m_RemovedPlayers.clear();
273  }
274 
275  // remove offline players from bg after 5 minutes
276  if (GetPlayersSize())
277  {
278  for (std::map<uint64, BattlegroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
279  {
280  Player* plr = sObjectMgr.GetPlayer(itr->first);
281  itr->second.LastOnlineTime += diff;
282 
283  if (plr)
284  {
285  itr->second.LastOnlineTime = 0; // update last online time
286  if (!plr->IsPvP()) // force all players PvP on
287  plr->UpdatePvP(true, true);
288  }
289  else if (itr->second.LastOnlineTime >= MAX_OFFLINE_TIME)
290  m_RemovedPlayers[itr->first] = 1; // add to remove list (BG)
291  }
292  }
293 
294  /*********************************************************/
295  /*** BATTLEGROUND RESSURECTION SYSTEM ***/
296  /*********************************************************/
297 
298  //this should be handled by spell system
299  m_LastResurrectTime += diff;
300  if (m_LastResurrectTime >= RESURRECTION_INTERVAL)
301  {
302  if (GetReviveQueueSize())
303  {
304  for (std::map<uint64, std::vector<uint64> >::iterator itr = m_ReviveQueue.begin(); itr != m_ReviveQueue.end(); ++itr)
305  {
306  Creature* sh = NULL;
307  for (std::vector<uint64>::iterator itr2 = (itr->second).begin(); itr2 != (itr->second).end(); ++itr2)
308  {
309  Player* plr = sObjectMgr.GetPlayer(*itr2);
310  if (!plr)
311  continue;
312 
313  if (!sh && plr->IsInWorld())
314  {
315  sh = plr->GetMap()->GetCreature(itr->first);
316  // only for visual effect
317  if (sh)
318  sh->CastSpell(sh, SPELL_SPIRIT_HEAL, true); // Spirit Heal, effect 117
319  }
320 
321  plr->CastSpell(plr, SPELL_RESURRECTION_VISUAL, true); // Resurrection visual
322  m_ResurrectQueue.push_back(*itr2);
323  }
324  (itr->second).clear();
325  }
326 
327  m_ReviveQueue.clear();
328  m_LastResurrectTime = 0;
329  }
330  else
331  // queue is clear and time passed, just update last resurrection time
332  m_LastResurrectTime = 0;
333  }
334  else if (m_LastResurrectTime > 500) // Resurrect players only half a second later, to see spirit heal effect on NPC
335  {
336  for (std::vector<uint64>::iterator itr = m_ResurrectQueue.begin(); itr != m_ResurrectQueue.end(); ++itr)
337  {
338  Player* player = sObjectMgr.GetPlayer(*itr);
339  if (!player)
340  continue;
341  player->ResurrectPlayer(1.0f);
342  player->CastSpell(player, SPELL_SUMMON_PET, true);
343  player->CastSpell(player, SPELL_SPIRIT_HEAL_MANA, true);
345  }
346  m_ResurrectQueue.clear();
347  }
348 
349  /*********************************************************/
350  /*** BATTLEGROUND BALLANCE SYSTEM ***/
351  /*********************************************************/
352 
353  // if less then minimum players are in on one side, then start premature finish timer
354  if (GetStatus() == STATUS_IN_PROGRESS && !isArena() && sBattlegroundMgr.GetPrematureFinishTime() && (GetPlayersCountByTeam(ALLIANCE) < GetMinPlayersPerTeam() || GetPlayersCountByTeam(HORDE) < GetMinPlayersPerTeam()))
355  {
356  if (!m_PrematureCountDown)
357  {
358  m_PrematureCountDown = true;
359  m_PrematureCountDownTimer = sBattlegroundMgr.GetPrematureFinishTime();
360  }
361  else if (m_PrematureCountDownTimer < diff)
362  {
363  // time's up!
364  EndBattleground(0); // noone wins
365  m_PrematureCountDown = false;
366  }
367  else if (!sBattlegroundMgr.isTesting())
368  {
369  uint32 newtime = m_PrematureCountDownTimer - diff;
370  // announce every minute
371  if (newtime > (MINUTE * IN_MILLISECONDS))
372  {
373  if (newtime / (MINUTE * IN_MILLISECONDS) != m_PrematureCountDownTimer / (MINUTE * IN_MILLISECONDS))
374  PSendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING, CHAT_MSG_SYSTEM, NULL, (uint32)(m_PrematureCountDownTimer / (MINUTE * IN_MILLISECONDS)));
375  }
376  else
377  {
378  //announce every 15 seconds
379  if (newtime / (15 * IN_MILLISECONDS) != m_PrematureCountDownTimer / (15 * IN_MILLISECONDS))
380  PSendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING_SECS, CHAT_MSG_SYSTEM, NULL, (uint32)(m_PrematureCountDownTimer / IN_MILLISECONDS));
381  }
382  m_PrematureCountDownTimer = newtime;
383  }
384  }
385  else if (m_PrematureCountDown)
386  m_PrematureCountDown = false;
387 
388  /*********************************************************/
389  /*** BATTLEGROUND STARTING SYSTEM ***/
390  /*********************************************************/
391 
392  if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize())
393  {
394  ModifyStartDelayTime(diff);
395  _CheckSafePositions(diff);
396 
397  if (!(m_Events & BG_STARTING_EVENT_1))
398  {
399  m_Events |= BG_STARTING_EVENT_1;
400 
401  // setup here, only when at least one player has ported to the map
402  if (!SetupBattleground())
403  {
404  EndNow();
405  return;
406  }
407 
408  StartingEventCloseDoors();
409  SetStartDelayTime(m_StartDelayTimes[BG_STARTING_EVENT_FIRST]);
410  //first start warning - 2 or 1 minute
411  SendMessageToAll(m_StartMessageIds[BG_STARTING_EVENT_FIRST], CHAT_MSG_BG_SYSTEM_NEUTRAL);
412  }
413  // After 1 minute or 30 seconds, warning is signalled
414  else if (GetStartDelayTime() <= m_StartDelayTimes[BG_STARTING_EVENT_SECOND] && !(m_Events & BG_STARTING_EVENT_2))
415  {
416  m_Events |= BG_STARTING_EVENT_2;
417  SendMessageToAll(m_StartMessageIds[BG_STARTING_EVENT_SECOND], CHAT_MSG_BG_SYSTEM_NEUTRAL);
418  }
419  // After 30 or 15 seconds, warning is signalled
420  else if (GetStartDelayTime() <= m_StartDelayTimes[BG_STARTING_EVENT_THIRD] && !(m_Events & BG_STARTING_EVENT_3))
421  {
422  m_Events |= BG_STARTING_EVENT_3;
423  SendMessageToAll(m_StartMessageIds[BG_STARTING_EVENT_THIRD], CHAT_MSG_BG_SYSTEM_NEUTRAL);
424  }
425  // delay expired (after 2 or 1 minute)
426  else if (GetStartDelayTime() <= 0 && !(m_Events & BG_STARTING_EVENT_4))
427  {
428  m_Events |= BG_STARTING_EVENT_4;
429 
430  StartingEventOpenDoors();
431 
432  SendMessageToAll(m_StartMessageIds[BG_STARTING_EVENT_FOURTH], CHAT_MSG_BG_SYSTEM_NEUTRAL);
433  SetStatus(STATUS_IN_PROGRESS);
434  SetStartDelayTime(m_StartDelayTimes[BG_STARTING_EVENT_FOURTH]);
435 
436  //remove preparation
437  if (isArena())
438  {
439  for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
440  if (Player* plr = sObjectMgr.GetPlayer(itr->first))
441  plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
442 
443  CheckArenaWinConditions();
444  }
445  else
446  {
447  PlaySoundToAll(SOUND_BG_START);
448 
449  for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
450  if (Player* plr = sObjectMgr.GetPlayer(itr->first))
451  plr->RemoveAurasDueToSpell(SPELL_PREPARATION);
452 
453  //Announce BG starting
454  Announce();
455  }
456  }
457  }
458 
459  /*********************************************************/
460  /*** BATTLEGROUND ENDING SYSTEM ***/
461  /*********************************************************/
462 
463  if (GetStatus() == STATUS_WAIT_LEAVE)
464  {
465  // remove all players from battleground after 2 minutes
466  m_EndTime += diff;
467  if (m_EndTime >= TIME_TO_AUTOREMOVE) // 2 minutes
468  {
469  for (std::map<uint64, BattlegroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
470  {
471  m_RemovedPlayers[itr->first] = 1; // add to remove list (BG)
472  }
473  // do not change any battleground's private variables
474  }
475  }
476 }
477 
478 void Battleground::SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O)
479 {
480  uint8 idx = GetTeamIndexByTeamId(TeamID);
481  m_TeamStartLocX[idx] = X;
482  m_TeamStartLocY[idx] = Y;
483  m_TeamStartLocZ[idx] = Z;
484  m_TeamStartLocO[idx] = O;
485 }
486 
488 {
489  for (std::map<uint64, BattlegroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
490  {
491  if (itr->second.LastOnlineTime)
492  continue;
493 
494  Player* plr = sObjectMgr.GetPlayer(itr->first);
495  if (plr)
496  plr->GetSession()->SendPacket(packet);
497  else
498  sLog.outError("Battleground: Player (GUID: %u) not found!", GUID_LOPART(itr->first));
499  }
500 }
501 
502 void Battleground::SendPacketToTeam(uint32 TeamID, WorldPacket* packet, Player* sender, bool self)
503 {
504  for (std::map<uint64, BattlegroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
505  {
506  if (itr->second.LastOnlineTime)
507  continue;
508 
509  Player* plr = sObjectMgr.GetPlayer(itr->first);
510 
511  if (!plr)
512  {
513  sLog.outError("Battleground: Player (GUID: %u) not found!", GUID_LOPART(itr->first));
514  continue;
515  }
516 
517  if (!self && sender == plr)
518  continue;
519 
520  uint32 team = itr->second.Team;
521  if (!team) team = plr->GetTeam();
522 
523  if (team == TeamID)
524  plr->GetSession()->SendPacket(packet);
525  }
526 }
527 
529 {
530  WorldPacket data;
531  sBattlegroundMgr.BuildPlaySoundPacket(&data, SoundID);
532  SendPacketToAll(&data);
533 }
534 
536 {
537  WorldPacket data;
538 
539  for (std::map<uint64, BattlegroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
540  {
541  if (itr->second.LastOnlineTime)
542  continue;
543 
544  Player* plr = sObjectMgr.GetPlayer(itr->first);
545 
546  if (!plr)
547  {
548  sLog.outError("Battleground: Player (GUID: %u) not found!", GUID_LOPART(itr->first));
549  continue;
550  }
551 
552  uint32 team = itr->second.Team;
553  if (!team) team = plr->GetTeam();
554 
555  if (team == TeamID)
556  {
557  sBattlegroundMgr.BuildPlaySoundPacket(&data, SoundID);
558  plr->GetSession()->SendPacket(&data);
559  }
560  }
561 }
562 
564 {
565  for (std::map<uint64, BattlegroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
566  {
567  if (itr->second.LastOnlineTime)
568  continue;
569 
570  Player* plr = sObjectMgr.GetPlayer(itr->first);
571 
572  if (!plr)
573  {
574  sLog.outError("Battleground: Player (GUID: %u) not found!", GUID_LOPART(itr->first));
575  continue;
576  }
577 
578  uint32 team = itr->second.Team;
579  if (!team) team = plr->GetTeam();
580 
581  if (team == TeamID)
582  plr->CastSpell(plr, SpellID, true);
583  }
584 }
585 
586 void Battleground::YellToAll(Creature* creature, const char* text, uint32 language)
587 {
588  for (std::map<uint64, BattlegroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
589  {
590  if (itr->second.LastOnlineTime)
591  continue;
592 
593  WorldPacket data(SMSG_MESSAGECHAT, 200);
594  Player* plr = sObjectMgr.GetPlayer(itr->first);
595  if (!plr)
596  {
597  sLog.outError("Battleground: Player (GUID: %u) not found!", GUID_LOPART(itr->first));
598  continue;
599  }
600  creature->BuildMonsterChat(&data, CHAT_MSG_MONSTER_YELL, text, language, creature->GetName(), itr->first);
601  plr->GetSession()->SendPacket(&data);
602  }
603 }
604 
605 
607 {
608  for (std::map<uint64, BattlegroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
609  {
610  if (itr->second.LastOnlineTime)
611  continue;
612 
613  Player* plr = sObjectMgr.GetPlayer(itr->first);
614 
615  if (!plr)
616  {
617  sLog.outError("Battleground: Player (GUID: %u) not found!", GUID_LOPART(itr->first));
618  continue;
619  }
620 
621  uint32 team = itr->second.Team;
622  if (!team) team = plr->GetTeam();
623 
624  if (team == TeamID)
625  UpdatePlayerScore(plr, SCORE_BONUS_HONOR, Honor);
626  }
627 }
628 
629 void Battleground::RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID)
630 {
631  FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id);
632  if (!factionEntry)
633  return;
634 
635  for (std::map<uint64, BattlegroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
636  {
637  if (itr->second.LastOnlineTime)
638  continue;
639 
640  Player* plr = sObjectMgr.GetPlayer(itr->first);
641 
642  if (!plr)
643  {
644  sLog.outError("Battleground: Player (GUID: %u) not found!", GUID_LOPART(itr->first));
645  continue;
646  }
647 
648  uint32 team = itr->second.Team;
649  if (!team) team = plr->GetTeam();
650 
651  if (team == TeamID)
652  {
653  uint32 repGain = Reputation;
656  plr->GetReputationMgr().ModifyReputation(factionEntry, Reputation);
657  }
658  }
659 }
660 
662 {
663  WorldPacket data;
664  sBattlegroundMgr.BuildUpdateWorldStatePacket(&data, Field, Value);
665  SendPacketToAll(&data);
666 }
667 
669 {
670  WorldPacket data;
671  sBattlegroundMgr.BuildUpdateWorldStatePacket(&data, Field, Value);
672  Source->GetSession()->SendPacket(&data);
673 }
674 
676 {
677  this->RemoveFromBGFreeSlotQueue();
678  uint32 almost_winning_team = HORDE;
679  ArenaTeam* winner_arena_team = NULL;
680  ArenaTeam* loser_arena_team = NULL;
681  uint32 loser_rating = 0;
682  uint32 winner_rating = 0;
683  WorldPacket data;
684  int32 winmsg_id = 0;
685 
686  if (winner == ALLIANCE)
687  {
688  winmsg_id = isBattleground() ? LANG_BG_A_WINS : LANG_ARENA_GOLD_WINS;
689 
690  PlaySoundToAll(SOUND_ALLIANCE_WINS); // alliance wins sound
691 
692  SetWinner(WINNER_ALLIANCE);
693  }
694  else if (winner == HORDE)
695  {
696  winmsg_id = isBattleground() ? LANG_BG_H_WINS : LANG_ARENA_GREEN_WINS;
697 
698  PlaySoundToAll(SOUND_HORDE_WINS); // horde wins sound
699 
700  SetWinner(WINNER_HORDE);
701  }
702  else
703  SetWinner(3);
704 
705  SetStatus(STATUS_WAIT_LEAVE);
706  m_EndTime = 0;
707 
708  // arena rating calculation
709  if (isArena() && isRated())
710  {
711  if (winner == ALLIANCE)
712  {
713  winner_arena_team = sObjectMgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE));
714  loser_arena_team = sObjectMgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE));
715  }
716  else if (winner == HORDE)
717  {
718  winner_arena_team = sObjectMgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE));
719  loser_arena_team = sObjectMgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE));
720  }
721  if (winner_arena_team && loser_arena_team)
722  {
723  loser_rating = loser_arena_team->GetStats().rating;
724  winner_rating = winner_arena_team->GetStats().rating;
725  int32 winner_change = winner_arena_team->WonAgainst(loser_rating);
726  int32 loser_change = loser_arena_team->LostAgainst(winner_rating);
727  sLog.outDebug("--- Winner rating: %u, Loser rating: %u, Winner change: %u, Losser change: %u ---", winner_rating, loser_rating, winner_change, loser_change);
728  if (winner == ALLIANCE)
729  {
730  SetArenaTeamRatingChangeForTeam(ALLIANCE, winner_change);
731  SetArenaTeamRatingChangeForTeam(HORDE, loser_change);
732  }
733  else
734  {
735  SetArenaTeamRatingChangeForTeam(HORDE, winner_change);
736  SetArenaTeamRatingChangeForTeam(ALLIANCE, loser_change);
737  }
738  sLog.outArena("Arena match Type: %u for Team1Id: %u - Team2Id: %u ended. WinnerTeamId: %u. Winner rating: %u, Loser rating: %u. RatingChange: %i.", m_ArenaType, m_ArenaTeamIds[BG_TEAM_ALLIANCE], m_ArenaTeamIds[BG_TEAM_HORDE], winner_arena_team->GetId(), winner_rating, loser_rating, winner_change);
739  if (sWorld.getConfig(CONFIG_ARENA_LOG_EXTENDED_INFO))
740  for (Battleground::BattlegroundScoreMap::const_iterator itr = GetPlayerScoresBegin(); itr != GetPlayerScoresEnd(); ++itr)
741  if (Player* player = sObjectMgr.GetPlayer(itr->first))
742  sLog.outArena("Statistics for %s (GUID: " UI64FMTD ", Team: %d, IP: %s): %u damage, %u healing, %u killing blows", player->GetName(), itr->first, player->GetArenaTeamId(m_ArenaType == 5 ? 2 : m_ArenaType == 3), player->GetSession()->GetRemoteAddress().c_str(), itr->second->DamageDone, itr->second->HealingDone, itr->second->KillingBlows);
743  }
744  else
745  {
746  SetArenaTeamRatingChangeForTeam(ALLIANCE, 0);
747  SetArenaTeamRatingChangeForTeam(HORDE, 0);
748  }
749  }
750 
751  if (!isArena())
752  {
753 
754  if (m_score[GetTeamIndexByTeamId(ALLIANCE)] == m_score[GetTeamIndexByTeamId(HORDE)])
755  almost_winning_team = 0; //no real winner
756  if (m_score[GetTeamIndexByTeamId(ALLIANCE)] > m_score[GetTeamIndexByTeamId(HORDE)])
757  almost_winning_team = ALLIANCE;
758 
759  }
760 
761  for (std::map<uint64, BattlegroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
762  {
763  Player* plr = sObjectMgr.GetPlayer(itr->first);
764  uint32 team = itr->second.Team;
765 
766  if (!plr)
767  {
768  //if rated arena match - make member lost!
769  if (isArena() && isRated() && winner_arena_team && loser_arena_team)
770  {
771  if (team == winner)
772  winner_arena_team->OfflineMemberLost(itr->first, loser_rating);
773  else
774  loser_arena_team->OfflineMemberLost(itr->first, winner_rating);
775  }
776  sLog.outError("Battleground: Player (GUID: %u) not found!", GUID_LOPART(itr->first));
777  continue;
778  }
779 
780  // should remove spirit of redemption
783 
784  if (!plr->IsAlive())
785  {
786  plr->ResurrectPlayer(1.0f);
787  plr->SpawnCorpseBones();
788  }
789 
790  //this line is obsolete - team is set ALWAYS
791  //if (!team) team = plr->GetTeam();
792 
793  // per player calculation
794  if (isArena() && isRated() && winner_arena_team && loser_arena_team)
795  {
796  if (team == winner)
797  winner_arena_team->MemberWon(plr, loser_rating);
798  else
799  loser_arena_team->MemberLost(plr, winner_rating);
800  }
801 
802  if (team == winner)
803  {
804  RewardMark(plr, ITEM_WINNER_COUNT);
805  UpdatePlayerScore(plr, SCORE_BONUS_HONOR, 20);
806  RewardQuest(plr);
807  }
808  else if (winner != 0)
809  RewardMark(plr, ITEM_LOSER_COUNT);
810  else if (winner == 0)
811  {
813  {
814  if (almost_winning_team == team) // player's team had more points
815  RewardMark(plr, ITEM_WINNER_COUNT);
816  else
817  RewardMark(plr, ITEM_LOSER_COUNT); // if scores were the same, each team gets 1 mark.
818  }
819  }
820 
821  plr->SetHealth(plr->GetMaxHealth());
823  plr->CombatStopWithPets(true);
824 
825  BlockMovement(plr);
826 
827  sBattlegroundMgr.BuildPvpLogDataPacket(&data, this);
828  plr->GetSession()->SendPacket(&data);
829 
830  uint32 bgQueueTypeId = sBattlegroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType());
831  sBattlegroundMgr.BuildBattlegroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime());
832  plr->GetSession()->SendPacket(&data);
833  }
834 
835  if (isArena() && isRated() && winner_arena_team && loser_arena_team)
836  {
837  // update arena points only after increasing the player's match count!
838  //obsolete: winner_arena_team->UpdateArenaPointsHelper();
839  //obsolete: loser_arena_team->UpdateArenaPointsHelper();
840  // save the stat changes
841  winner_arena_team->SaveToDB();
842  loser_arena_team->SaveToDB();
843  // send updated arena team stats to players
844  // this way all arena team members will get notified, not only the ones who participated in this match
845  winner_arena_team->NotifyStatsChanged();
846  loser_arena_team->NotifyStatsChanged();
847  }
848 
849  // inform invited players about the removal
850  sBattlegroundMgr.m_BattlegroundQueues[sBattlegroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this);
851 
852  if (winmsg_id)
853  SendMessageToAll(winmsg_id, CHAT_MSG_BG_SYSTEM_NEUTRAL);
854 }
855 
857 {
858  switch (GetTypeID())
859  {
860  case BATTLEGROUND_AV:
861  return 15972;
862  case BATTLEGROUND_WS:
863  return 14623;
864  case BATTLEGROUND_AB:
865  return 14879;
866  case BATTLEGROUND_EY:
867  return 22516;
868  case BATTLEGROUND_NA:
869  return 20200;
870  default:
871  return 0;
872  }
873 }
874 
876 {
877  if (!plr || !count)
878  return;
879 
880  // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens
882  return;
883 
884  BattlegroundMarks mark;
885  switch (GetTypeID())
886  {
887  case BATTLEGROUND_AV:
888  mark = ITEM_AV_MARK_OF_HONOR;
889  break;
890  case BATTLEGROUND_WS:
891  mark = ITEM_WS_MARK_OF_HONOR;
892  break;
893  case BATTLEGROUND_AB:
894  mark = ITEM_AB_MARK_OF_HONOR;
895  break;
896  case BATTLEGROUND_EY:
897  mark = ITEM_EY_MARK_OF_HONOR;
898  break;
899  default:
900  return;
901  }
902 
903  if (sObjectMgr.GetItemTemplate(mark))
904  {
905  ItemPosCountVec dest;
906  uint32 no_space_count = 0;
907  uint8 msg = plr->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, mark, count, &no_space_count);
908  if (msg != EQUIP_ERR_OK) // convert to possible store amount
909  count -= no_space_count;
910 
911  if (!dest.empty()) // can add some
912  if (Item* item = plr->StoreNewItem(dest, mark, true, 0))
913  plr->SendNewItem(item, count, false, true);
914 
915  if (no_space_count > 0)
916  SendRewardMarkByMail(plr, mark, no_space_count);
917  }
918 }
919 
921 {
922  uint32 bmEntry = GetBattlemasterEntry();
923  if (!bmEntry)
924  return;
925 
926  ItemTemplate const* markProto = sObjectMgr.GetItemTemplate(mark);
927  if (!markProto)
928  return;
929 
930  if (Item* markItem = Item::CreateItem(mark, count, plr))
931  {
932  // save new item before send
933  markItem->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
934 
935  // subject: item name
936  std::string subject = markProto->Name1;
937  int loc_idx = plr->GetSession()->GetSessionDbLocaleIndex();
938  if (loc_idx >= 0)
939  if (ItemLocale const* il = sObjectMgr.GetItemLocale(markProto->ItemId))
940  if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty())
941  subject = il->Name[loc_idx];
942 
943  // text
944  std::string textFormat = plr->GetSession()->GetOregonString(LANG_BG_MARK_BY_MAIL);
945  char textBuf[300];
946  snprintf(textBuf, 300, textFormat.c_str(), GetName(), GetName());
947  uint32 itemTextId = sObjectMgr.CreateItemText(textBuf);
948 
949  MailDraft(subject, itemTextId)
950  .AddItem(markItem)
951  .SendMailTo(plr, MailSender(MAIL_CREATURE, bmEntry));
952  }
953 }
954 
956 {
957  // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens
959  return;
960 
961  uint32 quest;
962  switch (GetTypeID())
963  {
964  case BATTLEGROUND_AV:
965  quest = SPELL_AV_QUEST_REWARD;
966  break;
967  case BATTLEGROUND_WS:
968  quest = SPELL_WS_QUEST_REWARD;
969  break;
970  case BATTLEGROUND_AB:
971  quest = SPELL_AB_QUEST_REWARD;
972  break;
973  case BATTLEGROUND_EY:
974  quest = SPELL_EY_QUEST_REWARD;
975  break;
976  default:
977  return;
978  }
979 
980  plr->CastSpell(plr, quest, true);
981 }
982 
984 {
985  plr->SetClientControl(plr, 0); // movement disabled NOTE: the effect will be automatically removed by client when the player is teleported from the battleground, so no need to send with uint8(1) in RemovePlayerAtLeave()
986 }
987 
988 void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket)
989 {
990  uint32 team = GetPlayerTeam(guid);
991  bool participant = false;
992  // Remove from lists/maps
993  std::map<uint64, BattlegroundPlayer>::iterator itr = m_Players.find(guid);
994  if (itr != m_Players.end())
995  {
996  UpdatePlayersCountByTeam(team, true); // -1 player
997  m_Players.erase(itr);
998  // check if the player was a participant of the match, or only entered through gm command (goname)
999  participant = true;
1000  }
1001 
1002  BattlegroundScoreMap::iterator itr2 = m_PlayerScores.find(guid);
1003  if (itr2 != m_PlayerScores.end())
1004  {
1005  delete itr2->second; // delete player's score
1006  m_PlayerScores.erase(itr2);
1007  }
1008 
1009  RemovePlayerFromResurrectQueue(guid);
1010 
1011  Player* player = sObjectMgr.GetPlayer(guid);
1012 
1013  if (player)
1014  {
1015  // should remove spirit of redemption
1018 
1020 
1021  if (!player->IsAlive()) // resurrect on exit
1022  {
1023  player->ResurrectPlayer(1.0f);
1024  player->SpawnCorpseBones();
1025  }
1026  } // try to resurrect the offline player. If he is alive, nothing will happen.
1028 
1029  RemovePlayer(player, guid); // BG subclass specific code
1030 
1031  if (participant)
1032  {
1033  if (player)
1034  {
1035  player->ClearAfkReports();
1036 
1037  if (!team) team = player->GetTeam();
1038 
1039  uint32 bgQueueTypeId = sBattlegroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType());
1040  // if arena, remove the specific arena auras
1041  if (isArena())
1042  {
1043  // summon old pet if there was one and there isn't a current pet
1044  if (!player->GetGuardianPet() && player->GetTemporaryUnsummonedPetNumber())
1045  {
1046  Pet* NewPet = new Pet(player);
1047  if (!NewPet->LoadPetFromDB(player, 0, (player)->GetTemporaryUnsummonedPetNumber(), true))
1048  delete NewPet;
1049 
1050  (player)->SetTemporaryUnsummonedPetNumber(0);
1051  }
1052 
1053  if (isRated() && GetStatus() == STATUS_IN_PROGRESS)
1054  {
1055  // left a rated match while the encounter was in progress, consider as loser
1056  ArenaTeam* winner_arena_team = sObjectMgr.GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(team)));
1057  ArenaTeam* loser_arena_team = sObjectMgr.GetArenaTeamById(GetArenaTeamIdForTeam(team));
1058  if (winner_arena_team && loser_arena_team)
1059  loser_arena_team->MemberLost(player, winner_arena_team->GetRating());
1060  }
1061  }
1062 
1063  WorldPacket data;
1064  if (SendPacket)
1065  {
1066  sBattlegroundMgr.BuildBattlegroundStatusPacket(&data, this, team, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_NONE, 0, 0);
1067  player->GetSession()->SendPacket(&data);
1068  }
1069 
1070  // this call is important, because player, when joins to battleground, this method is not called, so it must be called when leaving bg
1071  player->RemoveBattlegroundQueueId(bgQueueTypeId);
1072  }
1073  else
1074  {
1075  if (isRated() && GetStatus() == STATUS_IN_PROGRESS)
1076  {
1077  // left a rated match while the encounter was in progress, consider as loser
1078  ArenaTeam* others_arena_team = sObjectMgr.GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(team)));
1079  ArenaTeam* players_arena_team = sObjectMgr.GetArenaTeamById(GetArenaTeamIdForTeam(team));
1080  if (others_arena_team && players_arena_team)
1081  players_arena_team->OfflineMemberLost(guid, others_arena_team->GetRating());
1082  }
1083  }
1084 
1085  // remove from raid group if player is member
1086  if (Group* group = GetBgRaid(team))
1087  {
1088  if (!group->RemoveMember(guid)) // group was disbanded
1089  {
1090  SetBgRaid(team, NULL);
1091  delete group;
1092  }
1093  }
1094  DecreaseInvitedCount(team);
1095  // we should update battleground queue, but only if bg isn't ending
1096  if (isBattleground() && GetStatus() < STATUS_WAIT_LEAVE)
1097  {
1098  // a player has left the battleground, so there are free slots -> add to queue
1099  AddToBGFreeSlotQueue();
1100  }
1101  // Let others know
1102  WorldPacket data;
1103  sBattlegroundMgr.BuildPlayerLeftBattlegroundPacket(&data, guid);
1104  SendPacketToTeam(team, &data, player, false);
1105  }
1106 
1107  if (player)
1108  {
1109  // Do next only if found in battleground
1110  player->SetBattlegroundId(0); // We're not in BG.
1111  // reset destination bg team
1112  player->SetBGTeam(0);
1113 
1114  if (Transport)
1115  player->TeleportToBGEntryPoint();
1116 
1117  sLog.outDetail("BATTLEGROUND: Removed player %s from Battleground.", player->GetName());
1118  }
1119 
1120  if (!GetPlayersSize() && !GetInvitedCount(HORDE) && !GetInvitedCount(ALLIANCE))
1121  {
1122  // if no players left AND no invitees left, set this bg to delete in next update
1123  // direct deletion could cause crashes
1124  m_SetDeleteThis = true;
1125  // return to prevent addition to freeslotqueue
1126  return;
1127  }
1128 }
1129 
1130 // this method is called when no players remains in battleground
1132 {
1133  SetQueueType(MAX_BATTLEGROUND_QUEUES);
1134  SetWinner(WINNER_NONE);
1135  SetStatus(STATUS_WAIT_QUEUE);
1136  SetStartTime(0);
1137  SetEndTime(0);
1138  SetLastResurrectTime(0);
1139  SetArenaType(0);
1140  SetRated(false);
1141 
1142  m_Events = 0;
1143 
1144  if (m_InvitedAlliance > 0 || m_InvitedHorde > 0)
1145  sLog.outError("Battleground system: bad counter, m_InvitedAlliance: %d, m_InvitedHorde: %d", m_InvitedAlliance, m_InvitedHorde);
1146 
1147  m_InvitedAlliance = 0;
1148  m_InvitedHorde = 0;
1149  m_InBGFreeSlotQueue = false;
1150 
1151  m_Players.clear();
1152 
1153  for (BattlegroundScoreMap::const_iterator itr = m_PlayerScores.begin(); itr != m_PlayerScores.end(); ++itr)
1154  delete itr->second;
1155  m_PlayerScores.clear();
1156 
1157  ResetBGSubclass();
1158 }
1159 
1161 {
1162  SetStartTime(0);
1163  SetLastResurrectTime(0);
1164  if (m_IsRated)
1165  sLog.outArena("Arena match type: %u for Team1Id: %u - Team2Id: %u started.", m_ArenaType, m_ArenaTeamIds[BG_TEAM_ALLIANCE], m_ArenaTeamIds[BG_TEAM_HORDE]);
1166 }
1167 
1169 {
1170  // remove afk from player
1172  plr->ToggleAFK();
1173 
1174  // score struct must be created in inherited class
1175 
1176  uint64 guid = plr->GetGUID();
1177  uint32 team = plr->GetBGTeam();
1178 
1179  BattlegroundPlayer bp;
1180  bp.LastOnlineTime = 0;
1181  bp.Team = team;
1182 
1183  // Add to list/maps
1184  m_Players[guid] = bp;
1185 
1186  UpdatePlayersCountByTeam(team, false); // +1 player
1187 
1188  WorldPacket data;
1189  sBattlegroundMgr.BuildPlayerJoinedBattlegroundPacket(&data, plr);
1190  SendPacketToTeam(team, &data, plr, false);
1191 
1193  plr->CombatStop();
1195 
1196  // add arena specific auras
1197  if (isArena())
1198  {
1200  plr->RemoveArenaAuras();
1202  if (team == ALLIANCE) // gold
1203  {
1204  if (plr->GetTeam() == HORDE)
1205  plr->CastSpell(plr, SPELL_HORDE_GOLD_FLAG, true);
1206  else
1207  plr->CastSpell(plr, SPELL_ALLIANCE_GOLD_FLAG, true);
1208  }
1209  else // green
1210  {
1211  if (plr->GetTeam() == HORDE)
1212  plr->CastSpell(plr, SPELL_HORDE_GREEN_FLAG, true);
1213  else
1214  plr->CastSpell(plr, SPELL_ALLIANCE_GREEN_FLAG, true);
1215  }
1216 
1217  plr->DestroyConjuredItems(true);
1218 
1219  Pet* pet = plr->GetPet();
1220  if (pet)
1221  {
1222  if (pet->getPetType() == SUMMON_PET || pet->getPetType() == HUNTER_PET)
1223  {
1224  (plr)->SetTemporaryUnsummonedPetNumber(pet->GetCharmInfo()->GetPetNumber());
1225  (plr)->SetOldPetSpell(pet->GetUInt32Value(UNIT_CREATED_BY_SPELL));
1226  }
1227  (plr)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT);
1228  }
1229  else
1230  (plr)->SetTemporaryUnsummonedPetNumber(0);
1231 
1232  if (GetStatus() == STATUS_WAIT_JOIN) // not started yet
1233  {
1234  plr->CastSpell(plr, SPELL_ARENA_PREPARATION, true);
1235  plr->ResetAllPowers();
1236  }
1237  }
1238  else
1239  {
1240  if (GetStatus() == STATUS_WAIT_JOIN) // not started yet
1241  plr->CastSpell(plr, SPELL_PREPARATION, true); // reduces all mana cost of spells.
1242  }
1243 
1244  // Log
1245  sLog.outDetail("BATTLEGROUND: Player %s joined the battle.", plr->GetName());
1246 }
1247 
1248 // This method should be called when player logs out from running battleground
1250 {
1251  if (GetStatus() == STATUS_IN_PROGRESS)
1252  {
1253  if (isBattleground())
1254  EventPlayerDroppedFlag(player);
1255  }
1256 
1257  if (isArena())
1258  player->LeaveBattleground();
1259 }
1260 
1261 /* This method should be called only once ... it adds pointer to queue */
1263 {
1264  // make sure to add only once
1265  if (!m_InBGFreeSlotQueue)
1266  {
1267  sBattlegroundMgr.BGFreeSlotQueue[m_TypeID].push_front(this);
1268  m_InBGFreeSlotQueue = true;
1269  }
1270 }
1271 
1272 /* This method removes this battleground from free queue - it must be called when deleting battleground - not used now*/
1274 {
1275  // set to be able to re-add if needed
1276  m_InBGFreeSlotQueue = false;
1277  // uncomment this code when battlegrounds will work like instances
1278  for (std::list<Battleground*>::iterator itr = sBattlegroundMgr.BGFreeSlotQueue[m_TypeID].begin(); itr != sBattlegroundMgr.BGFreeSlotQueue[m_TypeID].end(); ++itr)
1279  {
1280  if ((*itr)->GetInstanceID() == m_InstanceID)
1281  {
1282  sBattlegroundMgr.BGFreeSlotQueue[m_TypeID].erase(itr);
1283  return;
1284  }
1285  }
1286 }
1287 
1288 // get the number of free slots for team
1289 // works in similar way that HasFreeSlotsForTeam did, but this is needed for join as group
1291 {
1292  //if BG is starting ... invite anyone
1293  if (GetStatus() == STATUS_WAIT_JOIN)
1294  return (GetInvitedCount(Team) < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - GetInvitedCount(Team) : 0;
1295  //if BG is already started .. do not allow to join too much players of one faction
1296  uint32 otherTeam;
1297  uint32 otherIn;
1298  if (Team == ALLIANCE)
1299  {
1300  otherTeam = GetInvitedCount(HORDE);
1301  otherIn = GetPlayersCountByTeam(HORDE);
1302  }
1303  else
1304  {
1305  otherTeam = GetInvitedCount(ALLIANCE);
1306  otherIn = GetPlayersCountByTeam(ALLIANCE);
1307  }
1308  if (GetStatus() == STATUS_IN_PROGRESS)
1309  {
1310  // difference based on ppl invited (not necessarily entered battle)
1311  // default: allow 0
1312  uint32 diff = 0;
1313  // allow join one person if the sides are equal (to fill up bg to minplayersperteam)
1314  if (otherTeam == GetInvitedCount(Team))
1315  diff = 1;
1316  // allow join more ppl if the other side has more players
1317  else if (otherTeam > GetInvitedCount(Team))
1318  diff = otherTeam - GetInvitedCount(Team);
1319 
1320  // difference based on max players per team (don't allow inviting more)
1321  uint32 diff2 = (GetInvitedCount(Team) < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - GetInvitedCount(Team) : 0;
1322 
1323  // difference based on players who already entered
1324  // default: allow 0
1325  uint32 diff3 = 0;
1326  // allow join one person if the sides are equal (to fill up bg minplayersperteam)
1327  if (otherIn == GetPlayersCountByTeam(Team))
1328  diff3 = 1;
1329  // allow join more ppl if the other side has more players
1330  else if (otherIn > GetPlayersCountByTeam(Team))
1331  diff3 = otherIn - GetPlayersCountByTeam(Team);
1332  // or other side has less than minPlayersPerTeam
1333  else if (GetInvitedCount(Team) <= GetMinPlayersPerTeam())
1334  diff3 = GetMinPlayersPerTeam() - GetInvitedCount(Team) + 1;
1335 
1336  // return the minimum of the 3 differences
1337 
1338  // min of diff and diff 2
1339  diff = diff < diff2 ? diff : diff2;
1340 
1341  // min of diff, diff2 and diff3
1342  return diff < diff3 ? diff : diff3 ;
1343  }
1344 
1345  return 0;
1346 }
1347 
1349 {
1350  return GetPlayersSize() < GetMaxPlayers();
1351 }
1352 
1354 {
1355  //this procedure is called from virtual function implemented in bg subclass
1356  BattlegroundScoreMap::const_iterator itr = m_PlayerScores.find(Source->GetGUID());
1357 
1358  if (itr == m_PlayerScores.end()) // player not found...
1359  return;
1360 
1361  switch (type)
1362  {
1363  case SCORE_KILLING_BLOWS: // Killing blows
1364  itr->second->KillingBlows += value;
1365  break;
1366  case SCORE_DEATHS: // Deaths
1367  itr->second->Deaths += value;
1368  break;
1369  case SCORE_HONORABLE_KILLS: // Honorable kills
1370  itr->second->HonorableKills += value;
1371  break;
1372  case SCORE_BONUS_HONOR: // Honor bonus
1373  // do not add honor in arenas
1374  if (isBattleground())
1375  {
1376  // reward honor instantly
1377  if (Source->RewardHonor(NULL, 1, value))
1378  itr->second->BonusHonor += value;
1379  }
1380  break;
1381  //used only in EY, but in MSG_PVP_LOG_DATA opcode
1382  case SCORE_DAMAGE_DONE: // Damage Done
1383  itr->second->DamageDone += value;
1384  break;
1385  case SCORE_HEALING_DONE: // Healing Done
1386  itr->second->HealingDone += value;
1387  break;
1388  default:
1389  sLog.outError("Battleground: Unknown player score type %u", type);
1390  break;
1391  }
1392 }
1393 
1395 {
1396  m_ReviveQueue[npc_guid].push_back(player_guid);
1397 
1398  Player* plr = sObjectMgr.GetPlayer(player_guid);
1399  if (!plr)
1400  return;
1401 
1402  plr->CastSpell(plr, SPELL_WAITING_FOR_RESURRECT, true);
1403  SpellEntry const* spellInfo = sSpellStore.LookupEntry(SPELL_WAITING_FOR_RESURRECT);
1404  if (spellInfo)
1405  {
1406  Aura* Aur = CreateAura(spellInfo, 0, NULL, plr);
1407  plr->AddAura(Aur);
1408  }
1409 }
1410 
1412 {
1413  for (std::map<uint64, std::vector<uint64> >::iterator itr = m_ReviveQueue.begin(); itr != m_ReviveQueue.end(); ++itr)
1414  {
1415  for (std::vector<uint64>::iterator itr2 = (itr->second).begin(); itr2 != (itr->second).end(); ++itr2)
1416  {
1417  if (*itr2 == player_guid)
1418  {
1419  (itr->second).erase(itr2);
1420 
1421  Player* plr = sObjectMgr.GetPlayer(player_guid);
1422  if (!plr)
1423  return;
1424 
1426 
1427  return;
1428  }
1429  }
1430  }
1431 }
1432 
1433 bool Battleground::AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 /*respawnTime*/)
1434 {
1435  Map* map = GetBgMap();
1436  if (!map)
1437  return false;
1438 
1439  // must be created this way, adding to godatamap would add it to the base map of the instance
1440  // and when loading it (in go::LoadFromDB()), a new guid would be assigned to the object, and a new object would be created
1441  // so we must create it specific for this instance
1442  GameObject* go = new GameObject;
1443  if (!go->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), entry, map, x, y, z, o, rotation0, rotation1, rotation2, rotation3, 100, GO_STATE_READY))
1444  {
1445  sLog.outErrorDb("Gameobject template %u not found in database! Battleground not created!", entry);
1446  sLog.outError("Cannot create gameobject template %u! Battleground not created!", entry);
1447  delete go;
1448  return false;
1449  }
1450  /*
1451  uint32 guid = go->GetGUIDLow();
1452 
1453  // without this, UseButtonOrDoor caused the crash, since it tried to get go info from godata
1454  // iirc that was changed, so adding to go data map is no longer required if that was the only function using godata from GameObject without checking if it existed
1455  GameObjectData& data = sObjectMgr.NewGOData(guid);
1456 
1457  data.id = entry;
1458  data.mapid = GetMapId();
1459  data.posX = x;
1460  data.posY = y;
1461  data.posZ = z;
1462  data.orientation = o;
1463  data.rotation0 = rotation0;
1464  data.rotation1 = rotation1;
1465  data.rotation2 = rotation2;
1466  data.rotation3 = rotation3;
1467  data.spawntimesecs = respawnTime;
1468  data.spawnMask = 1;
1469  data.animprogress = 100;
1470  data.go_state = 1;
1471  */
1472  // add to world, so it can be later looked up from HashMapHolder
1473  if (!map->AddToMap(go))
1474  {
1475  delete go;
1476  return false;
1477  }
1478  m_BgObjects[type] = go->GetGUID();
1479  return true;
1480 }
1481 
1482 //some doors aren't despawned so we cannot handle their closing in gameobject::update()
1483 //it would be nice to correctly implement GO_ACTIVATED state and open/close doors in gameobject code
1485 {
1486  GameObject* obj = GetBgMap()->GetGameObject(m_BgObjects[type]);
1487  if (obj)
1488  {
1489  //if doors are open, close it
1490  if (obj->getLootState() == GO_ACTIVATED && obj->GetGoState() != GO_STATE_READY)
1491  {
1492  //change state to allow door to be closed
1493  obj->SetLootState(GO_READY);
1495  }
1496  }
1497  else
1498  sLog.outError("Battleground: Door object not found (cannot close doors)");
1499 }
1500 
1502 {
1503  GameObject* obj = GetBgMap()->GetGameObject(m_BgObjects[type]);
1504  if (obj)
1505  {
1506  //change state to be sure they will be opened
1507  obj->SetLootState(GO_READY);
1509  }
1510  else
1511  sLog.outError("Battleground: Door object not found! - doors will be closed.");
1512 }
1513 
1515 {
1516  GameObject* obj = GetBgMap()->GetGameObject(m_BgObjects[type]);
1517  if (!obj)
1518  sLog.outError("couldn't get gameobject %i", type);
1519  return obj;
1520 }
1521 
1523 {
1524  Creature* creature = GetBgMap()->GetCreature(m_BgCreatures[type]);
1525  if (!creature)
1526  sLog.outError("couldn't get creature %i", type);
1527  return creature;
1528 }
1529 
1531 {
1532  Map* map = GetBgMap();
1533  if (!map)
1534  return;
1535  if (respawntime == 0)
1536  {
1537  GameObject* obj = map->GetGameObject(m_BgObjects[type]);
1538  if (obj)
1539  {
1540  //we need to change state from GO_JUST_DEACTIVATED to GO_READY in case battleground is starting again
1541  if (obj->getLootState() == GO_JUST_DEACTIVATED)
1542  obj->SetLootState(GO_READY);
1543  obj->SetRespawnTime(0);
1544  map->AddToMap(obj);
1545  }
1546  }
1547  else
1548  {
1549  GameObject* obj = map->GetGameObject(m_BgObjects[type]);
1550  if (obj)
1551  {
1552  map->AddToMap(obj);
1553  obj->SetRespawnTime(respawntime);
1555  }
1556  }
1557 }
1558 
1559 Creature* Battleground::AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o, uint32 /*respawntime*/)
1560 {
1561  Map* map = GetBgMap();
1562  if (!map)
1563  return NULL;
1564 
1565  Creature* creature = new Creature;
1566  if (!creature->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_UNIT), map, entry, teamval, x, y, z, o))
1567  {
1568  sLog.outError("Can't create creature entry: %u", entry);
1569  delete creature;
1570  return NULL;
1571  }
1572 
1573  creature->SetHomePosition(x, y, z, o);
1574 
1575  //creature->SetDungeonDifficulty(0);
1576 
1577  if (!map->AddToMap(creature))
1578  {
1579  delete creature;
1580  return NULL;
1581  }
1582 
1583  m_BgCreatures[type] = creature->GetGUID();
1584 
1585  return creature;
1586 }
1587 /*
1588 void Battleground::SpawnBGCreature(uint32 type, uint32 respawntime)
1589 {
1590  Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceId());
1591  if (!map)
1592  return false;
1593 
1594  if (respawntime == 0)
1595  {
1596  Creature* obj = HashMapHolder<Creature>::Find(m_BgCreatures[type]);
1597  if (obj)
1598  {
1599  //obj->Respawn(); // bugged
1600  obj->SetRespawnTime(0);
1601  sObjectMgr.SaveCreatureRespawnTime(obj->GetGUIDLow(), GetInstanceID(), 0);
1602  map->Add(obj);
1603  }
1604  }
1605  else
1606  {
1607  Creature* obj = HashMapHolder<Creature>::Find(m_BgCreatures[type]);
1608  if (obj)
1609  {
1610  obj->setDeathState(DEAD);
1611  obj->SetRespawnTime(respawntime);
1612  map->Add(obj);
1613  }
1614  }
1615 }
1616 */
1618 {
1619  if (!m_BgCreatures[type])
1620  return true;
1621 
1622  Creature* cr = GetBgMap()->GetCreature(m_BgCreatures[type]);
1623  if (!cr)
1624  {
1625  sLog.outError("Can't find creature guid: %u", GUID_LOPART(m_BgCreatures[type]));
1626  return false;
1627  }
1628  //@todo only delete creature after not in combat
1629  cr->AddObjectToRemoveList();
1630  m_BgCreatures[type] = 0;
1631  return true;
1632 }
1633 
1635 {
1636  if (!m_BgObjects[type])
1637  return true;
1638 
1639  GameObject* obj = GetBgMap()->GetGameObject(m_BgObjects[type]);
1640  if (!obj)
1641  {
1642  sLog.outError("Can't find gobject guid: %u", GUID_LOPART(m_BgObjects[type]));
1643  return false;
1644  }
1645 
1646  obj->SetRespawnTime(0); // not save respawn time
1647  obj->Delete();
1648  m_BgObjects[type] = 0;
1649  return true;
1650 }
1651 
1652 bool Battleground::AddSpiritGuide(uint32 type, float x, float y, float z, float o, uint32 team)
1653 {
1654  uint32 entry = 0;
1655 
1656  if (team == ALLIANCE)
1657  entry = 13116;
1658  else
1659  entry = 13117;
1660 
1661  Creature* pCreature = AddCreature(entry, type, team, x, y, z, o);
1662  if (!pCreature)
1663  {
1664  sLog.outError("Can't create Spirit guide. Battleground not created!");
1665  EndNow();
1666  return false;
1667  }
1668 
1669  pCreature->setDeathState(DEAD);
1670 
1671  pCreature->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, pCreature->GetGUID());
1672  // aura
1674  pCreature->SetUInt32Value(UNIT_FIELD_AURAFLAGS, 0x00000009);
1675  pCreature->SetUInt32Value(UNIT_FIELD_AURALEVELS, 0x0000003C);
1676  pCreature->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS, 0x000000FF);
1677  // casting visual effect
1679  // correct cast speed
1680  pCreature->SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f);
1681 
1682  //pCreature->CastSpell(pCreature, SPELL_SPIRIT_HEAL_CHANNEL, true);
1683 
1684  return true;
1685 }
1686 
1687 void Battleground::SendMessageToAll(int32 entry, ChatMsg type, Player const* source)
1688 {
1689  Oregon::BattlegroundChatBuilder bg_builder(type, entry, source);
1691  BroadcastWorker(bg_do);
1692 }
1693 
1694 void Battleground::PSendMessageToAll(int32 entry, ChatMsg type, Player const* source, ...)
1695 {
1696  va_list ap;
1697  va_start(ap, source);
1698 
1699  Oregon::BattlegroundChatBuilder bg_builder(type, entry, source, &ap);
1701  BroadcastWorker(bg_do);
1702 
1703  va_end(ap);
1704 }
1705 
1706 void Battleground::SendMessage2ToAll(int32 entry, ChatMsg type, Player const* source, int32 arg1, int32 arg2)
1707 {
1708  Oregon::Battleground2ChatBuilder bg_builder(type, entry, source, arg1, arg2);
1710  BroadcastWorker(bg_do);
1711 }
1712 
1714 {
1715  RemoveFromBGFreeSlotQueue();
1716  SetStatus(STATUS_WAIT_LEAVE);
1717  SetEndTime(TIME_TO_AUTOREMOVE);
1718  // inform invited players about the removal
1719  sBattlegroundMgr.m_BattlegroundQueues[sBattlegroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this);
1720 }
1721 
1722 // Battleground messages are localized using the dbc lang, they are not client language dependent
1724 {
1725  // FIXME: now we have different DBC locales and need localized message for each target client
1726  return sObjectMgr.GetOregonStringForDBCLocale(entry);
1727 }
1728 
1729 /*
1730 important notice:
1731 buffs aren't spawned/despawned when players captures anything
1732 buffs are in their positions when battleground starts
1733 */
1735 {
1736  GameObject* obj = GetBgMap()->GetGameObject(go_guid);
1737  if (!obj || obj->GetGoType() != GAMEOBJECT_TYPE_TRAP || !obj->isSpawned())
1738  return;
1739 
1740  //change buff type, when buff is used:
1741  int32 index = m_BgObjects.size() - 1;
1742  while (index >= 0 && m_BgObjects[index] != go_guid)
1743  index--;
1744  if (index < 0)
1745  {
1746  sLog.outError("Battleground (Type: %u) has buff gameobject (Guid: %u Entry: %u Type:%u) but it hasn't that object in its internal data", GetTypeID(), GUID_LOPART(go_guid), obj->GetEntry(), obj->GetGoType());
1747  return;
1748  }
1749 
1750  //randomly select new buff
1751  uint8 buff = urand(0, 2);
1752  uint32 entry = obj->GetEntry();
1753  if (m_BuffChange && entry != Buff_Entries[buff])
1754  {
1755  //despawn current buff
1756  SpawnBGObject(index, RESPAWN_ONE_DAY);
1757  //set index for new one
1758  for (uint8 currBuffTypeIndex = 0; currBuffTypeIndex < 3; ++currBuffTypeIndex)
1759  if (entry == Buff_Entries[currBuffTypeIndex])
1760  {
1761  index -= currBuffTypeIndex;
1762  index += buff;
1763  }
1764  }
1765 
1766  SpawnBGObject(index, BUFF_RESPAWN_TIME);
1767 }
1768 
1770 {
1771  // Keep in mind that for arena this will have to be changed a bit
1772 
1773  // Add +1 deaths
1774  UpdatePlayerScore(victim, SCORE_DEATHS, 1);
1775 
1776  // Add +1 kills to group and +1 killing_blows to killer
1777  if (killer)
1778  {
1779  // Don't reward credit for killing ourselves, like fall damage of hellfire (warlock)
1780  if (killer == victim)
1781  return;
1782 
1783  UpdatePlayerScore(killer, SCORE_HONORABLE_KILLS, 1);
1784  UpdatePlayerScore(killer, SCORE_KILLING_BLOWS, 1);
1785 
1786  for (std::map<uint64, BattlegroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
1787  {
1788  Player* creditedPlayer = sObjectMgr.GetPlayer(itr->first);
1789  if (!creditedPlayer || creditedPlayer == killer)
1790  continue;
1791 
1792  if (creditedPlayer->GetTeam() == killer->GetTeam() && creditedPlayer->IsAtGroupRewardDistance(victim))
1793  UpdatePlayerScore(creditedPlayer, SCORE_HONORABLE_KILLS, 1);
1794  }
1795  }
1796 
1797  // To be able to remove insignia -- ONLY IN Battlegrounds
1798  if (!isArena())
1800 }
1801 
1802 // return the player's team based on battlegroundplayer info
1803 // used in same faction arena matches mainly
1805 {
1806  std::map<uint64, BattlegroundPlayer>::const_iterator itr = m_Players.find(guid);
1807  if (itr != m_Players.end())
1808  return itr->second.Team;
1809  return 0;
1810 }
1811 
1813 {
1814  return (teamId) ? ((teamId == ALLIANCE) ? HORDE : ALLIANCE) : 0;
1815 }
1816 
1818 {
1819  std::map<uint64, BattlegroundPlayer>::const_iterator itr = m_Players.find(guid);
1820  if (itr != m_Players.end())
1821  return true;
1822  return false;
1823 }
1824 
1826 {
1827  if (GetStatus() != STATUS_WAIT_LEAVE)
1828  return;
1829 
1830  Player* plr = sObjectMgr.GetPlayer(guid);
1831  if (!plr)
1832  {
1833  sLog.outError("Battleground: Player (GUID: %u) not found!", GUID_LOPART(guid));
1834  return;
1835  }
1836 
1837  WorldPacket data;
1838  uint32 bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
1839 
1840  BlockMovement(plr);
1841 
1842  sBattlegroundMgr.BuildPvpLogDataPacket(&data, this);
1843  plr->GetSession()->SendPacket(&data);
1844 
1845  sBattlegroundMgr.BuildBattlegroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime());
1846  plr->GetSession()->SendPacket(&data);
1847 }
1848 
1850 {
1851  int count = 0;
1852  for (std::map<uint64, BattlegroundPlayer>::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
1853  {
1854  if (itr->second.Team == Team)
1855  {
1856  Player* pl = sObjectMgr.GetPlayer(itr->first);
1857  if (pl && pl->IsAlive() && !pl->HasByteFlag(UNIT_FIELD_BYTES_2, 3, FORM_SPIRITOFREDEMPTION))
1858  ++count;
1859  }
1860  }
1861  return count;
1862 }
1863 
1864 void Battleground::SetHoliday(bool is_holiday)
1865 {
1866  if (is_holiday)
1867  m_HonorMode = BG_HOLIDAY;
1868  else
1869  m_HonorMode = BG_NORMAL;
1870 }
1871 
1873 {
1874  for (uint32 i = 0; i < m_BgObjects.size(); ++i)
1875  if (m_BgObjects[i] == guid)
1876  return i;
1877  sLog.outError("Battleground: cheating? a player used a gameobject which isnt supposed to be a usable object!");
1878  return -1;
1879 }
1880 
1881 void Battleground::HandleKillUnit(Creature* /*creature*/, Player* /*killer*/)
1882 {
1883 }
1884 
1886 {
1887  if (!GetAlivePlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
1888  EndBattleground(HORDE);
1889  else if (GetPlayersCountByTeam(ALLIANCE) && !GetAlivePlayersCountByTeam(HORDE))
1890  EndBattleground(ALLIANCE);
1891 }
1892 
1894 {
1895  return sObjectMgr.GetClosestGraveYard(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), player->GetTeam());
1896 }
1897 
1899 {
1900  //send world message
1902  {
1903  uint32 queue_id = 0;
1904 
1905  for (std::map<uint64, BattlegroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
1906  if (Player* plr = sObjectMgr.GetPlayer(itr->first))
1907  queue_id = plr->GetBattlegroundQueueIdFromLevel();
1908 
1909  char const* bgName = GetName();
1910 
1911  uint32 q_min_level = Player::GetMinLevelForBattlegroundQueueId(queue_id);
1912  uint32 q_max_level = Player::GetMaxLevelForBattlegroundQueueId(queue_id);
1913 
1914  // replace hardcoded max level by player max level for nice output
1915  if (q_max_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
1916  q_max_level = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL);
1917 
1918  sWorld.SendWorldText(LANG_BG_QUEUE_ANNOUNCE_START, bgName, q_min_level, q_max_level);
1919  }
1920 }
1921 
1923 {
1924  float maxDist = GetStartMaxDist();
1925  if (!maxDist)
1926  return;
1927 
1928  m_ValidStartPositionTimer += diff;
1929  if (m_ValidStartPositionTimer >= CHECK_PLAYER_POSITION_INVERVAL)
1930  {
1931  m_ValidStartPositionTimer = 0;
1932 
1933  Position pos;
1934  float x, y, z, o;
1935  for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
1936  if (Player* player = ObjectAccessor::FindPlayer(itr->first))
1937  {
1938  pos = player->GetPosition();
1939  GetTeamStartLoc(player->GetBGTeam(), x, y, z, o);
1940  if (!pos.IsInDist2d(x, y, maxDist))
1941  {
1942  sLog.outDebug("BATTLEGROUND: Sending %s back to start location (map: %u) (possible exploit)", player->GetName(), GetMapId());
1943  player->TeleportTo(GetMapId(), x, y, z, o);
1944  }
1945  }
1946  }
1947 }
void OfflineMemberLost(uint64 guid, uint32 againstRating)
Definition: ArenaTeam.cpp:627
bool AddToMap(T *)
Definition: Map.cpp:424
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)
#define snprintf
Definition: Common.h:129
Definition: Unit.h:416
const uint32 & GetUInt32Value(uint16 index) const
Definition: Object.h:228
int32 GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
Definition: Unit.cpp:3727
virtual void HandleKillPlayer(Player *player, Player *killer)
void PSendMessageToAll(int32 entry, ChatMsg type, Player const *source,...)
uint32 GetFreeSlotsForTeam(uint32 Team) const
Guardian * GetGuardianPet() const
Definition: Unit.cpp:7600
void SetHoliday(bool is_holiday)
#define GUID_LOPART(x)
Definition: ObjectGuid.h:110
void RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID)
uint32 GetMaxHealth() const
Definition: Unit.h:1052
void CheckArenaWinConditions()
GOState GetGoState() const
Definition: GameObject.h:726
LootState getLootState() const
Definition: GameObject.h:746
Map * GetMap() const
Definition: Object.h:829
DatabaseType WorldDatabase
Accessor to the world database.
Definition: Main.cpp:53
virtual WorldSafeLocsEntry const * GetClosestGraveYard(Player *player)
uint32 GetTemporaryUnsummonedPetNumber() const
Definition: Player.h:2501
void RemovePlayerFromResurrectQueue(uint64 player_guid)
#define MAX_BATTLEGROUND_QUEUES
void RewardQuest(Player *plr)
int32 GetTotalAuraModifier(AuraType auratype) const
Definition: Unit.cpp:3615
void SendPacketToTeam(uint32 TeamID, WorldPacket *packet, Player *sender=NULL, bool self=true)
void MemberLost(Player *plr, uint32 againstRating)
Definition: ArenaTeam.cpp:605
void SendMessage2ToAll(int32 entry, ChatMsg type, Player const *source, int32 strId1=0, int32 strId2=0)
Definition: Field.h:24
uint32 rating
Definition: ArenaTeam.h:103
void SetBGTeam(uint32 team)
Definition: Player.h:2312
void _CheckSafePositions(uint32 diff)
bool IsPvP() const
Definition: Unit.h:1140
void YellToAll(Creature *creature, const char *text, uint32 language)
void RemoveSpellsCausingAura(AuraType auraType)
Definition: Unit.cpp:648
bool HasByteFlag(uint16 index, uint8 offset, uint8 flag) const
Definition: Object.h:316
void CombatStopWithPets(bool cast=false)
Definition: Unit.cpp:7459
#define sLog
Log class singleton.
Definition: Log.h:187
ChatMsg
void UpdatePvP(bool state, bool override=false)
Definition: Player.cpp:18356
virtual void RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket)
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:779
ACE_INT32 int32
Definition: Define.h:67
bool IsPlayerInBattleground(uint64 guid)
void SetHomePosition(float x, float y, float z, float o)
Definition: Creature.h:794
uint32 GetBGTeam() const
Definition: Player.h:2316
void SpawnBGObject(uint32 type, uint32 respawntime)
bool TeleportToBGEntryPoint()
Definition: Player.cpp:1831
uint32 GetPlayerTeam(uint64 guid)
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false)
Definition: Player.cpp:12144
bool IsAtGroupRewardDistance(WorldObject const *pRewardSource) const
Definition: Player.cpp:19908
bool DelObject(uint32 type)
void SetRespawnTime(int32 respawn)
Definition: GameObject.h:691
Definition: Pet.h:28
int32 LostAgainst(uint32 againstRating)
Definition: ArenaTeam.cpp:591
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0)
Definition: Player.cpp:10277
void UpdateWorldState(uint32 Field, uint32 Value)
void SpawnCorpseBones()
Definition: Player.cpp:4380
virtual ~Battleground()
void AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:13382
Aura * CreateAura(SpellEntry const *spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item *castItem)
Definition: SpellAuras.cpp:502
void SetFlag(uint16 index, uint32 newFlag)
Definition: Object.cpp:985
#define sObjectMgr
Definition: ObjectMgr.h:1285
void SendPacket(WorldPacket const *packet)
static GameObject * GetGameObject(WorldObject &object, uint64 guid)
Definition: GameObject.cpp:738
Creature * AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o, uint32 respawntime=0)
CharmInfo * GetCharmInfo()
Definition: Unit.h:1567
bool AddSpiritGuide(uint32 type, float x, float y, float z, float o, uint32 team)
static uint32 GetMinLevelForBattlegroundQueueId(uint32 queue_id)
Definition: Player.cpp:19416
bool Create(uint32 guidlow, uint32 name_id, Map *map, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state, uint32 ArtKit=0)
Definition: GameObject.cpp:166
uint32 GetAlivePlayersCountByTeam(uint32 Team) const
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
virtual void AddPlayer(Player *plr)
void RemoveArenaSpellCooldowns()
Definition: Player.cpp:3375
const ArenaTeamStats & GetStats() const
Definition: ArenaTeam.h:145
void DestroyConjuredItems(bool update)
Definition: Player.cpp:10960
uint8 CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=NULL) const
Definition: Player.h:1147
void RemoveAurasDueToSpell(uint32 spellId, Aura *except=NULL)
Definition: Unit.cpp:4316
Aura * GetDummyAura(uint32 spell_id) const
Definition: Unit.cpp:12210
uint32 GetRating() const
Definition: ArenaTeam.h:150
Definition: Common.h:179
void SetLootState(LootState s, Unit *unit=NULL)
uint32 GetOtherTeam(uint32 teamId)
void PlayerRelogin(uint64 guid)
Definition: Pet.h:27
Team
uint32 GetBattlemasterEntry() const
Creature * GetCreature(uint64 guid)
Definition: Map.cpp:2632
ACE_UINT8 uint8
Definition: Define.h:73
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:1080
void setDeathState(DeathState s) override
Definition: Creature.cpp:1558
#define UI64FMTD
Definition: Common.h:149
void PlaySoundToAll(uint32 SoundID)
void operator()(WorldPacket &data, int32 loc_idx)
Definition: Unit.h:297
void NotifyStatsChanged()
Definition: ArenaTeam.cpp:387
const bool & IsInWorld() const
Definition: Object.h:129
void SendPacketToAll(WorldPacket *packet)
uint32 GetBattlegroundQueueIndex(uint32 bgQueueType) const
Definition: Player.h:2234
HostileRefManager & getHostileRefManager()
Definition: Unit.h:1842
void CastSpellOnTeam(uint32 SpellID, uint32 TeamID)
void LeaveBattleground(bool teleportToEntryPoint=true)
Definition: Player.cpp:18607
void AddObjectToRemoveList()
Definition: Object.cpp:1987
uint32 GetPetNumber() const
Definition: Unit.h:779
void EventPlayerLoggedOut(Player *player)
BattlegroundChatBuilder(ChatMsg msgtype, int32 textId, Player const *source, va_list *args=NULL)
uint32 GetId() const
Definition: ArenaTeam.h:124
bool IsAlive() const
Definition: Unit.h:1433
void RemoveAurasByType(AuraType auraType, uint64 casterGUID=0, Aura *except=NULL, bool negative=true, bool positive=true)
Definition: Unit.cpp:4340
float GetPositionY() const
Definition: Position.h:98
void operator()(WorldPacket &data, int32 loc_idx)
#define MAKE_NEW_GUID(l, e, h)
Definition: ObjectGuid.h:80
uint8 GetChatTag() const
Definition: Player.cpp:1542
Definition: Item.h:196
void CastSpell(Unit *Victim, uint32 spellId, bool triggered, Item *castItem=NULL, Aura *triggeredByAura=NULL, uint64 originalCaster=0)
Definition: Unit.cpp:1174
static Item * CreateItem(uint32 item, uint32 count, Player const *player=NULL)
Definition: Item.cpp:936
void GetPosition(float &x, float &y) const
Definition: Position.h:102
static Player * FindPlayer(uint64, bool force=false)
etc mysql my cnf *Then change max_allowed_packet to a bigger value
float GetPositionZ() const
Definition: Position.h:99
void do_helper(WorldPacket &data, char const *text)
void CombatStop(bool cast=false)
Definition: Unit.cpp:7442
virtual void UpdatePlayerScore(Player *Source, uint32 type, uint32 value)
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition: Player.cpp:4209
void ResetAllPowers()
Definition: Player.cpp:2154
uint32 GetMapId() const
Definition: Object.h:585
void SendMailTo(MailReceiver const &receiver, MailSender const &sender, MailCheckMask checked=MAIL_CHECK_MASK_NONE, uint32 deliver_delay=0)
Definition: Mail.cpp:978
static uint32 BGQueueTypeId(uint32 bgTypeId, uint8 arenaType)
void RemoveFromBGFreeSlotQueue()
bool PExecute(const char *format,...) ATTR_PRINTF(2
Definition: Database.cpp:441
const char * GetOregonString(int32 entry) const
Definition: Map.h:266
void AddToBGFreeSlotQueue()
void SetUInt64Value(uint16 index, const uint64 &value)
Definition: Object.cpp:798
void SaveToDB()
Definition: ArenaTeam.cpp:702
void RewardHonorToTeam(uint32 Honor, uint32 TeamID)
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=NULL)
Definition: GameObject.cpp:950
void BroadcastWorker(Do &_do)
void SetBattlegroundId(uint32 val)
Definition: Player.h:2253
bool IsInDist2d(float x, float y, float dist) const
Definition: Position.h:178
const char * GetName() const
Definition: Object.h:692
ReputationMgr & GetReputationMgr()
Definition: Player.h:2091
std::vector< ItemPosCount > ItemPosCountVec
Definition: Player.h:605
ACE_UINT64 uint64
Definition: Define.h:70
void DoorOpen(uint32 type)
void ClearAfkReports()
Definition: Player.h:2325
MailDraft & AddItem(Item *item)
Definition: Mail.cpp:869
void AddPlayerToResurrectQueue(uint64 npc_guid, uint64 player_guid)
bool RewardHonor(Unit *victim, uint32 groupsize, float honor=-1, bool pvptoken=false)
Definition: Player.cpp:6057
int32 GetObjectType(uint64 guid)
void ToggleAFK()
Definition: Player.cpp:1522
bool isSpawned() const
Definition: GameObject.h:697
bool DelCreature(uint32 type)
GameobjectTypes GetGoType() const
Definition: GameObject.h:718
static uint32 GetMaxLevelForBattlegroundQueueId(uint32 queue_id)
Definition: Player.cpp:19427
void RewardMark(Player *plr, uint32 count)
Battleground2ChatBuilder(ChatMsg msgtype, int32 textId, Player const *source, int32 arg1, int32 arg2)
void HandleTriggerBuff(uint64 const &go_guid)
int GetSessionDbLocaleIndex() const
Definition: WorldSession.h:237
void BuildMonsterChat(WorldPacket *data, uint8 msgtype, char const *text, uint32 language, char const *name, uint64 TargetGuid) const
Definition: Object.cpp:1904
GameObject * GetBGObject(uint32 type)
bool LoadPetFromDB(Player *owner, uint32 petentry=0, uint32 petnumber=0, bool current=false)
Definition: Pet.cpp:131
void RemoveAllEnchantments(EnchantmentSlot slot, bool arena)
Definition: Player.cpp:11738
static Creature * GetCreature(WorldObject &object, uint64 guid)
Definition: Unit.cpp:10602
void SetFloatValue(uint16 index, float value)
Definition: Object.cpp:859
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
T AddPct(T &base, U pct)
Definition: Util.h:109
void MemberWon(Player *plr, uint32 againstRating)
Definition: ArenaTeam.cpp:649
void RemoveArenaAuras()
Definition: Unit.cpp:4531
bool HasFreeSlots() const
#define sBattlegroundMgr
uint32 GetTeam() const
Definition: Player.h:2075
void SetPower(Powers power, uint32 val)
Definition: Unit.cpp:10918
virtual void HandleKillUnit(Creature *, Player *)
void UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player *Source)
BattlegroundMarks
Definition: Battleground.h:48
void StartBattleground()
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:783
void PlaySoundToTeam(uint32 SoundID, uint32 TeamID)
uint32 GetEntry() const
Definition: Object.h:186
WorldSession * GetSession() const
Definition: Player.h:1959
#define sWorld
Definition: World.h:860
void SendRewardMarkByMail(Player *plr, uint32 mark, uint32 count)
DatabaseType CharacterDatabase
Accessor to the character database.
Definition: Main.cpp:54
void BlockMovement(Player *plr)
void SetHealth(uint32 val)
Definition: Unit.cpp:10826
void EndBattleground(uint32 winner)
bool ModifyReputation(FactionEntry const *factionEntry, int32 standing)
void SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O)
void SetClientControl(Unit *target, bool allowMove)
Definition: Player.cpp:19966
bool HasFlag(uint16 index, uint32 flag) const
Definition: Object.h:299
ACE_UINT32 uint32
Definition: Define.h:71
float GetPositionX() const
Definition: Position.h:97
const uint32 Buff_Entries[3]
Definition: Battleground.h:110
Pet * GetPet() const
Definition: Player.cpp:17104
GameObject * GetGameObject(uint64 guid)
Definition: Map.cpp:2638
Creature * GetBGCreature(uint32 type)
int32 WonAgainst(uint32 againstRating)
Definition: ArenaTeam.cpp:575
void RemoveBattlegroundQueueId(uint32 val)
Definition: Player.h:2277
Corpse * ConvertCorpseForPlayer(uint64 player_guid, bool insignia=false)
Definition: Player.h:922
const char * GetOregonString(int32 entry)
#define vsnprintf
Definition: Common.h:131
Definition: Pet.h:146
void DoorClose(uint32 type)
Definition: Group.h:154
PetType getPetType() const
Definition: Pet.h:155
uint32 urand(uint32 min, uint32 max)
Definition: Util.cpp:71
void SendMessageToAll(int32 entry, ChatMsg type, Player const *source=NULL)
void Delete()
Definition: GameObject.cpp:562
const uint64 & GetGUID() const
Definition: Object.h:156
virtual void Update(uint32 diff)
bool Create(uint32 guidlow, Map *map, uint32 Entry, uint32 team, float x, float y, float z, float ang, const CreatureData *data=NULL)
Definition: Creature.cpp:759