TrinityCore
Loading...
Searching...
No Matches
BattlegroundIC.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 "BattlegroundIC.h"
19#include "BattlegroundPackets.h"
20#include "GameObject.h"
21#include "Log.h"
22#include "Map.h"
23#include "Player.h"
24#include "ScriptedCreature.h"
25#include "Transport.h"
26#include "Vehicle.h"
27#include "WorldStatePackets.h"
28
33
58
60
69
71{
73 return;
74
75 if (!doorsClosed)
76 {
77 if (closeFortressDoorsTimer <= diff)
78 {
85
92
93 doorsClosed = true;
94 } else closeFortressDoorsTimer -= diff;
95 }
96
97 for (uint8 i = NODE_TYPE_REFINERY; i < MAX_NODE_TYPES; ++i)
98 {
99 if (nodePoint[i].nodeType == NODE_TYPE_DOCKS)
100 {
101 if (nodePoint[i].nodeState == NODE_STATE_CONTROLLED_A ||
102 nodePoint[i].nodeState == NODE_STATE_CONTROLLED_H)
103 {
104 if (docksTimer <= diff)
105 {
106 // we need to confirm this, i am not sure if this every 3 minutes
108 {
109 if (Creature* catapult = GetBGCreature(u))
110 {
111 if (!catapult->IsAlive())
112 catapult->Respawn(true);
113 }
114 }
115
116 // we need to confirm this is blizzlike, not sure if it is every 3 minutes
118 {
119 if (Creature* glaiveThrower = GetBGCreature(u))
120 {
121 if (!glaiveThrower->IsAlive())
122 glaiveThrower->Respawn(true);
123 }
124 }
125
127 } else docksTimer -= diff;
128 }
129 }
130
131 if (nodePoint[i].nodeType == NODE_TYPE_WORKSHOP)
132 {
133 if (nodePoint[i].nodeState == NODE_STATE_CONTROLLED_A ||
134 nodePoint[i].nodeState == NODE_STATE_CONTROLLED_H)
135 {
136 if (siegeEngineWorkshopTimer <= diff)
137 {
139
140 if (Creature* siege = GetBGCreature(siegeType)) // this always should be true
141 {
142 if (siege->IsAlive())
143 {
145 // following sniffs the vehicle always has UNIT_FLAG_CANNOT_SWIM
146 siege->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE | UNIT_FLAG_IMMUNE_TO_PC);
147 else
148 siege->SetHealth(siege->GetMaxHealth());
149 }
150 else
151 siege->Respawn(true);
152 }
153
154 // we need to confirm if it is every 3 minutes
156 {
157 if (Creature* demolisher = GetBGCreature(u))
158 {
159 if (!demolisher->IsAlive())
160 demolisher->Respawn(true);
161 }
162 }
164 } else siegeEngineWorkshopTimer -= diff;
165 }
166 }
167
168 // the point is waiting for a change on its banner
169 if (nodePoint[i].needChange)
170 {
171 if (nodePoint[i].timer <= diff)
172 {
173 uint32 nextBanner = GetNextBanner(&nodePoint[i], nodePoint[i].faction, true);
174
176 nodePoint[i].gameobject_entry = nextBanner;
177 // nodePoint[i].faction = the faction should be the same one...
178
179 GameObject* banner = GetBGObject(nodePoint[i].gameobject_type);
180
181 if (!banner) // this should never happen
182 return;
183
184 float cords[4] = {banner->GetPositionX(), banner->GetPositionY(), banner->GetPositionZ(), banner->GetOrientation() };
185
186 DelObject(nodePoint[i].gameobject_type);
187 AddObject(nodePoint[i].gameobject_type, nodePoint[i].gameobject_entry, cords[0], cords[1], cords[2], cords[3], 0, 0, 0, 0, RESPAWN_ONE_DAY);
188
189 GetBGObject(nodePoint[i].gameobject_type)->SetFaction(nodePoint[i].faction == TEAM_ALLIANCE ? BG_IC_Factions[1] : BG_IC_Factions[0]);
190
192 HandleCapturedNodes(&nodePoint[i], false);
193
194 if (nodePoint[i].faction == TEAM_ALLIANCE)
196 else
198
199 nodePoint[i].needChange = false;
201 } else nodePoint[i].timer -= diff;
202 }
203 }
204
205 if (resourceTimer <= diff)
206 {
207 for (uint8 i = 0; i < NODE_TYPE_DOCKS; ++i)
208 {
209 if (nodePoint[i].nodeState == NODE_STATE_CONTROLLED_A ||
210 nodePoint[i].nodeState == NODE_STATE_CONTROLLED_H)
211 {
215 }
216 }
218 } else resourceTimer -= diff;
219}
220
224
246
248{
249 bool const isInBattleground = IsPlayerInBattleground(player->GetGUID());
251 if (!isInBattleground)
252 PlayerScores[player->GetGUID()] = new BattlegroundICScore(player->GetGUID());
253
255 player->CastSpell(player, SPELL_QUARRY, true);
256
258 player->CastSpell(player, SPELL_OIL_REFINERY, true);
259}
260
261void BattlegroundIC::RemovePlayer(Player* player, ObjectGuid /*guid*/, uint32 /*team*/)
262{
263 if (player)
264 {
265 player->RemoveAura(SPELL_QUARRY);
267 }
268}
269
271{
272 // this is wrong way to implement these things. On official it done by gameobject spell cast.
274 return;
275
277 if (trigger == 5555 && player->GetTeamId() == TEAM_HORDE)
278 {
282 player->CastSpell(player, SPELL_BACK_DOOR_JOB_ACHIEVEMENT, true);
283 }
284 else if (trigger == 5535 && player->GetTeamId() == TEAM_ALLIANCE)
285 {
289 player->CastSpell(player, SPELL_BACK_DOOR_JOB_ACHIEVEMENT, true);
290 }
291}
292
294{
295 packet.Worldstates.emplace_back(BG_IC_ALLIANCE_RENFORT_SET, 1);
296 packet.Worldstates.emplace_back(BG_IC_HORDE_RENFORT_SET, 1);
299
300 for (uint8 itr = 0; itr < MAX_FORTRESS_GATES_SPAWNS; ++itr)
301 {
303 packet.Worldstates.emplace_back(worldState, 1);
304 }
305
306 for (uint8 itr = 0; itr < MAX_NODE_TYPES; ++itr)
307 packet.Worldstates.emplace_back(nodePoint[itr].worldStates[nodePoint[itr].nodeState], 1);
308}
309
311{
312 for (uint8 i = 0; i < MAX_NORMAL_GAMEOBJECTS_SPAWNS; ++i)
313 {
315 {
316 TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning gameobject {}", BG_IC_ObjSpawnlocs[i].entry);
317 return false;
318 }
319 }
320
321 for (uint8 i = 0; i < MAX_FORTRESS_TELEPORTERS_SPAWNS; ++i)
322 {
324 {
325 TC_LOG_ERROR("bg.battleground", "Isle of Conquest | Starting Event Open Doors: There was an error spawning gameobject {}", BG_IC_Teleporters[i].entry);
326 return false;
327 }
328 }
329
331 {
333 {
334 TC_LOG_ERROR("bg.battleground", "Isle of Conquest | Starting Event Open Doors: There was an error spawning gameobject {}", BG_IC_Teleporters[i].entry);
335 return false;
336 }
337 }
338
339 for (uint8 i = 2; i < MAX_NORMAL_NPCS_SPAWNS; ++i)
340 {
342 {
343 TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning creature {}", BG_IC_NpcSpawnlocs[i].entry);
344 return false;
345 }
346 }
347
352 {
353 TC_LOG_ERROR("bg.battleground", "Isle of Conquest: Failed to spawn initial spirit guide!");
354 return false;
355 }
356
357 gunshipHorde = sTransportMgr->CreateTransport(GO_HORDE_GUNSHIP, 0, GetBgMap());
359
361 {
362 TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error creating gunships!");
363 return false;
364 }
365
368
369 // setting correct factions for Keep Cannons
374
375 // correcting spawn time for keeps bombs
378
379 return true;
380}
381
383{
385 return;
386
387 uint32 entry = unit->GetEntry();
389 {
392 }
393 else if (entry == NPC_OVERLORD_AGMAR)
394 {
397 }
398
399 //Achievement Mowed Down
400 // TO-DO: This should be done on the script of each vehicle of the BG.
401 if (unit->IsVehicle())
402 killer->CastSpell(killer, SPELL_DESTROYED_VEHICLE_ACHIEVEMENT, true);
403}
404
406{
408 return;
409
410 Battleground::HandleKillPlayer(player, killer);
411
412 factionReinforcements[player->GetTeamId()] -= 1;
413
415
416 // we must end the battleground
417 if (factionReinforcements[player->GetTeamId()] < 1)
418 EndBattleground(killer->GetTeam());
419}
420
422{
424 return;
425
426 // All the node points are iterated to find the clicked one
427 for (uint8 i = 0; i < MAX_NODE_TYPES; ++i)
428 {
429 if (nodePoint[i].gameobject_entry == target_obj->GetEntry())
430 {
431 // THIS SHOULD NEEVEER HAPPEN
432 if (nodePoint[i].faction == player->GetTeamId())
433 return;
434
435 uint32 nextBanner = GetNextBanner(&nodePoint[i], player->GetTeamId(), false);
436
437 // we set the new settings of the nodePoint
438 nodePoint[i].faction = player->GetTeamId();
440 nodePoint[i].gameobject_entry = nextBanner;
441
442 // this is just needed if the next banner is grey
443 if (nodePoint[i].banners[BANNER_A_CONTESTED] == nextBanner || nodePoint[i].banners[BANNER_H_CONTESTED] == nextBanner)
444 {
445 nodePoint[i].timer = BANNER_STATE_CHANGE_TIME; // 1 minute for last change (real faction banner)
446 nodePoint[i].needChange = true;
447
449
450 // if we are here means that the point has been lost, or it is the first capture
451
452 if (nodePoint[i].nodeType != NODE_TYPE_REFINERY && nodePoint[i].nodeType != NODE_TYPE_QUARRY)
453 if (!BgCreatures[BG_IC_NPC_SPIRIT_GUIDE_1 + uint32(nodePoint[i].nodeType) - 2].IsEmpty())
455
457
458 if (nodePoint[i].faction == TEAM_ALLIANCE)
459 SendBroadcastText(ICNodes[i].TextAssaulted, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
460 else
461 SendBroadcastText(ICNodes[i].TextAssaulted, CHAT_MSG_BG_SYSTEM_HORDE, player);
462
464 }
465 else if (nextBanner == nodePoint[i].banners[BANNER_A_CONTROLLED] || nextBanner == nodePoint[i].banners[BANNER_H_CONTROLLED]) // if we are going to spawn the definitve faction banner, we dont need the timer anymore
466 {
468 nodePoint[i].needChange = false;
469
470 if (nodePoint[i].faction == TEAM_ALLIANCE)
471 SendBroadcastText(ICNodes[i].TextDefended, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
472 else
473 SendBroadcastText(ICNodes[i].TextDefended, CHAT_MSG_BG_SYSTEM_HORDE, player);
474
477 }
478
479 GameObject* banner = GetBGObject(nodePoint[i].gameobject_type);
480
481 if (!banner) // this should never happen
482 return;
483
484 float cords[4] = {banner->GetPositionX(), banner->GetPositionY(), banner->GetPositionZ(), banner->GetOrientation() };
485
486 DelObject(nodePoint[i].gameobject_type);
487 if (!AddObject(nodePoint[i].gameobject_type, nodePoint[i].gameobject_entry, cords[0], cords[1], cords[2], cords[3], 0, 0, 0, 0, RESPAWN_ONE_DAY))
488 {
489 TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning a banner (type: {}, entry: {}). Isle of Conquest BG cancelled.", nodePoint[i].gameobject_type, nodePoint[i].gameobject_entry);
491 }
492
493 GetBGObject(nodePoint[i].gameobject_type)->SetFaction(nodePoint[i].faction == TEAM_ALLIANCE ? BG_IC_Factions[1] : BG_IC_Factions[0]);
494
496 // we dont need iterating if we are here
497 // If the needChange bool was set true, we will handle the rest in the Update Map function.
498 return;
499 }
500 }
501}
502
504{
505 //updating worldstate
506 if (node->gameobject_entry == node->banners[BANNER_A_CONTROLLED])
508 else if (node->gameobject_entry == node->banners[BANNER_A_CONTESTED])
510 else if (node->gameobject_entry == node->banners[BANNER_H_CONTROLLED])
512 else if (node->gameobject_entry == node->banners[BANNER_H_CONTESTED])
514
515 uint32 worldstate = node->worldStates[node->nodeState];
516
517 // with this we are sure we dont bug the client
518 for (uint8 i = 0; i < 5; ++i)
519 {
520 if (node->worldStates[i] == worldstate)
521 continue;
522 UpdateWorldState(node->worldStates[i], 0);
523 }
524
525 UpdateWorldState(worldstate, 1);
526}
527
528uint32 BattlegroundIC::GetNextBanner(ICNodePoint* node, uint32 team, bool returnDefinitve)
529{
530 // this is only used in the update map function
531 if (returnDefinitve)
532 // here is a special case, here we must return the definitve faction banner after the grey banner was spawned 1 minute
534
535 // there were no changes, this point has never been captured by any faction or at least clicked
536 if (node->last_entry == 0)
537 // 1 returns the CONTESTED ALLIANCE BANNER, 3 returns the HORDE one
539
540 // If the actual banner is the definitive faction banner, we must return the grey banner of the player's faction
543
544 // If the actual banner is the grey faction banner, we must return the previous banner
546 return node->last_entry;
547
548 // we should never be here...
549 TC_LOG_ERROR("bg.battleground", "Isle Of Conquest: Unexpected return in GetNextBanner function");
550 return 0;
551}
552
554{
555 if (node->nodeType == NODE_TYPE_HANGAR)
556 {
558 (node->faction == TEAM_ALLIANCE ? gunshipHorde : gunshipAlliance)->EnableMovement(false);
559
561 DelObject(u);
562
564 DelObject(u);
565
567
568 for (uint8 u = 0; u < MAX_CAPTAIN_SPAWNS_PER_FACTION; ++u)
569 {
571 DelCreature(type);
572 }
573
574 std::list<Creature*> cannons;
575 if (node->faction == TEAM_HORDE)
577 else
579
580 for (Creature* cannon : cannons)
581 {
582 cannon->GetVehicleKit()->RemoveAllPassengers();
583 cannon->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
584 }
585 }
586 else if (node->nodeType == NODE_TYPE_WORKSHOP)
587 {
590 }
591}
592
594{
595 if (node->nodeType != NODE_TYPE_REFINERY && node->nodeType != NODE_TYPE_QUARRY)
596 {
598 TC_LOG_ERROR("bg.battleground", "Isle of Conquest: Failed to spawn spirit guide! point: {}, team: {}, ", node->nodeType, node->faction);
599 }
600
601 switch (node->gameobject_type)
602 {
604 {
606 break;
607
608 std::list<Creature*> cannons;
609 if (node->faction == TEAM_ALLIANCE)
611 else
613
614 for (Creature* cannon : cannons)
615 cannon->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
616
617 for (uint8 u = 0; u < MAX_HANGAR_TELEPORTERS_SPAWNS; ++u)
618 {
621 TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning a gunship portal. Type: {}", BG_IC_GO_HANGAR_TELEPORTER_1 + u);
622 }
623
624 for (uint8 u = 0; u < MAX_HANGAR_TELEPORTER_EFFECTS_SPAWNS; ++u)
625 {
628 TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning a gunship portal effects. Type: {}", BG_IC_GO_HANGAR_TELEPORTER_1 + u);
629 }
630
631 for (uint8 u = 0; u < MAX_TRIGGER_SPAWNS_PER_FACTION; ++u)
632 {
634 TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning a world trigger. Type: {}", BG_IC_NPC_WORLD_TRIGGER_NOT_FLOATING);
635 }
636
637 for (uint8 u = 0; u < MAX_CAPTAIN_SPAWNS_PER_FACTION; ++u)
638 {
640
641 if (type == BG_IC_NPC_GUNSHIP_CAPTAIN_1)
644
645 if (type == BG_IC_NPC_GUNSHIP_CAPTAIN_2)
647 TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning a world trigger. Type: {}", BG_IC_NPC_GUNSHIP_CAPTAIN_2);
648 }
649
650 (node->faction == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)->EnableMovement(true);
651 break;
652 }
656 break;
660 break;
662 if (recapture)
663 break;
664
667
668 // we must del opposing faction vehicles when the node is captured (unused ones)
670 {
671 if (Creature* glaiveThrower = GetBGCreature(i, false))
672 {
673 if (Vehicle* vehicleGlaive = glaiveThrower->GetVehicleKit())
674 {
675 if (!vehicleGlaive->GetPassenger(0))
676 DelCreature(i);
677 }
678 }
679 }
680
682 {
683 if (Creature* catapult = GetBGCreature(i, false))
684 {
685 if (Vehicle* vehicleGlaive = catapult->GetVehicleKit())
686 {
687 if (!vehicleGlaive->GetPassenger(0))
688 DelCreature(i);
689 }
690 }
691 }
692
693 // spawning glaive throwers
695 {
697
698 if (GetBGCreature(type, false) && GetBGCreature(type)->IsAlive())
699 continue;
700
702 GetBGCreature(type)->SetFaction(BG_IC_Factions[(node->faction == TEAM_ALLIANCE ? 0 : 1)]);
703 }
704
705 // spawning catapults
706 for (uint8 i = 0; i < MAX_CATAPULTS_SPAWNS_PER_FACTION; ++i)
707 {
709
710 if (GetBGCreature(type, false) && GetBGCreature(type)->IsAlive())
711 continue;
712
714 GetBGCreature(type)->SetFaction(BG_IC_Factions[(node->faction == TEAM_ALLIANCE ? 0 : 1)]);
715 }
716 break;
718 {
721
722 if (!recapture)
723 {
724 // we must del opposing faction vehicles when the node is captured (unused ones)
726 {
727 if (Creature* demolisher = GetBGCreature(i, false))
728 {
729 if (Vehicle* vehicleDemolisher = demolisher->GetVehicleKit())
730 {
731 // is IsVehicleInUse working as expected?
732 if (!vehicleDemolisher->IsVehicleInUse())
733 DelCreature(i);
734 }
735 }
736 }
737
738 for (uint8 i = 0; i < MAX_DEMOLISHERS_SPAWNS_PER_FACTION; ++i)
739 {
741
742 if (GetBGCreature(type, false) && GetBGCreature(type)->IsAlive())
743 continue;
744
746 GetBGCreature(type)->SetFaction(BG_IC_Factions[(node->faction == TEAM_ALLIANCE ? 0 : 1)]);
747 }
748
749 // we check if the opossing siege engine is in use
751
752 if (Creature* siegeEngine = GetBGCreature(enemySiege, false))
753 {
754 if (Vehicle* vehicleSiege = siegeEngine->GetVehicleKit())
755 {
756 // is VehicleInUse working as expected ?
757 if (!vehicleSiege->IsVehicleInUse())
758 DelCreature(enemySiege);
759 }
760 }
761
763 if (!GetBGCreature(siegeType, false) || !GetBGCreature(siegeType)->IsAlive())
764 {
767
768 if (Creature* siegeEngine = GetBGCreature(siegeType))
769 {
770 siegeEngine->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE | UNIT_FLAG_CANNOT_SWIM);
771 siegeEngine->SetImmuneToPC(true);
772 siegeEngine->SetFaction(BG_IC_Factions[(node->faction == TEAM_ALLIANCE ? 0 : 1)]);
773 }
774 }
775 }
776
777 for (uint8 i = 0; i < MAX_WORKSHOP_BOMBS_SPAWNS_PER_FACTION; ++i)
778 {
780 workshopBombs[i].GetPositionX(), workshopBombs[i].GetPositionY(),
781 workshopBombs[i].GetPositionZ(), workshopBombs[i].GetOrientation(),
782 0, 0, 0, 0, 10);
783
784 if (GameObject* seaforiumBombs = GetBGObject(BG_IC_GO_SEAFORIUM_BOMBS_1+i))
785 {
786 seaforiumBombs->SetRespawnTime(10);
787 seaforiumBombs->SetFaction(BG_IC_Factions[(node->faction == TEAM_ALLIANCE ? 0 : 1)]);
788 }
789 }
790 break;
791 }
792 default:
793 break;
794 }
795}
796
798{
800 uint32 uws_open = GetWorldStateFromGateEntry(go->GetEntry(), true);
801 uint32 uws_close = GetWorldStateFromGateEntry(go->GetEntry(), false);
802 if (uws_open)
803 {
804 UpdateWorldState(uws_close, 0);
805 UpdateWorldState(uws_open, 1);
806 }
807 if (player->GetTeamId() == TEAM_ALLIANCE)
808 {
811 }
812 else
813 {
816 }
817
818 uint32 textId;
819 ChatMsg msgType;
820 switch (go->GetEntry())
821 {
822 case GO_HORDE_GATE_1:
825 break;
826 case GO_HORDE_GATE_2:
829 break;
830 case GO_HORDE_GATE_3:
833 break;
836 msgType = CHAT_MSG_BG_SYSTEM_HORDE;
837 break;
840 msgType = CHAT_MSG_BG_SYSTEM_HORDE;
841 break;
844 msgType = CHAT_MSG_BG_SYSTEM_HORDE;
845 break;
846 default:
847 return;
848 }
849
850 if (go->GetEntry() == GO_HORDE_GATE_1 || go->GetEntry() == GO_HORDE_GATE_2 || go->GetEntry() == GO_HORDE_GATE_3)
851 {
853 TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning creature {}", BG_IC_NpcSpawnlocs[BG_IC_NPC_OVERLORD_AGMAR].entry);
854 }
855 else if (go->GetEntry() == GO_ALLIANCE_GATE_1 || go->GetEntry() == GO_ALLIANCE_GATE_2 || go->GetEntry() == GO_ALLIANCE_GATE_3)
856 {
858 TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning creature {}", BG_IC_NpcSpawnlocs[BG_IC_NPC_HIGH_COMMANDER_HALFORD_WYRMBANE].entry);
859 }
860
861 SendBroadcastText(textId, msgType);
862}
863
865{
866 TeamId teamIndex = GetTeamIndexByTeamId(player->GetTeam());
867
868 // Is there any occupied node for this team?
869 std::vector<uint8> nodes;
870 for (uint8 i = 0; i < MAX_NODE_TYPES; ++i)
871 if (nodePoint[i].faction == player->GetTeamId())
872 nodes.push_back(i);
873
874 WorldSafeLocsEntry const* good_entry = nullptr;
875 // If so, select the closest node to place ghost on
876 if (!nodes.empty())
877 {
878 float player_x = player->GetPositionX();
879 float player_y = player->GetPositionY();
880
881 float mindist = 999999.0f;
882 for (uint8 i = 0; i < nodes.size(); ++i)
883 {
884 WorldSafeLocsEntry const*entry = sWorldSafeLocsStore.LookupEntry(BG_IC_GraveyardIds[nodes[i]]);
885 if (!entry)
886 continue;
887 float dist = (entry->Loc.X - player_x)*(entry->Loc.X - player_x)+(entry->Loc.Y - player_y)*(entry->Loc.Y - player_y);
888 if (mindist > dist)
889 {
890 mindist = dist;
891 good_entry = entry;
892 }
893 }
894 nodes.clear();
895 }
896 // If not, place ghost on starting location
897 if (!good_entry)
898 good_entry = sWorldSafeLocsStore.LookupEntry(BG_IC_GraveyardIds[uint32(teamIndex) + MAX_NODE_TYPES]);
899
900 return good_entry;
901}
902
904{
905 uint32 count = 0;
907 for (int i = 0; i < NODE_TYPE_WORKSHOP; ++i)
908 {
909 if (nodePoint[i].nodeState == controlledState)
910 ++count;
911 }
912
913 return count == NODE_TYPE_WORKSHOP;
914}
915
916bool BattlegroundIC::IsSpellAllowed(uint32 spellId, Player const* player) const
917{
918 switch (spellId)
919 {
921 case SPELL_QUARRY:
922 {
923 uint32 team = player->GetTeamId();
926 return GetNodeState(nodeType) == nodeState;
927 }
928 default:
929 break;
930 }
931
932 return true;
933}
const uint32 BG_IC_GraveyardIds[MAX_NODE_TYPES+2]
@ RESOURCE_HONOR_AMOUNT
@ WINNER_HONOR_AMOUNT
@ BG_IC_TEXT_WEST_GATE_HORDE_DESTROYED
@ BG_IC_TEXT_FRONT_GATE_ALLIANCE_DESTROYED
@ BG_IC_TEXT_WEST_GATE_ALLIANCE_DESTROYED
@ BG_IC_TEXT_FRONT_GATE_HORDE_DESTROYED
@ BG_IC_TEXT_EAST_GATE_HORDE_DESTROYED
@ BG_IC_TEXT_EAST_GATE_ALLIANCE_DESTROYED
@ ACTION_GUNSHIP_READY
@ NODE_TYPE_REFINERY
@ NODE_TYPE_DOCKS
@ NODE_TYPE_HANGAR
@ NODE_TYPE_QUARRY
@ MAX_NODE_TYPES
@ NODE_TYPE_WORKSHOP
@ NPC_SIEGE_ENGINE_H
@ NPC_HORDE_GUNSHIP_CAPTAIN
@ NPC_SIEGE_ENGINE_A
@ NPC_HIGH_COMMANDER_HALFORD_WYRMBANE
@ NPC_GLAIVE_THROWER_A
@ NPC_WORLD_TRIGGER_NOT_FLOATING
@ NPC_GLAIVE_THROWER_H
@ NPC_OVERLORD_AGMAR
@ NPC_DEMOLISHER
@ NPC_CATAPULT
@ NPC_ALLIANCE_GUNSHIP_CANNON
@ NPC_HORDE_GUNSHIP_CANNON
@ NPC_ALLIANCE_GUNSHIP_CAPTAIN
@ DOCKS_UPDATE_TIME
@ CLOSE_DOORS_TIME
@ IC_RESOURCE_TIME
@ BANNER_STATE_CHANGE_TIME
@ WORKSHOP_UPDATE_TIME
ICNodeInfo const ICNodes[MAX_NODE_TYPES]
@ BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01
@ BG_IC_GO_HORDE_GATE_3
@ BG_IC_GO_HANGAR_BANNER
@ BG_IC_GO_HORDE_GATE_2
@ BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR02
@ BG_IC_GO_ALLIANCE_GATE_3
@ BG_IC_GO_DOODAD_PORTCULLISACTIVE02
@ BG_IC_GO_HORDE_BANNER
@ BG_IC_GO_HANGAR_TELEPORTER_EFFECT_3
@ BG_IC_GO_HANGAR_TELEPORTER_3
@ BG_IC_GO_WORKSHOP_BANNER
@ BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR03
@ BG_IC_GO_ALLIANCE_BANNER
@ BG_IC_GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01
@ BG_IC_GO_HANGAR_TELEPORTER_1
@ BG_IC_GO_ALLIANCE_GATE_1
@ BG_IC_GO_REFINERY_BANNER
@ BG_IC_GO_SEAFORIUM_BOMBS_1
@ BG_IC_GO_QUARRY_BANNER
@ BG_IC_GO_DOODAD_VR_PORTCULLIS01_2
@ BG_IC_GO_SEAFORIUM_BOMBS_2
@ BG_IC_GO_DOODAD_HU_PORTCULLIS01_1
@ BG_IC_GO_DOCKS_BANNER
@ BG_IC_GO_HORDE_KEEP_PORTCULLIS
@ BG_IC_GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR03
@ BG_IC_GO_HANGAR_TELEPORTER_EFFECT_1
@ BG_IC_GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR02
@ BG_IC_GO_DOODAD_VR_PORTCULLIS01_1
@ BG_IC_GO_HORDE_GATE_1
@ BG_IC_GO_HUGE_SEAFORIUM_BOMBS_A_1
@ BG_IC_GO_ALLIANCE_GATE_2
@ BG_IC_GO_DOODAD_HU_PORTCULLIS01_2
@ BG_IC_GO_HUGE_SEAFORIUM_BOMBS_H_4
const Position BG_IC_WorkshopVehicles[5]
const ICGo BG_IC_TeleporterEffects[MAX_FORTRESS_TELEPORTER_EFFECTS_SPAWNS]
@ BG_IC_H_FRONT
@ BG_IC_A_WEST
@ BG_IC_H_WEST
@ BG_IC_A_FRONT
@ BG_IC_MAXDOOR
@ BG_IC_A_EAST
@ BG_IC_H_EAST
Position const BG_IC_SpiritGuidePos[MAX_NODE_TYPES+2]
@ SPELL_QUARRY
@ SPELL_BACK_DOOR_JOB_ACHIEVEMENT
@ SPELL_DESTROYED_VEHICLE_ACHIEVEMENT
@ SPELL_OIL_REFINERY
@ MAX_WORKSHOP_SPAWNS
@ MAX_SPIRIT_GUIDES_SPAWNS
@ MAX_GLAIVE_THROWERS_SPAWNS_PER_FACTION
@ MAX_HANGAR_NPCS_SPAWNS
@ MAX_NORMAL_GAMEOBJECTS_SPAWNS
@ MAX_AIRSHIPS_SPAWNS
@ MAX_WORKSHOP_BOMBS_SPAWNS_PER_FACTION
@ MAX_DOCKS_SPAWNS
@ MAX_NORMAL_NPCS_SPAWNS
@ MAX_HANGAR_TELEPORTER_EFFECTS_SPAWNS
@ MAX_FORTRESS_TELEPORTER_EFFECTS_SPAWNS
@ MAX_CATAPULTS_SPAWNS_PER_FACTION
@ MAX_DEMOLISHERS_SPAWNS_PER_FACTION
@ MAX_FORTRESS_TELEPORTERS_SPAWNS
@ MAX_FORTRESS_GATES_SPAWNS
@ MAX_TRIGGER_SPAWNS_PER_FACTION
@ MAX_CAPTAIN_SPAWNS_PER_FACTION
@ MAX_HANGAR_TELEPORTERS_SPAWNS
const uint32 BG_IC_Factions[2]
@ BG_IC_HORDE_RENFORT
@ BG_IC_HORDE_RENFORT_SET
@ BG_IC_ALLIANCE_RENFORT_SET
@ BG_IC_ALLIANCE_RENFORT
#define MAX_REINFORCEMENTS
@ BG_IC_GATE_DESTROYED
@ BG_IC_GATE_OK
const ICGo BG_IC_ObjSpawnlocs[MAX_NORMAL_GAMEOBJECTS_SPAWNS]
const Position BG_IC_HangarTeleporters[3]
const Position BG_IC_HangarTrigger[2]
const ICNodePoint nodePointInitial[MAX_NODE_TYPES]
const ICNpc BG_IC_NpcSpawnlocs[MAX_NORMAL_NPCS_SPAWNS]
@ BANNER_A_CONTROLLED
@ BANNER_H_CONTESTED
@ BANNER_H_CONTROLLED
@ BANNER_A_CONTESTED
const Position workshopBombs[2]
ICNodeState
@ NODE_STATE_CONFLICT_H
@ NODE_STATE_CONTROLLED_A
@ NODE_STATE_CONTROLLED_H
@ NODE_STATE_CONFLICT_A
const Position BG_IC_DocksVehiclesGlaives[2]
const Position BG_IC_DocksVehiclesCatapults[4]
@ GO_ALLIANCE_GATE_3
@ GO_HORDE_GATE_2
@ GO_HORDE_GUNSHIP
@ GO_ALLIANCE_GUNSHIP_PORTAL_EFFECTS
@ GO_HORDE_GUNSHIP_PORTAL_EFFECTS
@ GO_HORDE_GATE_1
@ GO_SEAFORIUM_BOMBS
@ GO_ALLIANCE_GUNSHIP_PORTAL
@ GO_ALLIANCE_GUNSHIP
@ GO_HORDE_GATE_3
@ GO_ALLIANCE_GATE_2
@ GO_ALLIANCE_GATE_1
@ GO_HORDE_GUNSHIP_PORTAL
@ BG_IC_NPC_KEEP_CANNON_24
@ BG_IC_NPC_GLAIVE_THROWER_1_H
@ BG_IC_NPC_GUNSHIP_CAPTAIN_1
@ BG_IC_NPC_KEEP_CANNON_13
@ BG_IC_NPC_SIEGE_ENGINE_H
@ BG_IC_NPC_CATAPULT_4_H
@ BG_IC_NPC_DEMOLISHER_1_H
@ BG_IC_NPC_GUNSHIP_CAPTAIN_2
@ BG_IC_NPC_CATAPULT_1_A
@ BG_IC_NPC_CATAPULT_1_H
@ BG_IC_NPC_DEMOLISHER_1_A
@ BG_IC_NPC_OVERLORD_AGMAR
@ BG_IC_NPC_SIEGE_ENGINE_A
@ BG_IC_NPC_DEMOLISHER_4_A
@ BG_IC_NPC_KEEP_CANNON_12
@ BG_IC_NPC_KEEP_CANNON_1
@ BG_IC_NPC_CATAPULT_4_A
@ BG_IC_NPC_GLAIVE_THROWER_1_A
@ BG_IC_NPC_SPIRIT_GUIDE_1
@ BG_IC_NPC_GLAIVE_THROWER_2_A
@ BG_IC_NPC_HIGH_COMMANDER_HALFORD_WYRMBANE
@ BG_IC_NPC_GLAIVE_THROWER_2_H
@ BG_IC_NPC_WORLD_TRIGGER_NOT_FLOATING
@ BG_IC_NPC_DEMOLISHER_4_H
const Position BG_IC_HangarTeleporterEffects[3]
const Position BG_IC_HangarCaptains[4]
const ICGo BG_IC_Teleporters[MAX_FORTRESS_TELEPORTERS_SPAWNS]
@ SCORE_BASES_ASSAULTED
@ SCORE_BASES_DEFENDED
@ RESPAWN_ONE_DAY
@ STATUS_IN_PROGRESS
DBCStorage< WorldSafeLocsEntry > sWorldSafeLocsStore(WorldSafeLocsEntryfmt)
uint8_t uint8
Definition Define.h:135
int8_t int8
Definition Define.h:131
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
#define TC_LOG_ERROR(filterType__,...)
Definition Log.h:165
TeamId
@ TEAM_ALLIANCE
@ TEAM_HORDE
@ GO_DESTRUCTIBLE_DAMAGED
@ ALLIANCE
@ HORDE
ChatMsg
@ CHAT_MSG_BG_SYSTEM_ALLIANCE
@ CHAT_MSG_BG_SYSTEM_HORDE
@ GO_FLAG_NOT_SELECTABLE
@ GO_STATE_ACTIVE
#define sTransportMgr
@ UNIT_FLAG_CANNOT_SWIM
@ UNIT_FLAG_UNINTERACTIBLE
@ UNIT_FLAG_IMMUNE_TO_PC
void StartingEventCloseDoors() override
void HandleCapturedNodes(ICNodePoint *node, bool recapture)
void UpdateNodeWorldState(ICNodePoint *node)
bool IsSpellAllowed(uint32 spellId, Player const *player) const override
uint32 GetNodeState(uint8 nodeType) const
void HandleKillUnit(Creature *unit, Player *killer) override
void RemovePlayer(Player *player, ObjectGuid guid, uint32 team) override
Transport * gunshipHorde
void EventPlayerClickedOnFlag(Player *source, GameObject *) override
void FillInitialWorldStates(WorldPackets::WorldState::InitWorldStates &packet) override
BG_IC_GateState GateStatus[6]
WorldSafeLocsEntry const * GetClosestGraveyard(Player *player) override
void AddPlayer(Player *player) override
void HandleKillPlayer(Player *player, Player *killer) override
uint32 GetGateIDFromEntry(uint32 id)
Transport * gunshipAlliance
void HandleAreaTrigger(Player *player, uint32 trigger) override
uint16 factionReinforcements[2]
void DestroyGate(Player *player, GameObject *go) override
ICNodePoint nodePoint[7]
uint32 GetNextBanner(ICNodePoint *node, uint32 team, bool returnDefinitve)
uint32 closeFortressDoorsTimer
void StartingEventOpenDoors() override
uint32 siegeEngineWorkshopTimer
void PostUpdateImpl(uint32 diff) override
Post-update hook.
uint32 GetWorldStateFromGateEntry(uint32 id, bool open)
bool IsAllNodesControlledByTeam(uint32 team) const override
void HandlePlayerResurrect(Player *player) override
bool SetupBattleground() override
void HandleContestedNodes(ICNodePoint *node)
virtual void AddPlayer(Player *player)
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)
virtual void HandleKillPlayer(Player *player, Player *killer)
static TeamId GetTeamIndexByTeamId(uint32 Team)
void DoorOpen(uint32 type)
bool DelCreature(uint32 type)
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
void RemoveAuraOnTeam(uint32 SpellID, uint32 TeamID)
virtual bool AddSpiritGuide(uint32 type, float x, float y, float z, float o, TeamId teamId=TEAM_NEUTRAL)
GuidVector BgCreatures
bool IsPlayerInBattleground(ObjectGuid guid) const
void SendBroadcastText(uint32 id, ChatMsg msgType, WorldObject const *target=nullptr)
bool DelObject(uint32 type)
BattlegroundScoreMap PlayerScores
void RewardHonorToTeam(uint32 Honor, uint32 TeamID)
BattlegroundStatus GetStatus() const
virtual bool UpdatePlayerScore(Player *player, uint32 type, uint32 value, bool doAddHonor=true)
void UpdateWorldState(uint32 variable, uint32 value)
bool RemoveObjectFromWorld(uint32 type)
GameObject * GetBGObject(uint32 type, bool logError=true)
void SetGoState(GOState state)
void RemoveFlag(GameObjectFlags flags)
Definition GameObject.h:172
void SetDestructibleState(GameObjectDestructibleState state, WorldObject *attackerOrHealer=nullptr, bool setHealth=false)
void SetRespawnTime(int32 respawn)
void SetFaction(uint32 faction) override
Definition GameObject.h:286
uint32 GetEntry() const
Definition Object.h:81
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
uint32 GetTeam() const
Definition Player.h:1832
TeamId GetTeamId() const
Definition Player.h:1833
void EnableMovement(bool enabled)
virtual void DoAction(int32)
Definition UnitAI.h:154
bool IsVehicle() const
Definition Unit.h:887
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3638
void SetFaction(uint32 faction) override
Definition Unit.h:974
bool IsAlive() const
Definition Unit.h:1234
UnitAI * GetAI() const
Definition Unit.h:800
void GetCreatureListWithEntryInGrid(Container &creatureContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition Object.cpp:3153
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
std::vector< WorldStateInfo > Worldstates
void BuildObjectivesBlock(WorldPackets::Battleground::PVPLogData_Player &playerData) override
uint32 banners[4]
ICNodeState nodeState
ICNodePointType nodeType
uint32 gameobject_type
uint32 worldStates[5]
uint32 gameobject_entry
float GetPositionZ() const
Definition Position.h:81
float GetOrientation() const
Definition Position.h:82
float GetPositionX() const
Definition Position.h:79
float GetPositionY() const
Definition Position.h:80
DBCPosition3D Loc