TrinityCore
Loading...
Searching...
No Matches
BattlegroundAB.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore 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 "BattlegroundAB.h"
19#include "BattlegroundMgr.h"
20#include "BattlegroundPackets.h"
21#include "Creature.h"
22#include "DBCStores.h"
23#include "GameObject.h"
24#include "Log.h"
25#include "Map.h"
26#include "Player.h"
27#include "Random.h"
28#include "Util.h"
29#include "WorldSession.h"
30#include "WorldStatePackets.h"
31
36
38{
40 m_BuffChange = true;
42 BgCreatures.resize(BG_AB_ALL_NODES_COUNT + 5);//+5 for aura triggers
43
44 for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
45 {
46 m_Nodes[i] = 0;
47 m_prevNodes[i] = 0;
48 m_NodeTimers[i] = 0;
49 m_BannerTimers[i].timer = 0;
50 m_BannerTimers[i].type = 0;
52 }
53
54 for (uint8 i = 0; i < PVP_TEAMS_COUNT; ++i)
55 {
56 m_lastTick[i] = 0;
57 m_HonorScoreTics[i] = 0;
60 }
61
62 m_HonorTics = 0;
64}
65
67
69{
71 {
72 int team_points[PVP_TEAMS_COUNT] = { 0, 0 };
73
74 for (int node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node)
75 {
76 // 3 sec delay to spawn new banner instead previous despawned one
77 if (m_BannerTimers[node].timer)
78 {
79 if (m_BannerTimers[node].timer > diff)
80 m_BannerTimers[node].timer -= diff;
81 else
82 {
83 m_BannerTimers[node].timer = 0;
84 _CreateBanner(node, m_BannerTimers[node].type, m_BannerTimers[node].teamIndex, false);
85 }
86 }
87
88 // 1-minute to occupy a node from contested state
89 if (m_NodeTimers[node])
90 {
91 if (m_NodeTimers[node] > diff)
92 m_NodeTimers[node] -= diff;
93 else
94 {
95 m_NodeTimers[node] = 0;
96 // Change from contested to occupied !
97 uint8 teamIndex = m_Nodes[node]-1;
98 m_prevNodes[node] = m_Nodes[node];
99 m_Nodes[node] += 2;
100 // burn current contested banner
101 _DelBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex);
102 // create new occupied banner
103 _CreateBanner(node, BG_AB_NODE_TYPE_OCCUPIED, teamIndex, true);
104 _SendNodeUpdate(node);
105 _NodeOccupied(node, (teamIndex == TEAM_ALLIANCE) ? ALLIANCE : HORDE);
106 // Message to chatlog
107
108 if (teamIndex == TEAM_ALLIANCE)
109 {
110 SendBroadcastText(ABNodes[node].TextAllianceTaken, CHAT_MSG_BG_SYSTEM_ALLIANCE);
112 }
113 else
114 {
117 }
118 }
119 }
120
121 for (int team = 0; team < PVP_TEAMS_COUNT; ++team)
122 if (m_Nodes[node] == team + BG_AB_NODE_TYPE_OCCUPIED)
123 ++team_points[team];
124 }
125
126 // Accumulate points
127 for (int team = 0; team < PVP_TEAMS_COUNT; ++team)
128 {
129 int points = team_points[team];
130 if (!points)
131 continue;
132
133 m_lastTick[team] += diff;
134
135 if (m_lastTick[team] > BG_AB_TickIntervals[points])
136 {
137 m_lastTick[team] -= BG_AB_TickIntervals[points];
138 m_TeamScores[team] += BG_AB_TickPoints[points];
139 m_HonorScoreTics[team] += BG_AB_TickPoints[points];
141
143 {
146 }
147
148 if (m_HonorScoreTics[team] >= m_HonorTics)
149 {
152 }
153
155 {
156 if (team == TEAM_ALLIANCE)
157 {
160 }
161 else
162 {
165 }
167 }
168
171
172 if (team == TEAM_ALLIANCE)
174 else
176 // update achievement flags
177 // we increased m_TeamScores[team] so we just need to check if it is 500 more than other teams resources
178 uint8 otherTeam = (team + 1) % PVP_TEAMS_COUNT;
179 if (m_TeamScores[team] > m_TeamScores[otherTeam] + 500)
180 m_TeamScores500Disadvantage[otherTeam] = true;
181 }
182 }
183
184 // Test win condition
189 }
190}
191
210
212{
213 // spawn neutral banners
214 for (int banner = BG_AB_OBJECT_BANNER_NEUTRAL, i = 0; i < 5; banner += 8, ++i)
216 for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
217 {
218 //randomly select buff to spawn
219 uint8 buff = urand(0, 2);
221 }
224
225 // Achievement: Let's Get This Done
227}
228
230{
231 bool const isInBattleground = IsPlayerInBattleground(player->GetGUID());
233 if (!isInBattleground)
234 PlayerScores[player->GetGUID()] = new BattlegroundABScore(player->GetGUID());
235}
236
237void BattlegroundAB::RemovePlayer(Player* /*player*/, ObjectGuid /*guid*/, uint32 /*team*/)
238{
239}
240
242{
244 return;
245
246 switch (trigger)
247 {
248 case 3948: // Arathi Basin Alliance Exit.
249 if (player->GetTeam() != ALLIANCE)
250 player->GetSession()->SendAreaTriggerMessage("Only The Alliance can use that portal");
251 else
252 player->LeaveBattleground();
253 break;
254 case 3949: // Arathi Basin Horde Exit.
255 if (player->GetTeam() != HORDE)
256 player->GetSession()->SendAreaTriggerMessage("Only The Horde can use that portal");
257 else
258 player->LeaveBattleground();
259 break;
260 case 3866: // Stables
261 case 3869: // Gold Mine
262 case 3867: // Farm
263 case 3868: // Lumber Mill
264 case 3870: // Black Smith
265 case 4020: // Unk1
266 case 4021: // Unk2
267 case 4674: // Unk3
268 //break;
269 default:
270 Battleground::HandleAreaTrigger(player, trigger);
271 break;
272 }
273}
274
275/* type: 0-neutral, 1-contested, 3-occupied
276 teamIndex: 0-ally, 1-horde */
277void BattlegroundAB::_CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool delay)
278{
279 // Just put it into the queue
280 if (delay)
281 {
282 m_BannerTimers[node].timer = 2000;
283 m_BannerTimers[node].type = type;
284 m_BannerTimers[node].teamIndex = teamIndex;
285 return;
286 }
287
288 uint8 obj = node*8 + type + teamIndex;
289
291
292 // handle aura with banner
293 if (!type)
294 return;
295 obj = node * 8 + ((type == BG_AB_NODE_TYPE_OCCUPIED) ? (5 + teamIndex) : 7);
297}
298
299void BattlegroundAB::_DelBanner(uint8 node, uint8 type, uint8 teamIndex)
300{
301 uint8 obj = node*8 + type + teamIndex;
303
304 // handle aura with banner
305 if (!type)
306 return;
307 obj = node * 8 + ((type == BG_AB_NODE_TYPE_OCCUPIED) ? (5 + teamIndex) : 7);
309}
310
312{
313 const uint8 plusArray[] = {0, 2, 3, 0, 1};
314
315 // Node icons
316 for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node)
317 packet.Worldstates.emplace_back(BG_AB_OP_NODEICONS[node], (m_Nodes[node] == 0) ? 1 : 0);
318
319 // Node occupied states
320 for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node)
321 for (uint8 itr = 1; itr < BG_AB_DYNAMIC_NODES_COUNT; ++itr)
322 packet.Worldstates.emplace_back(BG_AB_OP_NODESTATES[node] + plusArray[itr], (m_Nodes[node] == itr) ? 1 : 0);
323
324 // How many bases each team owns
325 int32 ally = 0, horde = 0;
326 for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node)
328 ++ally;
330 ++horde;
331
332 packet.Worldstates.emplace_back(BG_AB_OP_OCCUPIED_BASES_ALLY, ally);
333 packet.Worldstates.emplace_back(BG_AB_OP_OCCUPIED_BASES_HORDE, horde);
334
335 // Team scores
340
341 // other unknown BG_AB_UNK_01
342 packet.Worldstates.emplace_back(1861, 2);
343}
344
346{
347 // Send node owner state update to refresh map icons on client
348 const uint8 plusArray[] = {0, 2, 3, 0, 1};
349
350 if (m_prevNodes[node])
351 UpdateWorldState(BG_AB_OP_NODESTATES[node] + plusArray[m_prevNodes[node]], 0);
352 else
354
355 UpdateWorldState(BG_AB_OP_NODESTATES[node] + plusArray[m_Nodes[node]], 1);
356
357 // How many bases each team owns
358 uint8 ally = 0, horde = 0;
359 for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
361 ++ally;
363 ++horde;
364
367}
368
370{
372 TC_LOG_ERROR("bg.battleground", "Failed to spawn spirit guide! point: {}, team: {}, ", node, team);
373
374 if (node >= BG_AB_DYNAMIC_NODES_COUNT)//only dynamic nodes, no start points
375 return;
376
377 uint8 capturedNodes = 0;
378 for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
380 ++capturedNodes;
381
382 if (capturedNodes >= 5)
384 if (capturedNodes >= 4)
386
387 Creature* trigger = !BgCreatures[node + 7] ? GetBGCreature(node + 7) : nullptr; // 0-6 spirit guides
388 if (!trigger)
389 trigger = AddCreature(WORLD_TRIGGER, node+7, BG_AB_NodePositions[node], GetTeamIndexByTeamId(team));
390
391 //add bonus honor aura trigger creature when node is accupied
392 //cast bonus aura (+50% honor in 25yards)
393 //aura should only apply to players who have accupied the node, set correct faction for trigger
394 if (trigger)
395 {
397 trigger->CastSpell(trigger, SPELL_HONORABLE_DEFENDER_25Y, false);
398 }
399}
400
402{
403 //only dynamic nodes, no start points
404 if (node >= BG_AB_DYNAMIC_NODES_COUNT)
405 return;
406
407 //remove bonus honor aura trigger creature when node is lost
408 DelCreature(node+7);//NULL checks are in DelCreature! 0-6 spirit guides
409
411
412 DelCreature(node);
413
414 // buff object isn't despawned
415}
416
417/* Invoked if a player used a banner as a gameobject */
419{
421 return;
422
424 GameObject* obj = GetBgMap()->GetGameObject(BgObjects[node*8+7]);
425 while ((node < BG_AB_DYNAMIC_NODES_COUNT) && ((!obj) || (!source->IsWithinDistInMap(obj, 10))))
426 {
427 ++node;
429 }
430
431 if (node == BG_AB_DYNAMIC_NODES_COUNT)
432 {
433 // this means our player isn't close to any of banners - maybe cheater ??
434 return;
435 }
436
437 TeamId teamIndex = GetTeamIndexByTeamId(source->GetTeam());
438
439 // Check if player really could use this banner, not cheated
440 if (!(m_Nodes[node] == 0 || teamIndex == m_Nodes[node]%2))
441 return;
442
444 uint32 sound = 0;
445 // If node is neutral, change to contested
446 if (m_Nodes[node] == BG_AB_NODE_TYPE_NEUTRAL)
447 {
449 m_prevNodes[node] = m_Nodes[node];
450 m_Nodes[node] = teamIndex + 1;
451 // burn current neutral banner
453 // create new contested banner
454 _CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true);
455 _SendNodeUpdate(node);
457
458 if (teamIndex == TEAM_ALLIANCE)
459 SendBroadcastText(ABNodes[node].TextAllianceClaims, CHAT_MSG_BG_SYSTEM_ALLIANCE, source);
460 else
461 SendBroadcastText(ABNodes[node].TextHordeClaims, CHAT_MSG_BG_SYSTEM_HORDE, source);
462
464 }
465 // If node is contested
467 {
468 // If last state is NOT occupied, change node to enemy-contested
470 {
472 m_prevNodes[node] = m_Nodes[node];
473 m_Nodes[node] = uint8(teamIndex) + BG_AB_NODE_TYPE_CONTESTED;
474 // burn current contested banner
475 _DelBanner(node, BG_AB_NODE_TYPE_CONTESTED, !teamIndex);
476 // create new contested banner
477 _CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true);
478 _SendNodeUpdate(node);
480
481 if (teamIndex == TEAM_ALLIANCE)
482 SendBroadcastText(ABNodes[node].TextAllianceAssaulted, CHAT_MSG_BG_SYSTEM_ALLIANCE, source);
483 else
484 SendBroadcastText(ABNodes[node].TextHordeAssaulted, CHAT_MSG_BG_SYSTEM_HORDE, source);
485 }
486 // If contested, change back to occupied
487 else
488 {
490 m_prevNodes[node] = m_Nodes[node];
491 m_Nodes[node] = uint8(teamIndex) + BG_AB_NODE_TYPE_OCCUPIED;
492 // burn current contested banner
493 _DelBanner(node, BG_AB_NODE_TYPE_CONTESTED, !teamIndex);
494 // create new occupied banner
495 _CreateBanner(node, BG_AB_NODE_TYPE_OCCUPIED, teamIndex, true);
496 _SendNodeUpdate(node);
497 m_NodeTimers[node] = 0;
498 _NodeOccupied(node, (teamIndex == TEAM_ALLIANCE) ? ALLIANCE : HORDE);
499
500 if (teamIndex == TEAM_ALLIANCE)
501 SendBroadcastText(ABNodes[node].TextAllianceDefended, CHAT_MSG_BG_SYSTEM_ALLIANCE, source);
502 else
503 SendBroadcastText(ABNodes[node].TextHordeDefended, CHAT_MSG_BG_SYSTEM_HORDE, source);
504 }
506 }
507 // If node is occupied, change to enemy-contested
508 else
509 {
511 m_prevNodes[node] = m_Nodes[node];
512 m_Nodes[node] = uint8(teamIndex) + BG_AB_NODE_TYPE_CONTESTED;
513 // burn current occupied banner
514 _DelBanner(node, BG_AB_NODE_TYPE_OCCUPIED, !teamIndex);
515 // create new contested banner
516 _CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true);
517 _SendNodeUpdate(node);
518 _NodeDeOccupied(node);
520
521 if (teamIndex == TEAM_ALLIANCE)
522 SendBroadcastText(ABNodes[node].TextAllianceAssaulted, CHAT_MSG_BG_SYSTEM_ALLIANCE, source);
523 else
524 SendBroadcastText(ABNodes[node].TextHordeAssaulted, CHAT_MSG_BG_SYSTEM_HORDE, source);
525
527 }
528
529 // If node is occupied again, send "X has taken the Y" msg.
531 {
532 if (teamIndex == TEAM_ALLIANCE)
533 SendBroadcastText(ABNodes[node].TextAllianceTaken, CHAT_MSG_BG_SYSTEM_ALLIANCE);
534 else
536 }
537 PlaySoundToAll(sound);
538}
539
541{
542 // How many bases each team owns
543 uint8 ally = 0, horde = 0;
544 for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
546 ++ally;
548 ++horde;
549
550 if (ally > horde)
551 return ALLIANCE;
552 else if (horde > ally)
553 return HORDE;
554
555 // If the values are equal, fall back to the original result (based on number of players on each team)
557}
558
560{
561 for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
562 {
563 if (!AddObject(BG_AB_OBJECT_BANNER_NEUTRAL + 8*i, BG_AB_OBJECTID_NODE_BANNER_0 + i, BG_AB_NodePositions[i], 0, 0, std::sin(BG_AB_NodePositions[i].GetOrientation()/2), std::cos(BG_AB_NodePositions[i].GetOrientation()/2), RESPAWN_ONE_DAY)
564 || !AddObject(BG_AB_OBJECT_BANNER_CONT_A + 8*i, BG_AB_OBJECTID_BANNER_CONT_A, BG_AB_NodePositions[i], 0, 0, std::sin(BG_AB_NodePositions[i].GetOrientation()/2), std::cos(BG_AB_NodePositions[i].GetOrientation()/2), RESPAWN_ONE_DAY)
565 || !AddObject(BG_AB_OBJECT_BANNER_CONT_H + 8*i, BG_AB_OBJECTID_BANNER_CONT_H, BG_AB_NodePositions[i], 0, 0, std::sin(BG_AB_NodePositions[i].GetOrientation()/2), std::cos(BG_AB_NodePositions[i].GetOrientation()/2), RESPAWN_ONE_DAY)
566 || !AddObject(BG_AB_OBJECT_BANNER_ALLY + 8*i, BG_AB_OBJECTID_BANNER_A, BG_AB_NodePositions[i], 0, 0, std::sin(BG_AB_NodePositions[i].GetOrientation()/2), std::cos(BG_AB_NodePositions[i].GetOrientation()/2), RESPAWN_ONE_DAY)
567 || !AddObject(BG_AB_OBJECT_BANNER_HORDE + 8*i, BG_AB_OBJECTID_BANNER_H, BG_AB_NodePositions[i], 0, 0, std::sin(BG_AB_NodePositions[i].GetOrientation()/2), std::cos(BG_AB_NodePositions[i].GetOrientation()/2), RESPAWN_ONE_DAY)
568 || !AddObject(BG_AB_OBJECT_AURA_ALLY + 8*i, BG_AB_OBJECTID_AURA_A, BG_AB_NodePositions[i], 0, 0, std::sin(BG_AB_NodePositions[i].GetOrientation()/2), std::cos(BG_AB_NodePositions[i].GetOrientation()/2), RESPAWN_ONE_DAY)
569 || !AddObject(BG_AB_OBJECT_AURA_HORDE + 8*i, BG_AB_OBJECTID_AURA_H, BG_AB_NodePositions[i], 0, 0, std::sin(BG_AB_NodePositions[i].GetOrientation()/2), std::cos(BG_AB_NodePositions[i].GetOrientation()/2), RESPAWN_ONE_DAY)
570 || !AddObject(BG_AB_OBJECT_AURA_CONTESTED + 8*i, BG_AB_OBJECTID_AURA_C, BG_AB_NodePositions[i], 0, 0, std::sin(BG_AB_NodePositions[i].GetOrientation()/2), std::cos(BG_AB_NodePositions[i].GetOrientation()/2), RESPAWN_ONE_DAY))
571 {
572 TC_LOG_ERROR("sql.sql", "BatteGroundAB: Failed to spawn some object Battleground not created!");
573 return false;
574 }
575 }
576
579 {
580 TC_LOG_ERROR("sql.sql", "BatteGroundAB: Failed to spawn door object Battleground not created!");
581 return false;
582 }
583
584 //buffs
585 for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
586 {
590 TC_LOG_ERROR("sql.sql", "BatteGroundAB: Failed to spawn buff object!");
591 }
592
593 return true;
594}
595
597{
598 //call parent's class reset
600
610 bool isBGWeekend = sBattlegroundMgr->IsBGWeekend(GetTypeID());
615
616 for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
617 {
618 m_Nodes[i] = 0;
619 m_prevNodes[i] = 0;
620 m_NodeTimers[i] = 0;
621 m_BannerTimers[i].timer = 0;
622 }
623
624 for (uint8 i = 0; i < BG_AB_ALL_NODES_COUNT + 5; ++i)//+5 for aura triggers
625 if (!BgCreatures[i].IsEmpty())
626 DelCreature(i);
627}
628
630{
631 // Win reward
632 if (winner == ALLIANCE)
634 if (winner == HORDE)
636 // Complete map_end rewards (even if no team wins)
639
641}
642
644{
645 TeamId teamIndex = GetTeamIndexByTeamId(player->GetTeam());
646
647 // Is there any occupied node for this team?
648 std::vector<uint8> nodes;
649 for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
650 if (m_Nodes[i] == teamIndex + 3)
651 nodes.push_back(i);
652
653 WorldSafeLocsEntry const* good_entry = nullptr;
654 // If so, select the closest node to place ghost on
655 if (!nodes.empty())
656 {
657 float plr_x = player->GetPositionX();
658 float plr_y = player->GetPositionY();
659
660 float mindist = 999999.0f;
661 for (uint8 i = 0; i < nodes.size(); ++i)
662 {
663 WorldSafeLocsEntry const* entry = sWorldSafeLocsStore.LookupEntry(BG_AB_GraveyardIds[nodes[i]]);
664 if (!entry)
665 continue;
666 float dist = (entry->Loc.X - plr_x)*(entry->Loc.X - plr_x)+(entry->Loc.Y - plr_y)*(entry->Loc.Y - plr_y);
667 if (mindist > dist)
668 {
669 mindist = dist;
670 good_entry = entry;
671 }
672 }
673 nodes.clear();
674 }
675 // If not, place ghost on starting location
676 if (!good_entry)
677 good_entry = sWorldSafeLocsStore.LookupEntry(BG_AB_GraveyardIds[teamIndex+5]);
678
679 return good_entry;
680}
681
682bool BattlegroundAB::UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor)
683{
684 if (!Battleground::UpdatePlayerScore(player, type, value, doAddHonor))
685 return false;
686
687 switch (type)
688 {
691 break;
694 break;
695 default:
696 break;
697 }
698 return true;
699}
700
702{
703 uint32 count = 0;
704 for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
705 if ((team == ALLIANCE && m_Nodes[i] == BG_AB_NODE_STATUS_ALLY_OCCUPIED) ||
707 ++count;
708
709 return count == BG_AB_DYNAMIC_NODES_COUNT;
710}
711
712bool BattlegroundAB::CheckAchievementCriteriaMeet(uint32 criteriaId, Player const* player, Unit const* target, uint32 miscvalue)
713{
714 switch (criteriaId)
715 {
718 }
719
720 return Battleground::CheckAchievementCriteriaMeet(criteriaId, player, target, miscvalue);
721}
Position const BG_AB_NodePositions[BG_AB_DYNAMIC_NODES_COUNT]
#define BG_AB_ABBGWeekendReputationTicks
const uint32 BG_AB_TickPoints[6]
Position const BG_AB_SpiritGuidePos[BG_AB_ALL_NODES_COUNT]
@ BG_AB_OBJECT_BANNER_HORDE
@ BG_AB_OBJECT_BANNER_ALLY
@ BG_AB_OBJECT_GATE_A
@ BG_AB_OBJECT_AURA_HORDE
@ BG_AB_OBJECT_MAX
@ BG_AB_OBJECT_GATE_H
@ BG_AB_OBJECT_BANNER_NEUTRAL
@ BG_AB_OBJECT_BANNER_CONT_H
@ BG_AB_OBJECT_SPEEDBUFF_STABLES
@ BG_AB_OBJECT_BANNER_CONT_A
@ BG_AB_OBJECT_AURA_ALLY
@ BG_AB_OBJECT_AURA_CONTESTED
#define AB_EVENT_START_BATTLE
const float BG_AB_BuffPositions[BG_AB_DYNAMIC_NODES_COUNT][4]
@ BG_AB_TEXT_ALLIANCE_NEAR_VICTORY
@ BG_AB_TEXT_HORDE_NEAR_VICTORY
@ BG_AB_NODE_TYPE_OCCUPIED
@ BG_AB_NODE_STATUS_ALLY_CONTESTED
@ BG_AB_NODE_STATUS_ALLY_OCCUPIED
@ BG_AB_NODE_STATUS_HORDE_OCCUPIED
@ BG_AB_NODE_STATUS_HORDE_CONTESTED
@ BG_AB_NODE_TYPE_NEUTRAL
@ BG_AB_NODE_TYPE_CONTESTED
const uint32 BG_AB_TickIntervals[6]
ABNodeInfo const ABNodes[BG_AB_DYNAMIC_NODES_COUNT]
const float BG_AB_DoorPositions[2][8]
const uint32 BG_AB_GraveyardIds[BG_AB_ALL_NODES_COUNT]
@ BG_AB_OBJECTID_BANNER_CONT_A
@ BG_AB_OBJECTID_BANNER_A
@ BG_AB_OBJECTID_AURA_A
@ BG_AB_OBJECTID_BANNER_H
@ BG_AB_OBJECTID_AURA_C
@ BG_AB_OBJECTID_AURA_H
@ BG_AB_OBJECTID_GATE_A
@ BG_AB_OBJECTID_BANNER_CONT_H
@ BG_AB_OBJECTID_GATE_H
@ BG_AB_NODE_STABLES
@ BG_AB_ALL_NODES_COUNT
@ BG_AB_DYNAMIC_NODES_COUNT
@ BG_AB_SPIRIT_HORDE
@ BG_AB_SPIRIT_ALIANCE
#define BG_AB_NotABBGWeekendReputationTicks
#define BG_AB_NotABBGWeekendHonorTicks
const uint32 BG_AB_OP_NODEICONS[5]
@ BG_AB_OBJECTID_NODE_BANNER_0
@ BG_AB_FLAG_CAPTURING_TIME
#define BG_AB_ABBGWeekendHonorTicks
@ AB_OBJECTIVE_ASSAULT_BASE
@ AB_OBJECTIVE_DEFEND_BASE
const uint32 BG_AB_OP_NODESTATES[5]
@ BG_AB_OP_RESOURCES_ALLY
@ BG_AB_OP_RESOURCES_MAX
@ BG_AB_OP_OCCUPIED_BASES_HORDE
@ BG_AB_OP_RESOURCES_HORDE
@ BG_AB_OP_RESOURCES_WARNING
@ BG_AB_OP_OCCUPIED_BASES_ALLY
@ BG_AB_WARNING_NEAR_VICTORY_SCORE
@ BG_AB_MAX_TEAM_SCORE
@ BG_AB_SOUND_NEAR_VICTORY_ALLIANCE
@ BG_AB_SOUND_NODE_CAPTURED_HORDE
@ BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE
@ BG_AB_SOUND_NODE_ASSAULTED_HORDE
@ BG_AB_SOUND_NEAR_VICTORY_HORDE
@ BG_AB_SOUND_NODE_CLAIMED
@ BG_AB_SOUND_NODE_CAPTURED_ALLIANCE
#define sBattlegroundMgr
@ SCORE_BASES_ASSAULTED
@ SCORE_BASES_DEFENDED
@ BG_CRITERIA_CHECK_RESILIENT_VICTORY
@ RESPAWN_IMMEDIATELY
@ RESPAWN_ONE_DAY
const uint32 Buff_Entries[3]
@ SPELL_HONORABLE_DEFENDER_25Y
@ STATUS_IN_PROGRESS
@ SPELL_AB_QUEST_REWARD_4_BASES
@ SPELL_AB_QUEST_REWARD_5_BASES
@ ACHIEVEMENT_TIMED_TYPE_EVENT
Definition DBCEnums.h:122
@ ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE
Definition DBCEnums.h:156
DBCStorage< WorldSafeLocsEntry > sWorldSafeLocsStore(WorldSafeLocsEntryfmt)
uint8_t uint8
Definition Define.h:135
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
#define TC_LOG_ERROR(filterType__,...)
Definition Log.h:165
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
TeamId
@ TEAM_ALLIANCE
@ TEAM_HORDE
uint8 constexpr PVP_TEAMS_COUNT
@ ALLIANCE
@ HORDE
@ CHAT_MSG_BG_SYSTEM_ALLIANCE
@ CHAT_MSG_BG_SYSTEM_HORDE
@ CHAT_MSG_BG_SYSTEM_NEUTRAL
@ FACTION_ALLIANCE_GENERIC
@ FACTION_HORDE_GENERIC
@ AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT
#define WORLD_TRIGGER
Definition Unit.h:35
void FillInitialWorldStates(WorldPackets::WorldState::InitWorldStates &packet) override
WorldSafeLocsEntry const * GetClosestGraveyard(Player *player) override
void _NodeOccupied(uint8 node, Team team)
bool m_TeamScores500Disadvantage[PVP_TEAMS_COUNT]
bool IsAllNodesControlledByTeam(uint32 team) const override
void StartingEventOpenDoors() override
void StartingEventCloseDoors() override
void EventPlayerClickedOnFlag(Player *source, GameObject *target_obj) override
uint32 GetPrematureWinner() override
bool SetupBattleground() override
void RemovePlayer(Player *player, ObjectGuid guid, uint32 team) override
void Reset() override
void _SendNodeUpdate(uint8 node)
uint32 m_NodeTimers[BG_AB_DYNAMIC_NODES_COUNT]
uint8 m_Nodes[BG_AB_DYNAMIC_NODES_COUNT]
uint32 m_HonorScoreTics[PVP_TEAMS_COUNT]
bool CheckAchievementCriteriaMeet(uint32, Player const *, Unit const *=nullptr, uint32=0) override
void HandleAreaTrigger(Player *Source, uint32 Trigger) override
void _CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool delay)
void _DelBanner(uint8 node, uint8 type, uint8 teamIndex)
uint32 m_ReputationScoreTics[PVP_TEAMS_COUNT]
void PostUpdateImpl(uint32 diff) override
Post-update hook.
uint8 m_prevNodes[BG_AB_DYNAMIC_NODES_COUNT]
bool UpdatePlayerScore(Player *player, uint32 type, uint32 value, bool doAddHonor=true) override
uint32 m_lastTick[PVP_TEAMS_COUNT]
void _NodeDeOccupied(uint8 node)
void AddPlayer(Player *player) override
BG_AB_BannerTimer m_BannerTimers[BG_AB_DYNAMIC_NODES_COUNT]
void EndBattleground(uint32 winner) override
virtual void AddPlayer(Player *player)
BattlegroundTypeId GetTypeID(bool GetRandom=false) const
virtual void EndBattleground(uint32 winner)
virtual Creature * AddCreature(uint32 entry, uint32 type, float x, float y, float z, float o, TeamId teamId=TEAM_NEUTRAL, uint32 respawntime=0, Transport *transport=nullptr)
void RelocateDeadPlayers(ObjectGuid guideGuid)
Relocate all players in ReviveQueue to the closest graveyard.
void CastSpellOnTeam(uint32 SpellID, uint32 TeamID)
static TeamId GetTeamIndexByTeamId(uint32 Team)
void DoorOpen(uint32 type)
bool DelCreature(uint32 type)
void SpawnBGObject(uint32 type, uint32 respawntime)
virtual void Reset()
virtual 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, GOState goState=GO_STATE_READY)
GuidVector BgObjects
Creature * GetBGCreature(uint32 type, bool logError=true)
BattlegroundMap * GetBgMap() const
virtual bool AddSpiritGuide(uint32 type, float x, float y, float z, float o, TeamId teamId=TEAM_NEUTRAL)
void DoorClose(uint32 type)
int32 m_TeamScores[PVP_TEAMS_COUNT]
GuidVector BgCreatures
bool IsPlayerInBattleground(ObjectGuid guid) const
void SendBroadcastText(uint32 id, ChatMsg msgType, WorldObject const *target=nullptr)
BattlegroundScoreMap PlayerScores
void RewardHonorToTeam(uint32 Honor, uint32 TeamID)
BattlegroundStatus GetStatus() const
virtual bool UpdatePlayerScore(Player *player, uint32 type, uint32 value, bool doAddHonor=true)
virtual void HandleAreaTrigger(Player *, uint32)
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry)
virtual bool CheckAchievementCriteriaMeet(uint32, Player const *, Unit const *=nullptr, uint32=0)
void UpdateWorldState(uint32 variable, uint32 value)
uint32 GetBonusHonorFromKill(uint32 kills) const
void RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID)
void PlaySoundToAll(uint32 soundID)
virtual uint32 GetPrematureWinner()
GameObject * GetGameObject(ObjectGuid const &guid)
Definition Map.cpp:4430
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
uint32 GetTeam() const
Definition Player.h:1832
void LeaveBattleground(bool teleportToEntryPoint=true, bool withoutDeserterDebuff=false)
Definition Player.cpp:21955
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, WorldObject *ref=nullptr)
Definition Player.cpp:24940
WorldSession * GetSession() const
Definition Player.h:1719
Definition Unit.h:769
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0)
Definition Unit.cpp:4022
void SetFaction(uint32 faction) override
Definition Unit.h:974
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1192
std::vector< WorldStateInfo > Worldstates
void SendAreaTriggerMessage(char const *Text,...) ATTR_PRINTF(2
void BuildObjectivesBlock(WorldPackets::Battleground::PVPLogData_Player &playerData) override
float GetPositionX() const
Definition Position.h:79
float GetPositionY() const
Definition Position.h:80
DBCPosition3D Loc