OregonCore  revision fb2a440-git
Your Favourite TBC server
BattlegroundAV.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 "Player.h"
19 #include "Battleground.h"
20 #include "BattlegroundAV.h"
21 #include "Creature.h"
22 #include "Object.h"
23 #include "ObjectMgr.h"
24 #include "ObjectAccessor.h"
25 #include "MapManager.h"
26 #include "Language.h"
27 #include "Formulas.h"
28 
30 {
33 
38 }
39 
41 {
42 }
43 
44 uint16 BattlegroundAV::GetBonusHonor(uint8 kills) //@todo move this function to Battleground.cpp (needs to find a way to get m_MaxLevel)
45 {
47 }
48 
50 {
52  return;
53 
54  Battleground::HandleKillPlayer(player, killer);
55  UpdateScore(player->GetTeam(), -1);
56 }
57 
59 {
60  sLog.outDebug("bg_av HandleKillUnit %i", unit->GetEntry());
62  return;
63  uint32 entry = unit->GetEntry();
64  if (entry == BG_AV_CreatureInfo[AV_NPC_A_BOSS][0])
65  {
66  CastSpellOnTeam(23658, HORDE); //this is a spell which finishes a quest where a player has to kill the boss
70  }
71  else if (entry == BG_AV_CreatureInfo[AV_NPC_H_BOSS][0])
72  {
73  CastSpellOnTeam(23658, ALLIANCE); //this is a spell which finishes a quest where a player has to kill the boss
77  }
78  else if (entry == BG_AV_CreatureInfo[AV_NPC_A_CAPTAIN][0])
79  {
80  if (!m_CaptainAlive[0])
81  {
82  sLog.outError("Killed a Captain twice, please report this bug, if you haven't done \".respawn\"");
83  return;
84  }
85  m_CaptainAlive[0] = false;
89  //spawn destroyed aura
90  for (uint8 i = 0; i <= 9; i++)
93  if (creature)
95 
96  }
97  else if (entry == BG_AV_CreatureInfo[AV_NPC_H_CAPTAIN][0])
98  {
99  if (!m_CaptainAlive[1])
100  {
101  sLog.outError("Killed a Captain twice, please report this bug, if you haven't done \".respawn\"");
102  return;
103  }
104  m_CaptainAlive[1] = false;
108  //spawn destroyed aura
109  for (uint8 i = 0; i <= 9; i++)
112  if (creature)
114  }
119 }
120 
122 {
123  if (GetStatus() != STATUS_IN_PROGRESS)
124  return;//maybe we should log this, cause this must be a cheater or a big bug
125  uint8 team = GetTeamIndexByTeamId(player->GetTeam());
126  //TODO add reputation, events (including quest not available anymore, next quest availabe, go/npc de/spawning)and maybe honor
127  sLog.outDebug("BattlegroundAV: Quest %i completed", questid);
128  switch (questid)
129  {
134  m_Team_QuestStatus[team][0] += 20;
135  if (m_Team_QuestStatus[team][0] == 500 || m_Team_QuestStatus[team][0] == 1000 || m_Team_QuestStatus[team][0] == 1500) //25,50,75 turn ins
136  {
137  sLog.outDebug("BattlegroundAV: Quest %i completed starting with unit upgrading..", questid);
139  if (m_Nodes[i].Owner == player->GetTeam() && m_Nodes[i].State == POINT_CONTROLLED)
140  {
141  DePopulateNode(i);
142  PopulateNode(i);
143  //maybe this is bad, because it will instantly respawn all creatures on every grave..
144  }
145  }
146  break;
149  m_Team_QuestStatus[team][1]++;
150  RewardReputationToTeam(team, 1, player->GetTeam());
151  if (m_Team_QuestStatus[team][1] == 30)
152  sLog.outDebug("BattlegroundAV: Quest %i completed (need to implement some events here", questid);
153  break;
156  m_Team_QuestStatus[team][2]++;
157  RewardReputationToTeam(team, 1, player->GetTeam());
158  if (m_Team_QuestStatus[team][2] == 60)
159  sLog.outDebug("BattlegroundAV: Quest %i completed (need to implement some events here", questid);
160  break;
163  m_Team_QuestStatus[team][3]++;
164  RewardReputationToTeam(team, 1, player->GetTeam());
165  if (m_Team_QuestStatus[team][1] == 120)
166  sLog.outDebug("BattlegroundAV: Quest %i completed (need to implement some events here", questid);
167  break;
168  case BG_AV_QUEST_A_BOSS1:
169  case BG_AV_QUEST_H_BOSS1:
170  m_Team_QuestStatus[team][4] += 9; //you can turn in 10 or 1 item..
171  case BG_AV_QUEST_A_BOSS2:
172  case BG_AV_QUEST_H_BOSS2:
173  m_Team_QuestStatus[team][4]++;
174  if (m_Team_QuestStatus[team][4] >= 200)
175  sLog.outDebug("BattlegroundAV: Quest %i completed (need to implement some events here", questid);
176  break;
179  m_Team_QuestStatus[team][5]++;
180  if (m_Team_QuestStatus[team][5] == 28)
181  {
182  sLog.outDebug("BattlegroundAV: Quest %i completed (need to implement some events here", questid);
183  if (m_Team_QuestStatus[team][6] == 7)
184  sLog.outDebug("BattlegroundAV: Quest %i completed (need to implement some events here - ground assault ready", questid);
185  }
186  break;
189  m_Team_QuestStatus[team][6]++;
190  if (m_Team_QuestStatus[team][6] == 7)
191  {
192  sLog.outDebug("BattlegroundAV: Quest %i completed (need to implement some events here", questid);
193  if (m_Team_QuestStatus[team][5] == 20)
194  sLog.outDebug("BattlegroundAV: Quest %i completed (need to implement some events here - ground assault ready", questid);
195  }
196  break;
199  m_Team_QuestStatus[team][7]++;
200  if (m_Team_QuestStatus[team][7] == 25)
201  {
202  sLog.outDebug("BattlegroundAV: Quest %i completed (need to implement some events here", questid);
203  if (m_Team_QuestStatus[team][8] == 25)
204  sLog.outDebug("BattlegroundAV: Quest %i completed (need to implement some events here - rider assault ready", questid);
205  }
206  break;
209  m_Team_QuestStatus[team][8]++;
210  if (m_Team_QuestStatus[team][8] == 25)
211  {
212  sLog.outDebug("BattlegroundAV: Quest %i completed (need to implement some events here", questid);
213  if (m_Team_QuestStatus[team][7] == 25)
214  sLog.outDebug("BattlegroundAV: Quest %i completed (need to implement some events here - rider assault ready", questid);
215  }
216  break;
217  default:
218  sLog.outDebug("BattlegroundAV: Quest %i completed but is not interesting at all", questid);
219  return;
220  break;
221  }
222 }
223 
225 {
226  //note: to remove reinforcementpoints points must be negative, for adding reinforcements points must be positive
227  ASSERT(team == ALLIANCE || team == HORDE);
228  uint8 teamindex = GetTeamIndexByTeamId(team); //0=ally 1=horde
229  m_Team_Scores[teamindex] += points;
230 
231  m_score[teamindex] = m_Team_Scores[teamindex];
232 
234  if (points < 0)
235  {
236  if (m_Team_Scores[teamindex] < 1)
237  {
238  m_Team_Scores[teamindex] = 0;
239  EndBattleground(((teamindex == BG_TEAM_HORDE) ? ALLIANCE : HORDE));
240  }
241  else if (!m_IsInformedNearVictory[teamindex] && m_Team_Scores[teamindex] < BG_AV_SCORE_NEAR_LOSE)
242  {
245  m_IsInformedNearVictory[teamindex] = true;
246  }
247  }
248 }
249 
251 {
252  uint32 level;
253  bool isStatic = false;
254  Creature* creature = NULL;
256  if (type >= AV_CPLACE_MAX) //static
257  {
258  type -= AV_CPLACE_MAX;
259  cinfoid = int(BG_AV_StaticCreaturePos[type][4]);
261  level = (BG_AV_StaticCreatureInfo[cinfoid][2] == BG_AV_StaticCreatureInfo[cinfoid][3]) ? BG_AV_StaticCreatureInfo[cinfoid][2] : urand(BG_AV_StaticCreatureInfo[cinfoid][2], BG_AV_StaticCreatureInfo[cinfoid][3]);
262  isStatic = true;
263  }
264  else
265  {
266  creature = AddCreature(BG_AV_CreatureInfo[cinfoid][0], type, BG_AV_CreatureInfo[cinfoid][1], BG_AV_CreaturePos[type][0], BG_AV_CreaturePos[type][1], BG_AV_CreaturePos[type][2], BG_AV_CreaturePos[type][3]);
267  level = (BG_AV_CreatureInfo[cinfoid][2] == BG_AV_CreatureInfo[cinfoid][3]) ? BG_AV_CreatureInfo[cinfoid][2] : urand(BG_AV_CreatureInfo[cinfoid][2], BG_AV_CreatureInfo[cinfoid][3]);
268  }
269  if (!creature)
270  return NULL;
271  if (creature->GetEntry() == BG_AV_CreatureInfo[AV_NPC_A_CAPTAIN][0] || creature->GetEntry() == BG_AV_CreatureInfo[AV_NPC_H_CAPTAIN][0])
272  creature->SetRespawnDelay(RESPAWN_ONE_DAY); // @todo look if this can be done by database + also add this for the wingcommanders
273 
274  if ((isStatic && cinfoid >= 10 && cinfoid <= 14) || (!isStatic && ((/*cinfoid >= AV_NPC_A_GRAVEDEFENSE0 && */cinfoid <= AV_NPC_A_GRAVEDEFENSE3) ||
275  (cinfoid >= AV_NPC_H_GRAVEDEFENSE0 && cinfoid <= AV_NPC_H_GRAVEDEFENSE3))))
276  {
277  if (!isStatic && ((/*cinfoid >= AV_NPC_A_GRAVEDEFENSE0 &&*/ cinfoid <= AV_NPC_A_GRAVEDEFENSE3)
278  || (cinfoid >= AV_NPC_H_GRAVEDEFENSE0 && cinfoid <= AV_NPC_H_GRAVEDEFENSE3)))
279  {
280  CreatureData& data = sObjectMgr.NewOrExistCreatureData(creature->GetDBTableGUIDLow());
281  data.spawndist = 5;
282  }
283  //else spawndist will be 15, so creatures move maximum=10
284  //creature->SetDefaultMovementType(RANDOM_MOTION_TYPE);
285  creature->GetMotionMaster()->Initialize();
286  creature->setDeathState(JUST_DIED);
287  creature->Respawn();
288  //@todo find a way to add a motionmaster without killing the creature (i
289  //just copied this code from a gm-command
290  }
291 
292  if (level != 0)
293  level += m_MaxLevel - 60; //maybe we can do this more generic for custom level-range.. actually it's blizzlike
294  creature->SetLevel(level);
295  return creature;
296 }
297 
299 {
300  Battleground::Update(diff);
301 
302  if (GetStatus() == STATUS_IN_PROGRESS)
303  {
304  for (uint8 i = 0; i <= 1; i++) //0=alliance, 1=horde
305  {
306  if (!m_CaptainAlive[i])
307  continue;
308  if (m_CaptainBuffTimer[i] > uint32(diff))
309  m_CaptainBuffTimer[i] -= diff;
310  else
311  {
312  if (i == 0)
313  {
315  Creature* creature = GetBGCreature(AV_CPLACE_MAX + 61);
316  if (creature)
318  }
319  else
320  {
322  Creature* creature = GetBGCreature(AV_CPLACE_MAX + 59); //@todo make the captains a dynamic creature
323  if (creature)
325  }
326  m_CaptainBuffTimer[i] = 120000 + urand(0, 4) * 60000; //as far as i could see, the buff is randomly so i make 2minutes (thats the duration of the buff itself) + 0-4minutes TODO get the right times
327  }
328  }
329  //add points from mine owning, and look if he neutral team wanrts to reclaim the mine
330  m_Mine_Timer -= diff;
331  for (uint8 mine = 0; mine < 2; mine++)
332  {
333  if (m_Mine_Owner[mine] == ALLIANCE || m_Mine_Owner[mine] == HORDE)
334  {
335  if (m_Mine_Timer <= 0)
336  UpdateScore(m_Mine_Owner[mine], 1);
337 
338  if (m_Mine_Reclaim_Timer[mine] > uint32(diff))
339  m_Mine_Reclaim_Timer[mine] -= diff;
340  else
342  }
343  }
344  if (m_Mine_Timer <= 0)
345  m_Mine_Timer = BG_AV_MINE_TICK_TIMER; //this is at the end, cause we need to update both mines
346 
347  // looks for all timers of the nodes and destroy the building (for graveyards the building wont get destroyed, it goes just to the other team
349  if (m_Nodes[i].State == POINT_ASSAULTED) //maybe remove this
350  {
351  if (m_Nodes[i].Timer > diff)
352  m_Nodes[i].Timer -= diff;
353  else
355  }
356  }
357 }
358 
360 {
363 }
364 
366 {
367  sLog.outDebug("BG_AV: start spawning mine stuff");
372  for (uint8 mine = BG_AV_NORTH_MINE; mine <= BG_AV_SOUTH_MINE; mine++) //mine population
373  ChangeMineOwner(mine, BG_AV_NEUTRAL_TEAM, true);
374 
377 
380 }
381 
383 {
385  // create score and add it to map, default values are set in constructor
387  m_PlayerScores[plr->GetGUID()] = sc;
388  if (m_MaxLevel == 0)
389  m_MaxLevel = (plr->getLevel() % 10 == 0) ? plr->getLevel() : (plr->getLevel() - (plr->getLevel() % 10)) + 10; //@todo just look at the code \^_^/ --but queue-info should provide this information..
390 
391 }
392 
394 {
395  // calculate bonuskills for both teams:
396  //first towers:
397  uint8 kills[BG_TEAMS_COUNT] = {0, 0}; //0=ally 1=horde
398  uint8 rep[BG_TEAMS_COUNT] = {0, 0}; //0=ally 1=horde
400  {
401  if (m_Nodes[i].State == POINT_CONTROLLED)
402  {
403  if (m_Nodes[i].Owner == ALLIANCE)
404  {
405  rep[0] += BG_AV_REP_SURVIVING_TOWER;
406  kills[0] += BG_AV_KILL_SURVIVING_TOWER;
407  }
408  else
409  {
410  rep[0] += BG_AV_KILL_SURVIVING_TOWER;
411  kills[1] += BG_AV_KILL_SURVIVING_TOWER;
412  }
413  }
414  }
415 
416  for (uint32 i = 0; i < BG_TEAMS_COUNT; i++)
417  {
418  if (m_CaptainAlive[i])
419  {
420  kills[i] += BG_AV_KILL_SURVIVING_CAPTAIN;
421  rep[i] += BG_AV_REP_SURVIVING_CAPTAIN;
422  }
423  if (rep[i] != 0)
424  RewardReputationToTeam((i == 0) ? 730 : 729, rep[i], (i == 0) ? ALLIANCE : HORDE);
425  if (kills[i] != 0)
426  RewardHonorToTeam(GetBonusHonor(kills[i]), (i == 0) ? ALLIANCE : HORDE);
427  }
428 
429  //TODO add enterevademode for all attacking creatures
431 }
432 
434 {
435  if (!plr)
436  {
437  sLog.outError("bg_AV no player at remove");
438  return;
439  }
440  //TODO search more buffs
444 }
445 
447 {
448  // this is wrong way to implement these things. On official it done by gameobject spell cast.
449  if (GetStatus() != STATUS_IN_PROGRESS)
450  return;
451 
452  uint32 SpellId = 0;
453  switch (Trigger)
454  {
455  case 95:
456  case 2608:
457  if (Source->GetTeam() != ALLIANCE)
458  Source->GetSession()->SendAreaTriggerMessage("Only The Alliance can use that portal");
459  else
460  Source->LeaveBattleground();
461  break;
462  case 2606:
463  if (Source->GetTeam() != HORDE)
464  Source->GetSession()->SendAreaTriggerMessage("Only The Horde can use that portal");
465  else
466  Source->LeaveBattleground();
467  break;
468  case 3326:
469  case 3327:
470  case 3328:
471  case 3329:
472  case 3330:
473  case 3331:
474  //Source->Dismount();
475  break;
476  default:
477  sLog.outDebug("BattlegroundAV: WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger);
478  // Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
479  break;
480  }
481 
482  if (SpellId)
483  Source->CastSpell(Source, SpellId, true);
484 }
485 
487 {
488  BattlegroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
489  if (itr == m_PlayerScores.end()) // player not found...
490  return;
491 
492  switch (type)
493  {
495  ((BattlegroundAVScore*)itr->second)->GraveyardsAssaulted += value;
496  break;
498  ((BattlegroundAVScore*)itr->second)->GraveyardsDefended += value;
499  break;
501  ((BattlegroundAVScore*)itr->second)->TowersAssaulted += value;
502  break;
504  ((BattlegroundAVScore*)itr->second)->TowersDefended += value;
505  break;
507  ((BattlegroundAVScore*)itr->second)->MinesCaptured += value;
508  break;
510  ((BattlegroundAVScore*)itr->second)->LeadersKilled += value;
511  break;
513  ((BattlegroundAVScore*)itr->second)->SecondaryObjectives += value;
514  break;
515  default:
516  Battleground::UpdatePlayerScore(Source, type, value);
517  break;
518  }
519 }
520 
522 {
523 
524  uint32 object = GetObjectThroughNode(node);
525  sLog.outDebug("bg_av: player destroyed point node %i object %i", node, object);
526 
527  // despawn banner
529  DestroyNode(node);
530  UpdateNodeWorldState(node);
531 
532  uint32 owner = m_Nodes[node].Owner;
533  if (IsTower(node))
534  {
535  uint8 tmp = node - BG_AV_NODES_DUNBALDAR_SOUTH;
536  //despawn marshal
539  else
540  sLog.outError("BattlegroundAV:: playerdestroyedpoint: marshal %i doesn't exist", AV_CPLACE_A_MARSHAL_SOUTH + tmp);
541  //spawn destroyed aura
542  for (uint8 i = 0; i <= 9; i++)
544 
545  UpdateScore((owner == ALLIANCE) ? HORDE : ALLIANCE, (-1)*BG_AV_RES_TOWER);
546  RewardReputationToTeam((owner == ALLIANCE) ? 730 : 729, BG_AV_REP_TOWER, owner);
548 
551  }
552  else
553  {
554  if (owner == ALLIANCE)
555  SpawnBGObject(object - 11, RESPAWN_IMMEDIATELY);
556  else
557  SpawnBGObject(object + 11, RESPAWN_IMMEDIATELY);
560  PopulateNode(node);
561  if (node == BG_AV_NODES_SNOWFALL_GRAVE) //snowfall eyecandy
562  {
563  for (uint8 i = 0; i < 4; i++)
564  {
567  }
568  }
569  }
570  //send a nice message to all :)
571  char buf[256];
572  if (IsTower(node))
574  else
576 
578  if (creature)
579  YellToAll(creature, buf, LANG_UNIVERSAL);
580 }
581 
582 void BattlegroundAV::ChangeMineOwner(uint8 mine, uint32 team, bool initial)
583 {
584  //mine=0 northmine mine=1 southmin
585  //changing the owner results in setting respawntim to infinite for current creatures, spawning new mine owners creatures and changing the chest-objects so that the current owning team can use them
586  ASSERT(mine == BG_AV_NORTH_MINE || mine == BG_AV_SOUTH_MINE);
587  if (team != ALLIANCE && team != HORDE)
588  team = BG_AV_NEUTRAL_TEAM;
589  else
591 
592  if (m_Mine_Owner[mine] == team && !initial)
593  return;
594  m_Mine_PrevOwner[mine] = m_Mine_Owner[mine];
595  m_Mine_Owner[mine] = team;
596 
597  if (!initial)
598  {
599  sLog.outDebug("bg_av depopulating mine %i (0=north,1=south)", mine);
600  if (mine == BG_AV_SOUTH_MINE)
602  if (m_BgCreatures[i])
603  DelCreature(i); //TODO just set the respawntime to 999999
605  if (m_BgCreatures[i])
606  DelCreature(i); //TODO here also
607  }
608  SendMineWorldStates(mine);
609 
610  sLog.outDebug("bg_av populating mine %i (0=north,1=south)", mine);
611  uint16 miner;
612  //also neutral team exists.. after a big time, the neutral team tries to conquer the mine
613  if (mine == BG_AV_NORTH_MINE)
614  {
615  if (team == ALLIANCE)
616  miner = AV_NPC_N_MINE_A_1;
617  else if (team == HORDE)
618  miner = AV_NPC_N_MINE_H_1;
619  else
620  miner = AV_NPC_N_MINE_N_1;
621  }
622  else
623  {
624  uint16 cinfo;
625  if (team == ALLIANCE)
626  miner = AV_NPC_S_MINE_A_1;
627  else if (team == HORDE)
628  miner = AV_NPC_S_MINE_H_1;
629  else
630  miner = AV_NPC_S_MINE_N_1;
631  //vermin
632  sLog.outDebug("spawning vermin");
633  if (team == ALLIANCE)
634  cinfo = AV_NPC_S_MINE_A_3;
635  else if (team == HORDE)
636  cinfo = AV_NPC_S_MINE_H_3;
637  else
638  cinfo = AV_NPC_S_MINE_N_S;
640  AddAVCreature(cinfo, i);
641  }
643  AddAVCreature(miner, i);
644  //the next chooses randomly between 2 cretures
646  AddAVCreature(miner + (urand(1, 2)), i);
648  //because the gameobjects in this mine have changed, update all surrounding players:
649  // for (uint16 i = ((mine == BG_AV_NORTH_MINE)?BG_AV_OBJECT_MINE_SUPPLY_N_MIN:BG_AV_OBJECT_MINE_SUPPLY_N_MIN); i <= ((mine == BG_AV_NORTH_MINE)?BG_AV_OBJECT_MINE_SUPPLY_N_MAX:BG_AV_OBJECT_MINE_SUPPLY_N_MAX); i++)
650  // {
651  //@todo add gameobject-update code
652  // }
653  if (team == ALLIANCE || team == HORDE)
654  {
656  char buf[256];
659  if (creature)
660  YellToAll(creature, buf, LANG_UNIVERSAL);
661  }
662  else
663  {
664  if (mine == BG_AV_SOUTH_MINE) //i think this gets called all the time
665  {
666  if (Creature* creature = GetBGCreature(AV_CPLACE_MINE_S_3))
668  }
669  }
670  return;
671 }
672 
674 {
675  if (GOId == BG_AV_OBJECTID_MINE_N)
676  return (m_Mine_Owner[BG_AV_NORTH_MINE] == team);
677  if (GOId == BG_AV_OBJECTID_MINE_S)
678  return (m_Mine_Owner[BG_AV_SOUTH_MINE] == team);
679  return true; // cause it's no mine'object it is ok if this is true
680 }
681 
683 {
684  uint32 owner = m_Nodes[node].Owner;
685  ASSERT(owner);
686 
687  uint32 c_place = AV_CPLACE_DEFENSE_STORM_AID + (4 * node);
688  uint32 creatureid;
689  if (IsTower(node))
690  creatureid = (owner == ALLIANCE) ? AV_NPC_A_TOWERDEFENSE : AV_NPC_H_TOWERDEFENSE;
691  else
692  {
693  uint8 team2 = GetTeamIndexByTeamId(owner);
694  if (m_Team_QuestStatus[team2][0] < 500)
695  creatureid = (owner == ALLIANCE) ? AV_NPC_A_GRAVEDEFENSE0 : AV_NPC_H_GRAVEDEFENSE0;
696  else if (m_Team_QuestStatus[team2][0] < 1000)
697  creatureid = (owner == ALLIANCE) ? AV_NPC_A_GRAVEDEFENSE1 : AV_NPC_H_GRAVEDEFENSE1;
698  else if (m_Team_QuestStatus[team2][0] < 1500)
699  creatureid = (owner == ALLIANCE) ? AV_NPC_A_GRAVEDEFENSE2 : AV_NPC_H_GRAVEDEFENSE2;
700  else
701  creatureid = (owner == ALLIANCE) ? AV_NPC_A_GRAVEDEFENSE3 : AV_NPC_H_GRAVEDEFENSE3;
702  //spiritguide
703  if (m_BgCreatures[node])
704  DelCreature(node);
705  if (!AddSpiritGuide(node, BG_AV_CreaturePos[node][0], BG_AV_CreaturePos[node][1], BG_AV_CreaturePos[node][2], BG_AV_CreaturePos[node][3], owner))
706  sLog.outError("AV: couldn't spawn spiritguide at node %i", node);
707 
708  }
709  for (uint8 i = 0; i < 4; i++)
710  AddAVCreature(creatureid, c_place + i);
711 
712 }
714 {
715  uint32 c_place = AV_CPLACE_DEFENSE_STORM_AID + (4 * node);
716  for (uint8 i = 0; i < 4; i++)
717  if (m_BgCreatures[c_place + i])
718  DelCreature(c_place + i);
719  //spiritguide
720  if (!IsTower(node) && m_BgCreatures[node])
721  DelCreature(node);
722 }
723 
725 {
726  sLog.outDebug("bg_AV getnodethroughobject %i", object);
728  return BG_AV_Nodes(object);
730  return BG_AV_Nodes(object - 11);
732  return BG_AV_Nodes(object - 7);
734  return BG_AV_Nodes(object - 22);
735  if (object <= BG_AV_OBJECT_FLAG_H_FROSTWOLF_HUT)
736  return BG_AV_Nodes(object - 33);
738  return BG_AV_Nodes(object - 29);
741  sLog.outError("BattlegroundAV: ERROR! GetPlace got a wrong object :(");
742  ASSERT(false);
743  return BG_AV_Nodes(0);
744 }
745 
747 {
748  //this function is the counterpart to GetNodeThroughObject()
749  sLog.outDebug("bg_AV GetObjectThroughNode %i", node);
750  if (m_Nodes[node].Owner == ALLIANCE)
751  {
752  if (m_Nodes[node].State == POINT_ASSAULTED)
753  {
754  if (node <= BG_AV_NODES_FROSTWOLF_HUT)
755  return node + 11;
757  return node + 7;
758  }
759  else if (m_Nodes[node].State == POINT_CONTROLLED)
760  if (node <= BG_AV_NODES_STONEHEART_BUNKER)
761  return node;
762  }
763  else if (m_Nodes[node].Owner == HORDE)
764  {
765  if (m_Nodes[node].State == POINT_ASSAULTED)
766  {
767  if (node <= BG_AV_NODES_STONEHEART_BUNKER)
768  return node + 22;
769  }
770  else if (m_Nodes[node].State == POINT_CONTROLLED)
771  {
772  if (node <= BG_AV_NODES_FROSTWOLF_HUT)
773  return node + 33;
775  return node + 29;
776  }
777  }
778  else if (m_Nodes[node].Owner == BG_AV_NEUTRAL_TEAM)
780  sLog.outError("BattlegroundAV: Error! GetPlaceNode couldn't resolve node %i", node);
781  ASSERT(false);
782  return 0;
783 }
784 
785 //called when using banner
786 
788 {
789  if (GetStatus() != STATUS_IN_PROGRESS)
790  return;
791  int32 object = GetObjectType(target_obj->GetGUID());
792  sLog.outDebug("BattlegroundAV: using gameobject %i with type %i", target_obj->GetEntry(), object);
793  if (object < 0)
794  return;
795  switch (target_obj->GetEntry())
796  {
802  EventPlayerAssaultsPoint(source, object);
803  break;
808  EventPlayerDefendsPoint(source, object);
809  break;
810  default:
811  break;
812  }
813 }
814 
816 {
818  BG_AV_Nodes node = GetNodeThroughObject(object);
819 
820  uint32 owner = m_Nodes[node].Owner; //maybe should name it prevowner
821  uint32 team = player->GetTeam();
822 
823  if (owner == player->GetTeam() || m_Nodes[node].State != POINT_ASSAULTED)
824  return;
825  if (m_Nodes[node].TotalOwner == BG_AV_NEUTRAL_TEAM)
826  {
827  //until snowfall doesn't belong to anyone it is better handled in assault-code
828  ASSERT(node == BG_AV_NODES_SNOWFALL_GRAVE); //currently the only neutral grave
829  EventPlayerAssaultsPoint(player, object);
830  return;
831  }
832  sLog.outDebug("player defends point object: %i node: %i", object, node);
833  if (m_Nodes[node].PrevOwner != team)
834  {
835  sLog.outError("BattlegroundAV: player defends point which doesn't belong to his team %i", node);
836  return;
837  }
838 
839  //spawn new go :)
840  if (m_Nodes[node].Owner == ALLIANCE)
841  SpawnBGObject(object + 22, RESPAWN_IMMEDIATELY); //spawn horde banner
842  else
843  SpawnBGObject(object - 22, RESPAWN_IMMEDIATELY); //spawn alliance banner
844 
845  if (!IsTower(node))
846  {
849  }
850  // despawn old go
852 
853  DefendNode(node, team);
854  PopulateNode(node);
855  UpdateNodeWorldState(node);
856 
857  if (IsTower(node))
858  {
859  //spawn big flag+aura on top of tower
864  }
865  else if (node == BG_AV_NODES_SNOWFALL_GRAVE) //snowfall eyecandy
866  {
867  for (uint8 i = 0; i < 4; i++)
868  {
871  }
872  }
873  //send a nice message to all :)
874  char buf[256];
877  if (creature)
878  YellToAll(creature, buf, LANG_UNIVERSAL);
879  //update the statistic for the defending player
881  if (IsTower(node))
883  else
885 }
886 
888 {
890 
891  BG_AV_Nodes node = GetNodeThroughObject(object);
892  uint32 owner = m_Nodes[node].Owner; //maybe name it prevowner
893  uint32 team = player->GetTeam();
894  sLog.outDebug("bg_av: player assaults point object %i node %i", object, node);
895  if (owner == team || team == m_Nodes[node].TotalOwner)
896  return; //surely a gm used this object
897 
898  if (node == BG_AV_NODES_SNOWFALL_GRAVE) //snowfall is a bit special in capping + it gets eyecandy stuff
899  {
900  if (object == BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE) //initial capping
901  {
902  ASSERT(owner == BG_AV_NEUTRAL_TEAM && m_Nodes[node].TotalOwner == BG_AV_NEUTRAL_TEAM);
903  if (team == ALLIANCE)
905  else
908  }
909  else if (m_Nodes[node].TotalOwner == BG_AV_NEUTRAL_TEAM) //recapping, when no team owns this node realy
910  {
911  ASSERT(m_Nodes[node].State != POINT_CONTROLLED);
912  if (team == ALLIANCE)
913  SpawnBGObject(object - 11, RESPAWN_IMMEDIATELY);
914  else
915  SpawnBGObject(object + 11, RESPAWN_IMMEDIATELY);
916  }
917  //eyecandy
918  uint32 spawn, despawn;
919  if (team == ALLIANCE)
920  {
923  }
924  else
925  {
928  }
929  for (uint8 i = 0; i < 4; i++)
930  {
931  SpawnBGObject(despawn + i, RESPAWN_ONE_DAY);
933  }
934  }
935 
936  //if snowfall gots capped it can be handled like all other graveyards
937  if (m_Nodes[node].TotalOwner != BG_AV_NEUTRAL_TEAM)
938  {
939  ASSERT(m_Nodes[node].Owner != BG_AV_NEUTRAL_TEAM);
940  if (team == ALLIANCE)
941  SpawnBGObject(object - 22, RESPAWN_IMMEDIATELY);
942  else
943  SpawnBGObject(object + 22, RESPAWN_IMMEDIATELY);
944  if (IsTower(node))
945  {
946  //spawning/despawning of bigflag+aura
951  }
952  else
953  {
954  //spawning/despawning of aura
957  // Those who are waiting to resurrect at this object are taken to the closest own object's graveyard
958  std::vector<uint64> ghost_list = m_ReviveQueue[m_BgCreatures[node]];
959  if (!ghost_list.empty())
960  {
961  Player* plr;
962  WorldSafeLocsEntry const* ClosestGrave = NULL;
963  for (std::vector<uint64>::iterator itr = ghost_list.begin(); itr != ghost_list.end(); ++itr)
964  {
965  plr = sObjectMgr.GetPlayer(*ghost_list.begin());
966  if (!plr)
967  continue;
968  if (!ClosestGrave)
969  ClosestGrave = GetClosestGraveYard(plr);
970  else
971  plr->TeleportTo(GetMapId(), ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, plr->GetOrientation());
972  }
973  m_ReviveQueue[m_BgCreatures[node]].clear();
974  }
975  }
976  DePopulateNode(node);
977  }
978 
979  SpawnBGObject(object, RESPAWN_ONE_DAY); //delete old banner
980  AssaultNode(node, team);
981  UpdateNodeWorldState(node);
982 
983  //send a nice message to all :)
984  char buf[256];
987  if (creature)
988  YellToAll(creature, buf, LANG_UNIVERSAL);
989  //update the statistic for the assaulting player
992 }
993 
995 {
996  bool stateok;
997  //graveyards
999  {
1000  for (uint8 j = 1; j <= 3; j += 2)
1001  {
1002  //j=1=assaulted j=3=controled
1003  stateok = (m_Nodes[i].State == j);
1004  data << uint32(BG_AV_NodeWorldStates[i][GetWorldStateType(j, ALLIANCE)]) << uint32((m_Nodes[i].Owner == ALLIANCE && stateok) ? 1 : 0);
1005  data << uint32(BG_AV_NodeWorldStates[i][GetWorldStateType(j, HORDE)]) << uint32((m_Nodes[i].Owner == HORDE && stateok) ? 1 : 0);
1006  }
1007  }
1008 
1009  //towers
1011  for (uint8 j = 1; j <= 3; j += 2)
1012  {
1013  //j=1=assaulted j=3=controled //i dont have j=2=destroyed cause destroyed is the same like enemy-team controll
1014  stateok = (m_Nodes[i].State == j || (m_Nodes[i].State == POINT_DESTROYED && j == 3));
1015  data << uint32(BG_AV_NodeWorldStates[i][GetWorldStateType(j, ALLIANCE)]) << uint32((m_Nodes[i].Owner == ALLIANCE && stateok) ? 1 : 0);
1016  data << uint32(BG_AV_NodeWorldStates[i][GetWorldStateType(j, HORDE)]) << uint32((m_Nodes[i].Owner == HORDE && stateok) ? 1 : 0);
1017  }
1018  if (m_Nodes[BG_AV_NODES_SNOWFALL_GRAVE].Owner == BG_AV_NEUTRAL_TEAM) //cause neutral teams aren't handled generic
1019  data << uint32(AV_SNOWFALL_N) << uint32(1);
1021  data << uint32(BG_AV_Horde_Score) << uint32(m_Team_Scores[1]);
1022  if (GetStatus() == STATUS_IN_PROGRESS) //only if game started the teamscores are displayed
1023  {
1024  data << uint32(BG_AV_SHOW_A_SCORE) << uint32(1);
1025  data << uint32(BG_AV_SHOW_H_SCORE) << uint32(1);
1026  }
1027  else
1028  {
1029  data << uint32(BG_AV_SHOW_A_SCORE) << uint32(0);
1030  data << uint32(BG_AV_SHOW_H_SCORE) << uint32(0);
1031  }
1034 }
1035 
1036 uint8 BattlegroundAV::GetWorldStateType(uint8 state, uint16 team) //this is used for node worldstates and returns values which fit good into the worldstatesarray
1037 {
1038  //neutral stuff cant get handled (currently its only snowfall)
1039  ASSERT(team != BG_AV_NEUTRAL_TEAM);
1040  //a_c a_a h_c h_a the positions in worldstate-array
1041  if (team == ALLIANCE)
1042  {
1043  if (state == POINT_CONTROLLED || state == POINT_DESTROYED)
1044  return 0;
1045  if (state == POINT_ASSAULTED)
1046  return 1;
1047  }
1048  if (team == HORDE)
1049  {
1050  if (state == POINT_DESTROYED || state == POINT_CONTROLLED)
1051  return 2;
1052  if (state == POINT_ASSAULTED)
1053  return 3;
1054  }
1055  sLog.outError("BattlegroundAV:: should update a strange worldstate state:%i team:%i", state, team);
1056  return 5; //this will crash the game, but i want to know if something is wrong here
1057 }
1058 
1060 {
1061  UpdateWorldState(BG_AV_NodeWorldStates[node][GetWorldStateType(m_Nodes[node].State, m_Nodes[node].Owner)], 1);
1062  if (m_Nodes[node].PrevOwner == BG_AV_NEUTRAL_TEAM) //currently only snowfall is supported as neutral node (i don't want to make an extra row (neutral states) in worldstatesarray just for one node
1064  else
1065  UpdateWorldState(BG_AV_NodeWorldStates[node][GetWorldStateType(m_Nodes[node].PrevState, m_Nodes[node].PrevOwner)], 0);
1066 }
1067 
1069 {
1070  ASSERT(mine == BG_AV_NORTH_MINE || mine == BG_AV_SOUTH_MINE);
1071  // currently i'm sure, that this works (:
1072  // ASSERT(m_Mine_PrevOwner[mine] == ALLIANCE || m_Mine_PrevOwner[mine] == HORDE || m_Mine_PrevOwner[mine] == BG_AV_NEUTRAL_TEAM);
1073  // ASSERT(m_Mine_Owner[mine] == ALLIANCE || m_Mine_Owner[mine] == HORDE || m_Mine_Owner[mine] == BG_AV_NEUTRAL_TEAM);
1074 
1075  uint8 owner, prevowner, mine2; //those variables are needed to access the right worldstate in the BG_AV_MineWorldStates array
1076  mine2 = (mine == BG_AV_NORTH_MINE) ? 0 : 1;
1077  if (m_Mine_PrevOwner[mine] == ALLIANCE)
1078  prevowner = 0;
1079  else if (m_Mine_PrevOwner[mine] == HORDE)
1080  prevowner = 2;
1081  else
1082  prevowner = 1;
1083  if (m_Mine_Owner[mine] == ALLIANCE)
1084  owner = 0;
1085  else if (m_Mine_Owner[mine] == HORDE)
1086  owner = 2;
1087  else
1088  owner = 1;
1089 
1090  UpdateWorldState(BG_AV_MineWorldStates[mine2][owner], 1);
1091  if (prevowner != owner)
1092  UpdateWorldState(BG_AV_MineWorldStates[mine2][prevowner], 0);
1093 }
1094 
1096 {
1097  WorldSafeLocsEntry const* pGraveyard = NULL;
1098  WorldSafeLocsEntry const* entry = NULL;
1099  float dist = 0;
1100  float minDist = 0;
1101  float x, y;
1102 
1103  player->GetPosition(x, y);
1104 
1105  pGraveyard = sWorldSafeLocsStore.LookupEntry(BG_AV_GraveyardIds[GetTeamIndexByTeamId(player->GetTeam()) + 7]);
1106  minDist = (pGraveyard->x - x) * (pGraveyard->x - x) + (pGraveyard->y - y) * (pGraveyard->y - y);
1107 
1109  if (m_Nodes[i].Owner == player->GetTeam() && m_Nodes[i].State == POINT_CONTROLLED)
1110  {
1111  entry = sWorldSafeLocsStore.LookupEntry(BG_AV_GraveyardIds[i]);
1112  if (entry)
1113  {
1114  dist = (entry->x - x) * (entry->x - x) + (entry->y - y) * (entry->y - y);
1115  if (dist < minDist)
1116  {
1117  minDist = dist;
1118  pGraveyard = entry;
1119  }
1120  }
1121  }
1122  return pGraveyard;
1123 }
1124 
1126 {
1127  // Create starting objects
1128  if (
1129  // alliance gates
1131  // horde gates
1133  {
1134  sLog.outErrorDb("BatteGroundAV: Failed to spawn some object Battleground not created!1");
1135  return false;
1136  }
1137 
1138  //spawn node-objects
1140  {
1141  if (i <= BG_AV_NODES_FROSTWOLF_HUT)
1142  {
1143  if ( !AddObject(i, BG_AV_OBJECTID_BANNER_A_B, BG_AV_ObjectPos[i][0], BG_AV_ObjectPos[i][1], BG_AV_ObjectPos[i][2], BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3] / 2), cos(BG_AV_ObjectPos[i][3] / 2), RESPAWN_ONE_DAY)
1144  || !AddObject(i + 11, BG_AV_OBJECTID_BANNER_CONT_A_B, BG_AV_ObjectPos[i][0], BG_AV_ObjectPos[i][1], BG_AV_ObjectPos[i][2], BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3] / 2), cos(BG_AV_ObjectPos[i][3] / 2), RESPAWN_ONE_DAY)
1145  || !AddObject(i + 33, BG_AV_OBJECTID_BANNER_H_B, BG_AV_ObjectPos[i][0], BG_AV_ObjectPos[i][1], BG_AV_ObjectPos[i][2], BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3] / 2), cos(BG_AV_ObjectPos[i][3] / 2), RESPAWN_ONE_DAY)
1146  || !AddObject(i + 22, BG_AV_OBJECTID_BANNER_CONT_H_B, BG_AV_ObjectPos[i][0], BG_AV_ObjectPos[i][1], BG_AV_ObjectPos[i][2], BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3] / 2), cos(BG_AV_ObjectPos[i][3] / 2), RESPAWN_ONE_DAY)
1147  //aura
1151  {
1152  sLog.outError("BatteGroundAV: Failed to spawn some object Battleground not created!2");
1153  return false;
1154  }
1155  }
1156  else //towers
1157  {
1158  if (i <= BG_AV_NODES_STONEHEART_BUNKER) //alliance towers
1159  {
1160  if ( !AddObject(i, BG_AV_OBJECTID_BANNER_A, BG_AV_ObjectPos[i][0], BG_AV_ObjectPos[i][1], BG_AV_ObjectPos[i][2], BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3] / 2), cos(BG_AV_ObjectPos[i][3] / 2), RESPAWN_ONE_DAY)
1161  || !AddObject(i + 22, BG_AV_OBJECTID_BANNER_CONT_H, BG_AV_ObjectPos[i][0], BG_AV_ObjectPos[i][1], BG_AV_ObjectPos[i][2], BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3] / 2), cos(BG_AV_ObjectPos[i][3] / 2), RESPAWN_ONE_DAY)
1166  {
1167  sLog.outError("BatteGroundAV: Failed to spawn some object Battleground not created!3");
1168  return false;
1169  }
1170  }
1171  else //horde towers
1172  {
1173  if ( !AddObject(i + 7, BG_AV_OBJECTID_BANNER_CONT_A, BG_AV_ObjectPos[i][0], BG_AV_ObjectPos[i][1], BG_AV_ObjectPos[i][2], BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3] / 2), cos(BG_AV_ObjectPos[i][3] / 2), RESPAWN_ONE_DAY)
1174  || !AddObject(i + 29, BG_AV_OBJECTID_BANNER_H, BG_AV_ObjectPos[i][0], BG_AV_ObjectPos[i][1], BG_AV_ObjectPos[i][2], BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3] / 2), cos(BG_AV_ObjectPos[i][3] / 2), RESPAWN_ONE_DAY)
1179  {
1180  sLog.outError("BatteGroundAV: Failed to spawn some object Battleground not created!4");
1181  return false;
1182  }
1183  }
1184  for (uint8 j = 0; j <= 9; j++) //burning aura
1185  {
1187  {
1188  sLog.outError("BatteGroundAV: Failed to spawn some object Battleground not created!5.%i", i);
1189  return false;
1190  }
1191  }
1192  }
1193  }
1194  for (uint8 i = 0; i < 2; i++) //burning aura for buildings
1195  {
1196  for (uint8 j = 0; j <= 9; j++)
1197  {
1198  if (j < 5)
1199  {
1201  {
1202  sLog.outError("BatteGroundAV: Failed to spawn some object Battleground not created!6.%i", i);
1203  return false;
1204  }
1205  }
1206  else
1207  {
1209  {
1210  sLog.outError("BatteGroundAV: Failed to spawn some object Battleground not created!7.%i", i);
1211  return false;
1212  }
1213  }
1214  }
1215  }
1217  {
1219  {
1220  sLog.outError("BatteGroundAV: Failed to spawn some mine supplies Battleground not created!7.5.%i", i);
1221  return false;
1222  }
1223  }
1225  {
1227  {
1228  sLog.outError("BatteGroundAV: Failed to spawn some mine supplies Battleground not created!7.6.%i", i);
1229  return false;
1230  }
1231  }
1232 
1233  if (!AddObject(BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE, BG_AV_OBJECTID_BANNER_SNOWFALL_N , BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][0], BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][1], BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][2], BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][3], 0, 0, sin(BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][3] / 2), cos(BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][3] / 2), RESPAWN_ONE_DAY))
1234  {
1235  sLog.outError("BatteGroundAV: Failed to spawn some object Battleground not created!8");
1236  return false;
1237  }
1238  for (uint8 i = 0; i < 4; i++)
1239  {
1244  {
1245  sLog.outError("BatteGroundAV: Failed to spawn some object Battleground not created!9.%i", i);
1246  return false;
1247  }
1248  }
1249 
1250  uint16 i;
1251  sLog.outDebug("Alterac Valley: entering state STATUS_WAIT_JOIN ...");
1252  // Initial Nodes
1253  for (i = 0; i < BG_AV_OBJECT_MAX; i++)
1256  {
1259  }
1263  {
1267  }
1269  {
1271  SpawnBGObject(i + 16, RESPAWN_IMMEDIATELY); //aura
1272  }
1274  {
1276  SpawnBGObject(i + 16, RESPAWN_IMMEDIATELY); //aura
1277  }
1278  //snowfall and the doors
1282 
1283  //creatures
1284  sLog.outDebug("BattlegroundAV: start poputlating nodes");
1286  {
1287  if (m_Nodes[i].Owner)
1288  PopulateNode(i);
1289  }
1290  //all creatures which don't get despawned through the script are static
1291  sLog.outDebug("BattlegroundAV: start spawning static creatures");
1292  for (i = 0; i < AV_STATICCPLACE_MAX; i++)
1293  AddAVCreature(0, i + AV_CPLACE_MAX);
1294  //mainspiritguides:
1295  sLog.outDebug("BattlegroundAV: start spawning spiritguides creatures");
1298  //spawn the marshals (those who get deleted, if a tower gets destroyed)
1299  sLog.outDebug("BattlegroundAV: start spawning marshal creatures");
1300  for (i = AV_NPC_A_MARSHAL_SOUTH; i <= AV_NPC_H_MARSHAL_WTOWER; i++)
1303  return true;
1304 }
1305 
1307 {
1308  switch (node)
1309  {
1340  default:
1341  sLog.outError("tried to get name for node %u", node);
1342  break;
1343  }
1344 
1345  return "Unknown";
1346 }
1347 
1349 {
1350  if (m_Nodes[node].TotalOwner == team)
1351  {
1352  sLog.outError("Crash alert! Assaulting team is TotalOwner of node");
1353  ASSERT(false);
1354  }
1355  if (m_Nodes[node].Owner == team)
1356  {
1357  sLog.outError("Crash alert! Assaulting team is owner of node");
1358  ASSERT(false);
1359  }
1360  if (m_Nodes[node].State == POINT_DESTROYED)
1361  {
1362  sLog.outError("Crash alert! Destroyed node is being assaulted");
1363  ASSERT(false);
1364  }
1365  if (m_Nodes[node].State == POINT_ASSAULTED && m_Nodes[node].TotalOwner) //only assault an assaulted node if no totalowner exists
1366  {
1367  sLog.outError("Crash alert! Assault on an not assaulted node with total owner");
1368  ASSERT(false);
1369  }
1370  // the timer gets another time, if the previous owner was 0 == Neutral
1372  m_Nodes[node].PrevOwner = m_Nodes[node].Owner;
1373  m_Nodes[node].Owner = team;
1374  m_Nodes[node].PrevState = m_Nodes[node].State;
1375  m_Nodes[node].State = POINT_ASSAULTED;
1376 }
1377 
1379 {
1380  ASSERT(m_Nodes[node].State == POINT_ASSAULTED);
1381 
1382  m_Nodes[node].TotalOwner = m_Nodes[node].Owner;
1383  m_Nodes[node].PrevOwner = m_Nodes[node].Owner;
1384  m_Nodes[node].PrevState = m_Nodes[node].State;
1386  m_Nodes[node].Timer = 0;
1387 }
1388 
1389 void BattlegroundAV::InitNode(BG_AV_Nodes node, uint16 team, bool tower)
1390 {
1391  m_Nodes[node].TotalOwner = team;
1392  m_Nodes[node].Owner = team;
1393  m_Nodes[node].PrevOwner = 0;
1394  m_Nodes[node].State = POINT_CONTROLLED;
1395  m_Nodes[node].PrevState = m_Nodes[node].State;
1396  m_Nodes[node].State = POINT_CONTROLLED;
1397  m_Nodes[node].Timer = 0;
1398  m_Nodes[node].Tower = tower;
1399 }
1400 
1402 {
1403  ASSERT(m_Nodes[node].TotalOwner == team);
1404  ASSERT(m_Nodes[node].Owner != team);
1405  ASSERT(m_Nodes[node].State != POINT_CONTROLLED && m_Nodes[node].State != POINT_DESTROYED);
1406  m_Nodes[node].PrevOwner = m_Nodes[node].Owner;
1407  m_Nodes[node].Owner = team;
1408  m_Nodes[node].PrevState = m_Nodes[node].State;
1409  m_Nodes[node].State = POINT_CONTROLLED;
1410  m_Nodes[node].Timer = 0;
1411 }
1412 
1414 {
1415  m_MaxLevel = 0;
1416 
1417  for (uint8 i = 0; i < BG_TEAMS_COUNT; i++)
1418  {
1419  for (uint8 j = 0; j < 9; j++) // 9 quests getting tracked
1420  m_Team_QuestStatus[i][j] = 0;
1422  m_IsInformedNearVictory[i] = false;
1423  m_CaptainAlive[i] = true;
1424  m_CaptainBuffTimer[i] = 120000 + urand(0, 4) * 60; //as far as i could see, the buff is randomly so i make 2minutes (thats the duration of the buff itself) + 0-4minutes TODO get the right times
1427  }
1428  for (BG_AV_Nodes i = BG_AV_NODES_FIRSTAID_STATION; i <= BG_AV_NODES_STONEHEART_GRAVE; ++i) //alliance graves
1429  InitNode(i, ALLIANCE, false);
1430  for (BG_AV_Nodes i = BG_AV_NODES_DUNBALDAR_SOUTH; i <= BG_AV_NODES_STONEHEART_BUNKER; ++i) //alliance towers
1431  InitNode(i, ALLIANCE, true);
1432  for (BG_AV_Nodes i = BG_AV_NODES_ICEBLOOD_GRAVE; i <= BG_AV_NODES_FROSTWOLF_HUT; ++i) //horde graves
1433  InitNode(i, HORDE, false);
1434  for (BG_AV_Nodes i = BG_AV_NODES_ICEBLOOD_TOWER; i <= BG_AV_NODES_FROSTWOLF_WTOWER; ++i) //horde towers
1435  InitNode(i, HORDE, true);
1436  InitNode(BG_AV_NODES_SNOWFALL_GRAVE, BG_AV_NEUTRAL_TEAM, false); //give snowfall neutral owner
1437 
1439  for (uint16 i = 0; i < AV_CPLACE_MAX + AV_STATICCPLACE_MAX; i++)
1440  if (m_BgCreatures[i])
1441  DelCreature(i);
1442 
1443 }
1444 
uint16 GetBonusHonor(uint8 kills)
BG_AV_Nodes
DBCStorage< WorldSafeLocsEntry > sWorldSafeLocsStore(WorldSafeLocsEntryfmt)
void UpdatePlayerScore(Player *Source, uint32 type, uint32 value)
virtual void StartingEventCloseDoors()
void Update(uint32 diff)
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)
bool PlayerCanDoMineQuest(int32 GOId, uint32 team)
uint32 m_StartMessageIds[BG_STARTING_EVENT_COUNT]
Definition: Battleground.h:728
const uint32 BG_AV_NodeWorldStates[16][4]
virtual void HandleKillPlayer(Player *player, Player *killer)
void PopulateNode(BG_AV_Nodes node)
uint32 m_Mine_Reclaim_Timer[BG_AV_MAX_MINES]
void RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID)
std::map< uint64, std::vector< uint64 > > m_ReviveQueue
Definition: Battleground.h:720
uint32 GetDBTableGUIDLow() const
Definition: Creature.h:476
void FillInitialWorldStates(WorldPacket &data)
const float BG_AV_StaticCreaturePos[AV_STATICCPLACE_MAX][5]
uint32 m_Team_Scores[BG_TEAMS_COUNT]
const char * GetNodeName(BG_AV_Nodes node)
#define BG_AV_SNOWFALL_FIRSTCAP
void YellToAll(Creature *creature, const char *text, uint32 language)
MotionMaster * GetMotionMaster()
Definition: Unit.h:1890
void EventPlayerDefendsPoint(Player *player, uint32 object)
virtual void StartingEventOpenDoors()
const float BG_AV_CreaturePos[AV_CPLACE_MAX][4]
#define BG_AV_KILL_BOSS
#define sLog
Log class singleton.
Definition: Log.h:187
void HandleQuestComplete(uint32 questid, Player *player)
ACE_INT32 int32
Definition: Define.h:67
void HandleAreaTrigger(Player *Source, uint32 Trigger)
float spawndist
Definition: Creature.h:279
void SpawnBGObject(uint32 type, uint32 respawntime)
#define BG_AV_REP_CAPTAIN
void AssaultNode(BG_AV_Nodes node, uint16 team)
void EventPlayerDestroyedPoint(BG_AV_Nodes node)
uint32 m_Mine_PrevOwner[BG_AV_MAX_MINES]
void UpdateWorldState(uint32 Field, uint32 Value)
void DestroyNode(BG_AV_Nodes node)
uint32 GetStatus() const
Definition: Battleground.h:317
BattlegroundScoreMap m_PlayerScores
Definition: Battleground.h:713
#define BG_AV_KILL_SURVIVING_TOWER
#define sObjectMgr
Definition: ObjectMgr.h:1285
uint8 GetTeamIndexByTeamId(uint32 Team) const
Definition: Battleground.h:609
Creature * AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o, uint32 respawntime=0)
bool AddSpiritGuide(uint32 type, float x, float y, float z, float o, uint32 team)
virtual void AddPlayer(Player *plr)
bool m_IsInformedNearVictory[2]
virtual void AddPlayer(Player *plr)
void HandleKillUnit(Creature *unit, Player *killer)
bool isStatic(MovementGenerator *mv)
#define BG_AV_REP_TOWER
#define BG_AV_KILL_CAPTAIN
uint8 getLevel() const
Definition: Unit.h:1057
void UpdateNodeWorldState(BG_AV_Nodes node)
bool m_CaptainAlive[BG_TEAMS_COUNT]
void RemoveAurasDueToSpell(uint32 spellId, Aura *except=NULL)
Definition: Unit.cpp:4371
BGCreatures m_BgCreatures
Definition: Battleground.h:673
#define BG_AV_SCORE_INITIAL_POINTS
#define LANG_BG_AV_H_CAPTAIN_BUFF
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0)
Definition: Player.cpp:1488
void UpdateScore(uint16 team, int16 points)
ACE_UINT8 uint8
Definition: Define.h:73
float GetOrientation() const
Definition: Position.h:100
BGObjects m_BgObjects
Definition: Battleground.h:672
void setDeathState(DeathState s) override
Definition: Creature.cpp:1575
void PlaySoundToAll(uint32 SoundID)
const uint32 BG_AV_CreatureInfo[AV_NPC_INFO_MAX][4]
void DePopulateNode(BG_AV_Nodes node)
virtual void ResetBGSubclass()
void CastSpellOnTeam(uint32 SpellID, uint32 TeamID)
void LeaveBattleground(bool teleportToEntryPoint=true)
Definition: Player.cpp:18624
#define BG_TEAMS_COUNT
Definition: Battleground.h:214
bool IsTower(BG_AV_Nodes node)
#define BG_AV_REP_SURVIVING_TOWER
void CastSpell(Unit *Victim, uint32 spellId, bool triggered, Item *castItem=NULL, Aura *triggeredByAura=NULL, uint64 originalCaster=0)
Definition: Unit.cpp:1223
void GetPosition(float &x, float &y) const
Definition: Position.h:102
uint32 m_CaptainBuffTimer[BG_TEAMS_COUNT]
etc mysql my cnf *Then change max_allowed_packet to a bigger value
uint8 GetWorldStateType(uint8 state, uint16 team)
virtual WorldSafeLocsEntry const * GetClosestGraveYard(Player *player)
BG_AV_States State
const uint32 BG_AV_MineWorldStates[2][3]
virtual void UpdatePlayerScore(Player *Source, uint32 type, uint32 value)
#define BG_AV_KILL_SURVIVING_CAPTAIN
const uint32 BG_AV_GraveyardIds[9]
uint32 m_Team_QuestStatus[BG_TEAMS_COUNT][9]
void HandleKillPlayer(Player *player, Player *killer)
void RewardHonorToTeam(uint32 Honor, uint32 TeamID)
#define BG_AV_REP_BOSS
void EventPlayerAssaultsPoint(Player *player, uint32 object)
ACE_UINT64 uint64
Definition: Define.h:70
void DoorOpen(uint32 type)
void Respawn(bool force=false)
Definition: Creature.cpp:1651
const float BG_AV_ObjectPos[AV_OPLACE_MAX][4]
int32 GetObjectType(uint64 guid)
bool DelCreature(uint32 type)
void SendMineWorldStates(uint32 mine)
uint32 hk_honor_at_level(uint32 level, uint32 count=1)
Definition: Formulas.h:27
void ChangeMineOwner(uint8 mine, uint32 team, bool initial=false)
#define BG_AV_RES_TOWER
uint32 m_Mine_Owner[BG_AV_MAX_MINES]
BG_AV_States PrevState
virtual void EventPlayerClickedOnFlag(Player *source, GameObject *target_obj)
void DefendNode(BG_AV_Nodes node, uint16 team)
uint32 GetTeam() const
Definition: Player.h:2063
uint32 GetObjectThroughNode(BG_AV_Nodes node)
const float BG_AV_DoorPositons[2][4]
#define ASSERT
Definition: Errors.h:29
void SendAreaTriggerMessage(const char *Text,...) ATTR_PRINTF(2
uint32 GetMapId() const
Definition: Battleground.h:539
void InitNode(BG_AV_Nodes node, uint16 team, bool tower)
void SetLevel(uint32 lvl)
Definition: Unit.cpp:10896
uint32 GetEntry() const
Definition: Object.h:192
#define BG_AV_SCORE_NEAR_LOSE
WorldSession * GetSession() const
Definition: Player.h:1944
uint32 m_score[2]
Definition: Battleground.h:731
#define BG_AV_CAPTIME
void EndBattleground(uint32 winner)
ACE_UINT16 uint16
Definition: Define.h:72
ACE_INT16 int16
Definition: Define.h:68
#define BG_AV_KILL_TOWER
Creature * AddAVCreature(uint32 cinfoid, uint32 type)
ACE_UINT32 uint32
Definition: Define.h:71
const uint32 BG_AV_StaticCreatureInfo[51][4]
void Initialize()
BG_AV_NodeInfo m_Nodes[BG_AV_NODES_MAX]
void EndBattleground(uint32 winner)
#define BG_AV_RES_CAPTAIN
Creature * GetBGCreature(uint32 type)
void SetRespawnDelay(uint32 delay)
Definition: Creature.h:668
Definition: Player.h:922
const char * GetOregonString(int32 entry)
#define LANG_BG_AV_A_CAPTAIN_BUFF
#define LANG_BG_AV_S_MINE_BOSS_CLAIMS
#define BG_AV_REP_SURVIVING_CAPTAIN
void RemovePlayer(Player *plr, uint64 guid)
void DoorClose(uint32 type)
uint32 urand(uint32 min, uint32 max)
Definition: Util.cpp:33
void SendMessageToAll(int32 entry, ChatMsg type, Player const *source=NULL)
const uint64 & GetGUID() const
Definition: Object.h:162
virtual void Update(uint32 diff)
BG_AV_Nodes GetNodeThroughObject(uint32 object)