Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
BattlegroundSA.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "BattlegroundSA.h"
7#include "BattlegroundMgr.h"
8#include "GameObject.h"
9#include "Language.h"
10#include "ObjectMgr.h"
11#include "Player.h"
12#include "WorldPacket.h"
13#include "WorldSession.h"
14
15#include <ctime>
16#include <sstream>
17#include <vector>
18
34
36
38{
39 TotalTime = 0;
40 Attackers = (std::rand() % 2) ? TEAM_ALLIANCE : TEAM_HORDE;
41 for (uint8 i = 0; i <= 5; i++)
43 ShipsStarted = false;
48 gateDestroyed = false;
52}
53
55{
56 return ResetObjs();
57}
58
60{
61 for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
62 if (Player* player = ObjectAccessor::FindPlayer(itr->first))
64
67
68 for (uint8 i = 0; i < BG_SA_MAXOBJ; i++)
69 DelObject(i);
70
71 for (uint8 i = 0; i < BG_SA_MAXNPC; i++)
72 DelCreature(i);
73
74 for (uint8 i = BG_SA_MAXNPC; i < BG_SA_MAXNPC + BG_SA_MAX_GY; i++)
75 DelCreature(i);
76
77 for (uint8 i = 0; i < 6; i++)
79
80 for (uint8 i = 0; i <= BG_SA_PORTAL_DEFFENDER_RED; i++)
81 {
83 return false;
84 }
85
86 for (uint8 i = BG_SA_BOAT_ONE; i <= BG_SA_BOAT_TWO; i++)
87 {
88 uint32 boatid = 0;
89 switch (i)
90 {
91 case BG_SA_BOAT_ONE:
93 break;
94 case BG_SA_BOAT_TWO:
96 break;
97 default:
98 break;
99 }
100 if (!AddObject(i, boatid, BG_SA_ObjSpawnlocs[i][0],
101 BG_SA_ObjSpawnlocs[i][1],
102 BG_SA_ObjSpawnlocs[i][2] + (Attackers ? -3.750f : 0),
103 BG_SA_ObjSpawnlocs[i][3], 0, 0, 0, 0, RESPAWN_ONE_DAY))
104 return false;
105 }
106
107 for (uint8 i = BG_SA_SIGIL_1; i <= BG_SA_LEFT_FLAGPOLE; i++)
108 {
109 if (!AddObject(i, BG_SA_ObjEntries[i],
112 0, 0, 0, 0, RESPAWN_ONE_DAY))
113 return false;
114 }
115
116 // MAD props for Kiper for discovering those values - 4 hours of his work.
123
124 //Cannons and demolishers - NPCs are spawned
125 //By capturing GYs.
126 for (uint8 i = 0; i < BG_SA_DEMOLISHER_5; i++)
127 {
130 BG_SA_NpcSpawnlocs[i][2], BG_SA_NpcSpawnlocs[i][3], 600))
131 return false;
132 }
133
136
137 for (uint8 i = 0; i <= BG_SA_PORTAL_DEFFENDER_RED; i++)
138 {
141 }
142
145
146 for (uint8 i = 0; i <= 5; i++)
148
149 TotalTime = 0;
150 ShipsStarted = false;
151 BoatDebugTimerActive = false;
155
156 //Graveyards
157 for (uint8 i = 0; i < BG_SA_MAX_GY; i++)
158 {
159 WorldSafeLocsEntry const* sg = NULL;
160 sg = sWorldSafeLocsStore.LookupEntry(BG_SA_GYEntries[i]);
161
162 if (!sg)
163 {
164 SF_LOG_ERROR("bg.battleground", "SOTA: Can't find GY entry %u", BG_SA_GYEntries[i]);
165 return false;
166 }
167
168 if (i == BG_SA_BEACH_GY)
169 {
172 }
173 else
174 {
176 if (!AddSpiritGuide(i + BG_SA_MAXNPC, sg->x, sg->y, sg->z, BG_SA_GYOrientation[i], ((Attackers == TEAM_HORDE) ? ALLIANCE : HORDE)))
177 SF_LOG_ERROR("bg.battleground", "SOTA: couldn't spawn GY: %u", i);
178 }
179 }
180
181 //GY capture points
182 for (uint8 i = BG_SA_CENTRAL_FLAG; i <= BG_SA_LEFT_FLAG; i++)
183 {
184 AddObject(i, (BG_SA_ObjEntries[i] - (Attackers == TEAM_ALLIANCE ? 1 : 0)),
187 0, 0, 0, 0, RESPAWN_ONE_DAY);
189 }
190
191 for (uint8 i = BG_SA_BOMB; i < BG_SA_MAXOBJ; i++)
192 {
196 0, 0, 0, 0, RESPAWN_ONE_DAY);
198 }
199
200 //Player may enter BEFORE we set up BG - lets update his worldstates anyway...
204
208
210 {
213
218
221 }
222 else
223 {
226
231
234 }
235
242
243 for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
244 if (Player* player = ObjectAccessor::FindPlayer(itr->first))
245 SendTransportInit(player);
246
247 // set status manually so preparation is cast correctly in 2nd round too
249
251 return true;
252}
253
255{
256 if (ShipsStarted)
257 return;
258
261 if (!boatOne || !boatTwo)
262 {
263 SF_LOG_ERROR("bg.battleground", "SOTA: cannot start ships, one or more boat objects are missing");
264 return;
265 }
266
267 uint32 shipTravelTime = 0;
269 shipTravelTime = BG_SA_WARMUPLENGTH - TotalTime;
271 shipTravelTime = 60 * IN_MILLISECONDS - TotalTime;
272
273 boatOne->StartLegacyTransportToFirstStop(shipTravelTime);
274 boatTwo->StartLegacyTransportToFirstStop(shipTravelTime);
275
277
278 ShipsStarted = true;
279}
280
282{
283 for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
284 {
285 Player* player = ObjectAccessor::FindPlayer(itr->first);
286 if (!player)
287 continue;
288
289 UpdateData createData(player->GetMapId());
290 for (uint8 i = BG_SA_BOAT_ONE; i <= BG_SA_BOAT_TWO; ++i)
291 {
292 if (GameObject* transport = GetBGObject(i))
293 transport->BuildValuesUpdateBlockForPlayer(&createData, player);
294 }
295
296 WorldPacket createPacket;
297 createData.BuildPacket(&createPacket);
298 player->SendDirectMessage(&createPacket);
299 }
300}
301
303{
305 return;
306
308 if (WorldSession* session = player->GetSession())
309 session->SendNotification("SOTA boat travel: %u ms", GetMSTimeDiffToNow(BoatDebugStartTime));
310}
311
312void BattlegroundSA::LogBoatDebugMarker(Player* player, char const* action, uint32 elapsedMs)
313{
314 if (!player)
315 return;
316
317 if (WorldSession* session = player->GetSession())
318 {
319 std::ostringstream marker;
320 marker << "SOTA_BOAT_DEBUG action=" << action
321 << " elapsed_ms=" << elapsedMs
322 << " bg_instance=" << GetInstanceID();
323 session->LogPacketMarker(marker.str());
324 }
325}
326
328{
331 if (!boatOne || !boatTwo)
332 return false;
333
337
341 BoatDebugPlayerGuid = player ? player->GetGUID() : 0;
342 ShipsStarted = true;
343 LogBoatDebugMarker(player, "start");
345 return true;
346}
347
349{
352 if (!boatOne || !boatTwo)
353 return false;
354
359
360 BoatDebugTimerActive = false;
364 ShipsStarted = true;
365 LogBoatDebugMarker(player, "stop", elapsedMs);
366 return true;
367}
368
370{
371 std::ostringstream status;
372 status << "boatsStarted=" << (ShipsStarted ? 1 : 0)
373 << " timerActive=" << (BoatDebugTimerActive ? 1 : 0);
374
375 for (uint8 i = BG_SA_BOAT_ONE; i <= BG_SA_BOAT_TWO; ++i)
376 {
377 GameObject* transport = GetBGObject(i);
378 if (!transport)
379 {
380 status << " boat" << uint32(i) << "=missing";
381 continue;
382 }
383
384 status << " boat" << uint32(i)
385 << "{entry=" << transport->GetEntry()
386 << " state=" << uint32(transport->GetGoState())
387 << " progress=" << transport->GetTransportPathProgress()
388 << " period=" << transport->GetTransportPeriod()
389 << "}";
390 }
391
392 return status.str();
393}
394
396{
397 if (ShipsStarted)
398 return true;
399
400 if (Status == BG_SA_WARMUP)
401 return TotalTime >= BG_SA_BOAT_START;
402
403 return Status == BG_SA_SECOND_WARMUP;
404}
405
407{
408 if (!sBattlegroundMgr->isTesting())
409 return false;
410
412 return false;
413
414 uint32 activePlayers = 0;
415 for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
416 {
417 Player* player = ObjectAccessor::FindPlayer(itr->first);
418 if (!player)
419 continue;
420
421 if (player->GetMapId() != GetMapId() || player->GetInstanceId() != GetInstanceID())
422 continue;
423
424 if (++activePlayers >= 2)
425 return false;
426 }
427
428 return true;
429}
430
432{
433 if (InitSecondRound)
434 {
435 if (UpdateWaitTimer < diff)
436 {
437 if (!SignaledRoundTwo)
438 {
439 SignaledRoundTwo = true;
440 InitSecondRound = false;
442 }
443 }
444 else
445 {
446 UpdateWaitTimer -= diff;
447 return;
448 }
449 }
450
451 TotalTime += diff;
453 {
454 if (BoatDebugUpdateTimer <= diff)
455 {
458 }
459 else
460 BoatDebugUpdateTimer -= diff;
461 }
462
463 if (Status == BG_SA_WARMUP)
464 {
467 {
468 TotalTime = 0;
469 ToggleTimer();
473 }
475 StartShips();
476 return;
477 }
478 else if (Status == BG_SA_SECOND_WARMUP)
479 {
480 if (RoundScores[0].time < BG_SA_ROUNDLENGTH)
481 EndRoundTimer = RoundScores[0].time;
482 else
484
485 if (TotalTime >= 60000)
486 {
488 TotalTime = 0;
489 ToggleTimer();
493 // status was set to STATUS_WAIT_JOIN manually for Preparation, set it back now
495 for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
496 if (Player* p = ObjectAccessor::FindPlayer(itr->first))
497 p->RemoveAurasDueToSpell(SPELL_PREPARATION);
498 }
499 if (TotalTime >= 30000)
500 {
502 {
505 }
506 }
507 StartShips();
508 return;
509 }
510 else if (GetStatus() == STATUS_IN_PROGRESS)
511 {
512 if (Status == BG_SA_ROUND_ONE)
513 {
515 {
516 RoundScores[0].winner = Attackers;
518 TotalTime = 0;
521 UpdateWaitTimer = 5000;
522 SignaledRoundTwo = false;
524 InitSecondRound = true;
525 ToggleTimer();
526 ResetObjs();
527 return;
528 }
529 }
530 else if (Status == BG_SA_ROUND_TWO)
531 {
533 {
536 if (RoundScores[0].time == RoundScores[1].time)
538 else if (RoundScores[0].time < RoundScores[1].time)
540 else
542 return;
543 }
544 }
546 {
547 SendTime();
549 }
550 }
551}
552
554
556
558{
559 uint32 ally_attacks = uint32(Attackers == TEAM_ALLIANCE ? 1 : 0);
560 uint32 horde_attacks = uint32(Attackers == TEAM_HORDE ? 1 : 0);
561
568
569 builder.AppendState(BG_SA_BONUS_TIMER, 0);
570
571 builder.AppendState(BG_SA_HORDE_ATTACKS, horde_attacks);
572 builder.AppendState(BG_SA_ALLY_ATTACKS, ally_attacks);
573
576 builder.AppendState(BG_SA_TIMER_MINS, 0);
579
583
587
588 builder.AppendState(BG_SA_HORDE_DEFENCE_TOKEN, ally_attacks);
589 builder.AppendState(BG_SA_ALLIANCE_DEFENCE_TOKEN, horde_attacks);
590
591 builder.AppendState(BG_SA_LEFT_ATT_TOKEN_HRD, horde_attacks);
592 builder.AppendState(BG_SA_RIGHT_ATT_TOKEN_HRD, horde_attacks);
593 builder.AppendState(BG_SA_RIGHT_ATT_TOKEN_ALL, ally_attacks);
594 builder.AppendState(BG_SA_LEFT_ATT_TOKEN_ALL, ally_attacks);
595}
596
598{
600 //create score and add it to map, default values are set in constructor
602
603 SendTransportInit(player);
604
606 {
607 if (player->GetTeamId() == Attackers)
608 {
609 player->CastSpell(player, 12438, true);//Without this player falls before boat loads...
610
611 if (std::rand() % 2)
612 player->TeleportTo(607, 2682.936f, -830.368f, 15.0f, 2.895f, 0);
613 else
614 player->TeleportTo(607, 2577.003f, 980.261f, 15.0f, 0.807f, 0);
615 }
616 else
617 player->TeleportTo(607, 1209.7f, -65.16f, 70.1f, 0.0f, 0);
618 }
619 else
620 {
621 if (player->GetTeamId() == Attackers)
622 player->TeleportTo(607, 1600.381f, -106.263f, 8.8745f, 3.78f, 0);
623 else
624 player->TeleportTo(607, 1209.7f, -65.16f, 70.1f, 0.0f, 0);
625 }
626 PlayerScores[player->GetGUID()] = sc;
627}
628
629void BattlegroundSA::RemovePlayer(Player* /*player*/, uint64 /*guid*/, uint32 /*team*/) { }
630
631void BattlegroundSA::HandleAreaTrigger(Player* /*Source*/, uint32 /*Trigger*/)
632{
633 // this is wrong way to implement these things. On official it done by gameobject spell cast.
635 return;
636}
637
638void BattlegroundSA::UpdatePlayerScore(Player* Source, uint32 type, uint32 value, bool doAddHonor)
639{
640 BattlegroundScoreMap::iterator itr = PlayerScores.find(Source->GetGUID());
641 if (itr == PlayerScores.end()) // player not found...
642 return;
643
644 if (type == SCORE_DESTROYED_DEMOLISHER)
645 ((BattlegroundSAScore*)itr->second)->demolishers_destroyed += value;
646 else if (type == SCORE_DESTROYED_WALL)
647 ((BattlegroundSAScore*)itr->second)->gates_destroyed += value;
648 else
649 Battleground::UpdatePlayerScore(Source, type, value, doAddHonor);
650}
651
653{
654 for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
655 {
656 if (Player* player = ObjectAccessor::FindPlayer(itr->first))
657 {
658 // should remove spirit of redemption
659 if (player->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
660 player->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT);
661
662 if (!player->IsAlive())
663 {
664 player->ResurrectPlayer(1.0f);
665 player->SpawnCorpseBones();
666 }
667
668 player->ResetAllPowers();
669 player->CombatStopWithPets(true);
670 player->CastSpell(player, SPELL_PREPARATION, true);
671
672 if (player->GetTeamId() == Attackers)
673 {
674 player->CastSpell(player, 12438, true); //Without this player falls before boat loads...
675
676 if (std::rand() % 2)
677 player->TeleportTo(607, 2682.936f, -830.368f, 15.0f, 2.895f, 0);
678 else
679 player->TeleportTo(607, 2577.003f, 980.261f, 15.0f, 0.807f, 0);
680 }
681 else
682 player->TeleportTo(607, 1209.7f, -65.16f, 70.1f, 0.0f, 0);
683 }
684 }
685}
686
688{
689 if (!go || !go->GetGOInfo())
690 return;
691
692 if (eventType == go->GetGOInfo()->building.damagedEvent)
693 {
697 if (uws)
699 }
700
701 if (eventType == go->GetGOInfo()->building.destroyedEvent)
702 {
705 else
707 }
708
709 if (eventType == go->GetGOInfo()->building.damageEvent)
711}
712
714{
715 if (creature->GetEntry() == NPC_DEMOLISHER_SA)
716 {
719 }
720}
721
722/*
723 You may ask what the fuck does it do?
724 Prevents owner overwriting guns faction with own.
725 */
727{
728 if (!BgCreatures[0])
729 return;
730
731 for (uint8 i = BG_SA_GUN_1; i <= BG_SA_GUN_10; i++)
732 {
733 if (Creature* gun = GetBGCreature(i))
734 gun->setFaction(BG_SA_Factions[Attackers ? TEAM_ALLIANCE : TEAM_HORDE]);
735 }
736
737 for (uint8 i = BG_SA_DEMOLISHER_1; i <= BG_SA_DEMOLISHER_4; i++)
738 {
739 if (Creature* dem = GetBGCreature(i))
740 dem->setFaction(BG_SA_Factions[Attackers]);
741 }
742}
743
745{
746 if (!BgCreatures[0])
747 return;
748
749 // set flags only for the demolishers on the beach, factory ones dont need it
750 for (uint8 i = BG_SA_DEMOLISHER_1; i <= BG_SA_DEMOLISHER_4; i++)
751 {
752 if (Creature* dem = GetBGCreature(i))
753 {
754 if (start)
756 else
758 }
759 }
760}
761
763{
765 if (!GateStatus[i])
766 return;
767
768 if (GameObject* g = GetBGObject(i))
769 {
770 if (g->GetGOValue()->Building.Health == 0)
771 {
774 if (uws)
776 bool rewardHonor = true;
777 gateDestroyed = true;
778 switch (i)
779 {
780 case BG_SA_GREEN_GATE:
782 rewardHonor = false;
783 break;
784 case BG_SA_BLUE_GATE:
786 rewardHonor = false;
787 break;
788 case BG_SA_RED_GATE:
790 rewardHonor = false;
791 break;
794 rewardHonor = false;
795 break;
796 default:
797 break;
798 }
799
800 if (i < 5)
801 DelObject(i + 14);
803 if (rewardHonor)
805 }
806 }
807}
808
810{
811 uint32 safeloc = 0;
812 WorldSafeLocsEntry const* ret;
813 WorldSafeLocsEntry const* closest;
814 float dist, nearest;
815 float x, y, z;
816
817 player->GetPosition(x, y, z);
818
819 if (player->GetTeamId() == Attackers)
821 else
823
824 closest = sWorldSafeLocsStore.LookupEntry(safeloc);
825 nearest = sqrt((closest->x - x) * (closest->x - x) + (closest->y - y) * (closest->y - y) + (closest->z - z) * (closest->z - z));
826
828 {
829 if (GraveyardStatus[i] != player->GetTeamId())
830 continue;
831
832 ret = sWorldSafeLocsStore.LookupEntry(BG_SA_GYEntries[i]);
833 dist = sqrt((ret->x - x) * (ret->x - x) + (ret->y - y) * (ret->y - y) + (ret->z - z) * (ret->z - z));
834 if (dist < nearest)
835 {
836 closest = ret;
837 nearest = dist;
838 }
839 }
840
841 return closest;
842}
843
848
850{
852 return 0;
853
854 uint32 const remaining = EndRoundTimer - TotalTime;
855 return uint32(time(NULL)) + ((remaining + IN_MILLISECONDS - 1) / IN_MILLISECONDS);
856}
857
859{
860 switch (target_obj->GetEntry())
861 {
862 case 191307:
863 case 191308:
866 break;
867 case 191305:
868 case 191306:
871 break;
872 case 191310:
873 case 191309:
876 break;
877 default:
878 return;
879 };
880}
881
883{
884 if (GraveyardStatus[i] == Attackers)
885 return;
886
888 GraveyardStatus[i] = Source->GetTeamId();
889 WorldSafeLocsEntry const* sg = sWorldSafeLocsStore.LookupEntry(BG_SA_GYEntries[i]);
890 if (!sg)
891 {
892 SF_LOG_ERROR("bg.battleground", "BattlegroundSA::CaptureGraveyard: non-existant GY entry: %u", BG_SA_GYEntries[i]);
893 return;
894 }
895
897 uint32 npc = 0;
898 uint32 flag = 0;
899
900 switch (i)
901 {
903 flag = BG_SA_LEFT_FLAG;
904 DelObject(flag);
905 AddObject(flag, (BG_SA_ObjEntries[flag] - (Source->GetTeamId() == TEAM_ALLIANCE ? 0 : 1)),
906 BG_SA_ObjSpawnlocs[flag][0], BG_SA_ObjSpawnlocs[flag][1],
907 BG_SA_ObjSpawnlocs[flag][2], BG_SA_ObjSpawnlocs[flag][3], 0, 0, 0, 0, RESPAWN_ONE_DAY);
908
913
914 for (uint8 j = BG_SA_DEMOLISHER_7; j <= BG_SA_DEMOLISHER_8; j++)
915 {
918 BG_SA_NpcSpawnlocs[j][2], BG_SA_NpcSpawnlocs[j][3], 600);
919
920 if (Creature* dem = GetBGCreature(j))
921 dem->setFaction(BG_SA_Factions[Attackers]);
922 }
923
926 if (Source->GetTeamId() == TEAM_ALLIANCE)
928 else
930 break;
932 flag = BG_SA_RIGHT_FLAG;
933 DelObject(flag);
934 AddObject(flag, (BG_SA_ObjEntries[flag] - (Source->GetTeamId() == TEAM_ALLIANCE ? 0 : 1)),
935 BG_SA_ObjSpawnlocs[flag][0], BG_SA_ObjSpawnlocs[flag][1],
936 BG_SA_ObjSpawnlocs[flag][2], BG_SA_ObjSpawnlocs[flag][3], 0, 0, 0, 0, RESPAWN_ONE_DAY);
937
942
943 for (uint8 j = BG_SA_DEMOLISHER_5; j <= BG_SA_DEMOLISHER_6; j++)
944 {
947 BG_SA_NpcSpawnlocs[j][2], BG_SA_NpcSpawnlocs[j][3], 600);
948
949 if (Creature* dem = GetBGCreature(j))
950 dem->setFaction(BG_SA_Factions[Attackers]);
951 }
952
955 if (Source->GetTeamId() == TEAM_ALLIANCE)
957 else
959 break;
961 flag = BG_SA_CENTRAL_FLAG;
962 DelObject(flag);
963 AddObject(flag, (BG_SA_ObjEntries[flag] - (Source->GetTeamId() == TEAM_ALLIANCE ? 0 : 1)),
964 BG_SA_ObjSpawnlocs[flag][0], BG_SA_ObjSpawnlocs[flag][1],
965 BG_SA_ObjSpawnlocs[flag][2], BG_SA_ObjSpawnlocs[flag][3], 0, 0, 0, 0, RESPAWN_ONE_DAY);
966
969 if (Source->GetTeamId() == TEAM_ALLIANCE)
971 else
973 break;
974 default:
975 ASSERT(false);
976 break;
977 };
978}
979
981{
982 if (object->GetEntry() == BG_SA_ObjEntries[BG_SA_TITAN_RELIC] &&
987 {
988 if (Source->GetTeamId() == Attackers)
989 {
990 if (Source->GetTeamId() == TEAM_ALLIANCE)
993
994 if (Status == BG_SA_ROUND_ONE)
995 {
996 RoundScores[0].winner = Attackers;
997 RoundScores[0].time = TotalTime;
998 //Achievement Storm the Beach (1310)
999 for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
1000 {
1001 if (Player* player = ObjectAccessor::FindPlayer(itr->first))
1002 if (player->GetTeamId() == Attackers)
1003 player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 65246);
1004 }
1005
1008 TotalTime = 0;
1009 ToggleTimer();
1011 UpdateWaitTimer = 5000;
1012 SignaledRoundTwo = false;
1014 InitSecondRound = true;
1015 ResetObjs();
1016 }
1017 else if (Status == BG_SA_ROUND_TWO)
1018 {
1019 RoundScores[1].winner = Attackers;
1020 RoundScores[1].time = TotalTime;
1021 ToggleTimer();
1022 //Achievement Storm the Beach (1310)
1023 for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
1024 {
1025 if (Player* player = ObjectAccessor::FindPlayer(itr->first))
1026 if (player->GetTeamId() == Attackers && RoundScores[1].winner == Attackers)
1027 player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 65246);
1028 }
1029
1030 if (RoundScores[0].time == RoundScores[1].time)
1031 EndBattleground(0);
1032 else if (RoundScores[0].time < RoundScores[1].time)
1034 else
1036 }
1037 }
1038 }
1039}
1040
1047
1049{
1050 TimerEnabled = false;
1052 SendTime();
1053
1054 //honor reward for winning
1055 if (winner == ALLIANCE)
1057 else if (winner == HORDE)
1059
1060 //complete map_end rewards (even if no team wins)
1063
1065
1066 std::vector<uint64> players;
1067 players.reserve(GetPlayersSize());
1068
1069 for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
1070 players.push_back(itr->first);
1071
1072 for (std::vector<uint64>::const_iterator itr = players.begin(); itr != players.end(); ++itr)
1073 RemovePlayerAtLeave(*itr, true, true);
1074}
1075
1077{
1078 for (uint8 i = BG_SA_DEMOLISHER_1; i <= BG_SA_DEMOLISHER_8; i++)
1079 {
1080 if (BgCreatures[i])
1081 {
1082 if (Creature* Demolisher = GetBGCreature(i))
1083 {
1084 if (Demolisher->isDead())
1085 {
1086 // Demolisher is not in list
1087 if (DemoliserRespawnList.find(i) == DemoliserRespawnList.end())
1088 {
1089 DemoliserRespawnList[i] = getMSTime() + 30000;
1090 }
1091 else
1092 {
1094 {
1095 Demolisher->Relocate(BG_SA_NpcSpawnlocs[i][0], BG_SA_NpcSpawnlocs[i][1],
1097
1098 Demolisher->Respawn();
1099 DemoliserRespawnList.erase(i);
1100 }
1101 }
1102 }
1103 }
1104 }
1105 }
1106}
1107
1109{
1112
1113 if (boatOne || boatTwo)
1114 {
1115 if (!ShipsStarted)
1116 {
1117 if (boatOne)
1119 if (boatTwo)
1121 }
1122
1123 UpdateData transData(player->GetMapId());
1124 if (boatOne)
1125 boatOne->BuildCreateUpdateBlockForPlayer(&transData, player);
1126 if (boatTwo)
1127 boatTwo->BuildCreateUpdateBlockForPlayer(&transData, player);
1128 WorldPacket packet;
1129 transData.BuildPacket(&packet);
1130 player->SendDirectMessage(&packet);
1131 }
1132}
1133
1135{
1138
1139 if (boatOne || boatTwo)
1140 {
1141 UpdateData transData(player->GetMapId());
1142 if (boatOne)
1143 boatOne->BuildOutOfRangeUpdateBlock(&transData);
1144 if (boatTwo)
1145 boatTwo->BuildOutOfRangeUpdateBlock(&transData);
1146 WorldPacket packet;
1147 transData.BuildPacket(&packet);
1148 player->SendDirectMessage(&packet);
1149 }
1150}
1151
1152bool BattlegroundSA::CheckAchievementCriteriaMeet(uint32 criteriaId, Player const* source, Unit const* target, uint32 miscValue)
1153{
1154 switch (criteriaId)
1155 {
1159 return source->GetTeamId() != Attackers && !gateDestroyed;
1160 }
1161
1162 return Battleground::CheckAchievementCriteriaMeet(criteriaId, source, target, miscValue);
1163}
@ BG_CRITERIA_CHECK_DEFENSE_OF_THE_ANCIENTS
@ BG_CRITERIA_CHECK_NOT_EVEN_A_SCRATCH
@ RESPAWN_IMMEDIATELY
@ RESPAWN_ONE_DAY
@ SPELL_PREPARATION
@ SCORE_BONUS_HONOR
@ SCORE_DESTROYED_WALL
@ SCORE_DESTROYED_DEMOLISHER
@ STATUS_WAIT_JOIN
@ STATUS_IN_PROGRESS
@ BG_STARTING_EVENT_THIRD
@ BG_STARTING_EVENT_SECOND
@ BG_STARTING_EVENT_FIRST
@ BG_STARTING_EVENT_FOURTH
#define sBattlegroundMgr
const uint8 BG_SA_MAXNPC
BG_SA_Graveyards
@ BG_SA_DEFENDER_LAST_GY
@ BG_SA_CENTRAL_CAPTURABLE_GY
@ BG_SA_BEACH_GY
@ BG_SA_LEFT_CAPTURABLE_GY
@ BG_SA_RIGHT_CAPTURABLE_GY
@ BG_SA_BOAT_START
@ BG_SA_WARMUPLENGTH
@ BG_SA_ROUNDLENGTH
@ BG_SA_GATE_DESTROYED
@ BG_SA_GATE_OK
@ BG_SA_GATE_DAMAGED
BG_SA_Status
@ BG_SA_ROUND_ONE
@ BG_SA_ROUND_TWO
@ BG_SA_NOTSTARTED
@ BG_SA_SECOND_WARMUP
@ BG_SA_WARMUP
@ BG_SA_BOAT_ONE_H
@ BG_SA_BOAT_TWO_H
@ BG_SA_BOAT_ONE_A
@ BG_SA_BOAT_TWO_A
@ BG_SA_TIMER
@ BG_SA_ENABLE_TIMER
@ BG_SA_ANCIENT_GATEWS
@ BG_SA_LEFT_ATT_TOKEN_ALL
@ BG_SA_PURPLE_GATEWS
@ BG_SA_TIMER_SEC_TENS
@ BG_SA_RED_GATEWS
@ BG_SA_BLUE_GATEWS
@ BG_SA_CENTER_GY_ALLIANCE
@ BG_SA_RIGHT_ATT_TOKEN_HRD
@ BG_SA_LEFT_GY_ALLIANCE
@ BG_SA_RIGHT_ATT_TOKEN_ALL
@ BG_SA_YELLOW_GATEWS
@ BG_SA_LEFT_GY_HORDE
@ BG_SA_ALLIANCE_DEFENCE_TOKEN
@ BG_SA_RIGHT_GY_ALLIANCE
@ BG_SA_HORDE_DEFENCE_TOKEN
@ BG_SA_LEFT_ATT_TOKEN_HRD
@ BG_SA_CENTER_GY_HORDE
@ BG_SA_GREEN_GATEWS
@ BG_SA_RIGHT_GY_HORDE
@ BG_SA_ALLY_ATTACKS
@ BG_SA_HORDE_ATTACKS
@ BG_SA_TIMER_SEC_DECS
@ BG_SA_BONUS_TIMER
@ BG_SA_TIMER_MINS
const uint32 BG_SA_GYEntries[BG_SA_MAX_GY]
uint32 const BG_SA_ObjEntries[BG_SA_MAXOBJ+BG_SA_FLAG_AMOUNT]
float const BG_SA_GYOrientation[BG_SA_MAX_GY]
float const BG_SA_NpcSpawnlocs[BG_SA_MAXNPC+BG_SA_DEMOLISHER_AMOUNT][4]
uint32 const BG_SA_Factions[2]
@ BG_SA_EVENT_ANCIENT_GATE_DESTROYED
@ NPC_DEMOLISHER_SA
@ BG_SA_YELLOW_GATE
@ BG_SA_BOAT_ONE
@ BG_SA_GREEN_GATE
@ BG_SA_CENTRAL_FLAG
@ BG_SA_SIGIL_1
@ BG_SA_RED_GATE
@ BG_SA_LEFT_FLAGPOLE
@ BG_SA_PURPLE_GATE
@ BG_SA_RIGHT_FLAG
@ BG_SA_BLUE_GATE
@ BG_SA_PORTAL_DEFFENDER_RED
@ BG_SA_BOAT_TWO
@ BG_SA_ANCIENT_GATE
@ BG_SA_LEFT_FLAG
@ BG_SA_TITAN_RELIC
@ BG_SA_BOMB
float const BG_SA_ObjSpawnlocs[BG_SA_MAXOBJ][4]
const uint8 BG_SA_MAXOBJ
const uint8 BG_SA_MAX_GY
@ BG_SA_GUN_10
@ BG_SA_DEMOLISHER_1
@ BG_SA_DEMOLISHER_4
@ BG_SA_DEMOLISHER_6
@ BG_SA_DEMOLISHER_7
@ BG_SA_DEMOLISHER_5
@ BG_SA_NPC_RIGSPARK
@ BG_SA_NPC_SPARKLIGHT
@ BG_SA_GUN_1
@ BG_SA_DEMOLISHER_8
uint32 const BG_SA_NpcEntries[BG_SA_MAXNPC]
@ IN_MILLISECONDS
Definition Common.h:125
@ ACHIEVEMENT_TIMED_TYPE_EVENT
Definition DBCEnums.h:158
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition DBCEnums.h:193
DBCStorage< WorldSafeLocsEntry > sWorldSafeLocsStore(WorldSafeLocsEntryfmt)
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::uint64_t uint64
Definition Define.h:76
#define ASSERT
Definition Errors.h:29
@ LANG_BG_SA_START_TWO_MINUTES
Definition Language.h:1216
@ LANG_BG_SA_A_GY_SOUTH
Definition Language.h:1228
@ LANG_BG_SA_HAS_BEGUN
Definition Language.h:1219
@ LANG_BG_SA_WAS_DESTROYED
Definition Language.h:1221
@ LANG_BG_SA_ROUND_TWO_START_HALF_MINUTE
Definition Language.h:1226
@ LANG_BG_SA_START_HALF_MINUTE
Definition Language.h:1218
@ LANG_BG_SA_HORDE_CAPTURED_RELIC
Definition Language.h:1224
@ LANG_BG_SA_H_GY_EAST
Definition Language.h:1233
@ LANG_BG_SA_ROUND_TWO_ONE_MINUTE
Definition Language.h:1225
@ LANG_BG_SA_CHAMBER_BREACHED
Definition Language.h:1227
@ LANG_BG_SA_ROUND_ONE_END
Definition Language.h:1222
@ LANG_BG_SA_H_GY_SOUTH
Definition Language.h:1231
@ LANG_BG_SA_A_GY_WEST
Definition Language.h:1229
@ LANG_BG_SA_A_GY_EAST
Definition Language.h:1230
@ LANG_BG_SA_IS_UNDER_ATTACK
Definition Language.h:1220
@ LANG_BG_SA_ALLIANCE_CAPTURED_RELIC
Definition Language.h:1223
@ LANG_BG_SA_START_ONE_MINUTE
Definition Language.h:1217
@ LANG_BG_SA_H_GY_WEST
Definition Language.h:1232
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
@ CHAT_MSG_BG_SYSTEM_NEUTRAL
TeamId
@ TEAM_ALLIANCE
@ TEAM_HORDE
@ ALLIANCE
@ HORDE
@ SPELL_AURA_MOD_SHAPESHIFT
@ SPELL_AURA_SPIRIT_OF_REDEMPTION
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:22
uint32 getMSTime()
Definition Timer.h:12
@ UNIT_FLAG_NON_ATTACKABLE
Definition Unit.h:626
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ UNIT_FIELD_FLAGS
@ GAMEOBJECT_FIELD_FACTION_TEMPLATE
virtual void AddPlayer(Player *player)
uint32 GetMapId() const
void EndBattleground(uint32 winner)
static TeamId GetTeamIndexByTeamId(uint32 Team)
bool DelCreature(uint32 type)
void SpawnBGObject(uint32 type, uint32 respawntime)
uint32 GetInstanceID() const
virtual void RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket)
BGObjects BgObjects
void UpdateWorldState(uint32 Field, uint32 Value)
void SetStatus(BattlegroundStatus Status)
bool DelObject(uint32 type)
BattlegroundPlayerMap const & GetPlayers() const
BattlegroundScoreMap PlayerScores
void RewardHonorToTeam(uint32 Honor, uint32 TeamID)
void SendWarningToAll(int32 entry,...)
bool AddSpiritGuide(uint32 type, float x, float y, float z, float o, uint32 team)
BattlegroundStatus GetStatus() const
virtual bool CheckAchievementCriteriaMeet(uint32, Player const *, Unit const *=NULL, uint32=0)
BGCreatures BgCreatures
GameObject * GetBGObject(uint32 type)
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry)
uint32 GetBonusHonorFromKill(uint32 kills) const
virtual void UpdatePlayerScore(Player *player, uint32 type, uint32 value, bool doAddHonor=true)
Creature * AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o, uint32 respawntime=0)
uint32 GetPlayersSize() const
void SendMessageToAll(int32 entry, ChatMsg type, Player const *source=NULL)
Creature * GetBGCreature(uint32 type)
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)
uint32 StartMessageIds[BG_STARTING_EVENT_COUNT]
bool TimerEnabled
used for know we are in timer phase or not (used for worldstate update)
void SendTransportInit(Player *player)
Send packet to player for create boats (client part).
void ToggleTimer()
Switch on/off timer worldstate.
BG_SA_Status Status
Statu of battle (Start or not, and what round).
TeamId Attackers
Id of attacker team.
void EndBattleground(uint32 winner)
Called on battleground ending.
void AddPlayer(Player *player) OVERRIDE
Called when a player join battle.
void EventPlayerClickedOnFlag(Player *Source, GameObject *target_obj) OVERRIDE
Called when a player click on flag (graveyard flag).
void EventPlayerUsedGO(Player *Source, GameObject *object) OVERRIDE
Called when a player use a gamobject (relic).
uint32 EndRoundTimer
Max time of round.
bool SignaledRoundTwo
for know if warning about second round start has been sent
void SendBoatDebugTimerUpdate()
bool DebugStartBoats(Player *player)
uint32 BoatDebugStartTime
bool SetupBattleground() OVERRIDE
Called for ini battleground, after that the first player be entered.
void DemolisherStartState(bool start)
Set selectable or not demolisher, called on battle start, when boats arrive to dock.
uint32 getGateIdFromDamagedOrDestroyEventId(uint32 id)
Return gate id, relative to bg data, according to gameobject id.
void OverrideGunFaction()
Called on start and between the two round -Update faction of all vehicle.
void EventPlayerDamagedGO(Player *player, GameObject *go, uint32 eventType) OVERRIDE
Called when a player deal damage to building (door).
bool BoatLaunchWindowStarted() const
bool CheckAchievementCriteriaMeet(uint32 criteriaId, Player const *source, Unit const *target=NULL, uint32 miscvalue1=0) OVERRIDE
void HandleAreaTrigger(Player *Source, uint32 Trigger) OVERRIDE
bool SignaledRoundTwoHalfMin
for know if warning about second round start has been sent
void TeleportPlayers()
Called between the two round -Teleport all players to good location.
void SendTime()
Update timer worldstate.
void HandleKillUnit(Creature *creature, Player *killer) OVERRIDE
Called when a player kill a unit in bg.
BG_SA_RoundScore RoundScores[2]
Score of each round.
void CaptureGraveyard(BG_SA_Graveyards i, Player *Source)
Called when a graveyard is capture -Update spiritguide -Update gameobject (flag) -Update Worldstate -...
uint32 UpdateWaitTimer
5secs before starting the 1min countdown for second round
void SendBoatTransportUpdates()
void UpdateDemolisherSpawns()
Respawn dead demolisher.
uint32 BoatDebugUpdateTimer
bool DebugStopBoats(Player *player)
void LogBoatDebugMarker(Player *player, char const *action, uint32 elapsedMs=0)
BG_SA_GateState GateStatus[6]
Status of each gate (Destroy/Damage/Intact).
uint64 BoatDebugPlayerGuid
void UpdatePlayerScore(Player *Source, uint32 type, uint32 value, bool doAddHonor=true) OVERRIDE
Update score board.
uint32 GetTimerWorldState() const
void PostUpdateImpl(uint32 diff) OVERRIDE
Called every time for update battle data -Update timer -Round switch.
void FillInitialWorldStates(WorldStateBuilder &builder) OVERRIDE
Called for generate packet contain worldstate data.
std::string GetBoatDebugStatus()
bool ShipsStarted
For know if boats has start moving or not yet.
bool InitSecondRound
for know if second round has been init
bool ResetObjs()
Called on setup and between the two round -Delete all gameobject / creature -Respawn all gameobject /...
std::map< uint32, uint32 > DemoliserRespawnList
bool _allVehiclesAlive[BG_TEAMS_COUNT]
void DestroyGate(Player *player, GameObject *go) OVERRIDE
Called when a gate is destroy -Give honor to player witch destroy it -Update worldstate -Delete gameo...
void StartingEventCloseDoors() OVERRIDE
Called when battle start.
WorldSafeLocsEntry const * GetClosestGraveYard(Player *player) OVERRIDE
Return the nearest graveyard where player can respawn.
uint32 getWorldStateFromGateId(uint32 id)
Return worldstate id, according to door id.
void StartingEventOpenDoors() OVERRIDE
bool ShouldDelayStartForDebug() const OVERRIDE
void StartShips()
Called for start ship movement.
void RemovePlayer(Player *player, uint64 guid, uint32 team) OVERRIDE
CAlled when a player leave battleground.
void SendTransportsRemove(Player *player)
Send packet to player for destroy boats (client part).
TeamId GraveyardStatus[BG_SA_MAX_GY]
Team witch conntrol each graveyard.
void Reset() OVERRIDE
uint32 TotalTime
Totale elapsed time of current round.
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:643
uint32 GetTransportPathProgress() const
Definition GameObject.h:722
GOState GetGoState() const
Definition GameObject.h:717
void UpdateRotationFields(float rotation2=0.0f, float rotation3=0.0f)
uint32 GetTransportPeriod() const
void StartLegacyTransportToFirstStop(uint32 travelTime)
void StopLegacyTransportAtInitialStop()
void Refresh()
void StopLegacyTransportAtCurrentProgress()
static Player * FindPlayer(uint64)
uint64 GetGUID() const
Definition Object.h:119
virtual void BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const
Definition Object.cpp:172
uint32 GetEntry() const
Definition Object.h:125
void BuildOutOfRangeUpdateBlock(UpdateData *data) const
Definition Object.cpp:282
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:1038
uint32 GetTeam() const
Definition Player.h:2527
void SendDirectMessage(WorldPacket *data)
Definition Player.cpp:6904
WorldSession * GetSession() const
Definition Player.h:2417
TeamId GetTeamId() const
Definition Player.h:2531
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0)
Definition Player.cpp:2090
Definition Unit.h:1367
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
bool BuildPacket(WorldPacket *packet)
uint32 GetMapId() const
Definition Object.h:546
uint32 GetInstanceId() const
Definition Object.h:638
Player session in the World.
void AppendState(uint32 worldstate, uint32 value)
std::string name
Definition GameObject.h:28
struct GameObjectTemplate::@046065176235271051340241126110345143267101032070::@240010171105306235035040051230330371375266145364 building
void GetPosition(float &x, float &y) const
Definition Object.h:333
float x
float z
float y