aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Battlegrounds/Arena.h4
-rw-r--r--src/server/game/Battlegrounds/Battleground.cpp352
-rw-r--r--src/server/game/Battlegrounds/Battleground.h60
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.cpp126
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.h12
-rw-r--r--src/server/game/Battlegrounds/BattlegroundScript.cpp135
-rw-r--r--src/server/game/Battlegrounds/BattlegroundScript.h77
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp480
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundAB.h254
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp898
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundAV.h637
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp83
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundBE.h68
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp159
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundDS.h115
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp491
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundEY.h319
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp706
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundIC.h376
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp80
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundNA.h67
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp78
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundRL.h63
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp146
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundRV.h109
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp843
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundSA.h365
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp559
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundWS.h201
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp4
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp48
-rw-r--r--src/server/game/Entities/Object/Object.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.cpp15
-rw-r--r--src/server/game/Entities/Vehicle/Vehicle.cpp4
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp3
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp3
-rw-r--r--src/server/game/Maps/Map.cpp40
-rw-r--r--src/server/game/Maps/Map.h11
-rw-r--r--src/server/game/Maps/MapManager.cpp1
-rw-r--r--src/server/game/Maps/ZoneScript.h2
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp65
-rw-r--r--src/server/game/Scripting/ScriptMgr.h30
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp7
-rw-r--r--src/server/game/Spells/SpellEffects.cpp18
-rw-r--r--src/server/game/Spells/SpellMgr.cpp6
-rw-r--r--src/server/game/World/World.cpp1
-rw-r--r--src/server/scripts/Battlegrounds/AlteracValley/alterac_valley.cpp (renamed from src/server/scripts/EasternKingdoms/AlteracValley/alterac_valley.cpp)29
-rw-r--r--src/server/scripts/Battlegrounds/AlteracValley/alterac_valley.h (renamed from src/server/game/Battlegrounds/Zones/BattlegroundBFG.cpp)25
-rw-r--r--src/server/scripts/Battlegrounds/AlteracValley/battleground_alterac_valley.cpp1369
-rw-r--r--src/server/scripts/Battlegrounds/AlteracValley/boss_balinda.cpp (renamed from src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp)0
-rw-r--r--src/server/scripts/Battlegrounds/AlteracValley/boss_drekthar.cpp (renamed from src/server/scripts/EasternKingdoms/AlteracValley/boss_drekthar.cpp)0
-rw-r--r--src/server/scripts/Battlegrounds/AlteracValley/boss_galvangar.cpp (renamed from src/server/scripts/EasternKingdoms/AlteracValley/boss_galvangar.cpp)0
-rw-r--r--src/server/scripts/Battlegrounds/AlteracValley/boss_vanndar.cpp (renamed from src/server/scripts/EasternKingdoms/AlteracValley/boss_vanndar.cpp)0
-rw-r--r--src/server/scripts/Battlegrounds/ArathiBasin/arathi_basin.cpp (renamed from src/server/scripts/EasternKingdoms/ArathiBasin/arathi_basin.cpp)0
-rw-r--r--src/server/scripts/Battlegrounds/ArathiBasin/battleground_arathi_basin.cpp605
-rw-r--r--src/server/scripts/Battlegrounds/BattleForGilneas/battleground_battle_for_gilneas.cpp (renamed from src/server/game/Battlegrounds/Zones/BattlegroundTP.h)28
-rw-r--r--src/server/scripts/Battlegrounds/BladesEdge/arena_blades_edge.cpp84
-rw-r--r--src/server/scripts/Battlegrounds/DalaranSewers/arena_dalaran_sewers.cpp266
-rw-r--r--src/server/scripts/Battlegrounds/EyeOfTheStorm/battleground_eye_of_the_storm.cpp677
-rw-r--r--src/server/scripts/Battlegrounds/IsleOfConquest/battleground_isle_of_conquest.cpp902
-rw-r--r--src/server/scripts/Battlegrounds/IsleOfConquest/boss_ioc_horde_alliance.cpp (renamed from src/server/scripts/Northrend/IsleOfConquest/boss_ioc_horde_alliance.cpp)2
-rw-r--r--src/server/scripts/Battlegrounds/IsleOfConquest/isle_of_conquest.cpp (renamed from src/server/scripts/Northrend/IsleOfConquest/isle_of_conquest.cpp)3
-rw-r--r--src/server/scripts/Battlegrounds/IsleOfConquest/isle_of_conquest.h132
-rw-r--r--src/server/scripts/Battlegrounds/NagrandArena/arena_nagrand_arena.cpp84
-rw-r--r--src/server/scripts/Battlegrounds/RingOfValor/arena_ring_of_valor.cpp302
-rw-r--r--src/server/scripts/Battlegrounds/RuinsOfLordaeron/arena_ruins_of_lordaeron.cpp80
-rw-r--r--src/server/scripts/Battlegrounds/StrandOfTheAncients/battleground_strand_of_the_ancients.cpp1059
-rw-r--r--src/server/scripts/Battlegrounds/StrandOfTheAncients/strand_of_the_ancients.cpp (renamed from src/server/scripts/Northrend/StrandOfTheAncients/strand_of_the_ancients.cpp)2
-rw-r--r--src/server/scripts/Battlegrounds/StrandOfTheAncients/strand_of_the_ancients.h (renamed from src/server/game/Battlegrounds/Zones/BattlegroundTP.cpp)12
-rw-r--r--src/server/scripts/Battlegrounds/TwinPeaks/battleground_twin_peaks.cpp (renamed from src/server/game/Battlegrounds/Zones/BattlegroundBFG.h)27
-rw-r--r--src/server/scripts/Battlegrounds/WarsongGulch/battleground_warsong_gulch.cpp608
-rw-r--r--src/server/scripts/Battlegrounds/battlegrounds_script_loader.cpp95
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp12
-rw-r--r--src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp12
-rw-r--r--src/server/scripts/Northrend/northrend_script_loader.cpp10
-rw-r--r--src/server/scripts/Northrend/zone_dalaran.cpp37
-rw-r--r--src/server/scripts/Spells/spell_item.cpp3
77 files changed, 6783 insertions, 7805 deletions
diff --git a/src/server/game/Battlegrounds/Arena.h b/src/server/game/Battlegrounds/Arena.h
index ccd1563b8e8..18c4ecc7ecf 100644
--- a/src/server/game/Battlegrounds/Arena.h
+++ b/src/server/game/Battlegrounds/Arena.h
@@ -55,9 +55,9 @@ enum ArenaWorldStates
class TC_GAME_API Arena : public Battleground
{
- protected:
+ public:
Arena(BattlegroundTemplate const* battlegroundTemplate);
-
+ protected:
void AddPlayer(Player* player, BattlegroundQueueTypeId queueId) override;
void RemovePlayer(Player* /*player*/, ObjectGuid /*guid*/, uint32 /*team*/) override;
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index edd00f0f041..fd145cab934 100644
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -19,6 +19,7 @@
#include "BattlegroundMgr.h"
#include "BattlegroundPackets.h"
#include "BattlegroundScore.h"
+#include "BattlegroundScript.h"
#include "ChatTextBuilder.h"
#include "Creature.h"
#include "CreatureTextMgr.h"
@@ -114,16 +115,6 @@ Battleground::Battleground(Battleground const&) = default;
Battleground::~Battleground()
{
- // remove objects and creatures
- // (this is done automatically in mapmanager update, when the instance is reset after the reset time)
- uint32 size = uint32(BgCreatures.size());
- for (uint32 i = 0; i < size; ++i)
- DelCreature(i);
-
- size = uint32(BgObjects.size());
- for (uint32 i = 0; i < size; ++i)
- DelObject(i);
-
// unload map
if (m_Map)
{
@@ -355,19 +346,12 @@ inline void Battleground::_ProcessJoin(uint32 diff)
return;
}
- // Setup here, only when at least one player has ported to the map
- if (!SetupBattleground())
- {
- EndNow();
- return;
- }
-
_preparationStartTime = GameTime::GetGameTime();
for (Group* group : m_BgRaids)
if (group)
group->StartCountdown(CountdownTimerType::Pvp, Seconds(StartDelayTimes[BG_STARTING_EVENT_FIRST] / 1000), _preparationStartTime);
- StartingEventCloseDoors();
+ GetBgMap()->GetBattlegroundScript()->OnPrepareStage1();
SetStartDelayTime(StartDelayTimes[BG_STARTING_EVENT_FIRST]);
// First start warning - 2 or 1 minute
if (StartMessageIds[BG_STARTING_EVENT_FIRST])
@@ -377,6 +361,7 @@ inline void Battleground::_ProcessJoin(uint32 diff)
else if (GetStartDelayTime() <= StartDelayTimes[BG_STARTING_EVENT_SECOND] && !(m_Events & BG_STARTING_EVENT_2))
{
m_Events |= BG_STARTING_EVENT_2;
+ GetBgMap()->GetBattlegroundScript()->OnPrepareStage2();
if (StartMessageIds[BG_STARTING_EVENT_SECOND])
SendBroadcastText(StartMessageIds[BG_STARTING_EVENT_SECOND], CHAT_MSG_BG_SYSTEM_NEUTRAL);
}
@@ -384,6 +369,7 @@ inline void Battleground::_ProcessJoin(uint32 diff)
else if (GetStartDelayTime() <= StartDelayTimes[BG_STARTING_EVENT_THIRD] && !(m_Events & BG_STARTING_EVENT_3))
{
m_Events |= BG_STARTING_EVENT_3;
+ GetBgMap()->GetBattlegroundScript()->OnPrepareStage3();
if (StartMessageIds[BG_STARTING_EVENT_THIRD])
SendBroadcastText(StartMessageIds[BG_STARTING_EVENT_THIRD], CHAT_MSG_BG_SYSTEM_NEUTRAL);
}
@@ -392,7 +378,7 @@ inline void Battleground::_ProcessJoin(uint32 diff)
{
m_Events |= BG_STARTING_EVENT_4;
- StartingEventOpenDoors();
+ GetBgMap()->GetBattlegroundScript()->OnStart();
if (StartMessageIds[BG_STARTING_EVENT_FOURTH])
SendBroadcastText(StartMessageIds[BG_STARTING_EVENT_FOURTH], CHAT_MSG_BG_SYSTEM_NEUTRAL);
@@ -785,6 +771,8 @@ void Battleground::EndBattleground(Team winner)
player->SendDirectMessage(pvpMatchComplete.GetRawPacket());
player->UpdateCriteria(CriteriaType::ParticipateInBattleground, player->GetMapId());
+
+ GetBgMap()->GetBattlegroundScript()->OnEnd(winner);
}
}
@@ -1081,6 +1069,8 @@ void Battleground::AddPlayer(Player* player, BattlegroundQueueTypeId queueId)
// setup BG group membership
PlayerAddedToBGCheckIfBGIsRunning(player);
AddOrSetPlayerToCorrectBgGroup(player, team);
+
+ GetBgMap()->GetBattlegroundScript()->OnPlayerJoined(player, isInBattleground);
}
// this method adds player to his team's bg group, or sets his correct group if player is already in bg group
@@ -1312,133 +1302,6 @@ void Battleground::UpdatePvpStat(Player* player, uint32 pvpStatId, uint32 value)
score->UpdatePvpStat(pvpStatId, value);
}
-bool Battleground::AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 /*respawnTime*/, GOState goState)
-{
- // If the assert is called, means that BgObjects must be resized!
- ASSERT(type < BgObjects.size());
-
- Map* map = FindBgMap();
- if (!map)
- return false;
-
- QuaternionData rot(rotation0, rotation1, rotation2, rotation3);
- // Temporally add safety check for bad spawns and send log (object rotations need to be rechecked in sniff)
- if (!rotation0 && !rotation1 && !rotation2 && !rotation3)
- {
- TC_LOG_DEBUG("bg.battleground", "Battleground::AddObject: gameoobject [entry: {}, object type: {}] for BG (map: {}) has zeroed rotation fields, "
- "orientation used temporally, but please fix the spawn", entry, type, GetMapId());
-
- rot = QuaternionData::fromEulerAnglesZYX(o, 0.f, 0.f);
- }
-
- // Must be created this way, adding to godatamap would add it to the base map of the instance
- // and when loading it (in go::LoadFromDB()), a new guid would be assigned to the object, and a new object would be created
- // So we must create it specific for this instance
- GameObject* go = GameObject::CreateGameObject(entry, GetBgMap(), Position(x, y, z, o), rot, 255, goState);
- if (!go)
- {
- TC_LOG_ERROR("bg.battleground", "Battleground::AddObject: cannot create gameobject (entry: {}) for BG (map: {}, instance id: {})!",
- entry, GetMapId(), m_InstanceID);
- return false;
- }
-
-/*
- uint32 guid = go->GetGUIDLow();
-
- // without this, UseButtonOrDoor caused the crash, since it tried to get go info from godata
- // iirc that was changed, so adding to go data map is no longer required if that was the only function using godata from GameObject without checking if it existed
- GameObjectData& data = sObjectMgr->NewGOData(guid);
-
- data.id = entry;
- data.mapid = GetMapId();
- data.posX = x;
- data.posY = y;
- data.posZ = z;
- data.orientation = o;
- data.rotation0 = rotation0;
- data.rotation1 = rotation1;
- data.rotation2 = rotation2;
- data.rotation3 = rotation3;
- data.spawntimesecs = respawnTime;
- data.spawnMask = 1;
- data.animprogress = 100;
- data.go_state = 1;
-*/
- // Add to world, so it can be later looked up from HashMapHolder
- if (!map->AddToMap(go))
- {
- delete go;
- return false;
- }
- BgObjects[type] = go->GetGUID();
- return true;
-}
-
-bool Battleground::AddObject(uint32 type, uint32 entry, Position const& pos, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime /*= 0*/, GOState goState /*= GO_STATE_READY*/)
-{
- return AddObject(type, entry, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), rotation0, rotation1, rotation2, rotation3, respawnTime, goState);
-}
-
-// Some doors aren't despawned so we cannot handle their closing in gameobject::update()
-// It would be nice to correctly implement GO_ACTIVATED state and open/close doors in gameobject code
-void Battleground::DoorClose(uint32 type)
-{
- if (GameObject* obj = GetBgMap()->GetGameObject(BgObjects[type]))
- {
- // If doors are open, close it
- if (obj->getLootState() == GO_ACTIVATED && obj->GetGoState() != GO_STATE_READY)
- {
- obj->SetLootState(GO_READY);
- obj->SetGoState(GO_STATE_READY);
- }
- }
- else
- TC_LOG_ERROR("bg.battleground", "Battleground::DoorClose: door gameobject (type: {}, {}) not found for BG (map: {}, instance id: {})!",
- type, BgObjects[type].ToString(), GetMapId(), m_InstanceID);
-}
-
-void Battleground::DoorOpen(uint32 type)
-{
- if (GameObject* obj = GetBgMap()->GetGameObject(BgObjects[type]))
- {
- obj->SetLootState(GO_ACTIVATED);
- obj->SetGoState(GO_STATE_ACTIVE);
- }
- else
- TC_LOG_ERROR("bg.battleground", "Battleground::DoorOpen: door gameobject (type: {}, {}) not found for BG (map: {}, instance id: {})!",
- type, BgObjects[type].ToString(), GetMapId(), m_InstanceID);
-}
-
-GameObject* Battleground::GetBGObject(uint32 type, bool logError)
-{
- GameObject* obj = GetBgMap()->GetGameObject(BgObjects[type]);
- if (!obj)
- {
- if (logError)
- TC_LOG_ERROR("bg.battleground", "Battleground::GetBGObject: gameobject (type: {}, {}) not found for BG (map: {}, instance id: {})!",
- type, BgObjects[type].ToString(), GetMapId(), m_InstanceID);
- else
- TC_LOG_INFO("bg.battleground", "Battleground::GetBGObject: gameobject (type: {}, {}) not found for BG (map: {}, instance id: {})!",
- type, BgObjects[type].ToString(), GetMapId(), m_InstanceID);
- }
- return obj;
-}
-
-Creature* Battleground::GetBGCreature(uint32 type, bool logError)
-{
- Creature* creature = GetBgMap()->GetCreature(BgCreatures[type]);
- if (!creature)
- {
- if (logError)
- TC_LOG_ERROR("bg.battleground", "Battleground::GetBGCreature: creature (type: {}, {}) not found for BG (map: {}, instance id: {})!",
- type, BgCreatures[type].ToString(), GetMapId(), m_InstanceID);
- else
- TC_LOG_INFO("bg.battleground", "Battleground::GetBGCreature: creature (type: {}, {}) not found for BG (map: {}, instance id: {})!",
- type, BgCreatures[type].ToString(), GetMapId(), m_InstanceID);
- }
- return creature;
-}
-
uint32 Battleground::GetMapId() const
{
return _battlegroundTemplate->BattlemasterEntry->MapID[0];
@@ -1448,169 +1311,11 @@ void Battleground::SetBgMap(BattlegroundMap* map)
{
m_Map = map;
if (map)
- {
_pvpStatIds = sDB2Manager.GetPVPStatIDsForMap(map->GetId());
- OnMapSet(map);
- }
else
_pvpStatIds = nullptr;
}
-void Battleground::SpawnBGObject(uint32 type, uint32 respawntime)
-{
- if (Map* map = FindBgMap())
- if (GameObject* obj = map->GetGameObject(BgObjects[type]))
- {
- if (respawntime)
- {
- obj->SetLootState(GO_JUST_DEACTIVATED);
-
- if (GameObjectOverride const* goOverride = obj->GetGameObjectOverride())
- if (goOverride->Flags & GO_FLAG_NODESPAWN)
- {
- // This function should be called in GameObject::Update() but in case of
- // GO_FLAG_NODESPAWN flag the function is never called, so we call it here
- obj->SendGameObjectDespawn();
- }
- }
- else if (obj->getLootState() == GO_JUST_DEACTIVATED)
- {
- // Change state from GO_JUST_DEACTIVATED to GO_READY in case battleground is starting again
- obj->SetLootState(GO_READY);
- }
- obj->SetRespawnTime(respawntime);
- map->AddToMap(obj);
- }
-}
-
-Creature* Battleground::AddCreature(uint32 entry, uint32 type, float x, float y, float z, float o, TeamId /*teamId = TEAM_NEUTRAL*/, uint32 respawntime /*= 0*/, Transport* transport)
-{
- // If the assert is called, means that BgCreatures must be resized!
- ASSERT(type < BgCreatures.size());
-
- Map* map = FindBgMap();
- if (!map)
- return nullptr;
-
- if (!sObjectMgr->GetCreatureTemplate(entry))
- {
- TC_LOG_ERROR("bg.battleground", "Battleground::AddCreature: creature template (entry: {}) does not exist for BG (map: {}, instance id: {})!",
- entry, GetMapId(), m_InstanceID);
- return nullptr;
- }
-
- if (transport)
- {
- if (Creature* creature = transport->SummonPassenger(entry, { x, y, z, o }, TEMPSUMMON_MANUAL_DESPAWN))
- {
- BgCreatures[type] = creature->GetGUID();
- return creature;
- }
-
- return nullptr;
- }
-
- Position pos = { x, y, z, o };
-
- Creature* creature = Creature::CreateCreature(entry, map, pos);
- if (!creature)
- {
- TC_LOG_ERROR("bg.battleground", "Battleground::AddCreature: cannot create creature (entry: {}) for BG (map: {}, instance id: {})!",
- entry, GetMapId(), m_InstanceID);
- return nullptr;
- }
-
- creature->SetHomePosition(pos);
-
- if (!map->AddToMap(creature))
- {
- delete creature;
- return nullptr;
- }
-
- BgCreatures[type] = creature->GetGUID();
-
- if (respawntime)
- creature->SetRespawnDelay(respawntime);
-
- return creature;
-}
-
-Creature* Battleground::AddCreature(uint32 entry, uint32 type, Position const& pos, TeamId teamId /*= TEAM_NEUTRAL*/, uint32 respawntime /*= 0*/, Transport* transport)
-{
- return AddCreature(entry, type, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teamId, respawntime, transport);
-}
-
-bool Battleground::DelCreature(uint32 type)
-{
- if (!BgCreatures[type])
- return true;
-
- if (Creature* creature = GetBgMap()->GetCreature(BgCreatures[type]))
- {
- creature->AddObjectToRemoveList();
- BgCreatures[type].Clear();
- return true;
- }
-
- TC_LOG_ERROR("bg.battleground", "Battleground::DelCreature: creature (type: {}, {}) not found for BG (map: {}, instance id: {})!",
- type, BgCreatures[type].ToString(), GetMapId(), m_InstanceID);
- BgCreatures[type].Clear();
- return false;
-}
-
-bool Battleground::DelObject(uint32 type)
-{
- if (!BgObjects[type])
- return true;
-
- if (GameObject* obj = GetBgMap()->GetGameObject(BgObjects[type]))
- {
- obj->SetRespawnTime(0); // not save respawn time
- obj->Delete();
- BgObjects[type].Clear();
- return true;
- }
- TC_LOG_ERROR("bg.battleground", "Battleground::DelObject: gameobject (type: {}, {}) not found for BG (map: {}, instance id: {})!",
- type, BgObjects[type].ToString(), GetMapId(), m_InstanceID);
- BgObjects[type].Clear();
- return false;
-}
-
-bool Battleground::RemoveObjectFromWorld(uint32 type)
-{
- if (!BgObjects[type])
- return true;
-
- if (GameObject* obj = GetBgMap()->GetGameObject(BgObjects[type]))
- {
- obj->RemoveFromWorld();
- BgObjects[type].Clear();
- return true;
- }
- TC_LOG_INFO("bg.battleground", "Battleground::RemoveObjectFromWorld: gameobject (type: {}, {}) not found for BG (map: {}, instance id: {})!",
- type, BgObjects[type].ToString(), GetMapId(), m_InstanceID);
- return false;
-}
-
-bool Battleground::AddSpiritGuide(uint32 type, float x, float y, float z, float o, TeamId teamId /*= TEAM_NEUTRAL*/)
-{
- uint32 entry = (teamId == TEAM_ALLIANCE) ? BG_CREATURE_ENTRY_A_SPIRITGUIDE : BG_CREATURE_ENTRY_H_SPIRITGUIDE;
-
- if (AddCreature(entry, type, x, y, z, o, teamId))
- return true;
-
- TC_LOG_ERROR("bg.battleground", "Battleground::AddSpiritGuide: cannot create spirit guide (type: {}, entry: {}) for BG (map: {}, instance id: {})!",
- type, entry, GetMapId(), m_InstanceID);
- EndNow();
- return false;
-}
-
-bool Battleground::AddSpiritGuide(uint32 type, Position const& pos, TeamId teamId /*= TEAM_NEUTRAL*/)
-{
- return AddSpiritGuide(type, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teamId);
-}
-
void Battleground::SendMessageToAll(uint32 entry, ChatMsg msgType, Player const* source)
{
if (!entry)
@@ -1693,6 +1398,15 @@ void Battleground::HandleKillPlayer(Player* victim, Player* killer)
victim->SetUnitFlag(UNIT_FLAG_SKINNABLE);
RewardXPAtKill(killer, victim);
}
+
+ if (BattlegroundScript* script = GetBgMap()->GetBattlegroundScript())
+ script->OnPlayerKilled(victim, killer);
+}
+
+void Battleground::HandleKillUnit(Creature* victim, Unit* killer)
+{
+ if (BattlegroundScript* script = GetBgMap()->GetBattlegroundScript())
+ script->OnUnitKilled(victim, killer);
}
// Return the player's team based on battlegroundplayer info
@@ -1748,16 +1462,6 @@ uint32 Battleground::GetAlivePlayersCountByTeam(Team team) const
return count;
}
-int32 Battleground::GetObjectType(ObjectGuid guid)
-{
- for (uint32 i = 0; i < BgObjects.size(); ++i)
- if (BgObjects[i] == guid)
- return i;
- TC_LOG_ERROR("bg.battleground", "Battleground::GetObjectType: player used gameobject ({}) which is not in internal data for BG (map: {}, instance id: {}), cheating?",
- guid.ToString(), GetMapId(), m_InstanceID);
- return -1;
-}
-
void Battleground::SetBgRaid(Team team, Group* bg_raid)
{
Group*& old_raid = team == ALLIANCE ? m_BgRaids[TEAM_ALLIANCE] : m_BgRaids[TEAM_HORDE];
@@ -1768,20 +1472,6 @@ void Battleground::SetBgRaid(Team team, Group* bg_raid)
old_raid = bg_raid;
}
-WorldSafeLocsEntry const* Battleground::GetClosestGraveyard(Player* player)
-{
- return sObjectMgr->GetClosestGraveyard(*player, GetPlayerTeam(player->GetGUID()), player);
-}
-
-void Battleground::TriggerGameEvent(uint32 gameEventId, WorldObject* source /*= nullptr*/, WorldObject* target /*= nullptr*/)
-{
- ProcessEvent(target, gameEventId, source);
- GameEvents::TriggerForMap(gameEventId, GetBgMap(), source, target);
- for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
- if (Player* player = ObjectAccessor::FindPlayer(itr->first))
- GameEvents::TriggerForPlayer(gameEventId, player);
-}
-
void Battleground::SetBracket(PVPDifficultyEntry const* bracketEntry)
{
_pvpDifficultyEntry = bracketEntry;
@@ -1805,12 +1495,6 @@ uint32 Battleground::GetTeamScore(TeamId teamId) const
return 0;
}
-void Battleground::HandleAreaTrigger(Player* player, uint32 trigger, bool /*entered*/)
-{
- TC_LOG_DEBUG("bg.battleground", "Unhandled AreaTrigger {} in Battleground {}. Player coords (x: {}, y: {}, z: {})",
- trigger, player->GetMapId(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ());
-}
-
char const* Battleground::GetName() const
{
return _battlegroundTemplate->BattlemasterEntry->Name[sWorld->GetDefaultDbcLocale()];
diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
index 2feb0fd9305..1a396c67e70 100644
--- a/src/server/game/Battlegrounds/Battleground.h
+++ b/src/server/game/Battlegrounds/Battleground.h
@@ -252,7 +252,7 @@ This class is used to:
3. some certain cases, same for all battlegrounds
4. It has properties same for all battlegrounds
*/
-class TC_GAME_API Battleground : public ZoneScript
+class TC_GAME_API Battleground
{
public:
Battleground(BattlegroundTemplate const* battlegroundTemplate);
@@ -263,17 +263,7 @@ class TC_GAME_API Battleground : public ZoneScript
void Update(uint32 diff);
- virtual bool SetupBattleground() // must be implemented in BG subclass
- {
- return true;
- }
- virtual void Reset(); // resets all common properties for battlegrounds, must be implemented and called in BG subclass
- virtual void StartingEventCloseDoors() { }
- virtual void StartingEventOpenDoors() { }
-
- virtual void DestroyGate(Player* /*player*/, GameObject* /*go*/) { }
-
- void TriggerGameEvent(uint32 gameEventId, WorldObject* source = nullptr, WorldObject* target = nullptr) override;
+ void Reset();
/* Battleground */
// Get methods:
@@ -386,7 +376,7 @@ class TC_GAME_API Battleground : public ZoneScript
BattlegroundScore const* GetBattlegroundScore(Player* player) const;
- virtual bool UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor = true);
+ bool UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor = true);
void UpdatePvpStat(Player* player, uint32 pvpStatId, uint32 value);
static TeamId GetTeamIndexByTeamId(Team team) { return team == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE; }
@@ -409,24 +399,13 @@ class TC_GAME_API Battleground : public ZoneScript
void SetArenaMatchmakerRating(Team team, uint32 MMR){ m_ArenaTeamMMR[GetTeamIndexByTeamId(team)] = MMR; }
uint32 GetArenaMatchmakerRating(Team team) const { return m_ArenaTeamMMR[GetTeamIndexByTeamId(team)]; }
- // Triggers handle
- // must be implemented in BG subclass
- virtual void HandleAreaTrigger(Player* /*player*/, uint32 /*trigger*/, bool /*entered*/);
// must be implemented in BG subclass if need AND call base class generic code
virtual void HandleKillPlayer(Player* player, Player* killer);
- virtual void HandleKillUnit(Creature* /*creature*/, Unit* /*killer*/) { }
+ virtual void HandleKillUnit(Creature* /*creature*/, Unit* /*killer*/);
// Battleground events
- virtual void EventPlayerDroppedFlag(Player* /*player*/) { }
- virtual void EventPlayerClickedOnFlag(Player* /*player*/, GameObject* /*target_obj*/) { }
void EventPlayerLoggedIn(Player* player);
void EventPlayerLoggedOut(Player* player);
- void ProcessEvent(WorldObject* /*obj*/, uint32 /*eventId*/, WorldObject* /*invoker*/) override { }
-
- virtual void HandlePlayerResurrect(Player* /*player*/) { }
-
- // Death related
- virtual WorldSafeLocsEntry const* GetClosestGraveyard(Player* player);
virtual WorldSafeLocsEntry const* GetExploitTeleportLocation(Team /*team*/) { return nullptr; }
// GetExploitTeleportLocation(TeamId) must be implemented in the battleground subclass.
@@ -437,25 +416,6 @@ class TC_GAME_API Battleground : public ZoneScript
void AddOrSetPlayerToCorrectBgGroup(Player* player, Team team);
virtual void RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool SendPacket);
- // can be extended in in BG subclass
-
- /// @todo make this protected:
- GuidVector BgObjects;
- GuidVector BgCreatures;
- void SpawnBGObject(uint32 type, uint32 respawntime);
- 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);
- bool AddObject(uint32 type, uint32 entry, Position const& pos, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime = 0, GOState goState = GO_STATE_READY);
- 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);
- Creature* AddCreature(uint32 entry, uint32 type, Position const& pos, TeamId teamId = TEAM_NEUTRAL, uint32 respawntime = 0, Transport* transport = nullptr);
- bool DelCreature(uint32 type);
- bool DelObject(uint32 type);
- bool RemoveObjectFromWorld(uint32 type);
- virtual bool AddSpiritGuide(uint32 type, float x, float y, float z, float o, TeamId teamId = TEAM_NEUTRAL);
- bool AddSpiritGuide(uint32 type, Position const& pos, TeamId teamId = TEAM_NEUTRAL);
- int32 GetObjectType(ObjectGuid guid);
-
- void DoorOpen(uint32 type);
- void DoorClose(uint32 type);
virtual bool HandlePlayerUnderMap(Player* /*player*/) { return false; }
@@ -470,14 +430,9 @@ class TC_GAME_API Battleground : public ZoneScript
void RewardXPAtKill(Player* killer, Player* victim);
bool CanAwardArenaPoints() const { return GetMinLevel() >= BG_AWARD_ARENA_POINTS_MIN_LEVEL; }
- virtual ObjectGuid GetFlagPickerGUID(int32 /*team*/ = -1) const { return ObjectGuid::Empty; }
- virtual void SetDroppedFlagGUID(ObjectGuid /*guid*/, int32 /*team*/ = -1) { }
- virtual void HandleQuestComplete(uint32 /*questid*/, Player* /*player*/) { }
- virtual bool CanActivateGO(int32 /*entry*/, uint32 /*team*/) const { return true; }
- virtual bool IsSpellAllowed(uint32 /*spellId*/, Player const* /*player*/) const { return true; }
uint32 GetTeamScore(TeamId teamId) const;
- virtual Team GetPrematureWinner();
+ Team GetPrematureWinner();
// because BattleGrounds with different types and same level range has different m_BracketId
uint8 GetUniqueBracketId() const;
@@ -494,8 +449,9 @@ class TC_GAME_API Battleground : public ZoneScript
return &itr->second;
}
- // Called when valid BattlegroundMap is assigned to the battleground
- virtual void OnMapSet([[maybe_unused]] BattlegroundMap* map) { }
+ void AddPoint(Team team, uint32 points = 1) { m_TeamScores[GetTeamIndexByTeamId(team)] += points; }
+ void SetTeamPoint(Team team, uint32 points = 0) { m_TeamScores[GetTeamIndexByTeamId(team)] = points; }
+ void RemovePoint(Team team, uint32 points = 1) { m_TeamScores[GetTeamIndexByTeamId(team)] -= points; }
Trinity::unique_weak_ptr<Battleground> GetWeakPtr() const { return m_weakRef; }
void SetWeakPtr(Trinity::unique_weak_ptr<Battleground> weakRef) { m_weakRef = std::move(weakRef); }
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
index 37311c718f2..edef0191304 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
@@ -16,20 +16,8 @@
*/
#include "BattlegroundMgr.h"
-#include "BattlegroundAB.h"
-#include "BattlegroundAV.h"
-#include "BattlegroundBE.h"
-#include "BattlegroundBFG.h"
-#include "BattlegroundDS.h"
-#include "BattlegroundEY.h"
-#include "BattlegroundIC.h"
-#include "BattlegroundNA.h"
+#include "Arena.h"
#include "BattlegroundPackets.h"
-#include "BattlegroundRL.h"
-#include "BattlegroundRV.h"
-#include "BattlegroundSA.h"
-#include "BattlegroundTP.h"
-#include "BattlegroundWS.h"
#include "Containers.h"
#include "DatabaseEnv.h"
#include "DB2Stores.h"
@@ -262,6 +250,59 @@ Battleground* BattlegroundMgr::GetBattleground(uint32 instanceId, BattlegroundTy
return nullptr;
}
+void BattlegroundMgr::LoadBattlegroundScriptTemplate()
+{
+ uint32 oldMSTime = getMSTime();
+ // 0 1 2
+ QueryResult result = WorldDatabase.Query("SELECT MapId, BattlemasterListId, ScriptName FROM battleground_scripts");
+
+ if (!result)
+ {
+ TC_LOG_INFO("server.loading", ">> Loaded 0 battleground scripts. DB table `battleground_scripts` is empty!");
+ return;
+ }
+
+ uint32 count = 0;
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 mapID = fields[0].GetUInt32();
+
+ MapEntry const* mapEntry = sMapStore.LookupEntry(mapID);
+ if (!mapEntry || !mapEntry->IsBattlegroundOrArena())
+ {
+ TC_LOG_ERROR("sql.sql", "BattlegroundMgr::LoadBattlegroundScriptTemplate: bad mapid {}! Map doesn't exist or is not a battleground/arena!", mapID);
+ continue;
+ }
+
+ BattlegroundTypeId bgTypeId = static_cast<BattlegroundTypeId>(fields[1].GetUInt32());
+ if (bgTypeId != BATTLEGROUND_TYPE_NONE && !Trinity::Containers::MapGetValuePtr(_battlegroundTemplates, bgTypeId))
+ {
+ TC_LOG_ERROR("sql.sql", "BattlegroundMgr::LoadBattlegroundScriptTemplate: bad battlemasterlist id {}! Battleground doesn't exist or is not supported in battleground_template!", bgTypeId);
+ continue;
+ }
+
+ BattlegroundScriptTemplate& scriptTemplate = _battlegroundScriptTemplates[{ mapID, bgTypeId }];
+ scriptTemplate.MapId = mapID;
+ scriptTemplate.Id = bgTypeId;
+ scriptTemplate.ScriptId = sObjectMgr->GetScriptId(fields[2].GetString());
+
+ ++count;
+ } while (result->NextRow());
+
+ TC_LOG_INFO("server.loading", ">> Loaded {} battleground scripts in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
+}
+
+BattlegroundScriptTemplate const* BattlegroundMgr::FindBattlegroundScriptTemplate(uint32 mapId, BattlegroundTypeId bgTypeId) const
+{
+ if (BattlegroundScriptTemplate const* scriptTemplate = Trinity::Containers::MapGetValuePtr(_battlegroundScriptTemplates, { mapId, bgTypeId }))
+ return scriptTemplate;
+
+ // fall back to 0 for no specific battleground type id
+ return Trinity::Containers::MapGetValuePtr(_battlegroundScriptTemplates, { mapId, BATTLEGROUND_TYPE_NONE });
+}
+
uint32 BattlegroundMgr::CreateClientVisibleInstanceId(BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id)
{
if (IsArenaType(bgTypeId))
@@ -309,56 +350,10 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundQueueTypeId que
}
Battleground* bg = nullptr;
- // create a copy of the BG template
- switch (bgTypeId)
- {
- case BATTLEGROUND_AV:
- bg = new BattlegroundAV(bg_template);
- break;
- case BATTLEGROUND_WS:
- case BATTLEGROUND_WG_CTF:
- bg = new BattlegroundWS(bg_template);
- break;
- case BATTLEGROUND_AB:
- case BATTLEGROUND_DOM_AB:
- bg = new BattlegroundAB(bg_template);
- break;
- case BATTLEGROUND_NA:
- bg = new BattlegroundNA(bg_template);
- break;
- case BATTLEGROUND_BE:
- bg = new BattlegroundBE(bg_template);
- break;
- case BATTLEGROUND_EY:
- bg = new BattlegroundEY(bg_template);
- break;
- case BATTLEGROUND_RL:
- bg = new BattlegroundRL(bg_template);
- break;
- case BATTLEGROUND_SA:
- bg = new BattlegroundSA(bg_template);
- break;
- case BATTLEGROUND_DS:
- bg = new BattlegroundDS(bg_template);
- break;
- case BATTLEGROUND_RV:
- bg = new BattlegroundRV(bg_template);
- break;
- case BATTLEGROUND_IC:
- bg = new BattlegroundIC(bg_template);
- break;
- case BATTLEGROUND_TP:
- bg = new BattlegroundTP(bg_template);
- break;
- case BATTLEGROUND_BFG:
- bg = new BattlegroundBFG(bg_template);
- break;
- case BATTLEGROUND_RB:
- case BATTLEGROUND_AA:
- case BATTLEGROUND_RANDOM_EPIC:
- default:
- return nullptr;
- }
+ if (bg_template->IsArena())
+ bg = new Arena(bg_template);
+ else
+ bg = new Battleground(bg_template);
bg->SetBracket(bracketEntry);
bg->SetInstanceID(sMapMgr->GenerateInstanceId());
@@ -689,6 +684,7 @@ BattlegroundTypeId BattlegroundMgr::GetRandomBG(BattlegroundTypeId bgTypeId)
ids.reserve(16);
std::vector<double> weights;
weights.reserve(16);
+ double totalWeight = 0.0;
for (int32 mapId : bgTemplate->BattlemasterEntry->MapID)
{
if (mapId == -1)
@@ -698,10 +694,12 @@ BattlegroundTypeId BattlegroundMgr::GetRandomBG(BattlegroundTypeId bgTypeId)
{
ids.push_back(bg->Id);
weights.push_back(bg->Weight);
+ totalWeight += bg->Weight;
}
}
- return *Trinity::Containers::SelectRandomWeightedContainerElement(ids, std::span(weights));
+ if (totalWeight > 0.0)
+ return *Trinity::Containers::SelectRandomWeightedContainerElement(ids, std::span(weights));
}
return BATTLEGROUND_TYPE_NONE;
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h
index 854f6da9cfa..3fa49dd29f7 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.h
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.h
@@ -60,6 +60,13 @@ struct BattlegroundTemplate
uint8 GetMaxLevel() const;
};
+struct BattlegroundScriptTemplate
+{
+ int32 MapId;
+ BattlegroundTypeId Id;
+ uint32 ScriptId;
+};
+
namespace WorldPackets
{
namespace Battleground
@@ -151,6 +158,9 @@ class TC_GAME_API BattlegroundMgr
return nullptr;
}
+ void LoadBattlegroundScriptTemplate();
+ BattlegroundScriptTemplate const* FindBattlegroundScriptTemplate(uint32 mapId, BattlegroundTypeId bgTypeId) const;
+
private:
uint32 CreateClientVisibleInstanceId(BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id);
static bool IsArenaType(BattlegroundTypeId bgTypeId);
@@ -190,6 +200,8 @@ class TC_GAME_API BattlegroundMgr
typedef std::map<uint32 /*mapId*/, BattlegroundTemplate*> BattlegroundMapTemplateContainer;
BattlegroundTemplateMap _battlegroundTemplates;
BattlegroundMapTemplateContainer _battlegroundMapTemplates;
+
+ std::map<std::pair<int32, uint32>, BattlegroundScriptTemplate> _battlegroundScriptTemplates;
};
#define sBattlegroundMgr BattlegroundMgr::instance()
diff --git a/src/server/game/Battlegrounds/BattlegroundScript.cpp b/src/server/game/Battlegrounds/BattlegroundScript.cpp
new file mode 100644
index 00000000000..a3bee1d6b38
--- /dev/null
+++ b/src/server/game/Battlegrounds/BattlegroundScript.cpp
@@ -0,0 +1,135 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "BattlegroundScript.h"
+#include "BattlegroundMgr.h"
+#include "Creature.h"
+#include "GameEventSender.h"
+#include "GameObject.h"
+#include "Log.h"
+#include "Map.h"
+#include "ObjectAccessor.h"
+#include "ObjectMgr.h"
+#include "ScriptMgr.h"
+#include "WorldStateMgr.h"
+
+BattlegroundScript::BattlegroundScript(BattlegroundMap* map) : battlegroundMap(map), battleground(map->GetBG())
+{
+#ifdef TRINITY_API_USE_DYNAMIC_LINKING
+ BattlegroundScriptTemplate const* scriptTemplate = sBattlegroundMgr->FindBattlegroundScriptTemplate(battlegroundMap->GetId(), battlegroundMap->GetBG()->GetTypeID());
+ if (!scriptTemplate)
+ return;
+
+ auto const scriptname = sObjectMgr->GetScriptName(scriptTemplate->ScriptId);
+ ASSERT(!scriptname.empty());
+ // Acquire a strong reference from the script module
+ // to keep it loaded until this object is destroyed.
+ module_reference = sScriptMgr->AcquireModuleReferenceOfScriptName(scriptname);
+#endif // #ifndef TRINITY_API_USE_DYNAMIC_LINKING
+}
+
+Team BattlegroundScript::GetPrematureWinner()
+{
+ Team winner = TEAM_OTHER;
+ if (battleground->GetPlayersCountByTeam(ALLIANCE) >= battleground->GetMinPlayersPerTeam())
+ winner = ALLIANCE;
+ else if (battleground->GetPlayersCountByTeam(HORDE) >= battleground->GetMinPlayersPerTeam())
+ winner = HORDE;
+
+ return winner;
+}
+
+void BattlegroundScript::TriggerGameEvent(uint32 gameEventId, WorldObject* source, WorldObject* target)
+{
+ ProcessEvent(target, gameEventId, source);
+ GameEvents::TriggerForMap(gameEventId, battlegroundMap, source, target);
+ for (auto const& [playerGuid, _] : battleground->GetPlayers())
+ if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
+ GameEvents::TriggerForPlayer(gameEventId, player);
+}
+
+void BattlegroundScript::UpdateWorldState(int32 worldStateId, int32 value, bool hidden) const
+{
+ sWorldStateMgr->SetValue(worldStateId, value, hidden, battlegroundMap);
+}
+
+ArenaScript::ArenaScript(BattlegroundMap* map) : BattlegroundScript(map)
+{
+
+}
+
+GameObject* ArenaScript::CreateObject(uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, GOState goState) const
+{
+ QuaternionData rot(rotation0, rotation1, rotation2, rotation3);
+ // Temporally add safety check for bad spawns and send log (object rotations need to be rechecked in sniff)
+ if (!rotation0 && !rotation1 && !rotation2 && !rotation3)
+ {
+ TC_LOG_DEBUG("bg.battleground", "Battleground::AddObject: gameoobject [entry: {}] for BG (map: {}) has zeroed rotation fields, "
+ "orientation used temporally, but please fix the spawn", entry, battlegroundMap->GetId());
+
+ rot = QuaternionData::fromEulerAnglesZYX(o, 0.f, 0.f);
+ }
+
+ // Must be created this way, adding to godatamap would add it to the base map of the instance
+ // and when loading it (in go::LoadFromDB()), a new guid would be assigned to the object, and a new object would be created
+ // So we must create it specific for this instance
+ GameObject* go = GameObject::CreateGameObject(entry, battlegroundMap, Position(x, y, z, o), rot, 255, goState);
+ if (!go)
+ {
+ TC_LOG_ERROR("bg.battleground", "Battleground::AddObject: cannot create gameobject (entry: {}) for BG (map: {}, instance id: {})!",
+ entry, battlegroundMap->GetId(), battleground->GetInstanceID());
+ return nullptr;
+ }
+
+ if (!battlegroundMap->AddToMap(go))
+ {
+ delete go;
+ return nullptr;
+ }
+
+ return go;
+}
+
+Creature* ArenaScript::CreateCreature(uint32 entry, float x, float y, float z, float o) const
+{
+ if (!sObjectMgr->GetCreatureTemplate(entry))
+ {
+ TC_LOG_ERROR("bg.battleground", "Battleground::AddCreature: creature template (entry: {}) does not exist for BG (map: {}, instance id: {})!",
+ entry, battlegroundMap->GetId(), battleground->GetInstanceID());
+ return nullptr;
+ }
+
+ Position pos = { x, y, z, o };
+
+ Creature* creature = Creature::CreateCreature(entry, battlegroundMap, pos);
+ if (!creature)
+ {
+ TC_LOG_ERROR("bg.battleground", "Battleground::AddCreature: cannot create creature (entry: {}) for BG (map: {}, instance id: {})!",
+ entry, battlegroundMap->GetId(), battleground->GetInstanceID());
+ return nullptr;
+ }
+
+ creature->SetHomePosition(pos);
+
+ if (!battlegroundMap->AddToMap(creature))
+ {
+ delete creature;
+ return nullptr;
+ }
+
+ return creature;
+}
diff --git a/src/server/game/Battlegrounds/BattlegroundScript.h b/src/server/game/Battlegrounds/BattlegroundScript.h
new file mode 100644
index 00000000000..1780052fc92
--- /dev/null
+++ b/src/server/game/Battlegrounds/BattlegroundScript.h
@@ -0,0 +1,77 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TRINITY_BATTLEGROUND_SCRIPT_H
+#define TRINITY_BATTLEGROUND_SCRIPT_H
+
+#include "SharedDefines.h"
+#include "ZoneScript.h"
+
+#ifdef TRINITY_API_USE_DYNAMIC_LINKING
+#include <memory>
+#endif
+
+class Battleground;
+class BattlegroundMap;
+class ModuleReference;
+
+class TC_GAME_API BattlegroundScript : public ZoneScript
+{
+public:
+ explicit BattlegroundScript(BattlegroundMap* map);
+ ~BattlegroundScript() override = default;
+
+ virtual void OnInit() { }
+ virtual void OnUpdate([[maybe_unused]] uint32 diff) { }
+ virtual void OnPrepareStage1() { }
+ virtual void OnPrepareStage2() { }
+ virtual void OnPrepareStage3() { }
+ virtual void OnStart() { }
+ virtual void OnEnd([[maybe_unused]] Team winner) { }
+ virtual void OnPlayerJoined([[maybe_unused]] Player* player, [[maybe_unused]] bool inBattleground) { }
+ virtual void OnPlayerLeft([[maybe_unused]] Player* player) { }
+ virtual void OnPlayerKilled([[maybe_unused]] Player* victim, [[maybe_unused]] Player* killer) { }
+ virtual void OnUnitKilled([[maybe_unused]] Creature* victim, [[maybe_unused]] Unit* killer) { }
+ virtual Team GetPrematureWinner();
+
+ void TriggerGameEvent(uint32 gameEventId, WorldObject* source = nullptr, WorldObject* target = nullptr) override;
+
+protected:
+ void UpdateWorldState(int32 worldStateId, int32 value, bool hidden = false) const;
+
+ BattlegroundMap* battlegroundMap;
+ Battleground* battleground;
+
+private:
+#ifdef TRINITY_API_USE_DYNAMIC_LINKING
+ // Strong reference to the associated script module
+ std::shared_ptr<ModuleReference> module_reference;
+#endif // #ifndef TRINITY_API_USE_DYNAMIC_LINKING
+};
+
+class TC_GAME_API ArenaScript : public BattlegroundScript
+{
+public:
+ explicit ArenaScript(BattlegroundMap* map);
+ ~ArenaScript() override = default;
+
+protected:
+ GameObject* CreateObject(uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, GOState goState = GO_STATE_READY) const;
+ Creature* CreateCreature(uint32 entry, float x, float y, float z, float o) const;
+};
+
+#endif // TRINITY_BATTLEGROUND_SCRIPT_H
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
deleted file mode 100644
index e3d532518a9..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "BattlegroundAB.h"
-#include "BattlegroundMgr.h"
-#include "BattlegroundPackets.h"
-#include "BattlegroundScore.h"
-#include "Creature.h"
-#include "GameObject.h"
-#include "Log.h"
-#include "Map.h"
-#include "ObjectMgr.h"
-#include "Player.h"
-#include "SpellInfo.h"
-
-enum ArathiBasinPvpStats
-{
- PVP_STAT_BASES_ASSAULTED = 926,
- PVP_STAT_BASES_DEFENDED = 927,
-};
-
-BattlegroundAB::BattlegroundAB(BattlegroundTemplate const* battlegroundTemplate) : Battleground(battlegroundTemplate)
-{
- m_IsInformedNearVictory = false;
- BgObjects.resize(0);
- BgCreatures.resize(0);
- m_lastTick = 0;
-
- for (uint8 i = 0; i < PVP_TEAMS_COUNT; ++i)
- {
- m_HonorScoreTics[i] = 0;
- m_ReputationScoreTics[i] = 0;
- }
-
- m_HonorTics = 0;
- m_ReputationTics = 0;
-}
-
-BattlegroundAB::~BattlegroundAB() { }
-
-void BattlegroundAB::PostUpdateImpl(uint32 diff)
-{
- if (GetStatus() == STATUS_IN_PROGRESS)
- {
- // Accumulate points
- m_lastTick += diff;
- if (m_lastTick > BG_AB_TickInterval)
- {
- m_lastTick -= BG_AB_TickInterval;
-
- uint8 ally = 0, horde = 0;
- _CalculateTeamNodes(ally, horde);
- uint8 points[PVP_TEAMS_COUNT] = { ally, horde };
-
- for (uint8 team = 0; team < PVP_TEAMS_COUNT; ++team)
- {
- if (!points[team])
- continue;
-
- m_TeamScores[team] += BG_AB_TickPoints[points[team]];
- m_HonorScoreTics[team] += BG_AB_TickPoints[points[team]];
- m_ReputationScoreTics[team] += BG_AB_TickPoints[points[team]];
-
- if (m_ReputationScoreTics[team] >= m_ReputationTics)
- {
- (team == TEAM_ALLIANCE) ? RewardReputationToTeam(509, 10, ALLIANCE) : RewardReputationToTeam(510, 10, HORDE);
- m_ReputationScoreTics[team] -= m_ReputationTics;
- }
-
- if (m_HonorScoreTics[team] >= m_HonorTics)
- {
- RewardHonorToTeam(GetBonusHonorFromKill(1), (team == TEAM_ALLIANCE) ? ALLIANCE : HORDE);
- m_HonorScoreTics[team] -= m_HonorTics;
- }
-
- if (!m_IsInformedNearVictory && m_TeamScores[team] > BG_AB_WARNING_NEAR_VICTORY_SCORE)
- {
- if (team == TEAM_ALLIANCE)
- {
- SendBroadcastText(BG_AB_TEXT_ALLIANCE_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
- PlaySoundToAll(BG_AB_SOUND_NEAR_VICTORY_ALLIANCE);
- }
- else
- {
- SendBroadcastText(BG_AB_TEXT_HORDE_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
- PlaySoundToAll(BG_AB_SOUND_NEAR_VICTORY_HORDE);
- }
- m_IsInformedNearVictory = true;
- }
-
- if (m_TeamScores[team] > BG_AB_MAX_TEAM_SCORE)
- m_TeamScores[team] = BG_AB_MAX_TEAM_SCORE;
-
- if (team == TEAM_ALLIANCE)
- UpdateWorldState(BG_AB_WS_RESOURCES_ALLY, m_TeamScores[team]);
- else
- UpdateWorldState(BG_AB_WS_RESOURCES_HORDE, m_TeamScores[team]);
- // update achievement flags
- // we increased m_TeamScores[team] so we just need to check if it is 500 more than other teams resources
- uint8 otherTeam = (team + 1) % PVP_TEAMS_COUNT;
- if (m_TeamScores[team] > m_TeamScores[otherTeam] + 500)
- {
- if (team == TEAM_ALLIANCE)
- UpdateWorldState(BG_AB_WS_HAD_500_DISADVANTAGE_HORDE, 1);
- else
- UpdateWorldState(BG_AB_WS_HAD_500_DISADVANTAGE_ALLIANCE, 1);
- }
- }
-
- UpdateWorldState(BG_AB_WS_OCCUPIED_BASES_ALLY, ally);
- UpdateWorldState(BG_AB_WS_OCCUPIED_BASES_HORDE, horde);
- }
-
- // Test win condition
- if (m_TeamScores[TEAM_ALLIANCE] >= BG_AB_MAX_TEAM_SCORE)
- EndBattleground(ALLIANCE);
- else if (m_TeamScores[TEAM_HORDE] >= BG_AB_MAX_TEAM_SCORE)
- EndBattleground(HORDE);
- }
-}
-
-void BattlegroundAB::StartingEventOpenDoors()
-{
- // Achievement: Let's Get This Done
- TriggerGameEvent(AB_EVENT_START_BATTLE);
-}
-
-void BattlegroundAB::_CalculateTeamNodes(uint8& alliance, uint8& horde)
-{
- alliance = 0;
- horde = 0;
-
- if (BattlegroundMap* map = FindBgMap())
- {
- for (ObjectGuid const& guid : _capturePoints)
- {
- if (GameObject* capturePoint = map->GetGameObject(guid))
- {
- int32 wsValue = map->GetWorldStateValue(capturePoint->GetGOInfo()->capturePoint.worldState1);
- switch (WorldPackets::Battleground::BattlegroundCapturePointState(wsValue))
- {
- case WorldPackets::Battleground::BattlegroundCapturePointState::AllianceCaptured:
- ++alliance;
- break;
- case WorldPackets::Battleground::BattlegroundCapturePointState::HordeCaptured:
- ++horde;
- break;
- default:
- break;
- }
- }
- }
- }
-}
-
-Team BattlegroundAB::GetPrematureWinner()
-{
- // How many bases each team owns
- uint8 ally = 0, horde = 0;
- _CalculateTeamNodes(ally, horde);
-
- if (ally > horde)
- return ALLIANCE;
- else if (horde > ally)
- return HORDE;
-
- // If the values are equal, fall back to the original result (based on number of players on each team)
- return Battleground::GetPrematureWinner();
-}
-
-void BattlegroundAB::ProcessEvent(WorldObject* /*source*/, uint32 eventId, WorldObject* invoker)
-{
- switch (eventId)
- {
- case AB_EVENT_START_BATTLE:
- {
- for (ObjectGuid const& guid : _creaturesToRemoveOnMatchStart)
- if (Creature* creature = GetBgMap()->GetCreature(guid))
- creature->DespawnOrUnsummon();
-
- for (ObjectGuid const& guid : _gameobjectsToRemoveOnMatchStart)
- if (GameObject* gameObject = GetBgMap()->GetGameObject(guid))
- gameObject->DespawnOrUnsummon();
-
- for (ObjectGuid const& guid : _doors)
- {
- if (GameObject* gameObject = GetBgMap()->GetGameObject(guid))
- {
- gameObject->UseDoorOrButton();
- gameObject->DespawnOrUnsummon(3s);
- }
- }
- break;
- }
- case AB_EVENT_CONTESTED_BLACKSMITH_ALLIANCE:
- UpdateWorldState(BG_AB_WS_BLACKSMITH_ALLIANCE_CONTROL_STATE, 1);
- UpdateWorldState(BG_AB_WS_BLACKSMITH_HORDE_CONTROL_STATE, 0);
- PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
- break;
- case AB_EVENT_DEFENDED_BLACKSMITH_ALLIANCE:
- UpdateWorldState(BG_AB_WS_BLACKSMITH_ALLIANCE_CONTROL_STATE, 2);
- UpdateWorldState(BG_AB_WS_BLACKSMITH_HORDE_CONTROL_STATE, 0);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
- break;
- case AB_EVENT_CAPTURE_BLACKSMITH_ALLIANCE:
- UpdateWorldState(BG_AB_WS_BLACKSMITH_ALLIANCE_CONTROL_STATE, 2);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
- break;
- case AB_EVENT_CONTESTED_BLACKSMITH_HORDE:
- UpdateWorldState(BG_AB_WS_BLACKSMITH_ALLIANCE_CONTROL_STATE, 0);
- UpdateWorldState(BG_AB_WS_BLACKSMITH_HORDE_CONTROL_STATE, 1);
- PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_HORDE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
- break;
- case AB_EVENT_DEFENDED_BLACKSMITH_HORDE:
- UpdateWorldState(BG_AB_WS_BLACKSMITH_ALLIANCE_CONTROL_STATE, 0);
- UpdateWorldState(BG_AB_WS_BLACKSMITH_HORDE_CONTROL_STATE, 2);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
- break;
- case AB_EVENT_CAPTURE_BLACKSMITH_HORDE:
- UpdateWorldState(BG_AB_WS_BLACKSMITH_HORDE_CONTROL_STATE, 2);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
- break;
- case AB_EVENT_CONTESTED_FARM_ALLIANCE:
- UpdateWorldState(BG_AB_WS_FARM_ALLIANCE_CONTROL_STATE, 1);
- UpdateWorldState(BG_AB_WS_FARM_HORDE_CONTROL_STATE, 0);
- PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
- break;
- case AB_EVENT_DEFENDED_FARM_ALLIANCE:
- UpdateWorldState(BG_AB_WS_FARM_ALLIANCE_CONTROL_STATE, 2);
- UpdateWorldState(BG_AB_WS_FARM_HORDE_CONTROL_STATE, 0);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
- break;
- case AB_EVENT_CAPTURE_FARM_ALLIANCE:
- UpdateWorldState(BG_AB_WS_FARM_ALLIANCE_CONTROL_STATE, 2);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
- break;
- case AB_EVENT_CONTESTED_FARM_HORDE:
- UpdateWorldState(BG_AB_WS_FARM_ALLIANCE_CONTROL_STATE, 0);
- UpdateWorldState(BG_AB_WS_FARM_HORDE_CONTROL_STATE, 1);
- PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_HORDE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
- break;
- case AB_EVENT_DEFENDED_FARM_HORDE:
- UpdateWorldState(BG_AB_WS_FARM_ALLIANCE_CONTROL_STATE, 0);
- UpdateWorldState(BG_AB_WS_FARM_HORDE_CONTROL_STATE, 2);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
- break;
- case AB_EVENT_CAPTURE_FARM_HORDE:
- UpdateWorldState(BG_AB_WS_FARM_HORDE_CONTROL_STATE, 2);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
- break;
- case AB_EVENT_CONTESTED_GOLD_MINE_ALLIANCE:
- UpdateWorldState(BG_AB_WS_GOLD_MINE_ALLIANCE_CONTROL_STATE, 1);
- UpdateWorldState(BG_AB_WS_GOLD_MINE_HORDE_CONTROL_STATE, 0);
- PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
- break;
- case AB_EVENT_DEFENDED_GOLD_MINE_ALLIANCE:
- UpdateWorldState(BG_AB_WS_GOLD_MINE_ALLIANCE_CONTROL_STATE, 2);
- UpdateWorldState(BG_AB_WS_GOLD_MINE_HORDE_CONTROL_STATE, 0);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
- break;
- case AB_EVENT_CAPTURE_GOLD_MINE_ALLIANCE:
- UpdateWorldState(BG_AB_WS_GOLD_MINE_ALLIANCE_CONTROL_STATE, 2);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
- break;
- case AB_EVENT_CONTESTED_GOLD_MINE_HORDE:
- UpdateWorldState(BG_AB_WS_GOLD_MINE_ALLIANCE_CONTROL_STATE, 0);
- UpdateWorldState(BG_AB_WS_GOLD_MINE_HORDE_CONTROL_STATE, 1);
- PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_HORDE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
- break;
- case AB_EVENT_DEFENDED_GOLD_MINE_HORDE:
- UpdateWorldState(BG_AB_WS_GOLD_MINE_ALLIANCE_CONTROL_STATE, 0);
- UpdateWorldState(BG_AB_WS_GOLD_MINE_HORDE_CONTROL_STATE, 2);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
- break;
- case AB_EVENT_CAPTURE_GOLD_MINE_HORDE:
- UpdateWorldState(BG_AB_WS_GOLD_MINE_HORDE_CONTROL_STATE, 2);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
- break;
- case AB_EVENT_CONTESTED_LUMBER_MILL_ALLIANCE:
- UpdateWorldState(BG_AB_WS_LUMBER_MILL_ALLIANCE_CONTROL_STATE, 1);
- UpdateWorldState(BG_AB_WS_LUMBER_MILL_HORDE_CONTROL_STATE, 0);
- PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
- break;
- case AB_EVENT_DEFENDED_LUMBER_MILL_ALLIANCE:
- UpdateWorldState(BG_AB_WS_LUMBER_MILL_ALLIANCE_CONTROL_STATE, 2);
- UpdateWorldState(BG_AB_WS_LUMBER_MILL_HORDE_CONTROL_STATE, 0);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
- break;
- case AB_EVENT_CAPTURE_LUMBER_MILL_ALLIANCE:
- UpdateWorldState(BG_AB_WS_LUMBER_MILL_ALLIANCE_CONTROL_STATE, 2);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
- break;
- case AB_EVENT_CONTESTED_LUMBER_MILL_HORDE:
- UpdateWorldState(BG_AB_WS_LUMBER_MILL_ALLIANCE_CONTROL_STATE, 0);
- UpdateWorldState(BG_AB_WS_LUMBER_MILL_HORDE_CONTROL_STATE, 1);
- PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_HORDE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
- break;
- case AB_EVENT_DEFENDED_LUMBER_MILL_HORDE:
- UpdateWorldState(BG_AB_WS_LUMBER_MILL_ALLIANCE_CONTROL_STATE, 0);
- UpdateWorldState(BG_AB_WS_LUMBER_MILL_HORDE_CONTROL_STATE, 2);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
- break;
- case AB_EVENT_CAPTURE_LUMBER_MILL_HORDE:
- UpdateWorldState(BG_AB_WS_LUMBER_MILL_HORDE_CONTROL_STATE, 2);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
- break;
- case AB_EVENT_CONTESTED_STABLES_ALLIANCE:
- UpdateWorldState(BG_AB_WS_STABLES_ALLIANCE_CONTROL_STATE, 1);
- UpdateWorldState(BG_AB_WS_STABLES_HORDE_CONTROL_STATE, 0);
- PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
- break;
- case AB_EVENT_DEFENDED_STABLES_ALLIANCE:
- UpdateWorldState(BG_AB_WS_STABLES_ALLIANCE_CONTROL_STATE, 2);
- UpdateWorldState(BG_AB_WS_STABLES_HORDE_CONTROL_STATE, 0);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
- break;
- case AB_EVENT_CAPTURE_STABLES_ALLIANCE:
- UpdateWorldState(BG_AB_WS_STABLES_ALLIANCE_CONTROL_STATE, 2);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
- break;
- case AB_EVENT_CONTESTED_STABLES_HORDE:
- UpdateWorldState(BG_AB_WS_STABLES_ALLIANCE_CONTROL_STATE, 0);
- UpdateWorldState(BG_AB_WS_STABLES_HORDE_CONTROL_STATE, 1);
- PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_HORDE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
- break;
- case AB_EVENT_DEFENDED_STABLES_HORDE:
- UpdateWorldState(BG_AB_WS_STABLES_ALLIANCE_CONTROL_STATE, 0);
- UpdateWorldState(BG_AB_WS_STABLES_HORDE_CONTROL_STATE, 2);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
- if (Player* player = invoker->ToPlayer())
- UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
- break;
- case AB_EVENT_CAPTURE_STABLES_HORDE:
- UpdateWorldState(BG_AB_WS_STABLES_HORDE_CONTROL_STATE, 2);
- PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
- break;
- default:
- TC_LOG_WARN("bg.events", "BattlegroundAB::ProcessEvent: Unhandled event %u.", eventId);
- break;
- }
-}
-
-void BattlegroundAB::OnCreatureCreate(Creature* creature)
-{
- switch (creature->GetEntry())
- {
- case BG_AB_NPC_THE_BLACK_BRIDE:
- case BG_AB_NPC_RADULF_LEDER:
- _creaturesToRemoveOnMatchStart.push_back(creature->GetGUID());
- break;
- default:
- break;
- }
-}
-
-void BattlegroundAB::OnGameObjectCreate(GameObject* gameObject)
-{
- if (gameObject->GetGOInfo()->type == GAMEOBJECT_TYPE_CAPTURE_POINT)
- _capturePoints.push_back(gameObject->GetGUID());
-
- switch (gameObject->GetEntry())
- {
- case BG_AB_OBJECTID_GHOST_GATE:
- _gameobjectsToRemoveOnMatchStart.push_back(gameObject->GetGUID());
- break;
- case BG_AB_OBJECTID_ALLIANCE_DOOR:
- case BG_AB_OBJECTID_HORDE_DOOR:
- _doors.push_back(gameObject->GetGUID());
- break;
- default:
- break;
- }
-}
-
-bool BattlegroundAB::SetupBattleground()
-{
- UpdateWorldState(BG_AB_WS_RESOURCES_MAX, BG_AB_MAX_TEAM_SCORE);
- UpdateWorldState(BG_AB_WS_RESOURCES_WARNING, BG_AB_WARNING_NEAR_VICTORY_SCORE);
-
- return true;
-}
-
-void BattlegroundAB::Reset()
-{
- //call parent's class reset
- Battleground::Reset();
-
- m_TeamScores[TEAM_ALLIANCE] = 0;
- m_TeamScores[TEAM_HORDE] = 0;
- m_lastTick = 0;
- m_HonorScoreTics[TEAM_ALLIANCE] = 0;
- m_HonorScoreTics[TEAM_HORDE] = 0;
- m_ReputationScoreTics[TEAM_ALLIANCE] = 0;
- m_ReputationScoreTics[TEAM_HORDE] = 0;
- m_IsInformedNearVictory = false;
- bool isBGWeekend = sBattlegroundMgr->IsBGWeekend(GetTypeID());
- m_HonorTics = (isBGWeekend) ? BG_AB_ABBGWeekendHonorTicks : BG_AB_NotABBGWeekendHonorTicks;
- m_ReputationTics = (isBGWeekend) ? BG_AB_ABBGWeekendReputationTicks : BG_AB_NotABBGWeekendReputationTicks;
-
- _creaturesToRemoveOnMatchStart.clear();
- _gameobjectsToRemoveOnMatchStart.clear();
- _doors.clear();
- _capturePoints.clear();
-}
-
-void BattlegroundAB::EndBattleground(Team winner)
-{
- // Win reward
- if (winner == ALLIANCE)
- RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
- if (winner == HORDE)
- RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
- // Complete map_end rewards (even if no team wins)
- RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
- RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
-
- Battleground::EndBattleground(winner);
-}
-
-WorldSafeLocsEntry const* BattlegroundAB::GetClosestGraveyard(Player* player)
-{
- return sObjectMgr->GetClosestGraveyard(player->GetWorldLocation(), player->GetTeam(), player);
-}
-
-WorldSafeLocsEntry const* BattlegroundAB::GetExploitTeleportLocation(Team team)
-{
- return sObjectMgr->GetWorldSafeLoc(team == ALLIANCE ? AB_EXPLOIT_TELEPORT_LOCATION_ALLIANCE : AB_EXPLOIT_TELEPORT_LOCATION_HORDE);
-}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h
deleted file mode 100644
index 45be094ba71..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __BATTLEGROUNDAB_H
-#define __BATTLEGROUNDAB_H
-
-#include "Battleground.h"
-#include "Object.h"
-
-enum BG_AB_WorldStates
-{
- BG_AB_WS_OCCUPIED_BASES_HORDE = 1778,
- BG_AB_WS_OCCUPIED_BASES_ALLY = 1779,
- BG_AB_WS_RESOURCES_ALLY = 1776,
- BG_AB_WS_RESOURCES_HORDE = 1777,
- BG_AB_WS_RESOURCES_MAX = 1780,
- BG_AB_WS_RESOURCES_WARNING = 1955,
-
- BG_AB_WS_STABLE_ICON = 1842, // Stable map icon (NONE)
- BG_AB_WS_STABLE_STATE_ALIENCE = 1767, // Stable map state (ALIENCE)
- BG_AB_WS_STABLE_STATE_HORDE = 1768, // Stable map state (HORDE)
- BG_AB_WS_STABLE_STATE_CON_ALI = 1769, // Stable map state (CON ALIENCE)
- BG_AB_WS_STABLE_STATE_CON_HOR = 1770, // Stable map state (CON HORDE)
- BG_AB_WS_FARM_ICON = 1845, // Farm map icon (NONE)
- BG_AB_WS_FARM_STATE_ALIENCE = 1772, // Farm state (ALIENCE)
- BG_AB_WS_FARM_STATE_HORDE = 1773, // Farm state (HORDE)
- BG_AB_WS_FARM_STATE_CON_ALI = 1774, // Farm state (CON ALIENCE)
- BG_AB_WS_FARM_STATE_CON_HOR = 1775, // Farm state (CON HORDE)
- BG_AB_WS_BLACKSMITH_ICON = 1846, // Blacksmith map icon (NONE)
- BG_AB_WS_BLACKSMITH_STATE_ALIENCE = 1782, // Blacksmith map state (ALIENCE)
- BG_AB_WS_BLACKSMITH_STATE_HORDE = 1783, // Blacksmith map state (HORDE)
- BG_AB_WS_BLACKSMITH_STATE_CON_ALI = 1784, // Blacksmith map state (CON ALIENCE)
- BG_AB_WS_BLACKSMITH_STATE_CON_HOR = 1785, // Blacksmith map state (CON HORDE)
- BG_AB_WS_LUMBERMILL_ICON = 1844, // Lumber Mill map icon (NONE)
- BG_AB_WS_LUMBERMILL_STATE_ALIENCE = 1792, // Lumber Mill map state (ALIENCE)
- BG_AB_WS_LUMBERMILL_STATE_HORDE = 1793, // Lumber Mill map state (HORDE)
- BG_AB_WS_LUMBERMILL_STATE_CON_ALI = 1794, // Lumber Mill map state (CON ALIENCE)
- BG_AB_WS_LUMBERMILL_STATE_CON_HOR = 1795, // Lumber Mill map state (CON HORDE)
- BG_AB_WS_GOLDMINE_ICON = 1843, // Gold Mine map icon (NONE)
- BG_AB_WS_GOLDMINE_STATE_ALIENCE = 1787, // Gold Mine map state (ALIENCE)
- BG_AB_WS_GOLDMINE_STATE_HORDE = 1788, // Gold Mine map state (HORDE)
- BG_AB_WS_GOLDMINE_STATE_CON_ALI = 1789, // Gold Mine map state (CON ALIENCE
- BG_AB_WS_GOLDMINE_STATE_CON_HOR = 1790, // Gold Mine map state (CON HORDE)
-
- BG_AB_WS_HAD_500_DISADVANTAGE_ALLIANCE = 3644,
- BG_AB_WS_HAD_500_DISADVANTAGE_HORDE = 3645,
-
- BG_AB_WS_FARM_ICON_NEW = 8808, // Farm map icon
- BG_AB_WS_LUMBER_MILL_ICON_NEW = 8805, // Lumber Mill map icon
- BG_AB_WS_BLACKSMITH_ICON_NEW = 8799, // Blacksmith map icon
- BG_AB_WS_GOLD_MINE_ICON_NEW = 8809, // Gold Mine map icon
- BG_AB_WS_STABLES_ICON_NEW = 5834, // Stable map icon
-
- BG_AB_WS_FARM_HORDE_CONTROL_STATE = 17328,
- BG_AB_WS_FARM_ALLIANCE_CONTROL_STATE = 17325,
- BG_AB_WS_LUMBER_MILL_HORDE_CONTROL_STATE = 17330,
- BG_AB_WS_LUMBER_MILL_ALLIANCE_CONTROL_STATE = 17326,
- BG_AB_WS_BLACKSMITH_HORDE_CONTROL_STATE = 17327,
- BG_AB_WS_BLACKSMITH_ALLIANCE_CONTROL_STATE = 17324,
- BG_AB_WS_GOLD_MINE_HORDE_CONTROL_STATE = 17329,
- BG_AB_WS_GOLD_MINE_ALLIANCE_CONTROL_STATE = 17323,
- BG_AB_WS_STABLES_HORDE_CONTROL_STATE = 17331,
- BG_AB_WS_STABLES_ALLIANCE_CONTROL_STATE = 17322,
-};
-
-/* Object id templates from DB */
-enum BG_AB_ObjectTypes
-{
- BG_AB_OBJECTID_CAPTURE_POINT_STABLES = 227420,
- BG_AB_OBJECTID_CAPTURE_POINT_BLACKSMITH = 227522,
- BG_AB_OBJECTID_CAPTURE_POINT_FARM = 227536,
- BG_AB_OBJECTID_CAPTURE_POINT_GOLD_MINE = 227538,
- BG_AB_OBJECTID_CAPTURE_POINT_LUMBER_MILL = 227544,
-
- BG_AB_OBJECTID_GHOST_GATE = 180322,
- BG_AB_OBJECTID_ALLIANCE_DOOR = 322273,
- BG_AB_OBJECTID_HORDE_DOOR = 322274
-};
-
-enum BG_AB_Creatures
-{
- BG_AB_NPC_THE_BLACK_BRIDE = 150501,
- BG_AB_NPC_RADULF_LEDER = 150505
-};
-
-enum BG_AB_Score
-{
- BG_AB_WARNING_NEAR_VICTORY_SCORE = 1200,
- BG_AB_MAX_TEAM_SCORE = 1500
-};
-
-/* do NOT change the order, else wrong behaviour */
-enum BG_AB_BattlegroundNodes
-{
- BG_AB_NODE_STABLES = 0,
- BG_AB_NODE_BLACKSMITH = 1,
- BG_AB_NODE_FARM = 2,
- BG_AB_NODE_LUMBER_MILL = 3,
- BG_AB_NODE_GOLD_MINE = 4,
-
- BG_AB_DYNAMIC_NODES_COUNT = 5, // dynamic nodes that can be captured
-
- BG_AB_SPIRIT_ALIANCE = 5,
- BG_AB_SPIRIT_HORDE = 6,
-
- BG_AB_ALL_NODES_COUNT = 7 // all nodes (dynamic and static)
-};
-
-enum BG_AB_BroadcastTexts
-{
- BG_AB_TEXT_ALLIANCE_NEAR_VICTORY = 10598,
- BG_AB_TEXT_HORDE_NEAR_VICTORY = 10599,
-};
-
-enum BG_AB_Sounds
-{
- BG_AB_SOUND_NODE_CLAIMED = 8192,
- BG_AB_SOUND_NODE_CAPTURED_ALLIANCE = 8173,
- BG_AB_SOUND_NODE_CAPTURED_HORDE = 8213,
- BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE = 8212,
- BG_AB_SOUND_NODE_ASSAULTED_HORDE = 8174,
- BG_AB_SOUND_NEAR_VICTORY_ALLIANCE = 8456,
- BG_AB_SOUND_NEAR_VICTORY_HORDE = 8457
-};
-
-enum BG_AB_ExploitTeleportLocations
-{
- AB_EXPLOIT_TELEPORT_LOCATION_ALLIANCE = 7056,
- AB_EXPLOIT_TELEPORT_LOCATION_HORDE = 7055
-};
-
-#define BG_AB_NotABBGWeekendHonorTicks 260
-#define BG_AB_ABBGWeekendHonorTicks 160
-#define BG_AB_NotABBGWeekendReputationTicks 160
-#define BG_AB_ABBGWeekendReputationTicks 120
-
-enum BG_AB_Events
-{
- AB_EVENT_START_BATTLE = 9158, // Achievement: Let's Get This Done
-
- AB_EVENT_CONTESTED_STABLES_HORDE = 28523,
- AB_EVENT_CAPTURE_STABLES_HORDE = 28527,
- AB_EVENT_DEFENDED_STABLES_HORDE = 28525,
- AB_EVENT_CONTESTED_STABLES_ALLIANCE = 28522,
- AB_EVENT_CAPTURE_STABLES_ALLIANCE = 28526,
- AB_EVENT_DEFENDED_STABLES_ALLIANCE = 28524,
-
- AB_EVENT_CONTESTED_BLACKSMITH_HORDE = 8876,
- AB_EVENT_CAPTURE_BLACKSMITH_HORDE = 8773,
- AB_EVENT_DEFENDED_BLACKSMITH_HORDE = 8770,
- AB_EVENT_CONTESTED_BLACKSMITH_ALLIANCE = 8874,
- AB_EVENT_CAPTURE_BLACKSMITH_ALLIANCE = 8769,
- AB_EVENT_DEFENDED_BLACKSMITH_ALLIANCE = 8774,
-
- AB_EVENT_CONTESTED_FARM_HORDE = 39398,
- AB_EVENT_CAPTURE_FARM_HORDE = 39399,
- AB_EVENT_DEFENDED_FARM_HORDE = 39400,
- AB_EVENT_CONTESTED_FARM_ALLIANCE = 39401,
- AB_EVENT_CAPTURE_FARM_ALLIANCE = 39402,
- AB_EVENT_DEFENDED_FARM_ALLIANCE = 39403,
-
- AB_EVENT_CONTESTED_GOLD_MINE_HORDE = 39404,
- AB_EVENT_CAPTURE_GOLD_MINE_HORDE = 39405,
- AB_EVENT_DEFENDED_GOLD_MINE_HORDE = 39406,
- AB_EVENT_CONTESTED_GOLD_MINE_ALLIANCE = 39407,
- AB_EVENT_CAPTURE_GOLD_MINE_ALLIANCE = 39408,
- AB_EVENT_DEFENDED_GOLD_MINE_ALLIANCE = 39409,
-
- AB_EVENT_CONTESTED_LUMBER_MILL_HORDE = 39387,
- AB_EVENT_CAPTURE_LUMBER_MILL_HORDE = 39388,
- AB_EVENT_DEFENDED_LUMBER_MILL_HORDE = 39389,
- AB_EVENT_CONTESTED_LUMBER_MILL_ALLIANCE = 39390,
- AB_EVENT_CAPTURE_LUMBER_MILL_ALLIANCE = 39391,
- AB_EVENT_DEFENDED_LUMBER_MILL_ALLIANCE = 39392
-};
-
-// Tick intervals and given points: case 0, 1, 2, 3, 4, 5 captured nodes
-const uint32 BG_AB_TickInterval = 2000;
-const uint32 BG_AB_TickPoints[6] = { 0, 2, 3, 4, 7, 60 };
-
-// WorldSafeLocs ids for 5 nodes, and for ally, and horde starting location
-enum BG_AB_Graveyards
-{
- AB_GRAVEYARD_ALLIANCE_BASE = 7251,
- AB_GRAVEYARD_STABLES = 7252,
- AB_GRAVEYARD_GOLD_MINE = 7253,
- AB_GRAVEYARD_LUMBER_MILL = 7254,
- AB_GRAVEYARD_HORDE_BASE = 7255,
- AB_GRAVEYARD_FARM = 7256,
- AB_GRAVEYARD_BLACKSMITH = 7257
-};
-
-const uint32 BG_AB_GraveyardIds[BG_AB_ALL_NODES_COUNT] =
-{
- AB_GRAVEYARD_STABLES,
- AB_GRAVEYARD_BLACKSMITH,
- AB_GRAVEYARD_FARM,
- AB_GRAVEYARD_LUMBER_MILL,
- AB_GRAVEYARD_GOLD_MINE,
- AB_GRAVEYARD_ALLIANCE_BASE,
- AB_GRAVEYARD_HORDE_BASE
-};
-
-class BattlegroundAB : public Battleground
-{
- public:
- BattlegroundAB(BattlegroundTemplate const* battlegroundTemplate);
- ~BattlegroundAB();
-
- void StartingEventOpenDoors() override;
- bool SetupBattleground() override;
- void Reset() override;
- void EndBattleground(Team winner) override;
- WorldSafeLocsEntry const* GetClosestGraveyard(Player* player) override;
- WorldSafeLocsEntry const* GetExploitTeleportLocation(Team team) override;
-
- Team GetPrematureWinner() override;
-
- void ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* invoker = nullptr) override;
-
- void OnCreatureCreate(Creature* creature) override;
- void OnGameObjectCreate(GameObject* gameObject) override;
- private:
- void PostUpdateImpl(uint32 diff) override;
-
- void _CalculateTeamNodes(uint8& alliance, uint8& horde);
-
- uint32 m_lastTick;
- uint32 m_HonorScoreTics[PVP_TEAMS_COUNT];
- uint32 m_ReputationScoreTics[PVP_TEAMS_COUNT];
- bool m_IsInformedNearVictory;
- uint32 m_HonorTics;
- uint32 m_ReputationTics;
-
- GuidVector _gameobjectsToRemoveOnMatchStart;
- GuidVector _creaturesToRemoveOnMatchStart;
- GuidVector _doors;
- GuidVector _capturePoints;
-};
-#endif
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
deleted file mode 100644
index d4723737e64..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
+++ /dev/null
@@ -1,898 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "BattlegroundAV.h"
-#include "Creature.h"
-#include "CreatureAI.h"
-#include "DB2Stores.h"
-#include "GameObject.h"
-#include "Log.h"
-#include "Map.h"
-#include "MotionMaster.h"
-#include "ObjectMgr.h"
-#include "Player.h"
-
-enum AlteracValleyPvpStats
-{
- PVP_STAT_TOWERS_ASSAULTED = 61,
- PVP_STAT_GRAVEYARDS_ASSAULTED = 63,
- PVP_STAT_TOWERS_DEFENDED = 64,
- PVP_STAT_GRAVEYARDS_DEFENDED = 65,
- PVP_STAT_SECONDARY_OBJECTIVES = 82
-};
-
-enum AlteracValleyMisc
-{
- NEAR_LOSE_POINTS = 140
-};
-
-enum AlteracValleyHonorKillBonus
-{
- HONOR_KILL_BONUS_BOSS = 4,
- HONOR_KILL_BONUS_CAPTAIN = 3,
- HONOR_KILL_BONUS_SURVIVING_TOWER = 2,
- HONOR_KILL_BONUS_SURVIVING_CAPTAIN = 2,
- HONOR_KILL_BONUS_DESTROY_TOWER = 3
-};
-
-enum AlteracValleyReputationGains
-{
- REP_GAIN_BOSS = 350,
- REP_GAIN_CAPTAIN = 125,
- REP_GAIN_DESTROY_TOWER = 12,
- REP_GAIN_SURVIVING_TOWER = 12,
- REP_GAIN_SURVIVING_CAPTAIN = 125
-};
-
-enum AlteracValleyResourceLoss
-{
- RESOURCE_LOSS_TOWER = -75,
- RESOURCE_LOSS_CAPTAIN = -100
-};
-
-enum AlteracValleySpells
-{
- SPELL_COMPLETE_ALTERAC_VALLEY_QUEST = 23658,
-};
-
-enum AlteracValleyFactions
-{
- FACTION_FROSTWOLF_CLAN = 729,
- FACTION_STORMPIKE_GUARD = 730,
-};
-
-BattlegroundAV::BattlegroundAV(BattlegroundTemplate const* battlegroundTemplate) : Battleground(battlegroundTemplate)
-{
- BgObjects.resize(0);
- BgCreatures.resize(0);
-
- _teamResources = { BG_AV_SCORE_INITIAL_POINTS, BG_AV_SCORE_INITIAL_POINTS };
- _isInformedNearVictory = { false, false };
-
- for (uint8 i = 0; i < 2; i++) //forloop for both teams (it just make 0 == alliance and 1 == horde also for both mines 0=north 1=south
- {
- for (uint8 j = 0; j < 9; j++)
- m_Team_QuestStatus[i][j] = 0;
-
- _captainBuffTimer[i].Reset(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
- }
-
- _mineInfo[uint8(AlteracValleyMine::North)] = { TEAM_OTHER, { AV_WS_IRONDEEP_MINE_OWNER, AV_WS_IRONDEEP_MINE_ALLIANCE_CONTROLLED, AV_WS_IRONDEEP_MINE_HORDE_CONTROLLED, AV_WS_IRONDEEP_MINE_TROGG_CONTROLLED, TEXT_IRONDEEP_MINE_ALLIANCE_TAKEN, TEXT_IRONDEEP_MINE_HORDE_TAKEN } };
- _mineInfo[uint8(AlteracValleyMine::South)] = { TEAM_OTHER, { AV_WS_COLDTOOTH_MINE_OWNER, AV_WS_COLDTOOTH_MINE_ALLIANCE_CONTROLLED, AV_WS_COLDTOOTH_MINE_HORDE_CONTROLLED, AV_WS_COLDTOOTH_MINE_KOBOLD_CONTROLLED, TEXT_COLDTOOTH_MINE_ALLIANCE_TAKEN, TEXT_COLDTOOTH_MINE_HORDE_TAKEN } };
-
- for (BG_AV_Nodes i = BG_AV_NODES_FIRSTAID_STATION; i <= BG_AV_NODES_STONEHEART_GRAVE; ++i) //alliance graves
- InitNode(i, ALLIANCE, false);
- for (BG_AV_Nodes i = BG_AV_NODES_DUNBALDAR_SOUTH; i <= BG_AV_NODES_STONEHEART_BUNKER; ++i) //alliance towers
- InitNode(i, ALLIANCE, true);
- for (BG_AV_Nodes i = BG_AV_NODES_ICEBLOOD_GRAVE; i <= BG_AV_NODES_FROSTWOLF_HUT; ++i) //horde graves
- InitNode(i, HORDE, false);
- for (BG_AV_Nodes i = BG_AV_NODES_ICEBLOOD_TOWER; i <= BG_AV_NODES_FROSTWOLF_WTOWER; ++i) //horde towers
- InitNode(i, HORDE, true);
- InitNode(BG_AV_NODES_SNOWFALL_GRAVE, TEAM_OTHER, false); //give snowfall neutral owner
-
- _mineResourceTimer.Reset(BG_AV_MINE_RESOURCE_TIMER);
-
- StartMessageIds[BG_STARTING_EVENT_SECOND] = BG_AV_TEXT_START_ONE_MINUTE;
- StartMessageIds[BG_STARTING_EVENT_THIRD] = BG_AV_TEXT_START_HALF_MINUTE;
- StartMessageIds[BG_STARTING_EVENT_FOURTH] = BG_AV_TEXT_BATTLE_HAS_BEGUN;
-}
-
-void BattlegroundAV::HandleKillPlayer(Player* player, Player* killer)
-{
- if (GetStatus() != STATUS_IN_PROGRESS)
- return;
-
- Battleground::HandleKillPlayer(player, killer);
- UpdateScore(GetPlayerTeam(player->GetGUID()), -1);
-}
-
-void BattlegroundAV::HandleKillUnit(Creature* unit, Unit* killer)
-{
- TC_LOG_DEBUG("bg.battleground", "bg_av HandleKillUnit {}", unit->GetEntry());
- if (GetStatus() != STATUS_IN_PROGRESS)
- return;
-
- switch (unit->GetEntry())
- {
- case BG_AV_CREATURE_VANNDAR:
- {
- UpdateWorldState(AV_WS_VANDAAR_ALIVE, 0);
- CastSpellOnTeam(SPELL_COMPLETE_ALTERAC_VALLEY_QUEST, HORDE); //this is a spell which finishes a quest where a player has to kill the boss
- RewardReputationToTeam(FACTION_FROSTWOLF_CLAN, REP_GAIN_BOSS, HORDE);
- RewardHonorToTeam(GetBonusHonorFromKill(HONOR_KILL_BONUS_BOSS), HORDE);
- EndBattleground(HORDE);
- break;
- }
- case BG_AV_CREATURE_DREKTHAR:
- {
- UpdateWorldState(AV_WS_DREKTHAR_ALIVE, 0);
- CastSpellOnTeam(SPELL_COMPLETE_ALTERAC_VALLEY_QUEST, ALLIANCE); //this is a spell which finishes a quest where a player has to kill the boss
- RewardReputationToTeam(FACTION_STORMPIKE_GUARD, REP_GAIN_BOSS, ALLIANCE);
- RewardHonorToTeam(GetBonusHonorFromKill(HONOR_KILL_BONUS_BOSS), ALLIANCE);
- EndBattleground(ALLIANCE);
- break;
- }
- case BG_AV_CREATURE_BALINDA:
- {
- UpdateWorldState(AV_WS_BALINDA_ALIVE, 0);
- RewardReputationToTeam(FACTION_FROSTWOLF_CLAN, REP_GAIN_CAPTAIN, HORDE);
- RewardHonorToTeam(GetBonusHonorFromKill(HONOR_KILL_BONUS_CAPTAIN), HORDE);
- UpdateScore(ALLIANCE, RESOURCE_LOSS_CAPTAIN);
- if (Creature* herald = FindHerald("bg_av_herald_horde_win"))
- herald->AI()->Talk(TEXT_STORMPIKE_GENERAL_DEAD);
- break;
- }
- case BG_AV_CREATURE_GALVANGAR:
- {
- UpdateWorldState(AV_WS_GALVAGAR_ALIVE, 0);
- RewardReputationToTeam(FACTION_STORMPIKE_GUARD, REP_GAIN_CAPTAIN, ALLIANCE);
- RewardHonorToTeam(GetBonusHonorFromKill(HONOR_KILL_BONUS_CAPTAIN), ALLIANCE);
- UpdateScore(HORDE, RESOURCE_LOSS_CAPTAIN);
- if (Creature* herald = FindHerald("bg_av_herald_alliance_win"))
- herald->AI()->Talk(TEXT_FROSTWOLF_GENERAL_DEAD);
- break;
- }
- case BG_AV_CREATURE_MORLOCH:
- {
- // if mine is not owned by morloch, then nothing happens
- if (_mineInfo[uint8(AlteracValleyMine::North)].Owner != TEAM_OTHER)
- break;
-
- Team killerTeam = GetPlayerTeam(Coalesce<Unit>(killer->GetCharmerOrOwnerPlayerOrPlayerItself(), killer)->GetGUID());
- ChangeMineOwner(AlteracValleyMine::North, killerTeam);
- break;
- }
- case BG_AV_CREATURE_TASKMASTER_SNIVVLE:
- {
- if (_mineInfo[uint8(AlteracValleyMine::South)].Owner != TEAM_OTHER)
- break;
-
- Team killerTeam = GetPlayerTeam(Coalesce<Unit>(killer->GetCharmerOrOwnerPlayerOrPlayerItself(), killer)->GetGUID());
- ChangeMineOwner(AlteracValleyMine::South, killerTeam);
- break;
- }
- case BG_AV_CREATURE_UMI_THORSON:
- case BG_AV_CREATURE_KEETAR:
- {
- Team killerTeam = GetPlayerTeam(Coalesce<Unit>(killer->GetCharmerOrOwnerPlayerOrPlayerItself(), killer)->GetGUID());
- ChangeMineOwner(AlteracValleyMine::North, killerTeam);
- break;
- }
- case BG_AV_CREATURE_AGI_RUMBLESTOMP:
- case BG_AV_CREATURE_MASHA_SWIFTCUT:
- {
- Team killerTeam = GetPlayerTeam(Coalesce<Unit>(killer->GetCharmerOrOwnerPlayerOrPlayerItself(), killer)->GetGUID());
- ChangeMineOwner(AlteracValleyMine::South, killerTeam);
- break;
- }
- }
-}
-
-void BattlegroundAV::HandleQuestComplete(uint32 questid, Player* player)
-{
- if (GetStatus() != STATUS_IN_PROGRESS)
- return;//maybe we should log this, cause this must be a cheater or a big bug
- Team team = GetPlayerTeam(player->GetGUID());
- TeamId teamIndex = GetTeamIndexByTeamId(team);
- /// @todo add reputation, events (including quest not available anymore, next quest available, go/npc de/spawning)and maybe honor
- TC_LOG_DEBUG("bg.battleground", "BG_AV Quest {} completed", questid);
- switch (questid)
- {
- case AV_QUEST_A_SCRAPS1:
- case AV_QUEST_A_SCRAPS2:
- case AV_QUEST_H_SCRAPS1:
- case AV_QUEST_H_SCRAPS2:
- m_Team_QuestStatus[teamIndex][0] += 20;
- break;
- case AV_QUEST_A_COMMANDER1:
- case AV_QUEST_H_COMMANDER1:
- m_Team_QuestStatus[teamIndex][1]++;
- RewardReputationToTeam(teamIndex, 1, team);
- if (m_Team_QuestStatus[teamIndex][1] == 30)
- TC_LOG_DEBUG("bg.battleground", "BG_AV Quest {} completed (need to implement some events here", questid);
- break;
- case AV_QUEST_A_COMMANDER2:
- case AV_QUEST_H_COMMANDER2:
- m_Team_QuestStatus[teamIndex][2]++;
- RewardReputationToTeam(teamIndex, 1, team);
- if (m_Team_QuestStatus[teamIndex][2] == 60)
- TC_LOG_DEBUG("bg.battleground", "BG_AV Quest {} completed (need to implement some events here", questid);
- break;
- case AV_QUEST_A_COMMANDER3:
- case AV_QUEST_H_COMMANDER3:
- m_Team_QuestStatus[teamIndex][3]++;
- RewardReputationToTeam(teamIndex, 1, team);
- if (m_Team_QuestStatus[teamIndex][3] == 120)
- TC_LOG_DEBUG("bg.battleground", "BG_AV Quest {} completed (need to implement some events here", questid);
- break;
- case AV_QUEST_A_BOSS1:
- case AV_QUEST_H_BOSS1:
- m_Team_QuestStatus[teamIndex][4] += 4; //you can turn in 5 or 1 item..
- [[fallthrough]];
- case AV_QUEST_A_BOSS2:
- case AV_QUEST_H_BOSS2:
- m_Team_QuestStatus[teamIndex][4]++;
- if (m_Team_QuestStatus[teamIndex][4] >= 200)
- TC_LOG_DEBUG("bg.battleground", "BG_AV Quest {} completed (need to implement some events here", questid);
- UpdateWorldState(teamIndex == TEAM_ALLIANCE ? AV_WS_IVUS_STORM_CRYSTAL_COUNT : AV_WS_LOKHOLAR_STORMPIKE_SOLDIERS_BLOOD_COUNT, m_Team_QuestStatus[teamIndex][4]);
- break;
- case AV_QUEST_A_NEAR_MINE:
- case AV_QUEST_H_NEAR_MINE:
- m_Team_QuestStatus[teamIndex][5]++;
- if (m_Team_QuestStatus[teamIndex][5] == 28)
- {
- TC_LOG_DEBUG("bg.battleground", "BG_AV Quest {} completed (need to implement some events here", questid);
- if (m_Team_QuestStatus[teamIndex][6] == 7)
- TC_LOG_DEBUG("bg.battleground", "BG_AV Quest {} completed (need to implement some events here - ground assault ready", questid);
- }
- break;
- case AV_QUEST_A_OTHER_MINE:
- case AV_QUEST_H_OTHER_MINE:
- m_Team_QuestStatus[teamIndex][6]++;
- if (m_Team_QuestStatus[teamIndex][6] == 7)
- {
- TC_LOG_DEBUG("bg.battleground", "BG_AV Quest {} completed (need to implement some events here", questid);
- if (m_Team_QuestStatus[teamIndex][5] == 20)
- TC_LOG_DEBUG("bg.battleground", "BG_AV Quest {} completed (need to implement some events here - ground assault ready", questid);
- }
- break;
- case AV_QUEST_A_RIDER_HIDE:
- case AV_QUEST_H_RIDER_HIDE:
- m_Team_QuestStatus[teamIndex][7]++;
- if (m_Team_QuestStatus[teamIndex][7] == 25)
- {
- TC_LOG_DEBUG("bg.battleground", "BG_AV Quest {} completed (need to implement some events here", questid);
- if (m_Team_QuestStatus[teamIndex][8] == 25)
- TC_LOG_DEBUG("bg.battleground", "BG_AV Quest {} completed (need to implement some events here - rider assault ready", questid);
- }
- break;
- case AV_QUEST_A_RIDER_TAME:
- case AV_QUEST_H_RIDER_TAME:
- m_Team_QuestStatus[teamIndex][8]++;
- if (m_Team_QuestStatus[teamIndex][8] == 25)
- {
- TC_LOG_DEBUG("bg.battleground", "BG_AV Quest {} completed (need to implement some events here", questid);
- if (m_Team_QuestStatus[teamIndex][7] == 25)
- TC_LOG_DEBUG("bg.battleground", "BG_AV Quest {} completed (need to implement some events here - rider assault ready", questid);
- }
- break;
- default:
- TC_LOG_DEBUG("bg.battleground", "BG_AV Quest {} completed but is not interesting at all", questid);
- break;
- }
-}
-
-void BattlegroundAV::UpdateScore(Team team, int16 points)
-{
- ASSERT(team == ALLIANCE || team == HORDE);
- TeamId teamindex = GetTeamIndexByTeamId(team);
- _teamResources[teamindex] += points;
-
- UpdateWorldState(teamindex == TEAM_HORDE ? AV_WS_HORDE_REINFORCEMENTS : AV_WS_ALLIANCE_REINFORCEMENTS, _teamResources[teamindex]);
- if (points < 0)
- {
- if (_teamResources[teamindex] < 1)
- {
- _teamResources[teamindex] = 0;
- EndBattleground(teamindex == TEAM_HORDE ? ALLIANCE : HORDE);
- }
- else if (!_isInformedNearVictory[teamindex] && _teamResources[teamindex] < NEAR_LOSE_POINTS)
- {
- if (teamindex == TEAM_ALLIANCE)
- SendBroadcastText(BG_AV_TEXT_ALLIANCE_NEAR_LOSE, CHAT_MSG_BG_SYSTEM_ALLIANCE);
- else
- SendBroadcastText(BG_AV_TEXT_HORDE_NEAR_LOSE, CHAT_MSG_BG_SYSTEM_HORDE);
- PlaySoundToAll(AV_SOUND_NEAR_VICTORY);
- _isInformedNearVictory[teamindex] = true;
- }
- }
-}
-
-void BattlegroundAV::PostUpdateImpl(uint32 diff)
-{
- if (GetStatus() != STATUS_IN_PROGRESS)
- return;
-
- _mineResourceTimer.Update(diff);
- if (_mineResourceTimer.Passed())
- {
- for (AlteracValleyMineInfo const& info : _mineInfo)
- {
- if (info.Owner == TEAM_OTHER)
- continue;
-
- UpdateScore(info.Owner, 1);
- }
-
- _mineResourceTimer.Reset(BG_AV_MINE_RESOURCE_TIMER);
- }
-
- for (uint8 i = TEAM_ALLIANCE; i <= TEAM_HORDE; i++)
- {
- if (!IsCaptainAlive(TeamId(i)))
- continue;
-
- _captainBuffTimer[i].Update(diff);
- if (_captainBuffTimer[i].Passed())
- {
- if (i == 0)
- {
- CastSpellOnTeam(AV_BUFF_A_CAPTAIN, ALLIANCE);
- if (Creature* creature = GetBgMap()->GetCreature(_balindaGUID))
- creature->AI()->DoAction(ACTION_BUFF_YELL);
- }
- else
- {
- CastSpellOnTeam(AV_BUFF_H_CAPTAIN, HORDE);
- if (Creature* creature = GetBgMap()->GetCreature(_galvangarGUID))
- creature->AI()->DoAction(ACTION_BUFF_YELL);
- }
-
- _captainBuffTimer[i].Reset(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
- }
- }
-}
-
-bool BattlegroundAV::IsCaptainAlive(TeamId teamId) const
-{
- if (teamId == TEAM_HORDE)
- return GetBgMap()->GetWorldStateValue(AV_WS_GALVAGAR_ALIVE) == 1;
- else if (teamId == TEAM_ALLIANCE)
- return GetBgMap()->GetWorldStateValue(AV_WS_BALINDA_ALIVE) == 1;
-
- return false;
-}
-
-void BattlegroundAV::StartingEventOpenDoors()
-{
- TC_LOG_DEBUG("bg.battleground", "BG_AV: start spawning mine stuff");
-
- UpdateWorldState(AV_WS_SHOW_HORDE_REINFORCEMENTS, 1);
- UpdateWorldState(AV_WS_SHOW_ALLIANCE_REINFORCEMENTS, 1);
-
- // Achievement: The Alterac Blitz
- TriggerGameEvent(BG_AV_EVENT_START_BATTLE);
-
- for (ObjectGuid const& guid : _doorGUIDs)
- {
- if (GameObject* gameObject = GetBgMap()->GetGameObject(guid))
- {
- gameObject->UseDoorOrButton();
- Seconds delay = gameObject->GetEntry() == BG_AV_GHOST_GATE ? 0s : 3s;
- gameObject->DespawnOrUnsummon(delay);
- }
- }
-}
-
-void BattlegroundAV::EndBattleground(Team winner)
-{
- //calculate bonuskills for both teams:
- //first towers:
- std::array<uint8, PVP_TEAMS_COUNT> kills = { 0, 0 };
- std::array<uint8, PVP_TEAMS_COUNT> rep = { 0, 0 };
-
- for (BG_AV_Nodes i = BG_AV_NODES_DUNBALDAR_SOUTH; i <= BG_AV_NODES_FROSTWOLF_WTOWER; ++i)
- {
- if (_nodes[i].State == POINT_CONTROLED)
- {
- if (_nodes[i].Owner == ALLIANCE)
- {
- rep[TEAM_ALLIANCE] += REP_GAIN_SURVIVING_TOWER;
- kills[TEAM_ALLIANCE] += HONOR_KILL_BONUS_SURVIVING_TOWER;
- }
- else
- {
- rep[TEAM_HORDE] += REP_GAIN_SURVIVING_TOWER;
- kills[TEAM_HORDE] += HONOR_KILL_BONUS_SURVIVING_TOWER;
- }
- }
- }
-
- for (uint8 i = TEAM_ALLIANCE; i <= TEAM_HORDE; ++i)
- {
- if (IsCaptainAlive(TeamId(i)))
- {
- kills[i] += HONOR_KILL_BONUS_SURVIVING_CAPTAIN;
- rep[i] += REP_GAIN_SURVIVING_CAPTAIN;
- }
- if (rep[i] != 0)
- RewardReputationToTeam(i == 0 ? FACTION_STORMPIKE_GUARD : FACTION_FROSTWOLF_CLAN, rep[i], i == 0 ? ALLIANCE : HORDE);
- if (kills[i] != 0)
- RewardHonorToTeam(GetBonusHonorFromKill(kills[i]), i == 0 ? ALLIANCE : HORDE);
- }
-
- /// @todo add enterevademode for all attacking creatures
- Battleground::EndBattleground(winner);
-}
-
-void BattlegroundAV::RemovePlayer(Player* player, ObjectGuid /*guid*/, uint32 /*team*/)
-{
- if (!player)
- {
- TC_LOG_ERROR("bg.battleground", "bg_AV no player at remove");
- return;
- }
- /// @todo search more buffs
- player->RemoveAurasDueToSpell(AV_BUFF_ARMOR);
-}
-
-void BattlegroundAV::EventPlayerDestroyedPoint(GameObject* gameobject)
-{
- if (!gameobject)
- return;
-
- BG_AV_Nodes node = GetNodeThroughObject(gameobject->GetEntry());
- DestroyNode(node);
- UpdateNodeWorldState(node);
-
- Team owner = _nodes[node].Owner;
- if (IsTower(node))
- {
- UpdateScore((owner == ALLIANCE) ? HORDE : ALLIANCE, RESOURCE_LOSS_TOWER);
- RewardReputationToTeam(owner == ALLIANCE ? FACTION_STORMPIKE_GUARD : FACTION_FROSTWOLF_CLAN, REP_GAIN_DESTROY_TOWER, owner);
- RewardHonorToTeam(GetBonusHonorFromKill(HONOR_KILL_BONUS_DESTROY_TOWER), owner);
- }
-
- if (StaticNodeInfo const* nodeInfo = GetStaticNodeInfo(node))
- if (Creature* herald = FindHerald(nodeInfo->StringIds.HordeOrDestroy))
- herald->AI()->Talk(owner == ALLIANCE ? nodeInfo->TextIds.AllianceCapture : nodeInfo->TextIds.HordeCapture);
-
- GetBgMap()->UpdateSpawnGroupConditions();
-}
-
-void BattlegroundAV::DoAction(uint32 actionId, WorldObject* source, WorldObject* target)
-{
- switch (actionId)
- {
- case ACTION_AV_CAPTURE_CAPTURABLE_OBJECT:
- EventPlayerDestroyedPoint(source->ToGameObject());
- break;
- case ACTION_AV_INTERACT_CAPTURABLE_OBJECT:
- if (target && source && source->IsPlayer())
- HandleInteractCapturableObject(source->ToPlayer(), target->ToGameObject());
- break;
- default:
- TC_LOG_ERROR("bg.battleground", "BattlegroundAV::DoAction: {}. Unhandled action.", actionId);
- break;
- }
-}
-
-void BattlegroundAV::ChangeMineOwner(AlteracValleyMine mine, Team team, bool initial)
-{
- if (team != ALLIANCE && team != HORDE)
- team = TEAM_OTHER;
-
- AlteracValleyMineInfo& mineInfo = _mineInfo[uint8(mine)];
-
- if (mineInfo.Owner == team && !initial)
- return;
-
- mineInfo.Owner = team;
-
- SendMineWorldStates(mine);
-
- uint8 textId = team == ALLIANCE ? mineInfo.StaticInfo.TextIdAlliance : mineInfo.StaticInfo.TextIdHorde;
-
- std::string stringId = team == ALLIANCE ? "bg_av_herald_mine_alliance" : "bg_av_herald_mine_horde";
-
- if (Creature* herald = FindHerald(stringId))
- herald->AI()->Talk(textId);
-}
-
-BG_AV_Nodes BattlegroundAV::GetNodeThroughObject(uint32 object)
-{
- switch (object)
- {
- case BG_AV_OBJECTID_AID_STATION_ALLIANCE_CONTROLLED:
- case BG_AV_OBJECTID_AID_STATION_HORDE_CONTESTED:
- case BG_AV_OBJECTID_AID_STATION_HORDE_CONTROLLED:
- case BG_AV_OBJECTID_AID_STATION_ALLIANCE_CONTESTED:
- return BG_AV_NODES_FIRSTAID_STATION;
- case BG_AV_OBJECTID_STORMPIKE_ALLIANCE_CONTROLLED:
- case BG_AV_OBJECTID_STORMPIKE_HORDE_CONTESTED:
- case BG_AV_OBJECTID_STORMPIKE_HORDE_CONTROLLED:
- case BG_AV_OBJECTID_STORMPIKE_ALLIANCE_CONTESTED:
- return BG_AV_NODES_STORMPIKE_GRAVE;
- case BG_AV_OBJECTID_STONEHEARTH_HORDE_CONTESTED:
- case BG_AV_OBJECTID_STONEHEARTH_HORDE_CONTROLLED:
- case BG_AV_OBJECTID_STONEHEARTH_ALLIANCE_CONTESTED:
- case BG_AV_OBJECTID_STONEHEARTH_ALLIANCE_CONTROLLED:
- return BG_AV_NODES_STONEHEART_GRAVE;
- case BG_AV_OBJECTID_SNOWFALL_NEUTRAL:
- case BG_AV_OBJECTID_SNOWFALL_HORDE_CONTESTED:
- case BG_AV_OBJECTID_SNOWFALL_ALLIANCE_CONTESTED:
- case BG_AV_OBJECTID_SNOWFALL_HORDE_CONTROLLED:
- case BG_AV_OBJECTID_SNOWFALL_ALLIANCE_CONTROLLED:
- return BG_AV_NODES_SNOWFALL_GRAVE;
- case BG_AV_OBJECTID_ICEBLOOD_HORDE_CONTROLLED:
- case BG_AV_OBJECTID_ICEBLOOD_ALLIANCE_CONTESTED:
- case BG_AV_OBJECTID_ICEBLOOD_ALLIANCE_CONTROLLED:
- case BG_AV_OBJECTID_ICEBLOOD_HORDE_CONTESTED:
- return BG_AV_NODES_ICEBLOOD_GRAVE;
- case BG_AV_OBJECTID_FROSTWOLF_HORDE_CONTROLLED:
- case BG_AV_OBJECTID_FROSTWOLF_ALLIANCE_CONTESTED:
- case BG_AV_OBJECTID_FROSTWOLF_ALLIANCE_CONTROLLED:
- case BG_AV_OBJECTID_FROSTWOLF_HORDE_CONTESTED:
- return BG_AV_NODES_FROSTWOLF_GRAVE;
- case BG_AV_OBJECTID_FROSTWOLF_HUT_HORDE_CONTROLLED:
- case BG_AV_OBJECTID_FROSTWOLF_HUT_ALLIANCE_CONTESTED:
- case BG_AV_OBJECTID_FROSTWOLF_HUT_ALLIANCE_CONTROLLED:
- case BG_AV_OBJECTID_FROSTWOLF_HUT_HORDE_CONTESTED:
- return BG_AV_NODES_FROSTWOLF_HUT;
- case BG_AV_OBJECTID_SOUTH_BUNKER_CONTROLLED_TOWER_BANNER:
- case BG_AV_OBJECTID_SOUTH_BUNKER_CONTROLLED_BANNER:
- case BG_AV_OBJECTID_SOUTH_BUNKER_CONTESTED_BANNER:
- case BG_AV_OBJECTID_SOUTH_BUNKER_CONTESTED_TOWER_BANNER:
- return BG_AV_NODES_DUNBALDAR_SOUTH;
- case BG_AV_OBJECTID_NORTH_BUNKER_CONTROLLED_TOWER_BANNER:
- case BG_AV_OBJECTID_NORTH_BUNKER_CONTROLLED_BANNER:
- case BG_AV_OBJECTID_NORTH_BUNKER_CONTESTED_BANNER:
- case BG_AV_OBJECTID_NORTH_BUNKER_CONTESTED_TOWER_BANNER:
- return BG_AV_NODES_DUNBALDAR_NORTH;
- case BG_AV_OBJECTID_EAST_TOWER_CONTROLLED_TOWER_BANNER:
- case BG_AV_OBJECTID_EAST_TOWER_CONTROLLED_BANNER:
- case BG_AV_OBJECTID_EAST_TOWER_CONTESTED_BANNER:
- case BG_AV_OBJECTID_EAST_TOWER_CONTESTED_TOWER_BANNER:
- return BG_AV_NODES_FROSTWOLF_ETOWER;
- case BG_AV_OBJECTID_WEST_TOWER_CONTROLLED_TOWER_BANNER:
- case BG_AV_OBJECTID_WEST_TOWER_CONTROLLED_BANNER:
- case BG_AV_OBJECTID_WEST_TOWER_CONTESTED_BANNER:
- case BG_AV_OBJECTID_WEST_TOWER_CONTESTED_TOWER_BANNER:
- return BG_AV_NODES_FROSTWOLF_WTOWER;
- case BG_AV_OBJECTID_TOWER_POINT_CONTROLLED_TOWER_BANNER:
- case BG_AV_OBJECTID_TOWER_POINT_CONTROLLED_BANNER:
- case BG_AV_OBJECTID_TOWER_POINT_CONTESTED_BANNER:
- case BG_AV_OBJECTID_TOWER_POINT_CONTESTED_TOWER_BANNER:
- return BG_AV_NODES_TOWER_POINT;
- case BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTROLLED_TOWER_BANNER:
- case BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTROLLED_BANNER:
- case BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTESTED_BANNER:
- case BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTESTED_TOWER_BANNER:
- return BG_AV_NODES_ICEBLOOD_TOWER;
- case BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTROLLED_TOWER_BANNER:
- case BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTROLLED_BANNER:
- case BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTESTED_BANNER:
- case BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTESTED_TOWER_BANNER:
- return BG_AV_NODES_STONEHEART_BUNKER;
- case BG_AV_OBJECTID_ICEWING_BUNKER_CONTROLLED_TOWER_BANNER:
- case BG_AV_OBJECTID_ICEWING_BUNKER_CONTROLLED_BANNER:
- case BG_AV_OBJECTID_ICEWING_BUNKER_CONTESTED_BANNER:
- case BG_AV_OBJECTID_ICEWING_BUNKER_CONTESTED_TOWER_BANNER:
- return BG_AV_NODES_ICEWING_BUNKER;
- default:
- TC_LOG_ERROR("bg.battleground", "BattlegroundAV: ERROR! GetPlace got a wrong object :(");
- ABORT();
- return BG_AV_Nodes(0);
- }
-}
-
-void BattlegroundAV::HandleInteractCapturableObject(Player* player, GameObject* target)
-{
- if (!player || !target)
- return;
-
- switch (target->GetEntry())
- {
- // graveyards
- case BG_AV_OBJECTID_AID_STATION_ALLIANCE_CONTROLLED:
- case BG_AV_OBJECTID_AID_STATION_HORDE_CONTROLLED:
- case BG_AV_OBJECTID_FROSTWOLF_ALLIANCE_CONTROLLED:
- case BG_AV_OBJECTID_FROSTWOLF_HORDE_CONTROLLED:
- case BG_AV_OBJECTID_FROSTWOLF_HUT_ALLIANCE_CONTROLLED:
- case BG_AV_OBJECTID_FROSTWOLF_HUT_HORDE_CONTROLLED:
- case BG_AV_OBJECTID_ICEBLOOD_ALLIANCE_CONTROLLED:
- case BG_AV_OBJECTID_ICEBLOOD_HORDE_CONTROLLED:
- case BG_AV_OBJECTID_STONEHEARTH_ALLIANCE_CONTROLLED:
- case BG_AV_OBJECTID_STONEHEARTH_HORDE_CONTROLLED:
- case BG_AV_OBJECTID_STORMPIKE_ALLIANCE_CONTROLLED:
- case BG_AV_OBJECTID_STORMPIKE_HORDE_CONTROLLED:
- // Snowfall
- case BG_AV_OBJECTID_SNOWFALL_NEUTRAL:
- case BG_AV_OBJECTID_SNOWFALL_ALLIANCE_CONTROLLED:
- case BG_AV_OBJECTID_SNOWFALL_HORDE_CONTROLLED:
- // towers
- case BG_AV_OBJECTID_EAST_TOWER_CONTROLLED_BANNER:
- case BG_AV_OBJECTID_WEST_TOWER_CONTROLLED_BANNER:
- case BG_AV_OBJECTID_TOWER_POINT_CONTROLLED_BANNER:
- case BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTROLLED_BANNER:
- case BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTROLLED_BANNER:
- case BG_AV_OBJECTID_ICEWING_BUNKER_CONTROLLED_BANNER:
- case BG_AV_OBJECTID_SOUTH_BUNKER_CONTROLLED_BANNER:
- case BG_AV_OBJECTID_NORTH_BUNKER_CONTROLLED_BANNER:
- EventPlayerAssaultsPoint(player, target->GetEntry());
- break;
- // graveyards
- case BG_AV_OBJECTID_AID_STATION_ALLIANCE_CONTESTED:
- case BG_AV_OBJECTID_AID_STATION_HORDE_CONTESTED:
- case BG_AV_OBJECTID_FROSTWOLF_ALLIANCE_CONTESTED:
- case BG_AV_OBJECTID_FROSTWOLF_HORDE_CONTESTED:
- case BG_AV_OBJECTID_FROSTWOLF_HUT_ALLIANCE_CONTESTED:
- case BG_AV_OBJECTID_FROSTWOLF_HUT_HORDE_CONTESTED:
- case BG_AV_OBJECTID_ICEBLOOD_ALLIANCE_CONTESTED:
- case BG_AV_OBJECTID_ICEBLOOD_HORDE_CONTESTED:
- case BG_AV_OBJECTID_STONEHEARTH_ALLIANCE_CONTESTED:
- case BG_AV_OBJECTID_STONEHEARTH_HORDE_CONTESTED:
- case BG_AV_OBJECTID_STORMPIKE_ALLIANCE_CONTESTED:
- case BG_AV_OBJECTID_STORMPIKE_HORDE_CONTESTED:
- // towers
- case BG_AV_OBJECTID_EAST_TOWER_CONTESTED_BANNER:
- case BG_AV_OBJECTID_WEST_TOWER_CONTESTED_BANNER:
- case BG_AV_OBJECTID_TOWER_POINT_CONTESTED_BANNER:
- case BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTESTED_BANNER:
- case BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTESTED_BANNER:
- case BG_AV_OBJECTID_ICEWING_BUNKER_CONTESTED_BANNER:
- case BG_AV_OBJECTID_SOUTH_BUNKER_CONTESTED_BANNER:
- case BG_AV_OBJECTID_NORTH_BUNKER_CONTESTED_BANNER:
- EventPlayerDefendsPoint(player, target->GetEntry());
- break;
- // Snowfall special cases (either defend/assault)
- case BG_AV_OBJECTID_SNOWFALL_ALLIANCE_CONTESTED:
- case BG_AV_OBJECTID_SNOWFALL_HORDE_CONTESTED:
- {
- BG_AV_Nodes node = GetNodeThroughObject(target->GetEntry());
- if (_nodes[node].TotalOwner == TEAM_OTHER)
- EventPlayerAssaultsPoint(player, target->GetEntry());
- else
- EventPlayerDefendsPoint(player, target->GetEntry());
- break;
- }
- default:
- break;
- }
-}
-
-void BattlegroundAV::EventPlayerDefendsPoint(Player* player, uint32 object)
-{
- BG_AV_Nodes node = GetNodeThroughObject(object);
-
- Team owner = _nodes[node].Owner;
- Team team = GetPlayerTeam(player->GetGUID());
-
- if (owner == team || _nodes[node].State != POINT_ASSAULTED)
- return;
-
- TC_LOG_DEBUG("bg.battleground", "player defends point object: {} node: {}", object, node);
- if (_nodes[node].PrevOwner != team)
- {
- TC_LOG_ERROR("bg.battleground", "BG_AV: player defends point which doesn't belong to his team {}", node);
- return;
- }
-
- DefendNode(node, team);
- UpdateNodeWorldState(node);
-
- if (StaticNodeInfo const* nodeInfo = GetStaticNodeInfo(node))
- {
- std::string stringId;
-
- if (IsTower(node))
- stringId = nodeInfo->StringIds.AllianceOrDefend;
- else
- stringId = team == ALLIANCE ? nodeInfo->StringIds.AllianceOrDefend : nodeInfo->StringIds.HordeOrDestroy;
-
- if (Creature* herald = FindHerald(stringId))
- herald->AI()->Talk(team == ALLIANCE ? nodeInfo->TextIds.AllianceCapture : nodeInfo->TextIds.HordeCapture);
- }
-
- // update the statistic for the defending player
- UpdatePvpStat(player, IsTower(node) ? PVP_STAT_TOWERS_DEFENDED : PVP_STAT_GRAVEYARDS_DEFENDED, 1);
- GetBgMap()->UpdateSpawnGroupConditions();
-}
-
-void BattlegroundAV::EventPlayerAssaultsPoint(Player* player, uint32 object)
-{
- BG_AV_Nodes node = GetNodeThroughObject(object);
- Team owner = _nodes[node].Owner; //maybe name it prevowner
- Team team = GetPlayerTeam(player->GetGUID());
-
- TC_LOG_DEBUG("bg.battleground", "bg_av: player assaults point object {} node {}", object, node);
- if (owner == team || team == _nodes[node].TotalOwner)
- return; //surely a gm used this object
-
- AssaultNode(node, team);
- UpdateNodeWorldState(node);
-
- if (StaticNodeInfo const* nodeInfo = GetStaticNodeInfo(node))
- {
- std::string stringId;
- if (IsTower(node))
- stringId = nodeInfo->StringIds.HordeOrDestroy;
- else
- stringId = team == ALLIANCE ? nodeInfo->StringIds.AllianceOrDefend : nodeInfo->StringIds.HordeOrDestroy;
-
- if (Creature* herald = FindHerald(stringId))
- herald->AI()->Talk(team == ALLIANCE ? nodeInfo->TextIds.AllianceAttack : nodeInfo->TextIds.HordeAttack);
- }
-
- // update the statistic for the assaulting player
- UpdatePvpStat(player, (IsTower(node)) ? PVP_STAT_TOWERS_ASSAULTED : PVP_STAT_GRAVEYARDS_ASSAULTED, 1);
- GetBgMap()->UpdateSpawnGroupConditions();
-}
-
-void BattlegroundAV::UpdateNodeWorldState(BG_AV_Nodes node)
-{
- if (StaticNodeInfo const* nodeInfo = GetStaticNodeInfo(node))
- {
- uint16 owner = _nodes[node].Owner;
- BG_AV_States state = _nodes[node].State;
-
- UpdateWorldState(nodeInfo->WorldStateIds.AllianceAssault, owner == ALLIANCE && state == POINT_ASSAULTED);
- UpdateWorldState(nodeInfo->WorldStateIds.AllianceControl, owner == ALLIANCE && state >= POINT_DESTROYED);
- UpdateWorldState(nodeInfo->WorldStateIds.HordeAssault, owner == HORDE && state == POINT_ASSAULTED);
- UpdateWorldState(nodeInfo->WorldStateIds.HordeControl, owner == HORDE && state >= POINT_DESTROYED);
- if (nodeInfo->WorldStateIds.Owner)
- UpdateWorldState(nodeInfo->WorldStateIds.Owner, owner == HORDE ? 2 : owner == ALLIANCE ? 1 : 0);
- }
-
- if (node == BG_AV_NODES_SNOWFALL_GRAVE)
- UpdateWorldState(AV_WS_SNOWFALL_GRAVEYARD_UNCONTROLLED, _nodes[node].Owner == TEAM_OTHER);
-}
-
-void BattlegroundAV::SendMineWorldStates(AlteracValleyMine mine)
-{
- AlteracValleyMineInfo& mineInfo = _mineInfo[uint8(mine)];
- UpdateWorldState(mineInfo.StaticInfo.WorldStateHordeControlled, mineInfo.Owner == HORDE);
- UpdateWorldState(mineInfo.StaticInfo.WorldStateAllianceControlled, mineInfo.Owner == ALLIANCE);
- UpdateWorldState(mineInfo.StaticInfo.WorldStateNeutralControlled, mineInfo.Owner == TEAM_OTHER);
- UpdateWorldState(mineInfo.StaticInfo.WorldStateOwner, mineInfo.Owner == HORDE ? 2 : mineInfo.Owner == ALLIANCE ? 1 : 0);
-}
-
-WorldSafeLocsEntry const* BattlegroundAV::GetExploitTeleportLocation(Team team)
-{
- return sObjectMgr->GetWorldSafeLoc(team == ALLIANCE ? AV_EXPLOIT_TELEPORT_LOCATION_ALLIANCE : AV_EXPLOIT_TELEPORT_LOCATION_HORDE);
-}
-
-bool BattlegroundAV::SetupBattleground()
-{
- return true;
-}
-
-void BattlegroundAV::AssaultNode(BG_AV_Nodes node, Team team)
-{
- _nodes[node].PrevOwner = _nodes[node].Owner;
- _nodes[node].Owner = team;
- _nodes[node].PrevState = _nodes[node].State;
- _nodes[node].State = POINT_ASSAULTED;
-}
-
-void BattlegroundAV::DestroyNode(BG_AV_Nodes node)
-{
- _nodes[node].TotalOwner = _nodes[node].Owner;
- _nodes[node].PrevOwner = _nodes[node].Owner;
- _nodes[node].PrevState = _nodes[node].State;
- _nodes[node].State = (_nodes[node].Tower)? POINT_DESTROYED : POINT_CONTROLED;
-}
-
-void BattlegroundAV::InitNode(BG_AV_Nodes node, Team team, bool tower)
-{
- _nodes[node].TotalOwner = team;
- _nodes[node].Owner = team;
- _nodes[node].PrevOwner = 0;
- _nodes[node].State = POINT_CONTROLED;
- _nodes[node].PrevState = _nodes[node].State;
- _nodes[node].State = POINT_CONTROLED;
- _nodes[node].Tower = tower;
-}
-
-void BattlegroundAV::DefendNode(BG_AV_Nodes node, Team team)
-{
- _nodes[node].PrevOwner = _nodes[node].Owner;
- _nodes[node].Owner = team;
- _nodes[node].PrevState = _nodes[node].State;
- _nodes[node].State = POINT_CONTROLED;
-}
-
-Team BattlegroundAV::GetPrematureWinner()
-{
- uint32 allianceScore = _teamResources[GetTeamIndexByTeamId(ALLIANCE)];
- uint32 hordeScore = _teamResources[GetTeamIndexByTeamId(HORDE)];
-
- if (allianceScore > hordeScore)
- return ALLIANCE;
- else if (hordeScore > allianceScore)
- return HORDE;
-
- return Battleground::GetPrematureWinner();
-}
-
-void BattlegroundAV::OnGameObjectCreate(GameObject* gameObject)
-{
- switch (gameObject->GetEntry())
- {
- case BG_AV_GHOST_GATE:
- case BG_AV_OBJECTID_GATE:
- _doorGUIDs.insert(gameObject->GetGUID());
- break;
- default:
- break;
- }
-}
-
-void BattlegroundAV::OnCreatureCreate(Creature* creature)
-{
- switch (creature->GetEntry())
- {
- case BG_AV_CREATURE_GALVANGAR:
- _galvangarGUID = creature->GetGUID();
- break;
- case BG_AV_CREATURE_BALINDA:
- _balindaGUID = creature->GetGUID();
- break;
- case BG_AV_CREATURE_HERALD:
- _heraldGUIDs.insert(creature->GetGUID());
- break;
- default:
- break;
- }
-}
-
-uint32 BattlegroundAV::GetData(uint32 dataId) const
-{
- auto getDefenderTierForTeam = [&](TeamId teamId) -> BG_AV_DefenderTier
- {
- if (m_Team_QuestStatus[teamId][0] < 500)
- return BG_AV_DEFENDER_TIER_DEFENDER;
-
- if (m_Team_QuestStatus[teamId][0] < 1000)
- return BG_AV_DEFENDER_TIER_SEASONED;
-
- if (m_Team_QuestStatus[teamId][0] < 1500)
- return BG_AV_DEFENDER_TIER_VETERAN;
-
- return BG_AV_DEFENDER_TIER_CHAMPION;
- };
-
- switch (dataId)
- {
- case DATA_DEFENDER_TIER_ALLIANCE:
- return getDefenderTierForTeam(TEAM_ALLIANCE);
- case DATA_DEFENDER_TIER_HORDE:
- return getDefenderTierForTeam(TEAM_HORDE);
- default:
- return Battleground::GetData(dataId);
- }
-}
-
-Creature* BattlegroundAV::FindHerald(std::string_view stringId) const
-{
- for (ObjectGuid const& guid : _heraldGUIDs)
- if (Creature* creature = GetBgMap()->GetCreature(guid))
- if (creature->HasStringId(stringId))
- return creature;
-
- return nullptr;
-}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h
deleted file mode 100644
index 767bdb80e20..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h
+++ /dev/null
@@ -1,637 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __BATTLEGROUNDAV_H
-#define __BATTLEGROUNDAV_H
-
-#include "Battleground.h"
-#include "BattlegroundScore.h"
-#include "Object.h"
-#include "QuaternionData.h"
-#include "Timer.h"
-
-constexpr uint32 BG_AV_SCORE_INITIAL_POINTS = 700;
-constexpr uint32 BG_AV_EVENT_START_BATTLE = 9166; // Achievement: The Alterac Blitz
-
-enum AlteracValleySharedActions
-{
- ACTION_BUFF_YELL = -30001,
- ACTION_AV_INTERACT_CAPTURABLE_OBJECT = 1,
- ACTION_AV_CAPTURE_CAPTURABLE_OBJECT = 2,
-};
-
-enum BG_AV_BroadcastTexts
-{
- BG_AV_TEXT_START_ONE_MINUTE = 10638,
- BG_AV_TEXT_START_HALF_MINUTE = 10639,
- BG_AV_TEXT_BATTLE_HAS_BEGUN = 10640,
-
- BG_AV_TEXT_ALLIANCE_NEAR_LOSE = 23210,
- BG_AV_TEXT_HORDE_NEAR_LOSE = 23211
-};
-
-enum BG_AV_Sounds
-{ /// @todo: get out if there comes a sound when neutral team captures mine
-
-/*
-8212:
- alliance grave assault
- alliance tower assault
- drek "mlanzenabschaum! In meiner Burg?! Toetet sie all" - nicht immer der sound
-8333:
- galv "sterbt fuer euch ist kein platz hier"
-
-8332:
- bal "Verschwinde, dreckiger Abschaum! Die Allianz wird im Alteractal "
-8174:
- horde tower assault
- horde grave assault
- van "es Sturmlanzenklans, euer General wird angegriffen! Ich fordere Unterst"
-8173:
- ally grave capture/defend
- tower destroy
- mine capture
- ally wins
-8192:
- ally tower destroy(only iceblood - found a bug^^)
- ally tower defend
- horde tower defend
-8213
-horde:
- grave defend/capture
- tower destroy
- mine capture
- horde wins
- */
-
- AV_SOUND_NEAR_VICTORY = 8456, /// @todo: Not confirmed yet
-
- AV_SOUND_ALLIANCE_ASSAULTS = 8212, //tower, grave + enemy boss if someone tries to attack him
- AV_SOUND_HORDE_ASSAULTS = 8174,
- AV_SOUND_ALLIANCE_GOOD = 8173, //if something good happens for the team: wins(maybe only through killing the boss), captures mine or grave, destroys tower and defends grave
- AV_SOUND_HORDE_GOOD = 8213,
- AV_SOUND_BOTH_TOWER_DEFEND = 8192,
-
- AV_SOUND_ALLIANCE_CAPTAIN = 8232, //gets called when someone attacks them and at the beginning after 5min+rand(x)*10sec (maybe buff)
- AV_SOUND_HORDE_CAPTAIN = 8333
-};
-
-constexpr Seconds BG_AV_MINE_RESOURCE_TIMER = 45s;
-
-enum class AlteracValleyMine : uint8
-{
- North = 0,
- South
-};
-
-enum BG_AV_CreatureIds
-{
- BG_AV_CREATURE_VANNDAR = 11948,
- BG_AV_CREATURE_DREKTHAR = 11946,
- BG_AV_CREATURE_BALINDA = 11949,
- BG_AV_CREATURE_GALVANGAR = 11947,
- BG_AV_CREATURE_MORLOCH = 11657,
- BG_AV_CREATURE_UMI_THORSON = 13078,
- BG_AV_CREATURE_KEETAR = 13079,
- BG_AV_CREATURE_TASKMASTER_SNIVVLE = 11677,
- BG_AV_CREATURE_AGI_RUMBLESTOMP = 13086,
- BG_AV_CREATURE_MASHA_SWIFTCUT = 13088,
- BG_AV_CREATURE_HERALD = 14848,
-
- BG_AV_CREATURE_STORMPIKE_DEFENDER = 12050,
- BG_AV_CREATURE_FROSTWOLF_GUARDIAN = 12053,
- BG_AV_CREATURE_SEASONED_DEFENDER = 13326,
- BG_AV_CREATURE_SEASONED_GUARDIAN = 13328,
- BG_AV_CREATURE_VETERAN_DEFENDER = 13331,
- BG_AV_CREATURE_VETERAN_GUARDIAN = 13332,
- BG_AV_CREATURE_CHAMPION_DEFENDER = 13422,
- BG_AV_CREATURE_CHAMPION_GUARDIAN = 13421
-};
-
-enum BG_AV_ObjectIds
-{
- //cause the mangos-system is a bit different, we don't use the right go-ids for every node.. if we want to be 100% like another big server, we must take one object for every node
- //snowfall 4flags as eyecandy 179424 (alliance neutral)
- //Banners - stolen from battleground_AB.h ;-)
- BG_AV_OBJECTID_BANNER_A = 178925, // can only be used by horde
- BG_AV_OBJECTID_BANNER_H = 178943, // can only be used by alliance
- BG_AV_OBJECTID_BANNER_CONT_A = 178940, // can only be used by horde
- BG_AV_OBJECTID_BANNER_CONT_H = 179435, // can only be used by alliance
-
- BG_AV_OBJECTID_BANNER_A_B = 178365,
- BG_AV_OBJECTID_BANNER_H_B = 178364,
- BG_AV_OBJECTID_BANNER_CONT_A_B = 179286,
- BG_AV_OBJECTID_BANNER_CONT_H_B = 179287,
- BG_AV_OBJECTID_BANNER_SNOWFALL_N = 180418,
-
- //snowfall eyecandy banner:
- BG_AV_OBJECTID_SNOWFALL_CANDY_A = 179044,
- BG_AV_OBJECTID_SNOWFALL_CANDY_PA = 179424,
- BG_AV_OBJECTID_SNOWFALL_CANDY_H = 179064,
- BG_AV_OBJECTID_SNOWFALL_CANDY_PH = 179425,
-
- //banners on top of towers:
- BG_AV_OBJECTID_TOWER_BANNER_A = 178927, //[PH] Alliance A1 Tower Banner BIG
- BG_AV_OBJECTID_TOWER_BANNER_H = 178955, //[PH] Horde H1 Tower Banner BIG
- BG_AV_OBJECTID_TOWER_BANNER_PA = 179446, //[PH] Alliance H1 Tower Pre-Banner BIG
- BG_AV_OBJECTID_TOWER_BANNER_PH = 179436, //[PH] Horde A1 Tower Pre-Banner BIG
-
- //Auras
- BG_AV_OBJECTID_AURA_A = 180421,
- BG_AV_OBJECTID_AURA_H = 180422,
- BG_AV_OBJECTID_AURA_N = 180423,
- BG_AV_OBJECTID_AURA_A_S = 180100,
- BG_AV_OBJECTID_AURA_H_S = 180101,
- BG_AV_OBJECTID_AURA_N_S = 180102,
-
- BG_AV_OBJECTID_GATE = 180424,
- BG_AV_GHOST_GATE = 180322,
-
- //mine supplies
- BG_AV_OBJECTID_MINE_N = 178785,
- BG_AV_OBJECTID_MINE_S = 178784,
-
- BG_AV_OBJECTID_FIRE = 179065,
- BG_AV_OBJECTID_SMOKE = 179066,
-
- // Towers
- BG_AV_OBJECTID_SOUTH_BUNKER_CONTROLLED_TOWER_BANNER = 178927,
- BG_AV_OBJECTID_SOUTH_BUNKER_CONTROLLED_BANNER = 178925,
- BG_AV_OBJECTID_SOUTH_BUNKER_CONTESTED_BANNER = 179435,
- BG_AV_OBJECTID_SOUTH_BUNKER_CONTESTED_TOWER_BANNER = 179436,
-
- BG_AV_OBJECTID_NORTH_BUNKER_CONTROLLED_TOWER_BANNER = 178932,
- BG_AV_OBJECTID_NORTH_BUNKER_CONTROLLED_BANNER = 178929,
- BG_AV_OBJECTID_NORTH_BUNKER_CONTESTED_BANNER = 179439,
- BG_AV_OBJECTID_NORTH_BUNKER_CONTESTED_TOWER_BANNER = 179440,
-
- BG_AV_OBJECTID_EAST_TOWER_CONTROLLED_TOWER_BANNER = 178956,
- BG_AV_OBJECTID_EAST_TOWER_CONTROLLED_BANNER = 178944,
- BG_AV_OBJECTID_EAST_TOWER_CONTESTED_BANNER = 179449,
- BG_AV_OBJECTID_EAST_TOWER_CONTESTED_TOWER_BANNER = 179450,
-
- BG_AV_OBJECTID_WEST_TOWER_CONTROLLED_TOWER_BANNER = 178955,
- BG_AV_OBJECTID_WEST_TOWER_CONTROLLED_BANNER = 178943,
- BG_AV_OBJECTID_WEST_TOWER_CONTESTED_BANNER = 179445,
- BG_AV_OBJECTID_WEST_TOWER_CONTESTED_TOWER_BANNER = 179446,
-
- BG_AV_OBJECTID_TOWER_POINT_CONTROLLED_TOWER_BANNER = 178957,
- BG_AV_OBJECTID_TOWER_POINT_CONTROLLED_BANNER = 178945,
- BG_AV_OBJECTID_TOWER_POINT_CONTESTED_BANNER = 179453,
- BG_AV_OBJECTID_TOWER_POINT_CONTESTED_TOWER_BANNER = 179454,
-
- BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTROLLED_TOWER_BANNER = 178958,
- BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTROLLED_BANNER = 178946,
- BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTESTED_BANNER = 178940,
- BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTESTED_TOWER_BANNER = 179458,
-
- BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTROLLED_TOWER_BANNER = 178948,
- BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTROLLED_BANNER = 178936,
- BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTESTED_BANNER = 179443,
- BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTESTED_TOWER_BANNER = 179444,
-
- BG_AV_OBJECTID_ICEWING_BUNKER_CONTROLLED_TOWER_BANNER = 178947,
- BG_AV_OBJECTID_ICEWING_BUNKER_CONTROLLED_BANNER = 178935,
- BG_AV_OBJECTID_ICEWING_BUNKER_CONTESTED_BANNER = 179441,
- BG_AV_OBJECTID_ICEWING_BUNKER_CONTESTED_TOWER_BANNER = 179442,
-
- // Graveyards
- BG_AV_OBJECTID_AID_STATION_ALLIANCE_CONTROLLED = 179465,
- BG_AV_OBJECTID_AID_STATION_HORDE_CONTESTED = 179468,
- BG_AV_OBJECTID_AID_STATION_HORDE_CONTROLLED = 179467,
- BG_AV_OBJECTID_AID_STATION_ALLIANCE_CONTESTED = 179466,
-
- BG_AV_OBJECTID_STORMPIKE_ALLIANCE_CONTROLLED = 178389,
- BG_AV_OBJECTID_STORMPIKE_HORDE_CONTESTED = 179287,
- BG_AV_OBJECTID_STORMPIKE_HORDE_CONTROLLED = 178388,
- BG_AV_OBJECTID_STORMPIKE_ALLIANCE_CONTESTED = 179286,
-
- BG_AV_OBJECTID_STONEHEARTH_HORDE_CONTESTED = 179310,
- BG_AV_OBJECTID_STONEHEARTH_HORDE_CONTROLLED = 179285,
- BG_AV_OBJECTID_STONEHEARTH_ALLIANCE_CONTESTED = 179308,
- BG_AV_OBJECTID_STONEHEARTH_ALLIANCE_CONTROLLED = 179284,
-
- BG_AV_OBJECTID_SNOWFALL_NEUTRAL = 180418,
- BG_AV_OBJECTID_SNOWFALL_HORDE_CONTESTED = 180420,
- BG_AV_OBJECTID_SNOWFALL_ALLIANCE_CONTESTED = 180419,
- BG_AV_OBJECTID_SNOWFALL_HORDE_CONTROLLED = 178364,
- BG_AV_OBJECTID_SNOWFALL_ALLIANCE_CONTROLLED = 178365,
-
- BG_AV_OBJECTID_ICEBLOOD_HORDE_CONTROLLED = 179483,
- BG_AV_OBJECTID_ICEBLOOD_ALLIANCE_CONTESTED = 179482,
- BG_AV_OBJECTID_ICEBLOOD_ALLIANCE_CONTROLLED = 179481,
- BG_AV_OBJECTID_ICEBLOOD_HORDE_CONTESTED = 179484,
-
- BG_AV_OBJECTID_FROSTWOLF_HORDE_CONTROLLED = 178393,
- BG_AV_OBJECTID_FROSTWOLF_ALLIANCE_CONTESTED = 179304,
- BG_AV_OBJECTID_FROSTWOLF_ALLIANCE_CONTROLLED = 178394,
- BG_AV_OBJECTID_FROSTWOLF_HORDE_CONTESTED = 179305,
-
- BG_AV_OBJECTID_FROSTWOLF_HUT_HORDE_CONTROLLED = 179472,
- BG_AV_OBJECTID_FROSTWOLF_HUT_ALLIANCE_CONTESTED = 179471,
- BG_AV_OBJECTID_FROSTWOLF_HUT_ALLIANCE_CONTROLLED = 179470,
- BG_AV_OBJECTID_FROSTWOLF_HUT_HORDE_CONTESTED = 179473
-};
-
-enum BG_AV_Nodes
-{
- BG_AV_NODES_FIRSTAID_STATION = 0,
- BG_AV_NODES_STORMPIKE_GRAVE = 1,
- BG_AV_NODES_STONEHEART_GRAVE = 2,
- BG_AV_NODES_SNOWFALL_GRAVE = 3,
- BG_AV_NODES_ICEBLOOD_GRAVE = 4,
- BG_AV_NODES_FROSTWOLF_GRAVE = 5,
- BG_AV_NODES_FROSTWOLF_HUT = 6,
- BG_AV_NODES_DUNBALDAR_SOUTH = 7,
- BG_AV_NODES_DUNBALDAR_NORTH = 8,
- BG_AV_NODES_ICEWING_BUNKER = 9,
- BG_AV_NODES_STONEHEART_BUNKER = 10,
- BG_AV_NODES_ICEBLOOD_TOWER = 11,
- BG_AV_NODES_TOWER_POINT = 12,
- BG_AV_NODES_FROSTWOLF_ETOWER = 13,
- BG_AV_NODES_FROSTWOLF_WTOWER = 14,
-
- BG_AV_NODES_MAX = 15
-};
-
-enum BG_AV_BUFF
-{ /// @todo: Add all other buffs here
- AV_BUFF_ARMOR = 21163,
- AV_BUFF_A_CAPTAIN = 23693, //the buff which the alliance captain does
- AV_BUFF_H_CAPTAIN = 22751 //the buff which the horde captain does
-};
-enum BG_AV_States
-{
- POINT_NEUTRAL = 0,
- POINT_ASSAULTED = 1,
- POINT_DESTROYED = 2,
- POINT_CONTROLED = 3
-};
-
-enum BG_AV_WorldStates
-{
- AV_WS_ALLIANCE_REINFORCEMENTS = 3127,
- AV_WS_HORDE_REINFORCEMENTS = 3128,
- AV_WS_SHOW_HORDE_REINFORCEMENTS = 3133,
- AV_WS_SHOW_ALLIANCE_REINFORCEMENTS = 3134,
- AV_WS_MAX_REINFORCEMENTS = 3136,
-
-// Graves
- // Alliance
- //Stormpike first aid station
- AV_WS_STORMPIKE_AID_STATION_ALLIANCE_CONTROLLED = 1325,
- AV_WS_STORMPIKE_AID_STATION_IN_CONFLICT_ALLIANCE_ATTACKING = 1326,
- AV_WS_STORMPIKE_AID_STATION_HORDE_CONTROLLED = 1327,
- AV_WS_STORMPIKE_AID_STATION_IN_CONFLICT_HORDE_ATTACKING = 1328,
- //Stormpike Graveyard
- AV_WS_STORMPIKE_GRAVEYARD_ALLIANCE_CONTROLLED = 1333,
- AV_WS_STORMPIKE_GRAVEYARD_IN_CONFLICT_ALLIANCE_ATTACKING = 1335,
- AV_WS_STORMPIKE_GRAVEYARD_HORDE_CONTROLLED = 1334,
- AV_WS_STORMPIKE_GRAVEYARD_IN_CONFLICT_HORDE_ATTACKING = 1336,
- //Stoneheart Grave
- AV_WS_STONEHEARTH_GRAVEYARD_ALLIANCE_CONTROLLED = 1302,
- AV_WS_STONEHEARTH_GRAVEYARD_IN_CONFLICT_ALLIANCE_ATTACKING = 1304,
- AV_WS_STONEHEARTH_GRAVEYARD_HORDE_CONTROLLED = 1301,
- AV_WS_STONEHEARTH_GRAVEYARD_IN_CONFLICT_HORDE_ATTACKING = 1303,
- //Neutral
- //Snowfall Grave
- AV_WS_SNOWFALL_GRAVEYARD_UNCONTROLLED = 1966,
- AV_WS_SNOWFALL_GRAVEYARD_ALLIANCE_CONTROLLED = 1341,
- AV_WS_SNOWFALL_GRAVEYARD_IN_CONFLICT_ALLIANCE_ATTACKING = 1343,
- AV_WS_SNOWFALL_GRAVEYARD_HORDE_CONTROLLED = 1342,
- AV_WS_SNOWFALL_GRAVEYARD_IN_CONFLICT_HORDE_ATTACKING = 1344,
- //Horde
- //Iceblood grave
- AV_WS_ICEBLOOD_GRAVEYARD_ALLIANCE_CONTROLLED = 1346,
- AV_WS_ICEBLOOD_GRAVEYARD_IN_CONFLICT_ALLIANCE_ATTACKING = 1348,
- AV_WS_ICEBLOOD_GRAVEYARD_HORDE_CONTROLLED = 1347,
- AV_WS_ICEBLOOD_GRAVEYARD_IN_CONFLICT_HORDE_ATTACKING = 1349,
- //Frostwolf Grave
- AV_WS_FROSTWOLF_GRAVEYARD_ALLIANCE_CONTROLLED = 1337,
- AV_WS_FROSTWOLF_GRAVEYARD_IN_CONFLICT_ALLIANCE_ATTACKING = 1339,
- AV_WS_FROSTWOLF_GRAVEYARD_HORDE_CONTROLLED = 1338,
- AV_WS_FROSTWOLF_GRAVEYARD_IN_CONFLICT_HORDE_ATTACKING = 1340,
- //Frostwolf Hut
- AV_WS_FROSTWOLF_RELIEF_HUT_ALLIANCE_CONTROLLED = 1329,
- AV_WS_FROSTWOLF_RELIEF_HUT_IN_CONFLICT_ALLIANCE_ATTACKING = 1331,
- AV_WS_FROSTWOLF_RELIEF_HUT_HORDE_CONTROLLED = 1330,
- AV_WS_FROSTWOLF_RELIEF_HUT_IN_CONFLICT_HORDE_ATTACKING = 1332,
-
-//Towers
- //Alliance
- //Dunbaldar South Bunker
- AV_WS_DUN_BALDAR_SOUTH_BUNKER_OWNER = 1181,
- AV_WS_DUN_BALDAR_SOUTH_BUNKER_ALLIANCE_CONTROLLED = 1361,
- AV_WS_DUN_BALDAR_SOUTH_BUNKER_DESTROYED = 1370,
- AV_WS_DUN_BALDAR_SOUTH_BUNKER_IN_CONFLICT_HORDE_ATTACKING = 1378,
- AV_WS_DUN_BALDAR_SOUTH_BUNKER_IN_CONFLICT_ALLIANCE_ATTACKING = 1374, // unused
- //Dunbaldar North Bunker
- AV_WS_DUN_BALDAR_NORTH_BUNKER_OWNER = 1182,
- AV_WS_DUN_BALDAR_NORTH_BUNKER_ALLIANCE_CONTROLLED = 1362,
- AV_WS_DUN_BALDAR_NORTH_BUNKER_DESTROYED = 1371,
- AV_WS_DUN_BALDAR_NORTH_BUNKER_IN_CONFLICT_HORDE_ATTACKING = 1379,
- AV_WS_DUN_BALDAR_NORTH_BUNKER_IN_CONFLICT_ALLIANCE_ATTACKING = 1375, // unused
- //Icewing Bunker
- AV_WS_ICEWING_BUNKER_OWNER = 1183,
- AV_WS_ICEWING_BUNKER_ALLIANCE_CONTROLLED = 1363,
- AV_WS_ICEWING_BUNKER_DESTROYED = 1372,
- AV_WS_ICEWING_BUNKER_IN_CONFLICT_HORDE_ATTACKING = 1380,
- AV_WS_ICEWING_BUNKER_IN_CONFLICT_ALLIANCE_ATTACKING = 1376, // unused
- //Stoneheart Bunker
- AV_WS_STONEHEARTH_BUNKER_OWNER = 1184,
- AV_WS_STONEHEARTH_BUNKER_ALLIANCE_CONTROLLED = 1364,
- AV_WS_STONEHEARTH_BUNKER_DESTROYED = 1373,
- AV_WS_STONEHEARTH_BUNKER_IN_CONFLICT_HORDE_ATTACKING = 1381,
- AV_WS_STONEHEARTH_BUNKER_IN_CONFLICT_ALLIANCE_ATTACKING = 1377, // unused
- //Horde
- //Iceblood Tower
- AV_WS_ICEBLOOD_TOWER_OWNER = 1187,
- AV_WS_ICEBLOOD_TOWER_DESTROYED = 1368,
- AV_WS_ICEBLOOD_TOWER_HORDE_CONTROLLED = 1385,
- AV_WS_ICEBLOOD_TOWER_IN_CONFLICT_ALLIANCE_ATTACKING = 1390,
- AV_WS_ICEBLOOD_TOWER_IN_CONFLICT_HORDE_ATTACKING = 1395, // unused
- //Tower Point
- AV_WS_TOWER_POINT_OWNER = 1188,
- AV_WS_TOWER_POINT_DESTROYED = 1367,
- AV_WS_TOWER_POINT_HORDE_CONTROLLED = 1384,
- AV_WS_TOWER_POINT_IN_CONFLICT_ALLIANCE_ATTACKING = 1389,
- AV_WS_TOWER_POINT_IN_CONFLICT_HORDE_ATTACKING = 1394, // unused
- //Frostwolf West
- AV_WS_WEST_FROSTWOLF_TOWER_OWNER = 1185,
- AV_WS_WEST_FROSTWOLF_TOWER_DESTROYED = 1365,
- AV_WS_WEST_FROSTWOLF_TOWER_HORDE_CONTROLLED = 1382,
- AV_WS_WEST_FROSTWOLF_TOWER_IN_CONFLICT_ALLIANCE_ATTACKING = 1387,
- AV_WS_WEST_FROSTWOLF_TOWER_IN_CONFLICT_HORDE_ATTACKING = 1392, // unused
- //Frostwolf East
- AV_WS_EAST_FROSTWOLF_TOWER_OWNER = 1186,
- AV_WS_EAST_FROSTWOLF_TOWER_DESTROYED = 1366,
- AV_WS_EAST_FROSTWOLF_TOWER_HORDE_CONTROLLED = 1383,
- AV_WS_EAST_FROSTWOLF_TOWER_IN_CONFLICT_ALLIANCE_ATTACKING = 1388,
- AV_WS_EAST_FROSTWOLF_TOWER_IN_CONFLICT_HORDE_ATTACKING = 1393, // unused
-
-//Mines
- AV_WS_IRONDEEP_MINE_OWNER = 801,
- AV_WS_IRONDEEP_MINE_TROGG_CONTROLLED = 1360,
- AV_WS_IRONDEEP_MINE_ALLIANCE_CONTROLLED = 1358,
- AV_WS_IRONDEEP_MINE_HORDE_CONTROLLED = 1359,
-
- AV_WS_COLDTOOTH_MINE_OWNER = 804,
- AV_WS_COLDTOOTH_MINE_KOBOLD_CONTROLLED = 1357,
- AV_WS_COLDTOOTH_MINE_ALLIANCE_CONTROLLED = 1355,
- AV_WS_COLDTOOTH_MINE_HORDE_CONTROLLED = 1356,
-
-//Turnins
- AV_WS_IVUS_STORM_CRYSTAL_COUNT = 1043,
- AV_WS_IVUS_STORM_CRYSTAL_MAX = 1044,
- AV_WS_LOKHOLAR_STORMPIKE_SOLDIERS_BLOOD_COUNT = 923,
- AV_WS_LOKHOLAR_STORMPIKE_SOLDIERS_BLOOD_MAX = 922,
-
-//Bosses
- AV_WS_DREKTHAR_ALIVE = 601,
- AV_WS_VANDAAR_ALIVE = 602,
-
-//Captains
- AV_WS_GALVAGAR_ALIVE = 1352,
- AV_WS_BALINDA_ALIVE = 1351,
-};
-
-enum BG_AV_QuestIds
-{
- AV_QUEST_A_SCRAPS1 = 7223,
- AV_QUEST_A_SCRAPS2 = 6781,
- AV_QUEST_H_SCRAPS1 = 7224,
- AV_QUEST_H_SCRAPS2 = 6741,
- AV_QUEST_A_COMMANDER1 = 6942, //soldier
- AV_QUEST_H_COMMANDER1 = 6825,
- AV_QUEST_A_COMMANDER2 = 6941, //leutnant
- AV_QUEST_H_COMMANDER2 = 6826,
- AV_QUEST_A_COMMANDER3 = 6943, //commander
- AV_QUEST_H_COMMANDER3 = 6827,
- AV_QUEST_A_BOSS1 = 7386, // 5 cristal/blood
- AV_QUEST_H_BOSS1 = 7385,
- AV_QUEST_A_BOSS2 = 6881, // 1
- AV_QUEST_H_BOSS2 = 6801,
- AV_QUEST_A_NEAR_MINE = 5892, //the mine near start location of team
- AV_QUEST_H_NEAR_MINE = 5893,
- AV_QUEST_A_OTHER_MINE = 6982, //the other mine ;)
- AV_QUEST_H_OTHER_MINE = 6985,
- AV_QUEST_A_RIDER_HIDE = 7026,
- AV_QUEST_H_RIDER_HIDE = 7002,
- AV_QUEST_A_RIDER_TAME = 7027,
- AV_QUEST_H_RIDER_TAME = 7001
-};
-
-struct StaticMineInfo
-{
- int32 WorldStateOwner;
- int32 WorldStateAllianceControlled;
- int32 WorldStateHordeControlled;
- int32 WorldStateNeutralControlled;
- uint8 TextIdAlliance;
- uint8 TextIdHorde;
-};
-
-struct AlteracValleyMineInfo
-{
- Team Owner;
-
- StaticMineInfo StaticInfo;
-};
-
-struct StaticNodeInfo
-{
- BG_AV_Nodes NodeId;
-
- struct
- {
- uint8 AllianceCapture;
- uint8 AllianceAttack;
- uint8 HordeCapture;
- uint8 HordeAttack;
- } TextIds;
-
- struct
- {
- int32 AllianceControl;
- int32 AllianceAssault;
- int32 HordeControl;
- int32 HordeAssault;
- int32 Owner;
- } WorldStateIds;
-
- struct
- {
- std::string AllianceOrDefend;
- std::string HordeOrDestroy;
- } StringIds;
-};
-
-static StaticNodeInfo const BGAVNodeInfo[] =
-{
- { BG_AV_NODES_FIRSTAID_STATION, { 47, 48, 45, 46 }, { 1325, 1326, 1327, 1328, 0 }, { "bg_av_herald_stormpike_aid_station_alliance", "bg_av_herald_stormpike_aid_station_horde" } }, // Stormpike First Aid Station
- { BG_AV_NODES_STORMPIKE_GRAVE, { 1, 2, 3, 4 }, { 1333, 1335, 1334, 1336, 0 }, { "bg_av_herald_stormpike_alliance", "bg_av_herald_stormpike_horde" } }, // Stormpike Graveyard
- { BG_AV_NODES_STONEHEART_GRAVE, { 55, 56, 53, 54 }, { 1302, 1304, 1301, 1303, 0 }, { "bg_av_herald_stonehearth_alliance", "bg_av_herald_stonehearth_horde" } }, // Stoneheart Graveyard
- { BG_AV_NODES_SNOWFALL_GRAVE, { 5, 6, 7, 8 }, { 1341, 1343, 1342, 1344, 0 }, { "bg_av_herald_snowfall_alliance", "bg_av_herald_snowfall_horde" } }, // Snowfall Graveyard
- { BG_AV_NODES_ICEBLOOD_GRAVE, { 59, 60, 57, 58 }, { 1346, 1348, 1347, 1349, 0 }, { "bg_av_herald_iceblood_alliance", "bg_av_herald_iceblood_horde" } }, // Iceblood Graveyard
- { BG_AV_NODES_FROSTWOLF_GRAVE, { 9, 10, 11, 12 }, { 1337, 1339, 1338, 1340, 0 }, { "bg_av_herald_frostwolf_alliance", "bg_av_herald_frostwolf_horde" } }, // Frostwolf Graveyard
- { BG_AV_NODES_FROSTWOLF_HUT, { 51, 52, 49, 50 }, { 1329, 1331, 1330, 1332, 0 }, { "bg_av_herald_frostwolf_hut_alliance", "bg_av_herald_frostwolf_hut_horde" } }, // Frostwolf Hut
- { BG_AV_NODES_DUNBALDAR_SOUTH, { 16, 15, 14, 13 }, { 1361, 1375, 1370, 1378, 1181 }, { "bg_av_herald_south_bunker_defend", "bg_av_herald_south_bunker_attack" } }, // Dunbaldar South Bunker
- { BG_AV_NODES_DUNBALDAR_NORTH, { 20, 19, 18, 17 }, { 1362, 1374, 1371, 1379, 1182 }, { "bg_av_herald_north_bunker_defend", "bg_av_herald_south_bunker_attack" } }, // Dunbaldar North Bunker
- { BG_AV_NODES_ICEWING_BUNKER, { 24, 23, 22, 21 }, { 1363, 1376, 1372, 1380, 1183 }, { "bg_av_herald_icewing_bunker_defend", "bg_av_herald_icewing_bunker_attack" } }, // Icewing Bunker
- { BG_AV_NODES_STONEHEART_BUNKER, { 28, 27, 26, 25 }, { 1364, 1377, 1373, 1381, 1184 }, { "bg_av_herald_stonehearth_bunker_defend", "bg_av_herald_stonehearth_bunker_attack" } }, // Stoneheart Bunker
- { BG_AV_NODES_ICEBLOOD_TOWER, { 44, 43, 42, 41 }, { 1368, 1390, 1385, 1395, 1188 }, { "bg_av_herald_iceblood_tower_defend", "bg_av_herald_iceblood_tower_attack" } }, // Iceblood Tower
- { BG_AV_NODES_TOWER_POINT, { 40, 39, 38, 37 }, { 1367, 1389, 1384, 1394, 1187 }, { "bg_av_herald_tower_point_defend", "bg_av_herald_tower_point_attack" } }, // Tower Point
- { BG_AV_NODES_FROSTWOLF_ETOWER, { 36, 35, 34, 33 }, { 1366, 1388, 1383, 1393, 1186 }, { "bg_av_herald_east_tower_defend", "bg_av_herald_east_tower_attack" } }, // Frostwolf East Tower
- { BG_AV_NODES_FROSTWOLF_WTOWER, { 32, 31, 30, 29 }, { 1365, 1387, 1382, 1392, 1185 }, { "bg_av_herald_west_tower_defend", "bg_av_herald_west_tower_attack" } }, // Frostwolf West Tower
-};
-
-enum Texts
-{
- // Herold
- // Towers/Graveyards = 1 - 60
- TEXT_COLDTOOTH_MINE_ALLIANCE_TAKEN = 61,
- TEXT_IRONDEEP_MINE_ALLIANCE_TAKEN = 62,
- TEXT_COLDTOOTH_MINE_HORDE_TAKEN = 63,
- TEXT_IRONDEEP_MINE_HORDE_TAKEN = 64,
- TEXT_FROSTWOLF_GENERAL_DEAD = 65, /// @todo: sound is missing
- TEXT_STORMPIKE_GENERAL_DEAD = 66, /// @todo: sound is missing
- TEXT_ALLIANCE_WINS = 67, // NYI /// @todo: sound is missing
- TEXT_HORDE_WINS = 68, // NYI /// @todo: sound is missing
-
- // Taskmaster Snivvle
- TEXT_SNIVVLE_RANDOM = 0
-};
-
-enum BG_AV_ExploitTeleportLocations
-{
- AV_EXPLOIT_TELEPORT_LOCATION_ALLIANCE = 3664,
- AV_EXPLOIT_TELEPORT_LOCATION_HORDE = 3665
-};
-
-struct BG_AV_NodeInfo
-{
- BG_AV_States State;
- BG_AV_States PrevState;
- uint16 TotalOwner;
- Team Owner;
- uint16 PrevOwner;
- bool Tower;
-};
-
-inline BG_AV_Nodes &operator++(BG_AV_Nodes& i) { return i = BG_AV_Nodes(i + 1); }
-
-enum BG_AV_Data : uint32
-{
- DATA_DEFENDER_TIER_HORDE = 1,
- DATA_DEFENDER_TIER_ALLIANCE = 2,
-};
-
-enum BG_AV_DefenderTier : uint32
-{
- BG_AV_DEFENDER_TIER_DEFENDER,
- BG_AV_DEFENDER_TIER_SEASONED,
- BG_AV_DEFENDER_TIER_VETERAN,
- BG_AV_DEFENDER_TIER_CHAMPION
-};
-
-class BattlegroundAV : public Battleground
-{
- public:
- BattlegroundAV(BattlegroundTemplate const* battlegroundTemplate);
- ~BattlegroundAV() = default;
-
- /* inherited from BattlegroundClass */
- void StartingEventOpenDoors() override;
-
- void RemovePlayer(Player* player, ObjectGuid guid, uint32 team) override;
- bool SetupBattleground() override;
-
- /*general stuff*/
- void UpdateScore(Team team, int16 points);
-
- // Handle Stuff
- void HandleInteractCapturableObject(Player* player, GameObject* target);
- //these are functions which get called from extern
- void HandleKillPlayer(Player* player, Player* killer) override;
- void HandleKillUnit(Creature* unit, Unit* killer) override;
- void HandleQuestComplete(uint32 questid, Player* player) override;
-
- void EndBattleground(Team winner) override;
-
- WorldSafeLocsEntry const* GetExploitTeleportLocation(Team team) override;
-
- Team GetPrematureWinner() override;
- void OnGameObjectCreate(GameObject* gameObject) override;
- void OnCreatureCreate(Creature* creature) override;
-
- uint32 GetData(uint32 dataId) const override;
-
- private:
- void PostUpdateImpl(uint32 diff) override;
- bool IsCaptainAlive(TeamId teamId) const;
-
- /* Nodes occupying */
- void EventPlayerAssaultsPoint(Player* player, uint32 object);
- void EventPlayerDefendsPoint(Player* player, uint32 object);
- void EventPlayerDestroyedPoint(GameObject* gameobject);
- void DoAction([[maybe_unused]] uint32 actionId, [[maybe_unused]] WorldObject* source = nullptr, [[maybe_unused]] WorldObject* target = nullptr) override;
-
- void AssaultNode(BG_AV_Nodes node, Team team);
- void DestroyNode(BG_AV_Nodes node);
- void InitNode(BG_AV_Nodes node, Team team, bool tower);
- void DefendNode(BG_AV_Nodes node, Team team);
-
- StaticNodeInfo const* GetStaticNodeInfo(BG_AV_Nodes node) const
- {
- for (uint8 i = 0; i < BG_AV_NODES_MAX; ++i)
- if (BGAVNodeInfo[i].NodeId == node)
- return &BGAVNodeInfo[i];
- return nullptr;
- }
-
- BG_AV_Nodes GetNodeThroughObject(uint32 object);
- bool IsTower(BG_AV_Nodes node) const { return _nodes[node].Tower; }
-
- /*mine*/
- void ChangeMineOwner(AlteracValleyMine mine, Team team, bool initial = false);
-
- /*worldstates*/
- void SendMineWorldStates(AlteracValleyMine mine);
- void UpdateNodeWorldState(BG_AV_Nodes node);
-
- Creature* FindHerald(std::string_view stringId) const;
-
- /*variables */
- std::array<int32, PVP_TEAMS_COUNT> _teamResources;
- uint32 m_Team_QuestStatus[PVP_TEAMS_COUNT][9]; //[x][y] x=team y=questcounter
-
- std::array<BG_AV_NodeInfo, BG_AV_NODES_MAX> _nodes;
-
- TimeTracker _mineResourceTimer; //ticks for both teams
-
- std::array<AlteracValleyMineInfo, 2> _mineInfo;
-
- std::array<TimeTracker, PVP_TEAMS_COUNT> _captainBuffTimer;
-
- std::array<bool, PVP_TEAMS_COUNT> _isInformedNearVictory;
- GuidUnorderedSet _doorGUIDs;
- ObjectGuid _balindaGUID;
- ObjectGuid _galvangarGUID;
- GuidUnorderedSet _heraldGUIDs;
-};
-
-#endif
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp
deleted file mode 100644
index 1e6c57cdd27..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "BattlegroundBE.h"
-#include "Log.h"
-#include "Player.h"
-
-BattlegroundBE::BattlegroundBE(BattlegroundTemplate const* battlegroundTemplate) : Arena(battlegroundTemplate)
-{
- BgObjects.resize(BG_BE_OBJECT_MAX);
-}
-
-void BattlegroundBE::PostUpdateImpl(uint32 diff)
-{
- if (GetStatus() != STATUS_IN_PROGRESS)
- return;
-
- _events.Update(diff);
-
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case BG_BE_EVENT_REMOVE_DOORS:
- for (uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_2; ++i)
- DelObject(i);
- break;
- default:
- break;
- }
- }
-}
-
-void BattlegroundBE::StartingEventCloseDoors()
-{
- for (uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_4; ++i)
- SpawnBGObject(i, RESPAWN_IMMEDIATELY);
-
- for (uint32 i = BG_BE_OBJECT_BUFF_1; i <= BG_BE_OBJECT_BUFF_2; ++i)
- SpawnBGObject(i, RESPAWN_ONE_DAY);
-}
-
-void BattlegroundBE::StartingEventOpenDoors()
-{
- for (uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_2; ++i)
- DoorOpen(i);
- _events.ScheduleEvent(BG_BE_EVENT_REMOVE_DOORS, BG_BE_REMOVE_DOORS_TIMER);
-
- for (uint32 i = BG_BE_OBJECT_BUFF_1; i <= BG_BE_OBJECT_BUFF_2; ++i)
- SpawnBGObject(i, 60);
-}
-
-bool BattlegroundBE::SetupBattleground()
-{
- // gates
- if (!AddObject(BG_BE_OBJECT_DOOR_1, BG_BE_OBJECT_TYPE_DOOR_1, 6287.277f, 282.1877f, 3.810925f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_BE_OBJECT_DOOR_2, BG_BE_OBJECT_TYPE_DOOR_2, 6189.546f, 241.7099f, 3.101481f, 0.8813917f, 0, 0, 0.4265689f, 0.9044551f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_BE_OBJECT_DOOR_3, BG_BE_OBJECT_TYPE_DOOR_3, 6299.116f, 296.5494f, 3.308032f, 0.8813917f, 0, 0, 0.4265689f, 0.9044551f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_BE_OBJECT_DOOR_4, BG_BE_OBJECT_TYPE_DOOR_4, 6177.708f, 227.3481f, 3.604374f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f, RESPAWN_IMMEDIATELY)
- // buffs
- || !AddObject(BG_BE_OBJECT_BUFF_1, BG_BE_OBJECT_TYPE_BUFF_1, 6249.042f, 275.3239f, 11.22033f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f, 120)
- || !AddObject(BG_BE_OBJECT_BUFF_2, BG_BE_OBJECT_TYPE_BUFF_2, 6228.26f, 249.566f, 11.21812f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f, 120))
- {
- TC_LOG_ERROR("sql.sql", "BatteGroundBE: Failed to spawn some object!");
- return false;
- }
-
- return true;
-}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundBE.h b/src/server/game/Battlegrounds/Zones/BattlegroundBE.h
deleted file mode 100644
index fb0d424829c..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundBE.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __BATTLEGROUNDBE_H
-#define __BATTLEGROUNDBE_H
-
-#include "Arena.h"
-#include "EventMap.h"
-
-enum BattlegroundBEObjectTypes
-{
- BG_BE_OBJECT_DOOR_1 = 0,
- BG_BE_OBJECT_DOOR_2 = 1,
- BG_BE_OBJECT_DOOR_3 = 2,
- BG_BE_OBJECT_DOOR_4 = 3,
- BG_BE_OBJECT_BUFF_1 = 4,
- BG_BE_OBJECT_BUFF_2 = 5,
- BG_BE_OBJECT_MAX = 6
-};
-
-enum BattlegroundBEGameObjects
-{
- BG_BE_OBJECT_TYPE_DOOR_1 = 183971,
- BG_BE_OBJECT_TYPE_DOOR_2 = 183973,
- BG_BE_OBJECT_TYPE_DOOR_3 = 183970,
- BG_BE_OBJECT_TYPE_DOOR_4 = 183972,
- BG_BE_OBJECT_TYPE_BUFF_1 = 184663,
- BG_BE_OBJECT_TYPE_BUFF_2 = 184664
-};
-
-inline constexpr Seconds BG_BE_REMOVE_DOORS_TIMER = 5s;
-
-enum BattlegroundBEEvents
-{
- BG_BE_EVENT_REMOVE_DOORS = 1
-};
-
-class BattlegroundBE : public Arena
-{
- public:
- BattlegroundBE(BattlegroundTemplate const* battlegroundTemplate);
-
- /* inherited from BattlegroundClass */
- void StartingEventCloseDoors() override;
- void StartingEventOpenDoors() override;
-
- bool SetupBattleground() override;
-
- private:
- void PostUpdateImpl(uint32 diff) override;
-
- EventMap _events;
-};
-#endif
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp
deleted file mode 100644
index d0488b43b41..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "BattlegroundDS.h"
-#include "Creature.h"
-#include "Log.h"
-#include "Player.h"
-
-BattlegroundDS::BattlegroundDS(BattlegroundTemplate const* battlegroundTemplate) : Arena(battlegroundTemplate)
-{
- BgObjects.resize(BG_DS_OBJECT_MAX);
- BgCreatures.resize(BG_DS_NPC_MAX);
-
- _pipeKnockBackTimer = 0;
- _pipeKnockBackCount = 0;
-}
-
-void BattlegroundDS::PostUpdateImpl(uint32 diff)
-{
- if (GetStatus() != STATUS_IN_PROGRESS)
- return;
-
- _events.Update(diff);
-
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case BG_DS_EVENT_WATERFALL_WARNING:
- // Add the water
- DoorClose(BG_DS_OBJECT_WATER_2);
- _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_ON, BG_DS_WATERFALL_WARNING_DURATION);
- break;
- case BG_DS_EVENT_WATERFALL_ON:
- // Active collision and start knockback timer
- DoorClose(BG_DS_OBJECT_WATER_1);
- _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_OFF, BG_DS_WATERFALL_DURATION);
- _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_KNOCKBACK, BG_DS_WATERFALL_KNOCKBACK_TIMER);
- break;
- case BG_DS_EVENT_WATERFALL_OFF:
- // Remove collision and water
- DoorOpen(BG_DS_OBJECT_WATER_1);
- DoorOpen(BG_DS_OBJECT_WATER_2);
- _events.CancelEvent(BG_DS_EVENT_WATERFALL_KNOCKBACK);
- _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_WARNING, BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX);
- break;
- case BG_DS_EVENT_WATERFALL_KNOCKBACK:
- // Repeat knockback while the waterfall still active
- if (Creature* waterSpout = GetBGCreature(BG_DS_NPC_WATERFALL_KNOCKBACK))
- waterSpout->CastSpell(waterSpout, BG_DS_SPELL_WATER_SPOUT, true);
- _events.ScheduleEvent(eventId, BG_DS_WATERFALL_KNOCKBACK_TIMER);
- break;
- case BG_DS_EVENT_PIPE_KNOCKBACK:
- for (uint32 i = BG_DS_NPC_PIPE_KNOCKBACK_1; i <= BG_DS_NPC_PIPE_KNOCKBACK_2; ++i)
- if (Creature* waterSpout = GetBGCreature(i))
- waterSpout->CastSpell(waterSpout, BG_DS_SPELL_FLUSH, true);
- break;
- }
- }
-
- if (_pipeKnockBackCount < BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT)
- {
- if (_pipeKnockBackTimer < diff)
- {
- for (uint32 i = BG_DS_NPC_PIPE_KNOCKBACK_1; i <= BG_DS_NPC_PIPE_KNOCKBACK_2; ++i)
- if (Creature* waterSpout = GetBGCreature(i))
- waterSpout->CastSpell(waterSpout, BG_DS_SPELL_FLUSH, true);
-
- ++_pipeKnockBackCount;
- _pipeKnockBackTimer = BG_DS_PIPE_KNOCKBACK_DELAY;
- }
- else
- _pipeKnockBackTimer -= diff;
- }
-}
-
-void BattlegroundDS::StartingEventCloseDoors()
-{
- for (uint32 i = BG_DS_OBJECT_DOOR_1; i <= BG_DS_OBJECT_DOOR_2; ++i)
- SpawnBGObject(i, RESPAWN_IMMEDIATELY);
-}
-
-void BattlegroundDS::StartingEventOpenDoors()
-{
- for (uint32 i = BG_DS_OBJECT_DOOR_1; i <= BG_DS_OBJECT_DOOR_2; ++i)
- DoorOpen(i);
-
- for (uint32 i = BG_DS_OBJECT_BUFF_1; i <= BG_DS_OBJECT_BUFF_2; ++i)
- SpawnBGObject(i, 60);
-
- _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_WARNING, BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX);
- //for (uint8 i = 0; i < BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT; ++i)
- // _events.ScheduleEvent(BG_DS_EVENT_PIPE_KNOCKBACK, BG_DS_PIPE_KNOCKBACK_FIRST_DELAY + i * BG_DS_PIPE_KNOCKBACK_DELAY);
-
- _pipeKnockBackCount = 0;
- _pipeKnockBackTimer = BG_DS_PIPE_KNOCKBACK_FIRST_DELAY;
-
- SpawnBGObject(BG_DS_OBJECT_WATER_2, RESPAWN_IMMEDIATELY);
-
- DoorOpen(BG_DS_OBJECT_WATER_1); // Turn off collision
- DoorOpen(BG_DS_OBJECT_WATER_2);
-
- // Remove effects of Demonic Circle Summon
- for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
- if (Player* player = _GetPlayer(itr, "BattlegroundDS::StartingEventOpenDoors"))
- player->RemoveAurasDueToSpell(SPELL_WARL_DEMONIC_CIRCLE);
-}
-
-bool BattlegroundDS::SetupBattleground()
-{
- // gates
- if (!AddObject(BG_DS_OBJECT_DOOR_1, BG_DS_OBJECT_TYPE_DOOR_1, 1350.95f, 817.2f, 20.8096f, 3.15f, 0, 0, 0.99627f, 0.0862864f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_DS_OBJECT_DOOR_2, BG_DS_OBJECT_TYPE_DOOR_2, 1232.65f, 764.913f, 20.0729f, 6.3f, 0, 0, 0.0310211f, -0.999519f, RESPAWN_IMMEDIATELY)
- // water
- || !AddObject(BG_DS_OBJECT_WATER_1, BG_DS_OBJECT_TYPE_WATER_1, 1291.56f, 790.837f, 7.1f, 3.14238f, 0, 0, 0.694215f, -0.719768f, 120)
- || !AddObject(BG_DS_OBJECT_WATER_2, BG_DS_OBJECT_TYPE_WATER_2, 1291.56f, 790.837f, 7.1f, 3.14238f, 0, 0, 0.694215f, -0.719768f, 120)
- // buffs
- || !AddObject(BG_DS_OBJECT_BUFF_1, BG_DS_OBJECT_TYPE_BUFF_1, 1291.7f, 813.424f, 7.11472f, 4.64562f, 0, 0, 0.730314f, -0.683111f, 120)
- || !AddObject(BG_DS_OBJECT_BUFF_2, BG_DS_OBJECT_TYPE_BUFF_2, 1291.7f, 768.911f, 7.11472f, 1.55194f, 0, 0, 0.700409f, 0.713742f, 120)
- // knockback creatures
- || !AddCreature(BG_DS_NPC_TYPE_WATER_SPOUT, BG_DS_NPC_WATERFALL_KNOCKBACK, 1292.587f, 790.2205f, 7.19796f, 3.054326f, TEAM_NEUTRAL, RESPAWN_IMMEDIATELY)
- || !AddCreature(BG_DS_NPC_TYPE_WATER_SPOUT, BG_DS_NPC_PIPE_KNOCKBACK_1, 1369.977f, 817.2882f, 16.08718f, 3.106686f, TEAM_NEUTRAL, RESPAWN_IMMEDIATELY)
- || !AddCreature(BG_DS_NPC_TYPE_WATER_SPOUT, BG_DS_NPC_PIPE_KNOCKBACK_2, 1212.833f, 765.3871f, 16.09484f, 0.0f, TEAM_NEUTRAL, RESPAWN_IMMEDIATELY))
- {
- TC_LOG_ERROR("sql.sql", "BatteGroundDS: Failed to spawn some object!");
- return false;
- }
-
- return true;
-}
-
-void BattlegroundDS::SetData(uint32 dataId, uint32 value)
-{
- Arena::SetData(dataId, value);
- if (dataId == BG_DS_DATA_PIPE_KNOCKBACK_COUNT)
- _pipeKnockBackCount = value;
-}
-
-uint32 BattlegroundDS::GetData(uint32 dataId) const
-{
- if (dataId == BG_DS_DATA_PIPE_KNOCKBACK_COUNT)
- return _pipeKnockBackCount;
-
- return Arena::GetData(dataId);
-}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundDS.h b/src/server/game/Battlegrounds/Zones/BattlegroundDS.h
deleted file mode 100644
index 75ac2c3e498..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundDS.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __BATTLEGROUNDDS_H
-#define __BATTLEGROUNDDS_H
-
-#include "Arena.h"
-#include "EventMap.h"
-
-enum BattlegroundDSObjectTypes
-{
- BG_DS_OBJECT_DOOR_1 = 0,
- BG_DS_OBJECT_DOOR_2 = 1,
- BG_DS_OBJECT_WATER_1 = 2, // Collision
- BG_DS_OBJECT_WATER_2 = 3,
- BG_DS_OBJECT_BUFF_1 = 4,
- BG_DS_OBJECT_BUFF_2 = 5,
- BG_DS_OBJECT_MAX = 6
-};
-
-enum BattlegroundDSGameObjects
-{
- BG_DS_OBJECT_TYPE_DOOR_1 = 192642,
- BG_DS_OBJECT_TYPE_DOOR_2 = 192643,
- BG_DS_OBJECT_TYPE_WATER_1 = 194395, // Collision
- BG_DS_OBJECT_TYPE_WATER_2 = 191877,
- BG_DS_OBJECT_TYPE_BUFF_1 = 184663,
- BG_DS_OBJECT_TYPE_BUFF_2 = 184664
-};
-
-enum BattlegroundDSCreatureTypes
-{
- BG_DS_NPC_WATERFALL_KNOCKBACK = 0,
- BG_DS_NPC_PIPE_KNOCKBACK_1 = 1,
- BG_DS_NPC_PIPE_KNOCKBACK_2 = 2,
- BG_DS_NPC_MAX = 3
-};
-
-enum BattlegroundDSCreatures
-{
- BG_DS_NPC_TYPE_WATER_SPOUT = 28567
-};
-
-enum BattlegroundDSSpells
-{
- BG_DS_SPELL_FLUSH = 57405, // Visual and target selector for the starting knockback from the pipe
- BG_DS_SPELL_FLUSH_KNOCKBACK = 61698, // Knockback effect for previous spell (triggered, not needed to be cast)
- BG_DS_SPELL_WATER_SPOUT = 58873, // Knockback effect of the central waterfall
-
- SPELL_WARL_DEMONIC_CIRCLE = 48018 // Demonic Circle Summon
-};
-
-enum BattlegroundDSData
-{
- // These values are NOT blizzlike... need the correct data!
- BG_DS_PIPE_KNOCKBACK_FIRST_DELAY = 5000,
- BG_DS_PIPE_KNOCKBACK_DELAY = 3000,
- BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT = 2,
-};
-
-// These values are NOT blizzlike... need the correct data!
-inline constexpr Seconds BG_DS_WATERFALL_TIMER_MIN = 30s;
-inline constexpr Seconds BG_DS_WATERFALL_TIMER_MAX = 60s;
-inline constexpr Seconds BG_DS_WATERFALL_WARNING_DURATION = 5s;
-inline constexpr Seconds BG_DS_WATERFALL_DURATION = 30s;
-inline constexpr Milliseconds BG_DS_WATERFALL_KNOCKBACK_TIMER = 1500ms;
-inline constexpr uint32 BG_DS_DATA_PIPE_KNOCKBACK_COUNT = 1;
-
-enum BattlegroundDSEvents
-{
- BG_DS_EVENT_WATERFALL_WARNING = 1, // Water starting to fall, but no LoS Blocking nor movement blocking
- BG_DS_EVENT_WATERFALL_ON = 2, // LoS and Movement blocking active
- BG_DS_EVENT_WATERFALL_OFF = 3,
- BG_DS_EVENT_WATERFALL_KNOCKBACK = 4,
-
- BG_DS_EVENT_PIPE_KNOCKBACK = 5
-};
-
-class BattlegroundDS : public Arena
-{
- public:
- BattlegroundDS(BattlegroundTemplate const* battlegroundTemplate);
-
- /* inherited from BattlegroundClass */
- void StartingEventCloseDoors() override;
- void StartingEventOpenDoors() override;
-
- bool SetupBattleground() override;
-
- void SetData(uint32 dataId, uint32 value) override;
- uint32 GetData(uint32 dataId) const override;
- private:
- void PostUpdateImpl(uint32 diff) override;
-
- EventMap _events;
-
- uint32 _pipeKnockBackTimer;
- uint8 _pipeKnockBackCount;
-};
-
-#endif
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
deleted file mode 100644
index f43d3d54023..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "BattlegroundEY.h"
-#include "AreaTrigger.h"
-#include "BattlegroundMgr.h"
-#include "BattlegroundPackets.h"
-#include "Creature.h"
-#include "GameObject.h"
-#include "Log.h"
-#include "Map.h"
-#include "ObjectAccessor.h"
-#include "ObjectMgr.h"
-#include "Player.h"
-#include "Random.h"
-#include "SpellAuras.h"
-#include "SpellInfo.h"
-#include "Util.h"
-
-enum EyeOfTheStormPvpStats
-{
- PVP_STAT_FLAG_CAPTURES = 183
-};
-
-BattlegroundEY::BattlegroundEY(BattlegroundTemplate const* battlegroundTemplate) : Battleground(battlegroundTemplate)
-{
- BgObjects.resize(0);
- BgCreatures.resize(0);
- m_HonorScoreTics = { 0, 0 };
- m_FlagCapturedBgObjectType = 0;
- m_HonorTics = 0;
- _pointsTimer.Reset(POINTS_TICK_TIME);
- _assaultEnabled = false;
- _assaultStackCount = 0;
- _flagAssaultTimer.Reset(BG_EY_FLAG_ASSAULT_TIMER);
-}
-
-BattlegroundEY::~BattlegroundEY() { }
-
-void BattlegroundEY::PostUpdateImpl(uint32 diff)
-{
- if (GetStatus() == STATUS_IN_PROGRESS)
- {
- _pointsTimer.Update(diff);
- if (_pointsTimer.Passed())
- {
- _pointsTimer.Reset(POINTS_TICK_TIME);
-
- uint8 baseCountAlliance = GetControlledBaseCount(TEAM_ALLIANCE);
- uint8 baseCountHorde = GetControlledBaseCount(TEAM_HORDE);
- if (baseCountAlliance > 0)
- AddPoints(ALLIANCE, BG_EY_TickPoints[baseCountAlliance - 1]);
- if (baseCountHorde > 0)
- AddPoints(HORDE, BG_EY_TickPoints[baseCountHorde - 1]);
- }
-
- if (_assaultEnabled)
- {
- _flagAssaultTimer.Update(diff);
- if (_flagAssaultTimer.Passed())
- {
- _flagAssaultTimer.Reset(BG_EY_FLAG_ASSAULT_TIMER);
- _assaultStackCount++;
-
- // update assault debuff stacks
- DoForFlagKeepers([&](Player* player) -> void
- {
- ApplyAssaultDebuffToPlayer(player);
- });
- }
- }
- }
-}
-
-void BattlegroundEY::StartingEventOpenDoors()
-{
- for (ObjectGuid const& door : _doorGUIDs)
- {
- if (GameObject* gameObject = GetBgMap()->GetGameObject(door))
- {
- gameObject->UseDoorOrButton();
- gameObject->DespawnOrUnsummon(3s);
- }
- }
-
- // Achievement: Flurry
- TriggerGameEvent(BG_EY_EVENT_START_BATTLE);
-}
-
-void BattlegroundEY::AddPoints(Team team, uint32 Points)
-{
- TeamId team_index = GetTeamIndexByTeamId(team);
- m_TeamScores[team_index] += Points;
- m_HonorScoreTics[team_index] += Points;
- if (m_HonorScoreTics[team_index] >= m_HonorTics)
- {
- RewardHonorToTeam(GetBonusHonorFromKill(1), team);
- m_HonorScoreTics[team_index] -= m_HonorTics;
- }
- UpdateTeamScore(team_index);
-}
-
-uint8 BattlegroundEY::GetControlledBaseCount(TeamId teamId) const
-{
- uint8 baseCount = 0;
- for (auto const& controlZoneHandler : _controlZoneHandlers)
- {
- uint32 point = controlZoneHandler.second->GetPoint();
- switch (teamId)
- {
- case TEAM_ALLIANCE:
- if (GetBgMap()->GetWorldStateValue(m_PointsIconStruct[point].WorldStateAllianceControlledIndex) == 1)
- baseCount++;
- break;
- case TEAM_HORDE:
- if (GetBgMap()->GetWorldStateValue(m_PointsIconStruct[point].WorldStateHordeControlledIndex) == 1)
- baseCount++;
- break;
- default:
- break;
- }
- }
- return baseCount;
-}
-
-void BattlegroundEY::DoForFlagKeepers(std::function<void(Player*)> action) const
-{
- if (GameObject* flag = GetBgMap()->GetGameObject(_flagGUID))
- {
- if (Player* carrier = ObjectAccessor::FindPlayer(flag->GetFlagCarrierGUID()))
- action(carrier);
- }
-}
-
-void BattlegroundEY::ResetAssaultDebuff()
-{
- _assaultEnabled = false;
- _assaultStackCount = 0;
- _flagAssaultTimer.Reset(BG_EY_FLAG_ASSAULT_TIMER);
- DoForFlagKeepers([&](Player* player) -> void
- {
- RemoveAssaultDebuffFromPlayer(player);
- });
-}
-
-void BattlegroundEY::ApplyAssaultDebuffToPlayer(Player* player)
-{
- if (_assaultStackCount == 0)
- return;
-
- uint32 spellId = BG_EY_FOCUSED_ASSAULT_SPELL;
- if (_assaultStackCount >= BG_EY_FLAG_BRUTAL_ASSAULT_STACK_COUNT)
- {
- player->RemoveAurasDueToSpell(BG_EY_FOCUSED_ASSAULT_SPELL);
- spellId = BG_EY_BRUTAL_ASSAULT_SPELL;
- }
-
- Aura* aura = player->GetAura(spellId);
- if (!aura)
- {
- player->CastSpell(player, spellId, true);
- aura = player->GetAura(spellId);
- }
-
- if (aura)
- aura->SetStackAmount(_assaultStackCount);
-}
-
-void BattlegroundEY::RemoveAssaultDebuffFromPlayer(Player* player)
-{
- player->RemoveAurasDueToSpell(BG_EY_FOCUSED_ASSAULT_SPELL);
- player->RemoveAurasDueToSpell(BG_EY_BRUTAL_ASSAULT_SPELL);
-}
-
-void BattlegroundEY::UpdateTeamScore(TeamId Team)
-{
- uint32 score = GetTeamScore(Team);
-
- if (score >= BG_EY_MAX_TEAM_SCORE)
- {
- score = BG_EY_MAX_TEAM_SCORE;
- if (Team == TEAM_ALLIANCE)
- EndBattleground(ALLIANCE);
- else
- EndBattleground(HORDE);
- }
-
- if (Team == TEAM_ALLIANCE)
- UpdateWorldState(EY_ALLIANCE_RESOURCES, score);
- else
- UpdateWorldState(EY_HORDE_RESOURCES, score);
-}
-
-void BattlegroundEY::EndBattleground(Team winner)
-{
- // Win reward
- if (winner == ALLIANCE)
- RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
- if (winner == HORDE)
- RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
-
- // Complete map reward
- RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
- RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
-
- Battleground::EndBattleground(winner);
-}
-
-void BattlegroundEY::UpdatePointsCount(TeamId teamId)
-{
- if (teamId == TEAM_ALLIANCE)
- UpdateWorldState(EY_ALLIANCE_BASE, GetControlledBaseCount(TEAM_ALLIANCE));
- else
- UpdateWorldState(EY_HORDE_BASE, GetControlledBaseCount(TEAM_HORDE));
-}
-
-void BattlegroundEY::OnGameObjectCreate(GameObject* gameObject)
-{
- switch (gameObject->GetEntry())
- {
- case BG_OBJECT_A_DOOR_EY_ENTRY:
- case BG_OBJECT_H_DOOR_EY_ENTRY:
- _doorGUIDs.insert(gameObject->GetGUID());
- break;
- case BG_OBJECT_FLAG2_EY_ENTRY:
- _flagGUID = gameObject->GetGUID();
- break;
- default:
- break;
- }
-}
-
-bool BattlegroundEY::CanCaptureFlag(AreaTrigger* areaTrigger, Player* player)
-{
- if (areaTrigger->GetEntry() != AREATRIGGER_CAPTURE_FLAG)
- return false;
-
- if (GameObject* flag = GetBgMap()->GetGameObject(_flagGUID))
- {
- if (flag->GetFlagCarrierGUID() != player->GetGUID())
- return false;
- }
-
- if (GameObject* controlzone = player->FindNearestGameObjectWithOptions(40.0f, { .StringId = "bg_eye_of_the_storm_control_zone" }))
- {
- uint32 point = _controlZoneHandlers[controlzone->GetEntry()]->GetPoint();
- switch (GetPlayerTeam(player->GetGUID()))
- {
- case ALLIANCE:
- return GetBgMap()->GetWorldStateValue(m_PointsIconStruct[point].WorldStateAllianceControlledIndex) == 1;
- case HORDE:
- return GetBgMap()->GetWorldStateValue(m_PointsIconStruct[point].WorldStateHordeControlledIndex) == 1;
- default:
- return false;
- }
- }
-
- return false;
-}
-
-void BattlegroundEY::OnCaptureFlag(AreaTrigger* areaTrigger, Player* player)
-{
- if (areaTrigger->GetEntry() != AREATRIGGER_CAPTURE_FLAG)
- return;
-
- uint32 baseCount = GetControlledBaseCount(GetTeamIndexByTeamId(GetPlayerTeam(player->GetGUID())));
-
- if (GameObject* gameObject = GetBgMap()->GetGameObject(_flagGUID))
- gameObject->HandleCustomTypeCommand(GameObjectType::SetNewFlagState(FlagState::Respawning, player));
-
- Team team = Team(GetPlayerTeam(player->GetGUID()));
- if (team == ALLIANCE)
- {
- SendBroadcastText(BG_EY_TEXT_ALLIANCE_CAPTURED_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
- PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE);
- }
- else
- {
- SendBroadcastText(BG_EY_TEXT_HORDE_CAPTURED_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, player);
- PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_HORDE);
- }
-
- if (baseCount > 0)
- AddPoints(team, BG_EY_FlagPoints[baseCount - 1]);
-
- UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_ON_BASE);
- UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_ON_BASE);
-
- UpdatePvpStat(player, PVP_STAT_FLAG_CAPTURES, 1);
-
- player->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
- player->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::PvPActive);
-}
-
-void BattlegroundEY::OnFlagStateChange(GameObject* /*flagInBase*/, FlagState /*oldValue*/, FlagState newValue, Player* player)
-{
- switch (newValue)
- {
- case FlagState::InBase:
- ResetAssaultDebuff();
- break;
- case FlagState::Dropped:
- player->CastSpell(player, SPELL_RECENTLY_DROPPED_NEUTRAL_FLAG, true);
- RemoveAssaultDebuffFromPlayer(player);
-
- UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
- UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
-
- if (GetPlayerTeam(player->GetGUID()) == ALLIANCE)
- SendBroadcastText(BG_EY_TEXT_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_ALLIANCE);
- else
- SendBroadcastText(BG_EY_TEXT_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_HORDE);
- break;
- case FlagState::Taken:
- if (GetPlayerTeam(player->GetGUID()) == ALLIANCE)
- {
- UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_ON_PLAYER);
- PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE);
- SendBroadcastText(BG_EY_TEXT_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
- }
- else
- {
- UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_ON_PLAYER);
- PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_HORDE);
- SendBroadcastText(BG_EY_TEXT_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, player);
- }
-
- ApplyAssaultDebuffToPlayer(player);
- _assaultEnabled = true;
-
- player->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::PvPActive);
- break;
- case FlagState::Respawning:
- ResetAssaultDebuff();
- break;
- default:
- break;
- }
-
- UpdateWorldState(NETHERSTORM_FLAG, AsUnderlyingType(newValue));
-}
-
-bool BattlegroundEY::SetupBattleground()
-{
- UpdateWorldState(EY_MAX_RESOURCES, BG_EY_MAX_TEAM_SCORE);
-
- _controlZoneHandlers[BG_OBJECT_FR_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(this, FEL_REAVER);
- _controlZoneHandlers[BG_OBJECT_BE_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(this, BLOOD_ELF);
- _controlZoneHandlers[BG_OBJECT_DR_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(this, DRAENEI_RUINS);
- _controlZoneHandlers[BG_OBJECT_HU_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(this, MAGE_TOWER);
-
- return true;
-}
-
-void BattlegroundEY::Reset()
-{
- //call parent's class reset
- Battleground::Reset();
-
- m_TeamScores[TEAM_ALLIANCE] = 0;
- m_TeamScores[TEAM_HORDE] = 0;
- m_HonorScoreTics = { 0, 0 };
- m_FlagCapturedBgObjectType = 0;
- bool isBGWeekend = sBattlegroundMgr->IsBGWeekend(GetTypeID());
- m_HonorTics = (isBGWeekend) ? BG_EY_EYWeekendHonorTicks : BG_EY_NotEYWeekendHonorTicks;
-}
-
-void BattlegroundEY::HandleKillPlayer(Player* player, Player* killer)
-{
- if (GetStatus() != STATUS_IN_PROGRESS)
- return;
-
- Battleground::HandleKillPlayer(player, killer);
- EventPlayerDroppedFlag(player);
-}
-
-void BattlegroundEY::EventTeamLostPoint(TeamId teamId, uint32 point, GameObject* controlZone)
-{
- if (teamId == TEAM_ALLIANCE)
- {
- SendBroadcastText(m_LosingPointTypes[point].MessageIdAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE, controlZone);
- UpdateWorldState(m_PointsIconStruct[point].WorldStateAllianceControlledIndex, 0);
- }
- else if (teamId == TEAM_HORDE)
- {
- SendBroadcastText(m_LosingPointTypes[point].MessageIdHorde, CHAT_MSG_BG_SYSTEM_HORDE, controlZone);
- UpdateWorldState(m_PointsIconStruct[point].WorldStateHordeControlledIndex, 0);
- }
-
- UpdateWorldState(m_PointsIconStruct[point].WorldStateControlIndex, 1);
- UpdatePointsCount(teamId);
-}
-
-void BattlegroundEY::EventTeamCapturedPoint(TeamId teamId, uint32 point, GameObject* controlZone)
-{
- if (teamId == TEAM_ALLIANCE)
- {
- SendBroadcastText(m_CapturingPointTypes[point].MessageIdAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE, controlZone);
- UpdateWorldState(m_PointsIconStruct[point].WorldStateAllianceControlledIndex, 1);
- }
- else if (teamId == TEAM_HORDE)
- {
- SendBroadcastText(m_CapturingPointTypes[point].MessageIdHorde, CHAT_MSG_BG_SYSTEM_HORDE, controlZone);
- UpdateWorldState(m_PointsIconStruct[point].WorldStateHordeControlledIndex, 1);
- }
-
- UpdateWorldState(m_PointsIconStruct[point].WorldStateControlIndex, 0);
- UpdatePointsCount(teamId);
-}
-
-WorldSafeLocsEntry const* BattlegroundEY::GetExploitTeleportLocation(Team team)
-{
- return sObjectMgr->GetWorldSafeLoc(team == ALLIANCE ? EY_EXPLOIT_TELEPORT_LOCATION_ALLIANCE : EY_EXPLOIT_TELEPORT_LOCATION_HORDE);
-}
-
-Team BattlegroundEY::GetPrematureWinner()
-{
- if (GetTeamScore(TEAM_ALLIANCE) > GetTeamScore(TEAM_HORDE))
- return ALLIANCE;
- else if (GetTeamScore(TEAM_HORDE) > GetTeamScore(TEAM_ALLIANCE))
- return HORDE;
-
- return Battleground::GetPrematureWinner();
-}
-
-void BattlegroundEY::ProcessEvent(WorldObject* target, uint32 eventId, WorldObject* invoker)
-{
- Battleground::ProcessEvent(target, eventId, invoker);
-
- if (invoker)
- {
- if (GameObject* gameobject = invoker->ToGameObject())
- {
- if (gameobject->GetGoType() == GAMEOBJECT_TYPE_CONTROL_ZONE)
- {
- if (!_controlZoneHandlers.contains(gameobject->GetEntry()))
- return;
-
- auto controlzone = gameobject->GetGOInfo()->controlZone;
- BattlegroundEYControlZoneHandler& handler = *_controlZoneHandlers[invoker->GetEntry()];
- if (eventId == controlzone.NeutralEventAlliance)
- handler.HandleNeutralEventAlliance(gameobject);
- else if (eventId == controlzone.NeutralEventHorde)
- handler.HandleNeutralEventHorde(gameobject);
- else if (eventId == controlzone.ProgressEventAlliance)
- handler.HandleProgressEventAlliance(gameobject);
- else if (eventId == controlzone.ProgressEventHorde)
- handler.HandleProgressEventHorde(gameobject);
- }
- }
- }
-}
-
-BattlegroundEYControlZoneHandler::BattlegroundEYControlZoneHandler(BattlegroundEY* bg, uint32 point) : ControlZoneHandler(),
- _battleground(bg), _point(point)
-{
-}
-
-void BattlegroundEYControlZoneHandler::HandleProgressEventHorde(GameObject* controlZone)
-{
- _battleground->EventTeamCapturedPoint(TEAM_HORDE, _point, controlZone);
-}
-
-void BattlegroundEYControlZoneHandler::HandleProgressEventAlliance(GameObject* controlZone)
-{
- _battleground->EventTeamCapturedPoint(TEAM_ALLIANCE, _point, controlZone);
-}
-
-void BattlegroundEYControlZoneHandler::HandleNeutralEventHorde(GameObject* controlZone)
-{
- _battleground->EventTeamLostPoint(TEAM_HORDE, _point, controlZone);
-}
-
-void BattlegroundEYControlZoneHandler::HandleNeutralEventAlliance(GameObject* controlZone)
-{
- _battleground->EventTeamLostPoint(TEAM_ALLIANCE, _point, controlZone);
-}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h
deleted file mode 100644
index 1ba4de41af5..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __BATTLEGROUNDEY_H
-#define __BATTLEGROUNDEY_H
-
-#include "Battleground.h"
-#include "BattlegroundScore.h"
-#include "Object.h"
-#include "Timer.h"
-
-static constexpr Seconds POINTS_TICK_TIME = 2s;
-static constexpr Seconds BG_EY_FLAG_ASSAULT_TIMER = 30s;
-static constexpr uint16 BG_EY_FLAG_BRUTAL_ASSAULT_STACK_COUNT = 5;
-
-enum BG_EY_Misc
-{
- BG_EY_EVENT_START_BATTLE = 13180 // Achievement: Flurry
-};
-
-enum BG_EY_WorldStates
-{
- EY_ALLIANCE_RESOURCES = 1776,
- EY_HORDE_RESOURCES = 1777,
- EY_MAX_RESOURCES = 1780,
- EY_ALLIANCE_BASE = 2752,
- EY_HORDE_BASE = 2753,
- DRAENEI_RUINS_HORDE_CONTROL = 2733,
- DRAENEI_RUINS_ALLIANCE_CONTROL = 2732,
- DRAENEI_RUINS_UNCONTROL = 2731,
- MAGE_TOWER_ALLIANCE_CONTROL = 2730,
- MAGE_TOWER_HORDE_CONTROL = 2729,
- MAGE_TOWER_UNCONTROL = 2728,
- FEL_REAVER_HORDE_CONTROL = 2727,
- FEL_REAVER_ALLIANCE_CONTROL = 2726,
- FEL_REAVER_UNCONTROL = 2725,
- BLOOD_ELF_HORDE_CONTROL = 2724,
- BLOOD_ELF_ALLIANCE_CONTROL = 2723,
- BLOOD_ELF_UNCONTROL = 2722,
- PROGRESS_BAR_PERCENT_GREY = 2720, //100 = empty (only grey), 0 = blue|red (no grey)
- PROGRESS_BAR_STATUS = 2719, //50 init!, 48 ... hordak bere .. 33 .. 0 = full 100% hordacky, 100 = full alliance
- PROGRESS_BAR_SHOW = 2718, //1 init, 0 druhy send - bez messagu, 1 = controlled aliance
- NETHERSTORM_FLAG = 8863,
- //set to 2 when flag is picked up, and to 1 if it is dropped
- NETHERSTORM_FLAG_STATE_ALLIANCE = 9808,
- NETHERSTORM_FLAG_STATE_HORDE = 9809,
-
- DRAENEI_RUINS_HORDE_CONTROL_STATE = 17362,
- DRAENEI_RUINS_ALLIANCE_CONTROL_STATE = 17366,
- MAGE_TOWER_HORDE_CONTROL_STATE = 17361,
- MAGE_TOWER_ALLIANCE_CONTROL_STATE = 17368,
- FEL_REAVER_HORDE_CONTROL_STATE = 17364,
- FEL_REAVER_ALLIANCE_CONTROL_STATE = 17367,
- BLOOD_ELF_HORDE_CONTROL_STATE = 17363,
- BLOOD_ELF_ALLIANCE_CONTROL_STATE = 17365,
-};
-
-enum BG_EY_Sounds
-{
- //strange ids, but sure about them
- BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE = 8212,
- BG_EY_SOUND_FLAG_CAPTURED_HORDE = 8213,
- BG_EY_SOUND_FLAG_PICKED_UP_HORDE = 8174,
- BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE = 8173,
- BG_EY_SOUND_FLAG_RESET = 8192
-};
-
-enum BG_EY_Spells
-{
- BG_EY_NETHERSTORM_FLAG_SPELL = 34976,
- BG_EY_PLAYER_DROPPED_FLAG_SPELL = 34991,
-
- // Focused/Brutal Assault
- BG_EY_FOCUSED_ASSAULT_SPELL = 46392,
- BG_EY_BRUTAL_ASSAULT_SPELL = 46393
-};
-
-enum EYBattlegroundObjectEntry
-{
- BG_OBJECT_A_DOOR_EY_ENTRY = 184719, //Alliance door
- BG_OBJECT_H_DOOR_EY_ENTRY = 184720, //Horde door
- BG_OBJECT_FLAG2_EY_ENTRY = 208977, //Netherstorm flag (flagstand)
- BG_OBJECT_BE_TOWER_CAP_EY_ENTRY = 184080, //BE Tower Cap Pt
- BG_OBJECT_FR_TOWER_CAP_EY_ENTRY = 184081, //Fel Reaver Cap Pt
- BG_OBJECT_HU_TOWER_CAP_EY_ENTRY = 184082, //Human Tower Cap Pt
- BG_OBJECT_DR_TOWER_CAP_EY_ENTRY = 184083, //Draenei Tower Cap Pt
-};
-
-enum EYBattlegroundPointsTrigger
-{
- AREATRIGGER_CAPTURE_FLAG = 33
-};
-
-enum EYBattlegroundPoints
-{
- FEL_REAVER = 0,
- BLOOD_ELF = 1,
- DRAENEI_RUINS = 2,
- MAGE_TOWER = 3,
-
- EY_PLAYERS_OUT_OF_POINTS = 4,
- EY_POINTS_MAX = 4
-};
-
-#define BG_EY_NotEYWeekendHonorTicks 260
-#define BG_EY_EYWeekendHonorTicks 160
-
-enum BG_EY_Score
-{
- BG_EY_WARNING_NEAR_VICTORY_SCORE = 1200,
- BG_EY_MAX_TEAM_SCORE = 1500
-};
-
-enum BG_EY_FlagState
-{
- BG_EY_FLAG_STATE_ON_BASE = 0,
- BG_EY_FLAG_STATE_WAIT_RESPAWN = 1,
- BG_EY_FLAG_STATE_ON_PLAYER = 2,
- BG_EY_FLAG_STATE_ON_GROUND = 3
-};
-
-enum EYBattlegroundPointState
-{
- EY_POINT_NO_OWNER = 0,
- EY_POINT_STATE_UNCONTROLLED = 0,
- EY_POINT_UNDER_CONTROL = 3
-};
-
-enum BG_EY_ExploitTeleportLocations
-{
- EY_EXPLOIT_TELEPORT_LOCATION_ALLIANCE = 3773,
- EY_EXPLOIT_TELEPORT_LOCATION_HORDE = 3772
-};
-
-enum BG_EY_BroadcastTexts
-{
- BG_EY_TEXT_ALLIANCE_TAKEN_FEL_REAVER_RUINS = 17828,
- BG_EY_TEXT_HORDE_TAKEN_FEL_REAVER_RUINS = 17829,
- BG_EY_TEXT_ALLIANCE_LOST_FEL_REAVER_RUINS = 91961,
- BG_EY_TEXT_HORDE_LOST_FEL_REAVER_RUINS = 91962,
-
- BG_EY_TEXT_ALLIANCE_TAKEN_BLOOD_ELF_TOWER = 17819,
- BG_EY_TEXT_HORDE_TAKEN_BLOOD_ELF_TOWER = 17823,
- BG_EY_TEXT_ALLIANCE_LOST_BLOOD_ELF_TOWER = 91957,
- BG_EY_TEXT_HORDE_LOST_BLOOD_ELF_TOWER = 91958,
-
- BG_EY_TEXT_ALLIANCE_TAKEN_DRAENEI_RUINS = 17827,
- BG_EY_TEXT_HORDE_TAKEN_DRAENEI_RUINS = 91917,
- BG_EY_TEXT_ALLIANCE_LOST_DRAENEI_RUINS = 91959,
- BG_EY_TEXT_HORDE_LOST_DRAENEI_RUINS = 91960,
-
- BG_EY_TEXT_ALLIANCE_TAKEN_MAGE_TOWER = 17824,
- BG_EY_TEXT_HORDE_TAKEN_MAGE_TOWER = 17825,
- BG_EY_TEXT_ALLIANCE_LOST_MAGE_TOWER = 91963,
- BG_EY_TEXT_HORDE_LOST_MAGE_TOWER = 91964,
-
- BG_EY_TEXT_TAKEN_FLAG = 18359,
- BG_EY_TEXT_FLAG_DROPPED = 18361,
- BG_EY_TEXT_FLAG_RESET = 18364,
- BG_EY_TEXT_ALLIANCE_CAPTURED_FLAG = 18375,
- BG_EY_TEXT_HORDE_CAPTURED_FLAG = 18384,
-};
-
-struct BattlegroundEYPointIconsStruct
-{
- BattlegroundEYPointIconsStruct(uint32 _WorldStateControlIndex, uint32 _WorldStateAllianceControlledIndex, uint32 _WorldStateHordeControlledIndex,
- uint32 worldStateAllianceStatusBarIcon, uint32 worldStateHordeStatusBarIcon)
- : WorldStateControlIndex(_WorldStateControlIndex), WorldStateAllianceControlledIndex(_WorldStateAllianceControlledIndex), WorldStateHordeControlledIndex(_WorldStateHordeControlledIndex),
- WorldStateAllianceStatusBarIcon(worldStateAllianceStatusBarIcon), WorldStateHordeStatusBarIcon(worldStateHordeStatusBarIcon) { }
- uint32 WorldStateControlIndex;
- uint32 WorldStateAllianceControlledIndex;
- uint32 WorldStateHordeControlledIndex;
- uint32 WorldStateAllianceStatusBarIcon;
- uint32 WorldStateHordeStatusBarIcon;
-};
-
-struct BattlegroundEYLosingPointStruct
-{
- BattlegroundEYLosingPointStruct(uint32 _MessageIdAlliance, uint32 _MessageIdHorde)
- : MessageIdAlliance(_MessageIdAlliance), MessageIdHorde(_MessageIdHorde)
- { }
-
- uint32 MessageIdAlliance;
- uint32 MessageIdHorde;
-};
-
-struct BattlegroundEYCapturingPointStruct
-{
- BattlegroundEYCapturingPointStruct(uint32 _MessageIdAlliance, uint32 _MessageIdHorde)
- : MessageIdAlliance(_MessageIdAlliance), MessageIdHorde(_MessageIdHorde)
- { }
-
- uint32 MessageIdAlliance;
- uint32 MessageIdHorde;
-};
-
-class BattlegroundEY;
-
-class BattlegroundEYControlZoneHandler : public ControlZoneHandler
-{
-public:
- explicit BattlegroundEYControlZoneHandler(BattlegroundEY* bg, uint32 point);
-
- void HandleProgressEventHorde(GameObject* controlZone) override;
- void HandleProgressEventAlliance(GameObject* controlZone) override;
- void HandleNeutralEventHorde(GameObject* controlZone) override;
- void HandleNeutralEventAlliance(GameObject* controlZone) override;
-
- uint32 GetPoint() const { return _point; }
-
-private:
- BattlegroundEY* _battleground;
- uint32 _point;
-};
-
-const std::array<uint8, EY_POINTS_MAX> BG_EY_TickPoints = { 1, 2, 5, 10 };
-const std::array<uint32, EY_POINTS_MAX> BG_EY_FlagPoints = { 75, 85, 100, 500 };
-
-//constant arrays:
-const std::array<BattlegroundEYPointIconsStruct, EY_POINTS_MAX> m_PointsIconStruct =
-{
- BattlegroundEYPointIconsStruct(FEL_REAVER_UNCONTROL, FEL_REAVER_ALLIANCE_CONTROL, FEL_REAVER_HORDE_CONTROL, FEL_REAVER_ALLIANCE_CONTROL_STATE, FEL_REAVER_HORDE_CONTROL_STATE),
- BattlegroundEYPointIconsStruct(BLOOD_ELF_UNCONTROL, BLOOD_ELF_ALLIANCE_CONTROL, BLOOD_ELF_HORDE_CONTROL, BLOOD_ELF_ALLIANCE_CONTROL_STATE, BLOOD_ELF_HORDE_CONTROL_STATE),
- BattlegroundEYPointIconsStruct(DRAENEI_RUINS_UNCONTROL, DRAENEI_RUINS_ALLIANCE_CONTROL, DRAENEI_RUINS_HORDE_CONTROL, DRAENEI_RUINS_ALLIANCE_CONTROL_STATE, DRAENEI_RUINS_HORDE_CONTROL_STATE),
- BattlegroundEYPointIconsStruct(MAGE_TOWER_UNCONTROL, MAGE_TOWER_ALLIANCE_CONTROL, MAGE_TOWER_HORDE_CONTROL, MAGE_TOWER_ALLIANCE_CONTROL_STATE, MAGE_TOWER_HORDE_CONTROL_STATE)
-};
-
-const std::array<BattlegroundEYLosingPointStruct, EY_POINTS_MAX> m_LosingPointTypes =
-{
- BattlegroundEYLosingPointStruct(BG_EY_TEXT_ALLIANCE_LOST_FEL_REAVER_RUINS, BG_EY_TEXT_HORDE_LOST_FEL_REAVER_RUINS),
- BattlegroundEYLosingPointStruct(BG_EY_TEXT_ALLIANCE_LOST_BLOOD_ELF_TOWER, BG_EY_TEXT_HORDE_LOST_BLOOD_ELF_TOWER),
- BattlegroundEYLosingPointStruct(BG_EY_TEXT_ALLIANCE_LOST_DRAENEI_RUINS, BG_EY_TEXT_HORDE_LOST_DRAENEI_RUINS),
- BattlegroundEYLosingPointStruct(BG_EY_TEXT_ALLIANCE_LOST_MAGE_TOWER, BG_EY_TEXT_HORDE_LOST_MAGE_TOWER)
-};
-
-const std::array<BattlegroundEYCapturingPointStruct, EY_POINTS_MAX> m_CapturingPointTypes =
-{
- BattlegroundEYCapturingPointStruct(BG_EY_TEXT_ALLIANCE_TAKEN_FEL_REAVER_RUINS, BG_EY_TEXT_HORDE_TAKEN_FEL_REAVER_RUINS),
- BattlegroundEYCapturingPointStruct(BG_EY_TEXT_ALLIANCE_TAKEN_BLOOD_ELF_TOWER, BG_EY_TEXT_HORDE_TAKEN_BLOOD_ELF_TOWER),
- BattlegroundEYCapturingPointStruct(BG_EY_TEXT_ALLIANCE_TAKEN_DRAENEI_RUINS, BG_EY_TEXT_HORDE_TAKEN_DRAENEI_RUINS),
- BattlegroundEYCapturingPointStruct(BG_EY_TEXT_ALLIANCE_TAKEN_MAGE_TOWER, BG_EY_TEXT_HORDE_TAKEN_MAGE_TOWER)
-};
-
-class BattlegroundEY : public Battleground
-{
- public:
- BattlegroundEY(BattlegroundTemplate const* battlegroundTemplate);
- ~BattlegroundEY();
-
- /* inherited from BattlegroundClass */
- void StartingEventOpenDoors() override;
-
- void HandleKillPlayer(Player* player, Player* killer) override;
- WorldSafeLocsEntry const* GetExploitTeleportLocation(Team team) override;
- bool SetupBattleground() override;
- void Reset() override;
- void UpdateTeamScore(TeamId Team);
- void EndBattleground(Team winner) override;
-
- Team GetPrematureWinner() override;
-
- void ProcessEvent(WorldObject* target, uint32 eventId, WorldObject* invoker) override;
- void PostUpdateImpl(uint32 diff) override;
-
- void EventTeamCapturedPoint(TeamId teamId, uint32 point, GameObject* controlZone);
- void EventTeamLostPoint(TeamId teamId, uint32 point, GameObject* controlZone);
- void UpdatePointsCount(TeamId teamId);
-
- void OnGameObjectCreate(GameObject* gameObject) override;
-
- bool CanCaptureFlag([[maybe_unused]] AreaTrigger* areaTrigger, [[maybe_unused]] Player* player) override;
- void OnCaptureFlag([[maybe_unused]] AreaTrigger* areaTrigger, [[maybe_unused]] Player* player) override;
- void OnFlagStateChange(GameObject* flagInBase, FlagState oldValue, FlagState newValue, Player* player) override;
-
- private:
- /* Scorekeeping */
- void AddPoints(Team team, uint32 Points);
-
- void RemovePoint(Team team, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(team)] -= Points; }
- void SetTeamPoint(Team team, uint32 Points = 0) { m_TeamScores[GetTeamIndexByTeamId(team)] = Points; }
-
- uint8 GetControlledBaseCount(TeamId teamId) const;
-
- std::array<uint32, PVP_TEAMS_COUNT> m_HonorScoreTics;
-
- uint32 m_FlagCapturedBgObjectType; // type that should be despawned when flag is captured
-
- TimeTracker _pointsTimer;
- uint32 m_HonorTics;
-
- std::unordered_map<uint32, std::unique_ptr<BattlegroundEYControlZoneHandler>> _controlZoneHandlers;
- GuidUnorderedSet _doorGUIDs;
- ObjectGuid _flagGUID;
-
- // Focused/Brutal Assault
- bool _assaultEnabled;
- TimeTracker _flagAssaultTimer;
- uint16 _assaultStackCount;
-
- void DoForFlagKeepers(std::function<void(Player*)> action) const;
- void ResetAssaultDebuff();
- void ApplyAssaultDebuffToPlayer(Player* player);
- void RemoveAssaultDebuffFromPlayer(Player* player);
-};
-#endif
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp
deleted file mode 100644
index 639fa4510de..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "BattlegroundIC.h"
-#include "Creature.h"
-#include "GameObject.h"
-#include "Log.h"
-#include "Map.h"
-#include "ObjectMgr.h"
-#include "Player.h"
-#include "TemporarySummon.h"
-#include "Transport.h"
-#include "UnitAI.h"
-#include "Vehicle.h"
-
-enum IsleOfConquestPvpStats
-{
- PVP_STAT_BASES_ASSAULTED = 245,
- PVP_STAT_BASES_DEFENDED = 246
-};
-
-enum IsleOfConquestGameObjects
-{
- GO_TELEPORTER_1 = 195314, // 195314 H-OUT 66549
- GO_TELEPORTER_2 = 195313, // 195313 H-IN 66548
-
- GO_TELEPORTER_3 = 195315, // 195315 A-OUT 66549
- GO_TELEPORTER_4 = 195316, // 195316 A-IN 66548
-
- GO_TELEPORTER_EFFECTS_A = 195701,
- GO_TELEPORTER_EFFECTS_H = 195702,
-
- GO_DOODAD_HU_PORTCULLIS01 = 195436,
- GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01 = 195703,
- GO_DOODAD_PORTCULLISACTIVE02 = 195452,
- GO_DOODAD_VR_PORTCULLIS01 = 195437,
-
- GO_HORDE_GATE_1 = 195494,
- GO_HORDE_GATE_2 = 195495,
- GO_HORDE_GATE_3 = 195496,
-
- GO_ALLIANCE_GATE_1 = 195699,
- GO_ALLIANCE_GATE_2 = 195700,
- GO_ALLIANCE_GATE_3 = 195698,
-
- GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01 = 195491,
-
- // banners
- GO_BANNER_WORKSHOP_CONTROLLED_H = 195130,
- GO_BANNER_WORKSHOP_CONTROLLED_A = 195132,
- GO_BANNER_WORKSHOP_CONTROLLED_N = 195133,
- GO_BANNER_WORKSHOP_CONTESTED_A = 195144,
- GO_BANNER_WORKSHOP_CONTESTED_H = 195145,
-
- GO_BANNER_DOCKS_CONTROLLED_A = 195149,
- GO_BANNER_DOCKS_CONTESTED_A = 195150,
- GO_BANNER_DOCKS_CONTROLLED_H = 195151,
- GO_BANNER_DOCKS_CONTESTED_H = 195152,
- GO_BANNER_DOCKS_CONTROLLED_N = 195157,
-
- GO_BANNER_HANGAR_CONTROLLED_A = 195153,
- GO_BANNER_HANGAR_CONTESTED_A = 195154,
- GO_BANNER_HANGAR_CONTROLLED_H = 195155,
- GO_BANNER_HANGAR_CONTESTED_H = 195156,
- GO_BANNER_HANGAR_CONTROLLED_N = 195158,
-
- GO_BANNER_QUARRY_CONTROLLED_A = 195334,
- GO_BANNER_QUARRY_CONTROLLED_H = 195336,
- GO_BANNER_QUARRY_CONTESTED_A = 195335,
- GO_BANNER_QUARRY_CONTESTED_H = 195337,
- GO_BANNER_QUARRY_CONTROLLED_N = 195338,
-
- GO_BANNER_REFINERY_CONTROLLED_A = 195339,
- GO_BANNER_REFINERY_CONTROLLED_H = 195341,
- GO_BANNER_REFINERY_CONTESTED_A = 195340,
- GO_BANNER_REFINERY_CONTESTED_H = 195342,
- GO_BANNER_REFINERY_CONTROLLED_N = 195343,
-
- GO_BANNER_HORDE_KEEP_CONTROLLED_A = 195391,
- GO_BANNER_HORDE_KEEP_CONTROLLED_H = 195393,
- GO_BANNER_HORDE_KEEP_CONTESTED_A = 195392,
- GO_BANNER_HORDE_KEEP_CONTESTED_H = 195394,
-
- GO_BANNER_ALLIANCE_KEEP_CONTROLLED_A = 195396,
- GO_BANNER_ALLIANCE_KEEP_CONTROLLED_H = 195398,
- GO_BANNER_ALLIANCE_KEEP_CONTESTED_A = 195397,
- GO_BANNER_ALLIANCE_KEEP_CONTESTED_H = 195399,
-
- GO_KEEP_GATE_H = 195223,
- GO_KEEP_GATE_A = 195451,
- GO_KEEP_GATE_2_A = 195452,
-
- GO_HORDE_GUNSHIP = 195276,
- GO_ALLIANCE_GUNSHIP = 195121
-};
-
-static constexpr Seconds IOC_RESOURCE_TIMER = 45s;
-
-Position const GunshipTeleportTriggerPosition[2] =
-{
- { 11.69964981079101562f, 0.034145999699831008f, 20.62075996398925781f, 3.211405754089355468f },
- { 7.30560922622680664f, -0.09524600207805633f, 34.51021575927734375f, 3.159045934677124023f }
-};
-
-BattlegroundIC::BattlegroundIC(BattlegroundTemplate const* battlegroundTemplate) : Battleground(battlegroundTemplate)
-{
- _factionReinforcements = { MAX_REINFORCEMENTS, MAX_REINFORCEMENTS };
-
- _gateStatus = { BG_IC_GATE_OK, BG_IC_GATE_OK, BG_IC_GATE_OK, BG_IC_GATE_OK, BG_IC_GATE_OK, BG_IC_GATE_OK };
-
- _gunshipGUIDs = { };
- _cannonGUIDs = { };
- _nodePoints = { };
- _keepGateGUIDs = { };
- _keepBannerGUIDs = { };
-
- _nodePoints[NODE_TYPE_REFINERY] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::Neutral, nodePointInitial[NODE_TYPE_REFINERY]);
- _nodePoints[NODE_TYPE_QUARRY] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::Neutral, nodePointInitial[NODE_TYPE_QUARRY]);
- _nodePoints[NODE_TYPE_DOCKS] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::Neutral, nodePointInitial[NODE_TYPE_DOCKS]);
- _nodePoints[NODE_TYPE_HANGAR] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::Neutral, nodePointInitial[NODE_TYPE_HANGAR]);
- _nodePoints[NODE_TYPE_WORKSHOP] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::Neutral, nodePointInitial[NODE_TYPE_WORKSHOP]);
- _nodePoints[NODE_TYPE_GRAVEYARD_A] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::ControlledA, nodePointInitial[NODE_TYPE_GRAVEYARD_A]);
- _nodePoints[NODE_TYPE_GRAVEYARD_H] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::ControlledH, nodePointInitial[NODE_TYPE_GRAVEYARD_H]);
-
- _resourceTimer.Reset(IOC_RESOURCE_TIMER);
-}
-
-BattlegroundIC::~BattlegroundIC() = default;
-
-void BattlegroundIC::PostUpdateImpl(uint32 diff)
-{
- if (GetStatus() != STATUS_IN_PROGRESS)
- return;
-
- _scheduler.Update(diff);
- _resourceTimer.Update(diff);
- if (_resourceTimer.Passed())
- {
- for (uint8 i = 0; i < NODE_TYPE_DOCKS; ++i)
- {
- if (_nodePoints[i]->GetLastControlledTeam() != TEAM_NEUTRAL && !_nodePoints[i]->IsContested())
- {
- _factionReinforcements[_nodePoints[i]->GetLastControlledTeam()] += 1;
- RewardHonorToTeam(RESOURCE_HONOR_AMOUNT, _nodePoints[i]->GetLastControlledTeam() == TEAM_ALLIANCE ? ALLIANCE : HORDE);
- UpdateWorldState((_nodePoints[i]->GetLastControlledTeam() == TEAM_ALLIANCE ? BG_IC_ALLIANCE_REINFORCEMENTS : BG_IC_HORDE_REINFORCEMENTS), _factionReinforcements[_nodePoints[i]->GetLastControlledTeam()]);
- }
- }
-
- _resourceTimer.Reset(IOC_RESOURCE_TIMER);
- }
-}
-
-void BattlegroundIC::StartingEventOpenDoors()
-{
- auto gameobjectAction = [&](GuidVector const& guids, std::function<void(GameObject*)> const& action) -> void
- {
- for (ObjectGuid const& guid : guids)
- if (GameObject* gameObject = GetBgMap()->GetGameObject(guid))
- action(gameObject);
- };
-
- gameobjectAction(_mainGateDoorGUIDs, [&](GameObject* gameobject) -> void
- {
- gameobject->UseDoorOrButton();
- gameobject->DespawnOrUnsummon(20s);
- });
-
- gameobjectAction(_portcullisGUIDs, [&](GameObject* gameobject) -> void
- {
- gameobject->UseDoorOrButton();
- });
-
- gameobjectAction(_teleporterGUIDs, [&](GameObject* gameobject) -> void
- {
- gameobject->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
- });
-
- gameobjectAction(_teleporterEffectGUIDs, [&](GameObject* gameobject) -> void
- {
- gameobject->SetGoState(GO_STATE_ACTIVE);
- });
-
- _scheduler.Schedule(20s, [&](TaskContext)
- {
- for (ObjectGuid const& guid : _wallGUIDs)
- if (GameObject* gameobject = GetBgMap()->GetGameObject(guid))
- gameobject->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED);
- });
-}
-
-void BattlegroundIC::HandleKillUnit(Creature* unit, Unit* killer)
-{
- if (GetStatus() != STATUS_IN_PROGRESS)
- return;
-
- uint32 entry = unit->GetEntry();
- if (entry == NPC_HIGH_COMMANDER_HALFORD_WYRMBANE)
- {
- RewardHonorToTeam(WINNER_HONOR_AMOUNT, HORDE);
- EndBattleground(HORDE);
- }
- else if (entry == NPC_OVERLORD_AGMAR)
- {
- RewardHonorToTeam(WINNER_HONOR_AMOUNT, ALLIANCE);
- EndBattleground(ALLIANCE);
- }
-
- //Achievement Mowed Down
- // TO-DO: This should be done on the script of each vehicle of the BG.
- if (unit->IsVehicle())
- {
- if (Player* killerPlayer = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
- killerPlayer->CastSpell(killerPlayer, SPELL_DESTROYED_VEHICLE_ACHIEVEMENT, true);
- }
-}
-
-void BattlegroundIC::HandleKillPlayer(Player* player, Player* killer)
-{
- if (GetStatus() != STATUS_IN_PROGRESS)
- return;
-
- Battleground::HandleKillPlayer(player, killer);
-
- TeamId const victimTeamId = GetTeamIndexByTeamId(GetPlayerTeam(player->GetGUID()));
- _factionReinforcements[victimTeamId] -= 1;
-
- UpdateWorldState((GetPlayerTeam(player->GetGUID()) == ALLIANCE ? BG_IC_ALLIANCE_REINFORCEMENTS : BG_IC_HORDE_REINFORCEMENTS), _factionReinforcements[victimTeamId]);
-
- // we must end the battleground
- if (_factionReinforcements[victimTeamId] < 1)
- EndBattleground(GetPlayerTeam(killer->GetGUID()));
-}
-
-uint32 BattlegroundIC::GetGateIDFromEntry(uint32 id)
-{
- switch (id)
- {
- case GO_HORDE_GATE_1:
- return BG_IC_H_FRONT;
- case GO_HORDE_GATE_2:
- return BG_IC_H_WEST;
- case GO_HORDE_GATE_3:
- return BG_IC_H_EAST;
- case GO_ALLIANCE_GATE_3:
- return BG_IC_A_FRONT;
- case GO_ALLIANCE_GATE_1:
- return BG_IC_A_WEST;
- case GO_ALLIANCE_GATE_2:
- return BG_IC_A_EAST;
- default:
- return 0;
- }
-}
-
-int32 BattlegroundIC::GetWorldStateFromGateEntry(uint32 id, bool open)
-{
- int32 uws = 0;
-
- switch (id)
- {
- case GO_HORDE_GATE_1:
- uws = (open ? BG_IC_GATE_FRONT_H_WS_OPEN : BG_IC_GATE_FRONT_H_WS_CLOSED);
- break;
- case GO_HORDE_GATE_2:
- uws = (open ? BG_IC_GATE_WEST_H_WS_OPEN : BG_IC_GATE_WEST_H_WS_CLOSED);
- break;
- case GO_HORDE_GATE_3:
- uws = (open ? BG_IC_GATE_EAST_H_WS_OPEN : BG_IC_GATE_EAST_H_WS_CLOSED);
- break;
- case GO_ALLIANCE_GATE_3:
- uws = (open ? BG_IC_GATE_FRONT_A_WS_OPEN : BG_IC_GATE_FRONT_A_WS_CLOSED);
- break;
- case GO_ALLIANCE_GATE_1:
- uws = (open ? BG_IC_GATE_WEST_A_WS_OPEN : BG_IC_GATE_WEST_A_WS_CLOSED);
- break;
- case GO_ALLIANCE_GATE_2:
- uws = (open ? BG_IC_GATE_EAST_A_WS_OPEN : BG_IC_GATE_EAST_A_WS_CLOSED);
- break;
- default:
- break;
- }
- return uws;
-}
-
-void BattlegroundIC::UpdateNodeWorldState(ICNodePoint const& node)
-{
- UpdateWorldState(node.GetNodeInfo().WorldStateIds.ConflictA, node.GetState() == IsleOfConquestNodeState::ConflictA);
- UpdateWorldState(node.GetNodeInfo().WorldStateIds.ConflictH, node.GetState() == IsleOfConquestNodeState::ConflictH);
- UpdateWorldState(node.GetNodeInfo().WorldStateIds.ControlledA, node.GetState() == IsleOfConquestNodeState::ControlledA);
- UpdateWorldState(node.GetNodeInfo().WorldStateIds.ControlledH, node.GetState() == IsleOfConquestNodeState::ControlledH);
- UpdateWorldState(node.GetNodeInfo().WorldStateIds.Uncontrolled, node.GetState() == IsleOfConquestNodeState::Neutral);
-}
-
-ICNodePointType BattlegroundIC::BannerToNodeType(uint32 bannerId)
-{
- switch (bannerId)
- {
- case GO_BANNER_ALLIANCE_KEEP_CONTESTED_A:
- case GO_BANNER_ALLIANCE_KEEP_CONTESTED_H:
- case GO_BANNER_ALLIANCE_KEEP_CONTROLLED_A:
- case GO_BANNER_ALLIANCE_KEEP_CONTROLLED_H:
- return NODE_TYPE_GRAVEYARD_A;
- case GO_BANNER_HORDE_KEEP_CONTESTED_A:
- case GO_BANNER_HORDE_KEEP_CONTESTED_H:
- case GO_BANNER_HORDE_KEEP_CONTROLLED_A:
- case GO_BANNER_HORDE_KEEP_CONTROLLED_H:
- return NODE_TYPE_GRAVEYARD_H;
- case GO_BANNER_DOCKS_CONTESTED_A:
- case GO_BANNER_DOCKS_CONTESTED_H:
- case GO_BANNER_DOCKS_CONTROLLED_A:
- case GO_BANNER_DOCKS_CONTROLLED_H:
- case GO_BANNER_DOCKS_CONTROLLED_N:
- return NODE_TYPE_DOCKS;
- case GO_BANNER_HANGAR_CONTESTED_A:
- case GO_BANNER_HANGAR_CONTESTED_H:
- case GO_BANNER_HANGAR_CONTROLLED_A:
- case GO_BANNER_HANGAR_CONTROLLED_H:
- case GO_BANNER_HANGAR_CONTROLLED_N:
- return NODE_TYPE_HANGAR;
- case GO_BANNER_WORKSHOP_CONTESTED_A:
- case GO_BANNER_WORKSHOP_CONTESTED_H:
- case GO_BANNER_WORKSHOP_CONTROLLED_A:
- case GO_BANNER_WORKSHOP_CONTROLLED_H:
- case GO_BANNER_WORKSHOP_CONTROLLED_N:
- return NODE_TYPE_WORKSHOP;
- case GO_BANNER_QUARRY_CONTESTED_A:
- case GO_BANNER_QUARRY_CONTESTED_H:
- case GO_BANNER_QUARRY_CONTROLLED_A:
- case GO_BANNER_QUARRY_CONTROLLED_H:
- case GO_BANNER_QUARRY_CONTROLLED_N:
- return NODE_TYPE_QUARRY;
- case GO_BANNER_REFINERY_CONTESTED_A:
- case GO_BANNER_REFINERY_CONTESTED_H:
- case GO_BANNER_REFINERY_CONTROLLED_A:
- case GO_BANNER_REFINERY_CONTROLLED_H:
- case GO_BANNER_REFINERY_CONTROLLED_N:
- return NODE_TYPE_REFINERY;
- default:
- break;
- }
-
- return MAX_NODE_TYPES;
-}
-
-void BattlegroundIC::HandleCapturedNodes(ICNodePoint& node)
-{
- if (node.GetLastControlledTeam() == TEAM_NEUTRAL)
- return;
-
- switch (node.GetNodeInfo().NodeType)
- {
- case NODE_TYPE_QUARRY:
- case NODE_TYPE_REFINERY:
- GetBgMap()->UpdateAreaDependentAuras();
- break;
- case NODE_TYPE_HANGAR:
- if (Transport* transport = GetBgMap()->GetTransport(_gunshipGUIDs[node.GetLastControlledTeam()]))
- {
- // Can't have this in spawngroup, creature is on a transport
- if (TempSummon* trigger = transport->SummonPassenger(NPC_WORLD_TRIGGER_NOT_FLOATING, GunshipTeleportTriggerPosition[node.GetLastControlledTeam()], TEMPSUMMON_MANUAL_DESPAWN))
- _gunshipTeleportTarget = trigger->GetGUID();
-
- transport->EnableMovement(true);
- }
-
- for (ObjectGuid const& guid : _cannonGUIDs[node.GetLastControlledTeam()])
- if (Creature* cannon = GetBgMap()->GetCreature(guid))
- cannon->SetUninteractible(false);
- break;
- default:
- break;
- }
-}
-
-WorldSafeLocsEntry const* BattlegroundIC::GetExploitTeleportLocation(Team team)
-{
- return sObjectMgr->GetWorldSafeLoc(team == ALLIANCE ? IC_EXPLOIT_TELEPORT_LOCATION_ALLIANCE : IC_EXPLOIT_TELEPORT_LOCATION_HORDE);
-}
-
-void BattlegroundIC::OnCreatureCreate(Creature* creature)
-{
- Battleground::OnCreatureCreate(creature);
- if (creature->HasStringId("bg_ioc_faction_1735"))
- creature->SetFaction(FACTION_HORDE_GENERIC_WG);
- else if (creature->HasStringId("bg_ioc_faction_1732"))
- creature->SetFaction(FACTION_ALLIANCE_GENERIC_WG);
-
- switch (creature->GetEntry())
- {
- case NPC_ALLIANCE_GUNSHIP_CANNON:
- _cannonGUIDs[TEAM_ALLIANCE].emplace_back(creature->GetGUID());
- creature->SetUninteractible(true);
- creature->SetControlled(true, UNIT_STATE_ROOT);
- break;
- case NPC_HORDE_GUNSHIP_CANNON:
- _cannonGUIDs[TEAM_HORDE].emplace_back(creature->GetGUID());
- creature->SetUninteractible(true);
- creature->SetControlled(true, UNIT_STATE_ROOT);
- break;
- default:
- break;
- }
-}
-
-void BattlegroundIC::OnGameObjectCreate(GameObject* gameobject)
-{
- Battleground::OnGameObjectCreate(gameobject);
-
- if (gameobject->IsDestructibleBuilding())
- _wallGUIDs.emplace_back(gameobject->GetGUID());
-
- if (gameobject->HasStringId("bg_ioc_faction_1735"))
- gameobject->SetFaction(FACTION_HORDE_GENERIC_WG);
- else if (gameobject->HasStringId("bg_ioc_faction_1732"))
- gameobject->SetFaction(FACTION_ALLIANCE_GENERIC_WG);
-
- switch (gameobject->GetEntry())
- {
- case GO_TELEPORTER_1:
- case GO_TELEPORTER_2:
- case GO_TELEPORTER_3:
- case GO_TELEPORTER_4:
- _teleporterGUIDs.emplace_back(gameobject->GetGUID());
- break;
- case GO_TELEPORTER_EFFECTS_A:
- case GO_TELEPORTER_EFFECTS_H:
- _teleporterEffectGUIDs.emplace_back(gameobject->GetGUID());
- break;
- case GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01:
- case GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01:
- _mainGateDoorGUIDs.emplace_back(gameobject->GetGUID());
- break;
- case GO_DOODAD_HU_PORTCULLIS01:
- case GO_DOODAD_VR_PORTCULLIS01:
- _portcullisGUIDs.emplace_back(gameobject->GetGUID());
- break;
- case GO_KEEP_GATE_H:
- _keepGateGUIDs[TEAM_HORDE].emplace_back(gameobject->GetGUID());
- break;
- case GO_KEEP_GATE_A:
- case GO_KEEP_GATE_2_A:
- _keepGateGUIDs[TEAM_ALLIANCE].emplace_back(gameobject->GetGUID());
- break;
- case GO_BANNER_ALLIANCE_KEEP_CONTROLLED_A:
- _keepBannerGUIDs[TEAM_ALLIANCE] = gameobject->GetGUID();
- break;
- case GO_BANNER_HORDE_KEEP_CONTROLLED_H:
- _keepBannerGUIDs[TEAM_HORDE] = gameobject->GetGUID();
- break;
- default:
- break;
- }
-}
-
-void BattlegroundIC::OnMapSet(BattlegroundMap* map)
-{
- Battleground::OnMapSet(map);
-
- if (Transport* transport = sTransportMgr->CreateTransport(GO_HORDE_GUNSHIP, map))
- {
- _gunshipGUIDs[TEAM_HORDE] = transport->GetGUID();
- transport->EnableMovement(false);
- }
-
- if (Transport* transport = sTransportMgr->CreateTransport(GO_ALLIANCE_GUNSHIP, map))
- {
- _gunshipGUIDs[TEAM_ALLIANCE] = transport->GetGUID();
- transport->EnableMovement(false);
- }
-}
-
-void BattlegroundIC::DoAction(uint32 actionId, WorldObject* source, WorldObject* target)
-{
-
- switch (actionId)
- {
- case ACTION_IOC_INTERACT_CAPTURABLE_OBJECT:
- OnPlayerInteractWithBanner(WorldObject::ToPlayer(source), WorldObject::ToGameObject(target));
- break;
- case ACTION_IOC_CAPTURE_CAPTURABLE_OBJECT:
- HandleCaptureNodeAction(WorldObject::ToGameObject(target));
- break;
- default:
- break;
- }
-}
-
-void BattlegroundIC::OnPlayerInteractWithBanner(Player* player, GameObject* banner)
-{
- if (!player || !banner)
- return;
-
- Team const playerTeam = GetPlayerTeam(player->GetGUID());
- TeamId const playerTeamId = GetTeamIndexByTeamId(playerTeam);
- ICNodePointType const nodeType = BannerToNodeType(banner->GetEntry());
- if (nodeType == MAX_NODE_TYPES)
- return;
-
- ICNodePoint& node = *_nodePoints[nodeType];
-
- bool assault = false;
- bool defend = false;
-
- switch (node.GetState())
- {
- case IsleOfConquestNodeState::Neutral:
- assault = true;
- break;
- case IsleOfConquestNodeState::ControlledH:
- assault = playerTeamId != TEAM_HORDE;
- break;
- case IsleOfConquestNodeState::ControlledA:
- assault = playerTeamId != TEAM_ALLIANCE;
- break;
- case IsleOfConquestNodeState::ConflictA:
- defend = playerTeamId == node.GetLastControlledTeam();
- assault = !defend && playerTeamId == TEAM_HORDE;
- break;
- case IsleOfConquestNodeState::ConflictH:
- defend = playerTeamId == node.GetLastControlledTeam();
- assault = !defend && playerTeamId == TEAM_ALLIANCE;
- break;
- }
-
- if (assault)
- OnPlayerAssaultNode(player, node);
- else if (defend)
- OnPlayerDefendNode(player, node);
-
- GetBgMap()->UpdateSpawnGroupConditions();
-}
-
-void BattlegroundIC::OnPlayerAssaultNode(Player* player, ICNodePoint& node)
-{
- if (!player)
- return;
-
- Team const playerTeam = GetPlayerTeam(player->GetGUID());
- TeamId const playerTeamId = GetTeamIndexByTeamId(playerTeam);
-
- IsleOfConquestNodeState const newState = playerTeamId == TEAM_HORDE ? IsleOfConquestNodeState::ConflictH : IsleOfConquestNodeState::ConflictA;
- node.UpdateState(newState);
-
- UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
-
- ChatMsg const messageType = playerTeamId == TEAM_ALLIANCE ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE;
- SendBroadcastText(node.GetNodeInfo().TextIds.Assaulted, messageType, player);
- UpdateNodeWorldState(node);
-
- // apply side effects of each node, only if it wasn't neutral before
- if (node.GetLastControlledTeam() == TEAM_NEUTRAL)
- return;
-
- switch (node.GetNodeInfo().NodeType)
- {
- case NODE_TYPE_HANGAR:
- if (Transport* transport = GetBgMap()->GetTransport(_gunshipGUIDs[node.GetLastControlledTeam()]))
- transport->EnableMovement(false);
-
- for (ObjectGuid const& guid : _cannonGUIDs[node.GetLastControlledTeam()])
- {
- if (Creature* cannon = GetBgMap()->GetCreature(guid))
- {
- cannon->GetVehicleKit()->RemoveAllPassengers();
- cannon->SetUninteractible(true);
- }
- }
-
- // Despawn teleport trigger target
- if (Creature* creature = FindBgMap()->GetCreature(_gunshipTeleportTarget))
- creature->DespawnOrUnsummon();
- break;
- default:
- break;
- }
-}
-
-void BattlegroundIC::OnPlayerDefendNode(Player* player, ICNodePoint& node)
-{
- if (!player)
- return;
-
- Team const playerTeam = GetPlayerTeam(player->GetGUID());
- TeamId const playerTeamId = GetTeamIndexByTeamId(playerTeam);
-
- node.UpdateState(playerTeamId == TEAM_HORDE ? IsleOfConquestNodeState::ControlledH : IsleOfConquestNodeState::ControlledA);
- HandleCapturedNodes(node);
- UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
-
- ChatMsg const messageType = playerTeamId == TEAM_ALLIANCE ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE;
- SendBroadcastText(node.GetNodeInfo().TextIds.Defended, messageType, player);
- UpdateNodeWorldState(node);
-}
-
-void BattlegroundIC::ProcessEvent(WorldObject* target, uint32 eventId, WorldObject* invoker)
-{
- Battleground::ProcessEvent(target, eventId, invoker);
-
- if (GameObject* obj = Object::ToGameObject(target))
- if (obj->GetGoType() == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
- if (obj->GetGOInfo()->destructibleBuilding.DestroyedEvent == eventId)
- OnGateDestroyed(obj, invoker);
-}
-
-void BattlegroundIC::HandleCaptureNodeAction(GameObject* banner)
-{
- if (!banner)
- return;
-
- ICNodePointType const nodeType = BannerToNodeType(banner->GetEntry());
- if (nodeType == MAX_NODE_TYPES)
- return;
-
- ICNodePoint& node = *_nodePoints[nodeType];
- if (node.GetState() == IsleOfConquestNodeState::ConflictH)
- node.UpdateState(IsleOfConquestNodeState::ControlledH);
- else if (node.GetState() == IsleOfConquestNodeState::ConflictA)
- node.UpdateState(IsleOfConquestNodeState::ControlledA);
-
- HandleCapturedNodes(node);
-
- ChatMsg const messageType = node.GetLastControlledTeam() == TEAM_ALLIANCE ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE;
- uint32 const textId = node.GetLastControlledTeam() == TEAM_ALLIANCE ? node.GetNodeInfo().TextIds.AllianceTaken : node.GetNodeInfo().TextIds.HordeTaken;
- SendBroadcastText(textId, messageType);
- UpdateNodeWorldState(node);
-}
-
-void BattlegroundIC::OnGateDestroyed(GameObject* gate, WorldObject* destroyer)
-{
- _gateStatus[GetGateIDFromEntry(gate->GetEntry())] = BG_IC_GATE_DESTROYED;
- int32 const wsGateOpen = GetWorldStateFromGateEntry(gate->GetEntry(), true);
- int32 const wsGateClosed = GetWorldStateFromGateEntry(gate->GetEntry(), false);
- if (wsGateOpen)
- {
- UpdateWorldState(wsGateClosed, 0);
- UpdateWorldState(wsGateOpen, 1);
- }
-
- TeamId teamId = TEAM_NEUTRAL;
- uint32 textId;
- ChatMsg msgType;
- switch (gate->GetEntry())
- {
- case GO_HORDE_GATE_1:
- textId = BG_IC_TEXT_FRONT_GATE_HORDE_DESTROYED;
- msgType = CHAT_MSG_BG_SYSTEM_ALLIANCE;
- teamId = TEAM_HORDE;
- break;
- case GO_HORDE_GATE_2:
- textId = BG_IC_TEXT_WEST_GATE_HORDE_DESTROYED;
- msgType = CHAT_MSG_BG_SYSTEM_ALLIANCE;
- teamId = TEAM_HORDE;
- break;
- case GO_HORDE_GATE_3:
- textId = BG_IC_TEXT_EAST_GATE_HORDE_DESTROYED;
- msgType = CHAT_MSG_BG_SYSTEM_ALLIANCE;
- teamId = TEAM_HORDE;
- break;
- case GO_ALLIANCE_GATE_1:
- textId = BG_IC_TEXT_WEST_GATE_ALLIANCE_DESTROYED;
- msgType = CHAT_MSG_BG_SYSTEM_HORDE;
- teamId = TEAM_ALLIANCE;
- break;
- case GO_ALLIANCE_GATE_2:
- textId = BG_IC_TEXT_EAST_GATE_ALLIANCE_DESTROYED;
- msgType = CHAT_MSG_BG_SYSTEM_HORDE;
- teamId = TEAM_ALLIANCE;
- break;
- case GO_ALLIANCE_GATE_3:
- textId = BG_IC_TEXT_FRONT_GATE_ALLIANCE_DESTROYED;
- msgType = CHAT_MSG_BG_SYSTEM_HORDE;
- teamId = TEAM_ALLIANCE;
- break;
- default:
- return;
- }
-
- if (teamId != TEAM_NEUTRAL)
- {
- GuidVector const keepGates = _keepGateGUIDs[teamId];
- ObjectGuid const bannerGuid = _keepBannerGUIDs[teamId];
-
- for (ObjectGuid const& guid : keepGates)
- if (GameObject* keepGate = GetBgMap()->GetGameObject(guid))
- keepGate->UseDoorOrButton();
-
- if (GameObject* banner = GetBgMap()->GetGameObject(bannerGuid))
- banner->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
- }
-
- SendBroadcastText(textId, msgType, destroyer);
-}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h
deleted file mode 100644
index c7d47d90d1f..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __BATTLEGROUNDIC_H
-#define __BATTLEGROUNDIC_H
-
-#include "Battleground.h"
-#include "Object.h"
-#include "TaskScheduler.h"
-#include "Timer.h"
-
-const uint32 BG_IC_Factions[2] =
-{
- 1732, // Alliance
- 1735 // Horde
-};
-
-enum creaturesIC
-{
- NPC_HIGH_COMMANDER_HALFORD_WYRMBANE = 34924, // Alliance Boss
- NPC_OVERLORD_AGMAR = 34922, // Horde Boss
- NPC_KOR_KRON_GUARD = 34918, // horde guard
- NPC_SEVEN_TH_LEGION_INFANTRY = 34919, // alliance guard
- NPC_KEEP_CANNON = 34944,
- NPC_DEMOLISHER = 34775,
- NPC_SIEGE_ENGINE_H = 35069,
- NPC_SIEGE_ENGINE_A = 34776,
- NPC_GLAIVE_THROWER_A = 34802,
- NPC_GLAIVE_THROWER_H = 35273,
- NPC_CATAPULT = 34793,
- NPC_HORDE_GUNSHIP_CANNON = 34935,
- NPC_ALLIANCE_GUNSHIP_CANNON = 34929,
- NPC_HORDE_GUNSHIP_CAPTAIN = 35003,
- NPC_ALLIANCE_GUNSHIP_CAPTAIN = 34960,
- NPC_WORLD_TRIGGER_NOT_FLOATING = 34984,
- NPC_WORLD_TRIGGER_ALLIANCE_FRIENDLY = 20213,
- NPC_WORLD_TRIGGER_HORDE_FRIENDLY = 20212
-};
-
-#define MAX_REINFORCEMENTS 400
-
-enum Actions
-{
- ACTION_GUNSHIP_READY = 1,
- ACTION_IOC_INTERACT_CAPTURABLE_OBJECT = 2,
- ACTION_IOC_CAPTURE_CAPTURABLE_OBJECT = 3
-};
-
-enum BannersTypes
-{
- BANNER_A_CONTROLLED,
- BANNER_A_CONTESTED,
- BANNER_H_CONTROLLED,
- BANNER_H_CONTESTED
-};
-
-enum BG_IC_ExploitTeleportLocations
-{
- IC_EXPLOIT_TELEPORT_LOCATION_ALLIANCE = 3986,
- IC_EXPLOIT_TELEPORT_LOCATION_HORDE = 3983
-};
-
-enum Spells
-{
- SPELL_OIL_REFINERY = 68719,
- SPELL_QUARRY = 68720,
- SPELL_PARACHUTE = 66656,
- SPELL_SLOW_FALL = 12438,
- SPELL_DESTROYED_VEHICLE_ACHIEVEMENT = 68357,
- SPELL_BACK_DOOR_JOB_ACHIEVEMENT = 68502,
- SPELL_DRIVING_CREDIT_DEMOLISHER = 68365,
- SPELL_DRIVING_CREDIT_GLAIVE = 68363,
- SPELL_DRIVING_CREDIT_SIEGE = 68364,
- SPELL_DRIVING_CREDIT_CATAPULT = 68362,
- SPELL_SIMPLE_TELEPORT = 12980,
- SPELL_TELEPORT_VISUAL_ONLY = 51347,
- SPELL_PARACHUTE_IC = 66657,
- SPELL_LAUNCH_NO_FALLING_DAMAGE = 66251
-};
-
-enum ICWorldStates
-{
- BG_IC_ALLIANCE_REINFORCEMENTS_SET = 4221,
- BG_IC_HORDE_REINFORCEMENTS_SET = 4222,
- BG_IC_ALLIANCE_REINFORCEMENTS = 4226,
- BG_IC_HORDE_REINFORCEMENTS = 4227,
- BG_IC_MAX_REINFORCEMENTS = 17377,
-
- BG_IC_GATE_FRONT_H_WS_CLOSED = 4317,
- BG_IC_GATE_WEST_H_WS_CLOSED = 4318,
- BG_IC_GATE_EAST_H_WS_CLOSED = 4319,
- BG_IC_GATE_FRONT_A_WS_CLOSED = 4328,
- BG_IC_GATE_WEST_A_WS_CLOSED = 4327,
- BG_IC_GATE_EAST_A_WS_CLOSED = 4326,
- BG_IC_GATE_FRONT_H_WS_OPEN = 4322,
- BG_IC_GATE_WEST_H_WS_OPEN = 4321,
- BG_IC_GATE_EAST_H_WS_OPEN = 4320,
- BG_IC_GATE_FRONT_A_WS_OPEN = 4323,
- BG_IC_GATE_WEST_A_WS_OPEN = 4324,
- BG_IC_GATE_EAST_A_WS_OPEN = 4325,
-
- BG_IC_DOCKS_UNCONTROLLED = 4301,
- BG_IC_DOCKS_CONFLICT_A = 4305,
- BG_IC_DOCKS_CONFLICT_H = 4302,
- BG_IC_DOCKS_CONTROLLED_A = 4304,
- BG_IC_DOCKS_CONTROLLED_H = 4303,
-
- BG_IC_HANGAR_UNCONTROLLED = 4296,
- BG_IC_HANGAR_CONFLICT_A = 4300,
- BG_IC_HANGAR_CONFLICT_H = 4297,
- BG_IC_HANGAR_CONTROLLED_A = 4299,
- BG_IC_HANGAR_CONTROLLED_H = 4298,
-
- BG_IC_QUARRY_UNCONTROLLED = 4306,
- BG_IC_QUARRY_CONFLICT_A = 4310,
- BG_IC_QUARRY_CONFLICT_H = 4307,
- BG_IC_QUARRY_CONTROLLED_A = 4309,
- BG_IC_QUARRY_CONTROLLED_H = 4308,
-
- BG_IC_REFINERY_UNCONTROLLED = 4311,
- BG_IC_REFINERY_CONFLICT_A = 4315,
- BG_IC_REFINERY_CONFLICT_H = 4312,
- BG_IC_REFINERY_CONTROLLED_A = 4314,
- BG_IC_REFINERY_CONTROLLED_H = 4313,
-
- BG_IC_WORKSHOP_UNCONTROLLED = 4294,
- BG_IC_WORKSHOP_CONFLICT_A = 4228,
- BG_IC_WORKSHOP_CONFLICT_H = 4293,
- BG_IC_WORKSHOP_CONTROLLED_A = 4229,
- BG_IC_WORKSHOP_CONTROLLED_H = 4230,
-
- BG_IC_ALLIANCE_KEEP_UNCONTROLLED = 4341,
- BG_IC_ALLIANCE_KEEP_CONFLICT_A = 4342,
- BG_IC_ALLIANCE_KEEP_CONFLICT_H = 4343,
- BG_IC_ALLIANCE_KEEP_CONTROLLED_A = 4339,
- BG_IC_ALLIANCE_KEEP_CONTROLLED_H = 4340,
-
- BG_IC_HORDE_KEEP_UNCONTROLLED = 4346,
- BG_IC_HORDE_KEEP_CONFLICT_A = 4347,
- BG_IC_HORDE_KEEP_CONFLICT_H = 4348,
- BG_IC_HORDE_KEEP_CONTROLLED_A = 4344,
- BG_IC_HORDE_KEEP_CONTROLLED_H = 4345
-};
-
-enum BG_IC_GateState
-{
- BG_IC_GATE_OK = 1,
- BG_IC_GATE_DAMAGED = 2,
- BG_IC_GATE_DESTROYED = 3
-};
-
-enum ICDoorList
-{
- BG_IC_H_FRONT,
- BG_IC_H_WEST,
- BG_IC_H_EAST,
- BG_IC_A_FRONT,
- BG_IC_A_WEST,
- BG_IC_A_EAST,
- BG_IC_MAXDOOR
-};
-
-enum ICNodePointType
-{
- NODE_TYPE_REFINERY,
- NODE_TYPE_QUARRY,
- NODE_TYPE_DOCKS,
- NODE_TYPE_HANGAR,
- NODE_TYPE_WORKSHOP,
-
- // Graveyards
- NODE_TYPE_GRAVEYARD_A,
- NODE_TYPE_GRAVEYARD_H,
-
- MAX_NODE_TYPES
-};
-
-enum class IsleOfConquestNodeState
-{
- Neutral,
- ConflictA,
- ConflictH,
- ControlledA,
- ControlledH
-};
-
-Position const BG_IC_SpiritGuidePos[MAX_NODE_TYPES+2] =
-{
- {0.0f, 0.0f, 0.0f, 0.0f}, // no grave
- {0.0f, 0.0f, 0.0f, 0.0f}, // no grave
- {629.57f, -279.83f, 11.33f, 0.0f}, // dock
- {780.729f, -1103.08f, 135.51f, 2.27f}, // hangar
- {775.74f, -652.77f, 9.31f, 4.27f}, // workshop
- {278.42f, -883.20f, 49.89f, 1.53f}, // alliance starting base
- {1300.91f, -834.04f, 48.91f, 1.69f}, // horde starting base
- {438.86f, -310.04f, 51.81f, 5.87f}, // last resort alliance
- {1148.65f, -1250.98f, 16.60f, 1.74f}, // last resort horde
-};
-
-enum ICBroadcastTexts
-{
- BG_IC_TEXT_FRONT_GATE_HORDE_DESTROYED = 35409,
- BG_IC_TEXT_FRONT_GATE_ALLIANCE_DESTROYED = 35410,
- BG_IC_TEXT_WEST_GATE_HORDE_DESTROYED = 35411,
- BG_IC_TEXT_WEST_GATE_ALLIANCE_DESTROYED = 35412,
- BG_IC_TEXT_EAST_GATE_HORDE_DESTROYED = 35413,
- BG_IC_TEXT_EAST_GATE_ALLIANCE_DESTROYED = 35414
-};
-
-// I.E: Hangar, Quarry, Graveyards .. etc
-struct IoCStaticNodeInfo
-{
- ICNodePointType NodeType;
-
- struct
- {
- uint32 Assaulted;
- uint32 Defended;
- uint32 AllianceTaken;
- uint32 HordeTaken;
- } TextIds;
-
- struct
- {
- int32 Uncontrolled;
- int32 ConflictA;
- int32 ConflictH;
- int32 ControlledA;
- int32 ControlledH;
- } WorldStateIds;
-};
-
-class ICNodePoint
-{
-public:
- explicit ICNodePoint(IsleOfConquestNodeState state, IoCStaticNodeInfo const& nodeInfo) : _state(state), _nodeInfo(nodeInfo)
- {
- switch (state)
- {
- case IsleOfConquestNodeState::ControlledH:
- _lastControlled = TEAM_HORDE;
- break;
- case IsleOfConquestNodeState::ControlledA:
- _lastControlled = TEAM_ALLIANCE;
- break;
- case IsleOfConquestNodeState::ConflictA:
- case IsleOfConquestNodeState::ConflictH:
- case IsleOfConquestNodeState::Neutral:
- _lastControlled = TEAM_NEUTRAL;
- break;
- }
- }
-
- IsleOfConquestNodeState GetState() const { return _state; }
-
- bool IsContested() const
- {
- return _state == IsleOfConquestNodeState::ConflictA || _state == IsleOfConquestNodeState::ConflictH;
- }
-
- TeamId GetLastControlledTeam() const { return _lastControlled; }
-
- IoCStaticNodeInfo const& GetNodeInfo() const { return _nodeInfo; }
-
- void UpdateState(IsleOfConquestNodeState state)
- {
- switch (state)
- {
- case IsleOfConquestNodeState::ControlledA:
- _lastControlled = TEAM_ALLIANCE;
- break;
- case IsleOfConquestNodeState::ControlledH:
- _lastControlled = TEAM_HORDE;
- break;
- case IsleOfConquestNodeState::Neutral:
- _lastControlled = TEAM_NEUTRAL;
- break;
- case IsleOfConquestNodeState::ConflictA:
- case IsleOfConquestNodeState::ConflictH:
- break;
- }
-
- _state = state;
- }
-private:
- IsleOfConquestNodeState _state;
- TeamId _lastControlled;
- IoCStaticNodeInfo _nodeInfo;
-};
-
-const IoCStaticNodeInfo nodePointInitial[MAX_NODE_TYPES] =
-{
- { NODE_TYPE_REFINERY, { 35377, 35378, 35379, 35380 }, { BG_IC_REFINERY_UNCONTROLLED, BG_IC_REFINERY_CONFLICT_A, BG_IC_REFINERY_CONFLICT_H, BG_IC_REFINERY_CONTROLLED_A, BG_IC_REFINERY_CONTROLLED_H } },
- { NODE_TYPE_QUARRY, { 35373, 35374, 35375, 35376 }, { BG_IC_QUARRY_UNCONTROLLED, BG_IC_QUARRY_CONFLICT_A, BG_IC_QUARRY_CONFLICT_H, BG_IC_QUARRY_CONTROLLED_A, BG_IC_QUARRY_CONTROLLED_H } },
- { NODE_TYPE_DOCKS, { 35365, 35366, 35367, 35368 }, { BG_IC_DOCKS_UNCONTROLLED, BG_IC_DOCKS_CONFLICT_A, BG_IC_DOCKS_CONFLICT_H, BG_IC_DOCKS_CONTROLLED_A, BG_IC_DOCKS_CONTROLLED_H } },
- { NODE_TYPE_HANGAR, { 35369, 35370, 35371, 35372 }, { BG_IC_HANGAR_UNCONTROLLED, BG_IC_HANGAR_CONFLICT_A, BG_IC_HANGAR_CONFLICT_H, BG_IC_HANGAR_CONTROLLED_A, BG_IC_HANGAR_CONTROLLED_H } },
- { NODE_TYPE_WORKSHOP, { 35278, 35286, 35279, 35280 }, { BG_IC_WORKSHOP_UNCONTROLLED, BG_IC_WORKSHOP_CONFLICT_A, BG_IC_WORKSHOP_CONFLICT_H, BG_IC_WORKSHOP_CONTROLLED_A, BG_IC_WORKSHOP_CONTROLLED_H } },
- { NODE_TYPE_GRAVEYARD_A, { 35461, 35459, 35463, 35466 }, { BG_IC_ALLIANCE_KEEP_UNCONTROLLED, BG_IC_ALLIANCE_KEEP_CONFLICT_A, BG_IC_ALLIANCE_KEEP_CONFLICT_H, BG_IC_ALLIANCE_KEEP_CONTROLLED_A, BG_IC_ALLIANCE_KEEP_CONTROLLED_H } },
- { NODE_TYPE_GRAVEYARD_H, { 35462, 35460, 35464, 35465 }, { BG_IC_HORDE_KEEP_UNCONTROLLED, BG_IC_HORDE_KEEP_CONFLICT_A, BG_IC_HORDE_KEEP_CONFLICT_H, BG_IC_HORDE_KEEP_CONTROLLED_A, BG_IC_HORDE_KEEP_CONTROLLED_H } }
-};
-
-enum HonorRewards
-{
- RESOURCE_HONOR_AMOUNT = 12,
- WINNER_HONOR_AMOUNT = 500
-};
-
-class BattlegroundIC : public Battleground
-{
- public:
- BattlegroundIC(BattlegroundTemplate const* battlegroundTemplate);
- ~BattlegroundIC() override;
-
- /* inherited from BattlegroundClass */
- void StartingEventOpenDoors() override;
- void PostUpdateImpl(uint32 diff) override;
-
- void HandleKillUnit(Creature* unit, Unit* killer) override;
- void HandleKillPlayer(Player* player, Player* killer) override;
-
- WorldSafeLocsEntry const* GetExploitTeleportLocation(Team team) override;
-
- void OnCreatureCreate(Creature* creature) override;
- void OnGameObjectCreate(GameObject* gameobject) override;
- void OnMapSet(BattlegroundMap* map) override;
-
- void DoAction(uint32 actionId, WorldObject* source, WorldObject* target) override;
- void OnPlayerInteractWithBanner(Player* player, GameObject* banner);
- void OnPlayerAssaultNode(Player* player, ICNodePoint& node);
- void OnPlayerDefendNode(Player* player, ICNodePoint& node);
- void ProcessEvent(WorldObject* target, uint32 eventId, WorldObject* invoker) override;
-
- private:
- std::array<uint16, PVP_TEAMS_COUNT> _factionReinforcements;
- std::array<BG_IC_GateState, 6> _gateStatus;
- std::array<std::unique_ptr<ICNodePoint>, 7> _nodePoints;
- std::array<ObjectGuid, PVP_TEAMS_COUNT> _gunshipGUIDs;
- GuidVector _teleporterGUIDs;
- GuidVector _teleporterEffectGUIDs;
- GuidVector _mainGateDoorGUIDs;
- GuidVector _portcullisGUIDs;
- GuidVector _wallGUIDs;
- std::array<GuidVector, PVP_TEAMS_COUNT> _cannonGUIDs;
- std::array<GuidVector, PVP_TEAMS_COUNT> _keepGateGUIDs;
- std::array<ObjectGuid, PVP_TEAMS_COUNT> _keepBannerGUIDs;
- ObjectGuid _gunshipTeleportTarget;
-
- TaskScheduler _scheduler;
- TimeTracker _resourceTimer;
-
- static uint32 GetGateIDFromEntry(uint32 id);
- static int32 GetWorldStateFromGateEntry(uint32 id, bool open);
-
- void UpdateNodeWorldState(ICNodePoint const& node);
- void HandleCapturedNodes(ICNodePoint& node);
- void HandleCaptureNodeAction(GameObject* banner);
- void OnGateDestroyed(GameObject* gate, WorldObject* destroyer);
-
- static ICNodePointType BannerToNodeType(uint32 bannerId);
-};
-
-#endif
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp
deleted file mode 100644
index 00cbaeb5ba4..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "BattlegroundNA.h"
-#include "Log.h"
-#include "Player.h"
-
-BattlegroundNA::BattlegroundNA(BattlegroundTemplate const* battlegroundTemplate) : Arena(battlegroundTemplate)
-{
- BgObjects.resize(BG_NA_OBJECT_MAX);
-}
-
-void BattlegroundNA::PostUpdateImpl(uint32 diff)
-{
- if (GetStatus() != STATUS_IN_PROGRESS)
- return;
-
- _events.Update(diff);
-
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case BG_NA_EVENT_REMOVE_DOORS:
- for (uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_2; ++i)
- DelObject(i);
- break;
- default:
- break;
- }
- }
-}
-
-void BattlegroundNA::StartingEventCloseDoors()
-{
- for (uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_4; ++i)
- SpawnBGObject(i, RESPAWN_IMMEDIATELY);
-}
-
-void BattlegroundNA::StartingEventOpenDoors()
-{
- for (uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_2; ++i)
- DoorOpen(i);
- _events.ScheduleEvent(BG_NA_EVENT_REMOVE_DOORS, BG_NA_REMOVE_DOORS_TIMER);
-
- for (uint32 i = BG_NA_OBJECT_BUFF_1; i <= BG_NA_OBJECT_BUFF_2; ++i)
- SpawnBGObject(i, 60);
-}
-
-bool BattlegroundNA::SetupBattleground()
-{
- // gates
- if (!AddObject(BG_NA_OBJECT_DOOR_1, BG_NA_OBJECT_TYPE_DOOR_1, 4031.854f, 2966.833f, 12.6462f, -2.648788f, 0, 0, 0.9697962f, -0.2439165f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_NA_OBJECT_DOOR_2, BG_NA_OBJECT_TYPE_DOOR_2, 4081.179f, 2874.97f, 12.39171f, 0.4928045f, 0, 0, 0.2439165f, 0.9697962f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_NA_OBJECT_DOOR_3, BG_NA_OBJECT_TYPE_DOOR_3, 4023.709f, 2981.777f, 10.70117f, -2.648788f, 0, 0, 0.9697962f, -0.2439165f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_NA_OBJECT_DOOR_4, BG_NA_OBJECT_TYPE_DOOR_4, 4090.064f, 2858.438f, 10.23631f, 0.4928045f, 0, 0, 0.2439165f, 0.9697962f, RESPAWN_IMMEDIATELY)
- // buffs
- || !AddObject(BG_NA_OBJECT_BUFF_1, BG_NA_OBJECT_TYPE_BUFF_1, 4009.189941f, 2895.250000f, 13.052700f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f, 120)
- || !AddObject(BG_NA_OBJECT_BUFF_2, BG_NA_OBJECT_TYPE_BUFF_2, 4103.330078f, 2946.350098f, 13.051300f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f, 120))
- {
- TC_LOG_ERROR("sql.sql", "BatteGroundNA: Failed to spawn some object!");
- return false;
- }
-
- return true;
-}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundNA.h b/src/server/game/Battlegrounds/Zones/BattlegroundNA.h
deleted file mode 100644
index ba8ee0ad9a8..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundNA.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef __BATTLEGROUNDNA_H
-#define __BATTLEGROUNDNA_H
-
-#include "Arena.h"
-#include "EventMap.h"
-
-enum BattlegroundNAObjectTypes
-{
- BG_NA_OBJECT_DOOR_1 = 0,
- BG_NA_OBJECT_DOOR_2 = 1,
- BG_NA_OBJECT_DOOR_3 = 2,
- BG_NA_OBJECT_DOOR_4 = 3,
- BG_NA_OBJECT_BUFF_1 = 4,
- BG_NA_OBJECT_BUFF_2 = 5,
- BG_NA_OBJECT_MAX = 6
-};
-
-enum BattlegroundNAGameObjects
-{
- BG_NA_OBJECT_TYPE_DOOR_1 = 183978,
- BG_NA_OBJECT_TYPE_DOOR_2 = 183980,
- BG_NA_OBJECT_TYPE_DOOR_3 = 183977,
- BG_NA_OBJECT_TYPE_DOOR_4 = 183979,
- BG_NA_OBJECT_TYPE_BUFF_1 = 184663,
- BG_NA_OBJECT_TYPE_BUFF_2 = 184664
-};
-
-inline constexpr Seconds BG_NA_REMOVE_DOORS_TIMER = 5s;
-
-enum BattlegroundNAEvents
-{
- BG_NA_EVENT_REMOVE_DOORS = 1
-};
-
-class BattlegroundNA : public Arena
-{
- public:
- BattlegroundNA(BattlegroundTemplate const* battlegroundTemplate);
-
- /* inherited from BattlegroundClass */
- void StartingEventCloseDoors() override;
- void StartingEventOpenDoors() override;
-
- bool SetupBattleground() override;
-
- private:
- void PostUpdateImpl(uint32 diff) override;
-
- EventMap _events;
-};
-#endif
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp
deleted file mode 100644
index 0f4aacb33c8..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "BattlegroundRL.h"
-#include "Log.h"
-#include "Player.h"
-
-BattlegroundRL::BattlegroundRL(BattlegroundTemplate const* battlegroundTemplate) : Arena(battlegroundTemplate)
-{
- BgObjects.resize(BG_RL_OBJECT_MAX);
-}
-
-void BattlegroundRL::PostUpdateImpl(uint32 diff)
-{
- if (GetStatus() != STATUS_IN_PROGRESS)
- return;
-
- _events.Update(diff);
-
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case BG_RL_EVENT_REMOVE_DOORS:
- for (uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; ++i)
- DelObject(i);
- break;
- default:
- break;
- }
- }
-}
-
-void BattlegroundRL::StartingEventCloseDoors()
-{
- for (uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; ++i)
- SpawnBGObject(i, RESPAWN_IMMEDIATELY);
-}
-
-void BattlegroundRL::StartingEventOpenDoors()
-{
- for (uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; ++i)
- DoorOpen(i);
- _events.ScheduleEvent(BG_RL_EVENT_REMOVE_DOORS, BG_RL_REMOVE_DOORS_TIMER);
-
- for (uint32 i = BG_RL_OBJECT_BUFF_1; i <= BG_RL_OBJECT_BUFF_2; ++i)
- SpawnBGObject(i, 60);
-}
-
-bool BattlegroundRL::SetupBattleground()
-{
- // gates
- if (!AddObject(BG_RL_OBJECT_DOOR_1, BG_RL_OBJECT_TYPE_DOOR_1, 1293.561f, 1601.938f, 31.60557f, -1.457349f, 0, 0, -0.6658813f, 0.7460576f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_RL_OBJECT_DOOR_2, BG_RL_OBJECT_TYPE_DOOR_2, 1278.648f, 1730.557f, 31.60557f, 1.684245f, 0, 0, 0.7460582f, 0.6658807f, RESPAWN_IMMEDIATELY)
- // buffs
- || !AddObject(BG_RL_OBJECT_BUFF_1, BG_RL_OBJECT_TYPE_BUFF_1, 1328.719971f, 1632.719971f, 36.730400f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f, 120)
- || !AddObject(BG_RL_OBJECT_BUFF_2, BG_RL_OBJECT_TYPE_BUFF_2, 1243.300049f, 1699.170044f, 34.872601f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f, 120))
- {
- TC_LOG_ERROR("sql.sql", "BatteGroundRL: Failed to spawn some object!");
- return false;
- }
-
- return true;
-}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRL.h b/src/server/game/Battlegrounds/Zones/BattlegroundRL.h
deleted file mode 100644
index 574038d5e20..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundRL.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef __BATTLEGROUNDRL_H
-#define __BATTLEGROUNDRL_H
-
-#include "Arena.h"
-#include "EventMap.h"
-
-enum BattlegroundRLObjectTypes
-{
- BG_RL_OBJECT_DOOR_1 = 0,
- BG_RL_OBJECT_DOOR_2 = 1,
- BG_RL_OBJECT_BUFF_1 = 2,
- BG_RL_OBJECT_BUFF_2 = 3,
- BG_RL_OBJECT_MAX = 4
-};
-
-enum BattlegroundRLGameObjects
-{
- BG_RL_OBJECT_TYPE_DOOR_1 = 185918,
- BG_RL_OBJECT_TYPE_DOOR_2 = 185917,
- BG_RL_OBJECT_TYPE_BUFF_1 = 184663,
- BG_RL_OBJECT_TYPE_BUFF_2 = 184664
-};
-
-inline constexpr Seconds BG_RL_REMOVE_DOORS_TIMER = 5s;
-
-enum BattlegroundRLEvents
-{
- BG_RL_EVENT_REMOVE_DOORS = 1
-};
-
-class BattlegroundRL : public Arena
-{
- public:
- BattlegroundRL(BattlegroundTemplate const* battlegroundTemplate);
-
- /* inherited from BattlegroundClass */
- void StartingEventCloseDoors() override;
- void StartingEventOpenDoors() override;
-
- bool SetupBattleground() override;
-
- private:
- void PostUpdateImpl(uint32 diff) override;
-
- EventMap _events;
-};
-#endif
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp
deleted file mode 100644
index e66f1ec7e41..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "BattlegroundRV.h"
-#include "GameObject.h"
-#include "Log.h"
-#include "ObjectAccessor.h"
-#include "Player.h"
-
-BattlegroundRV::BattlegroundRV(BattlegroundTemplate const* battlegroundTemplate) : Arena(battlegroundTemplate)
-{
- BgObjects.resize(BG_RV_OBJECT_MAX);
-
- _timer = 0;
- _state = 0;
- _pillarCollision = false;
-}
-
-void BattlegroundRV::PostUpdateImpl(uint32 diff)
-{
- if (GetStatus() != STATUS_IN_PROGRESS)
- return;
-
- if (_timer < diff)
- {
- switch (_state)
- {
- case BG_RV_STATE_OPEN_FENCES:
- // Open fire (only at game start)
- for (uint8 i = BG_RV_OBJECT_FIRE_1; i <= BG_RV_OBJECT_FIREDOOR_2; ++i)
- DoorOpen(i);
- _timer = BG_RV_CLOSE_FIRE_TIMER;
- _state = BG_RV_STATE_CLOSE_FIRE;
- break;
- case BG_RV_STATE_CLOSE_FIRE:
- for (uint8 i = BG_RV_OBJECT_FIRE_1; i <= BG_RV_OBJECT_FIREDOOR_2; ++i)
- DoorClose(i);
- // Fire got closed after five seconds, leaves twenty seconds before toggling pillars
- _timer = BG_RV_FIRE_TO_PILLAR_TIMER;
- _state = BG_RV_STATE_SWITCH_PILLARS;
- break;
- case BG_RV_STATE_SWITCH_PILLARS:
- TogglePillarCollision();
- _timer = BG_RV_PILLAR_SWITCH_TIMER;
- break;
- }
- }
- else
- _timer -= diff;
-}
-
-void BattlegroundRV::StartingEventOpenDoors()
-{
- // Buff respawn
- SpawnBGObject(BG_RV_OBJECT_BUFF_1, 90);
- SpawnBGObject(BG_RV_OBJECT_BUFF_2, 90);
- // Elevators
- DoorOpen(BG_RV_OBJECT_ELEVATOR_1);
- DoorOpen(BG_RV_OBJECT_ELEVATOR_2);
-
- _state = BG_RV_STATE_OPEN_FENCES;
- _timer = BG_RV_FIRST_TIMER;
-
- // Should be false at first, TogglePillarCollision will do it.
- _pillarCollision = true;
- TogglePillarCollision();
-}
-
-bool BattlegroundRV::SetupBattleground()
-{
- // elevators
- if (!AddObject(BG_RV_OBJECT_ELEVATOR_1, BG_RV_OBJECT_TYPE_ELEVATOR_1, 763.536377f, -294.535767f, 0.505383f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_RV_OBJECT_ELEVATOR_2, BG_RV_OBJECT_TYPE_ELEVATOR_2, 763.506348f, -273.873352f, 0.505383f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY)
- // buffs
- || !AddObject(BG_RV_OBJECT_BUFF_1, BG_RV_OBJECT_TYPE_BUFF_1, 735.551819f, -284.794678f, 28.276682f, 0.034906f, 0, 0, 0, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_RV_OBJECT_BUFF_2, BG_RV_OBJECT_TYPE_BUFF_2, 791.224487f, -284.794464f, 28.276682f, 2.600535f, 0, 0, 0, RESPAWN_IMMEDIATELY)
- // fire
- || !AddObject(BG_RV_OBJECT_FIRE_1, BG_RV_OBJECT_TYPE_FIRE_1, 743.543457f, -283.799469f, 28.286655f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_RV_OBJECT_FIRE_2, BG_RV_OBJECT_TYPE_FIRE_2, 782.971802f, -283.799469f, 28.286655f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_RV_OBJECT_FIREDOOR_1, BG_RV_OBJECT_TYPE_FIREDOOR_1, 743.711060f, -284.099609f, 27.542587f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_RV_OBJECT_FIREDOOR_2, BG_RV_OBJECT_TYPE_FIREDOOR_2, 783.221252f, -284.133362f, 27.535686f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY)
- // Gear
- || !AddObject(BG_RV_OBJECT_GEAR_1, BG_RV_OBJECT_TYPE_GEAR_1, 763.664551f, -261.872986f, 26.686588f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_RV_OBJECT_GEAR_2, BG_RV_OBJECT_TYPE_GEAR_2, 763.578979f, -306.146149f, 26.665222f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
- // Pulley
- || !AddObject(BG_RV_OBJECT_PULLEY_1, BG_RV_OBJECT_TYPE_PULLEY_1, 700.722290f, -283.990662f, 39.517582f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_RV_OBJECT_PULLEY_2, BG_RV_OBJECT_TYPE_PULLEY_2, 826.303833f, -283.996429f, 39.517582f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY)
- // Pilars
- || !AddObject(BG_RV_OBJECT_PILAR_1, BG_RV_OBJECT_TYPE_PILAR_1, 763.632385f, -306.162384f, 25.909504f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_RV_OBJECT_PILAR_2, BG_RV_OBJECT_TYPE_PILAR_2, 723.644287f, -284.493256f, 24.648525f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_RV_OBJECT_PILAR_3, BG_RV_OBJECT_TYPE_PILAR_3, 763.611145f, -261.856750f, 25.909504f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_RV_OBJECT_PILAR_4, BG_RV_OBJECT_TYPE_PILAR_4, 802.211609f, -284.493256f, 24.648525f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY)
-
- // Pilars Collision
- || !AddObject(BG_RV_OBJECT_PILAR_COLLISION_1, BG_RV_OBJECT_TYPE_PILAR_COLLISION_1, 763.632385f, -306.162384f, 30.639660f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_RV_OBJECT_PILAR_COLLISION_2, BG_RV_OBJECT_TYPE_PILAR_COLLISION_2, 723.644287f, -284.493256f, 32.382710f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_RV_OBJECT_PILAR_COLLISION_3, BG_RV_OBJECT_TYPE_PILAR_COLLISION_3, 763.611145f, -261.856750f, 30.639660f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_RV_OBJECT_PILAR_COLLISION_4, BG_RV_OBJECT_TYPE_PILAR_COLLISION_4, 802.211609f, -284.493256f, 32.382710f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY))
- {
- TC_LOG_ERROR("sql.sql", "BatteGroundRV: Failed to spawn some object!");
- return false;
- }
- return true;
-}
-
-void BattlegroundRV::TogglePillarCollision()
-{
- // Toggle visual pillars, pulley, gear, and collision based on previous state
- for (uint8 i = BG_RV_OBJECT_PILAR_1; i <= BG_RV_OBJECT_GEAR_2; ++i)
- _pillarCollision ? DoorOpen(i) : DoorClose(i);
-
- for (uint8 i = BG_RV_OBJECT_PILAR_2; i <= BG_RV_OBJECT_PULLEY_2; ++i)
- _pillarCollision ? DoorClose(i) : DoorOpen(i);
-
- for (uint8 i = BG_RV_OBJECT_PILAR_1; i <= BG_RV_OBJECT_PILAR_COLLISION_4; ++i)
- {
- if (GameObject* go = GetBGObject(i))
- {
- if (i >= BG_RV_OBJECT_PILAR_COLLISION_1)
- {
- GOState state = ((go->GetGOInfo()->door.startOpen != 0) == _pillarCollision) ? GO_STATE_ACTIVE : GO_STATE_READY;
- go->SetGoState(state);
- }
-
- for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
- if (Player* player = ObjectAccessor::FindPlayer(itr->first))
- go->SendUpdateToPlayer(player);
- }
- }
-
- _pillarCollision = !_pillarCollision;
-}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRV.h b/src/server/game/Battlegrounds/Zones/BattlegroundRV.h
deleted file mode 100644
index 4f8f813fafc..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundRV.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef __BATTLEGROUNDRV_H
-#define __BATTLEGROUNDRV_H
-
-#include "Arena.h"
-
-enum BattlegroundRVObjectTypes
-{
- BG_RV_OBJECT_BUFF_1,
- BG_RV_OBJECT_BUFF_2,
- BG_RV_OBJECT_FIRE_1,
- BG_RV_OBJECT_FIRE_2,
- BG_RV_OBJECT_FIREDOOR_1,
- BG_RV_OBJECT_FIREDOOR_2,
-
- BG_RV_OBJECT_PILAR_1,
- BG_RV_OBJECT_PILAR_3,
- BG_RV_OBJECT_GEAR_1,
- BG_RV_OBJECT_GEAR_2,
-
- BG_RV_OBJECT_PILAR_2,
- BG_RV_OBJECT_PILAR_4,
- BG_RV_OBJECT_PULLEY_1,
- BG_RV_OBJECT_PULLEY_2,
-
- BG_RV_OBJECT_PILAR_COLLISION_1,
- BG_RV_OBJECT_PILAR_COLLISION_2,
- BG_RV_OBJECT_PILAR_COLLISION_3,
- BG_RV_OBJECT_PILAR_COLLISION_4,
-
- BG_RV_OBJECT_ELEVATOR_1,
- BG_RV_OBJECT_ELEVATOR_2,
- BG_RV_OBJECT_MAX
-};
-
-enum BattlegroundRVGameObjects
-{
- BG_RV_OBJECT_TYPE_BUFF_1 = 184663,
- BG_RV_OBJECT_TYPE_BUFF_2 = 184664,
- BG_RV_OBJECT_TYPE_FIRE_1 = 192704,
- BG_RV_OBJECT_TYPE_FIRE_2 = 192705,
-
- BG_RV_OBJECT_TYPE_FIREDOOR_2 = 192387,
- BG_RV_OBJECT_TYPE_FIREDOOR_1 = 192388,
- BG_RV_OBJECT_TYPE_PULLEY_1 = 192389,
- BG_RV_OBJECT_TYPE_PULLEY_2 = 192390,
- BG_RV_OBJECT_TYPE_GEAR_1 = 192393,
- BG_RV_OBJECT_TYPE_GEAR_2 = 192394,
- BG_RV_OBJECT_TYPE_ELEVATOR_1 = 194582,
- BG_RV_OBJECT_TYPE_ELEVATOR_2 = 194586,
-
- BG_RV_OBJECT_TYPE_PILAR_COLLISION_1 = 194580, // axe
- BG_RV_OBJECT_TYPE_PILAR_COLLISION_2 = 194579, // arena
- BG_RV_OBJECT_TYPE_PILAR_COLLISION_3 = 194581, // lightning
- BG_RV_OBJECT_TYPE_PILAR_COLLISION_4 = 194578, // ivory
-
- BG_RV_OBJECT_TYPE_PILAR_1 = 194583, // axe
- BG_RV_OBJECT_TYPE_PILAR_2 = 194584, // arena
- BG_RV_OBJECT_TYPE_PILAR_3 = 194585, // lightning
- BG_RV_OBJECT_TYPE_PILAR_4 = 194587 // ivory
-};
-
-enum BattlegroundRVData
-{
- BG_RV_STATE_OPEN_FENCES,
- BG_RV_STATE_SWITCH_PILLARS,
- BG_RV_STATE_CLOSE_FIRE,
-
- BG_RV_PILLAR_SWITCH_TIMER = 25000,
- BG_RV_FIRE_TO_PILLAR_TIMER = 20000,
- BG_RV_CLOSE_FIRE_TIMER = 5000,
- BG_RV_FIRST_TIMER = 20133,
-};
-
-class BattlegroundRV : public Arena
-{
- public:
- BattlegroundRV(BattlegroundTemplate const* battlegroundTemplate);
-
- /* inherited from BattlegroundClass */
- void StartingEventOpenDoors() override;
-
- bool SetupBattleground() override;
-
- private:
- void PostUpdateImpl(uint32 diff) override;
-
- void TogglePillarCollision();
-
- uint32 _timer;
- uint32 _state;
- bool _pillarCollision;
-};
-#endif
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp
deleted file mode 100644
index f1f0f9b5eba..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp
+++ /dev/null
@@ -1,843 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "BattlegroundSA.h"
-#include "BattlegroundScore.h"
-#include "Creature.h"
-#include "CreatureAI.h"
-#include "DB2Stores.h"
-#include "GameObject.h"
-#include "GameTime.h"
-#include "Log.h"
-#include "Map.h"
-#include "ObjectAccessor.h"
-#include "ObjectMgr.h"
-#include "Player.h"
-#include "Random.h"
-#include "UpdateData.h"
-#include "WorldStateMgr.h"
-
-enum StrandOfTheAncientsPvpStats
-{
- PVP_STAT_GATES_DESTROYED = 231,
- PVP_STAT_DEMOLISHERS_DESTROYED = 232
-};
-
-enum StrandOfTheAncientsEvents
-{
- EVENT_HORDE_ASSAULT_STARTED = 21702,
- EVENT_ALLIANCE_ASSAULT_STARTED = 23748,
- EVENT_TITAN_RELIC_ACTIVATED = 20572
-};
-
-enum StrandOfTheAncientsCreatures
-{
- NPC_KANRETHAD = 29,
- NPC_DEMOLISHER = 28781,
- NPC_ANTIPERSONNEL_CANNON = 27894,
- NPC_RIGGER_SPARKLIGHT = 29260,
- NPC_GORGRIL_RIGSPARK = 29262,
- NPC_WORLD_TRIGGER = 22515,
- NPC_DEMOLISHER_SA = 28781
-};
-
-enum StrandOfTheAncientsSpawnPositions
-{
- SPAWN_DEFENDERS = 1399
-};
-
-enum StrandOfTheAncientsData
-{
- DATA_ATTACKERS = 1,
- DATA_STATUS = 2
-};
-
-enum StrandOfTheAncientSpells
-{
- SPELL_TELEPORT_DEFENDER = 52364,
- SPELL_TELEPORT_ATTACKERS = 60178,
- SPELL_END_OF_ROUND = 52459,
- SPELL_REMOVE_SEAFORIUM = 59077,
- SPELL_ALLIANCE_CONTROL_PHASE_SHIFT = 60027,
- SPELL_HORDE_CONTROL_PHASE_SHIFT = 60028,
- SPELL_CARRYING_SEAFORIUM_CHARGE = 52415
-};
-
-Position const spawnPositionOnTransport[] =
-{
- { 0.0f, 5.0f, 9.6f, 3.14f },
- { -6.0f, -3.0f, 8.6f, 0.0f }
-};
-
-BattlegroundSA::BattlegroundSA(BattlegroundTemplate const* battlegroundTemplate) : Battleground(battlegroundTemplate)
-{
- StartMessageIds[BG_STARTING_EVENT_FOURTH] = 0; // handle by Kanrethad
-
- BgObjects.resize(0);
- BgCreatures.resize(0);
- TimerEnabled = false;
- UpdateWaitTimer = 0;
- SignaledRoundTwo = false;
- SignaledRoundTwoHalfMin = false;
- InitSecondRound = false;
- Attackers = static_cast<TeamId>(urand(TEAM_ALLIANCE, TEAM_HORDE));
- TotalTime = 0;
- EndRoundTimer = 0;
- ShipsStarted = false;
- Status = BG_SA_NOT_STARTED;
-
- for (BG_SA_RoundScore& roundScore : RoundScores)
- {
- roundScore.winner = TEAM_ALLIANCE;
- roundScore.time = 0;
- }
-
- _boatGUIDs = { };
- _staticBombGUIDs = { };
-}
-
-BattlegroundSA::~BattlegroundSA() = default;
-
-void BattlegroundSA::Reset()
-{
- TotalTime = 0;
- ShipsStarted = false;
- Status = BG_SA_WARMUP;
-}
-
-bool BattlegroundSA::SetupBattleground()
-{
- return true;
-}
-
-bool BattlegroundSA::ResetObjs()
-{
- for (ObjectGuid const& bombGuid : _dynamicBombGUIDs)
- if (GameObject* bomb = GetBgMap()->GetGameObject(bombGuid))
- bomb->Delete();
-
- _dynamicBombGUIDs.clear();
-
- TeamId const defenders = Attackers == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE;
-
- TotalTime = 0;
- ShipsStarted = false;
-
- UpdateWorldState(BG_SA_ALLY_ATTACKS, Attackers == TEAM_ALLIANCE);
- UpdateWorldState(BG_SA_HORDE_ATTACKS, Attackers == TEAM_HORDE);
-
- UpdateWorldState(BG_SA_RIGHT_ATT_TOKEN_ALL, Attackers == TEAM_ALLIANCE);
- UpdateWorldState(BG_SA_LEFT_ATT_TOKEN_ALL, Attackers == TEAM_ALLIANCE);
-
- UpdateWorldState(BG_SA_RIGHT_ATT_TOKEN_HRD, Attackers == TEAM_HORDE);
- UpdateWorldState(BG_SA_LEFT_ATT_TOKEN_HRD, Attackers == TEAM_HORDE);
-
- UpdateWorldState(BG_SA_HORDE_DEFENCE_TOKEN, defenders == TEAM_HORDE);
- UpdateWorldState(BG_SA_ALLIANCE_DEFENCE_TOKEN, defenders == TEAM_ALLIANCE);
-
- CaptureGraveyard(StrandOfTheAncientsGraveyard::Central, defenders);
- CaptureGraveyard(StrandOfTheAncientsGraveyard::West, defenders);
- CaptureGraveyard(StrandOfTheAncientsGraveyard::East, defenders);
-
- UpdateWorldState(BG_SA_ATTACKER_TEAM, Attackers);
-
- for (ObjectGuid const& guid : _gateGUIDs)
- if (GameObject* gate = GetBgMap()->GetGameObject(guid))
- gate->SetDestructibleState(GO_DESTRUCTIBLE_INTACT, nullptr, true);
-
- BG_SA_GateState const state = Attackers == TEAM_ALLIANCE ? BG_SA_HORDE_GATE_OK : BG_SA_ALLIANCE_GATE_OK;
- UpdateWorldState(BG_SA_PURPLE_GATEWS, state);
- UpdateWorldState(BG_SA_RED_GATEWS, state);
- UpdateWorldState(BG_SA_BLUE_GATEWS, state);
- UpdateWorldState(BG_SA_GREEN_GATEWS, state);
- UpdateWorldState(BG_SA_YELLOW_GATEWS, state);
- UpdateWorldState(BG_SA_ANCIENT_GATEWS, state);
-
- GetBgMap()->UpdateSpawnGroupConditions();
-
- if (GameObject* door = GetBgMap()->GetGameObject(_collisionDoorGUID))
- door->ResetDoorOrButton();
-
- SetStatus(STATUS_WAIT_JOIN);
- GetBgMap()->DoOnPlayers([&](Player* player)
- {
- SendTransportInit(player);
- });
-
- TeleportPlayers();
- return true;
-}
-
-void BattlegroundSA::StartShips()
-{
- if (ShipsStarted)
- return;
-
- for (ObjectGuid const& guid : _boatGUIDs[Attackers])
- {
- if (GameObject* boat = GetBgMap()->GetGameObject(guid))
- {
- boat->SetGoState(GO_STATE_TRANSPORT_STOPPED);
-
- // make sure every player knows the transport exists & is moving
- for (auto const& [playerGuid, _] : GetPlayers())
- {
- if (Player const* player = ObjectAccessor::FindPlayer(playerGuid))
- {
- UpdateData data(player->GetMapId());
- WorldPacket pkt;
- boat->BuildValuesUpdateBlockForPlayer(&data, player);
- data.BuildPacket(&pkt);
- player->SendDirectMessage(&pkt);
- }
- }
- }
- }
-
- ShipsStarted = true;
-}
-
-void BattlegroundSA::PostUpdateImpl(uint32 diff)
-{
- if (InitSecondRound)
- {
- if (UpdateWaitTimer < diff)
- {
- if (!SignaledRoundTwo)
- {
- SignaledRoundTwo = true;
- InitSecondRound = false;
- SendBroadcastText(BG_SA_TEXT_ROUND_TWO_START_ONE_MINUTE, CHAT_MSG_BG_SYSTEM_NEUTRAL);
- }
- }
- else
- {
- UpdateWaitTimer -= diff;
- return;
- }
- }
- TotalTime += diff;
-
- if (Status == BG_SA_WARMUP)
- {
- EndRoundTimer = BG_SA_ROUNDLENGTH;
- UpdateWorldState(BG_SA_TIMER, GameTime::GetGameTime() + (EndRoundTimer / 1000));
- if (TotalTime >= BG_SA_WARMUPLENGTH)
- {
- if (Creature* c = FindKanrethad())
- SendChatMessage(c, TEXT_ROUND_STARTED);
-
- TotalTime = 0;
- ToggleTimer();
- Status = BG_SA_ROUND_ONE;
- TriggerGameEvent((Attackers == TEAM_ALLIANCE) ? EVENT_ALLIANCE_ASSAULT_STARTED : EVENT_HORDE_ASSAULT_STARTED);
- }
- if (TotalTime >= BG_SA_BOAT_START)
- StartShips();
- return;
- }
- else if (Status == BG_SA_SECOND_WARMUP)
- {
- if (RoundScores[0].time<BG_SA_ROUNDLENGTH)
- EndRoundTimer = RoundScores[0].time;
- else
- EndRoundTimer = BG_SA_ROUNDLENGTH;
-
- UpdateWorldState(BG_SA_TIMER, GameTime::GetGameTime() + (EndRoundTimer / 1000));
- if (TotalTime >= 60000)
- {
- if (Creature* c = FindKanrethad())
- SendChatMessage(c, TEXT_ROUND_STARTED);
-
- TotalTime = 0;
- ToggleTimer();
- Status = BG_SA_ROUND_TWO;
- TriggerGameEvent((Attackers == TEAM_ALLIANCE) ? EVENT_ALLIANCE_ASSAULT_STARTED : EVENT_HORDE_ASSAULT_STARTED);
- // status was set to STATUS_WAIT_JOIN manually for Preparation, set it back now
- SetStatus(STATUS_IN_PROGRESS);
- for (const auto& [playerGuid, bp] : GetPlayers())
- if (Player* p = ObjectAccessor::FindPlayer(playerGuid))
- p->RemoveAurasDueToSpell(SPELL_PREPARATION);
- }
- if (TotalTime >= 30000)
- {
- if (!SignaledRoundTwoHalfMin)
- {
- SignaledRoundTwoHalfMin = true;
- SendBroadcastText(BG_SA_TEXT_ROUND_TWO_START_HALF_MINUTE, CHAT_MSG_BG_SYSTEM_NEUTRAL);
- }
- }
- StartShips();
- return;
- }
- else if (GetStatus() == STATUS_IN_PROGRESS)
- {
- if (Status == BG_SA_ROUND_ONE)
- {
- if (TotalTime >= BG_SA_ROUNDLENGTH)
- {
- EndRound();
- return;
- }
- }
- else if (Status == BG_SA_ROUND_TWO)
- {
- if (TotalTime >= EndRoundTimer)
- {
- CastSpellOnTeam(SPELL_END_OF_ROUND, ALLIANCE);
- CastSpellOnTeam(SPELL_END_OF_ROUND, HORDE);
- RoundScores[1].time = BG_SA_ROUNDLENGTH;
- RoundScores[1].winner = (Attackers == TEAM_ALLIANCE) ? TEAM_HORDE : TEAM_ALLIANCE;
- if (RoundScores[0].time == RoundScores[1].time)
- EndBattleground(TEAM_OTHER);
- else if (RoundScores[0].time < RoundScores[1].time)
- EndBattleground(RoundScores[0].winner == TEAM_ALLIANCE ? ALLIANCE : HORDE);
- else
- EndBattleground(RoundScores[1].winner == TEAM_ALLIANCE ? ALLIANCE : HORDE);
- return;
- }
- }
- }
-}
-
-void BattlegroundSA::AddPlayer(Player* player, BattlegroundQueueTypeId queueId)
-{
- bool const isInBattleground = IsPlayerInBattleground(player->GetGUID());
- Battleground::AddPlayer(player, queueId);
-
- SendTransportInit(player);
-
- if (!isInBattleground)
- TeleportToEntrancePosition(player);
-}
-
-void BattlegroundSA::RemovePlayer(Player* /*player*/, ObjectGuid /*guid*/, uint32 /*team*/) { }
-
-void BattlegroundSA::TeleportPlayers() const
-{
- for (auto const& [playerGuid, bp] : GetPlayers())
- {
- if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
- {
- // should remove spirit of redemption
- if (player->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
- player->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT);
-
- if (!player->IsAlive())
- {
- player->ResurrectPlayer(1.0f);
- player->SpawnCorpseBones();
- }
-
- player->ResetAllPowers();
- player->CombatStopWithPets(true);
-
- player->CastSpell(player, SPELL_PREPARATION, true);
-
- TeleportToEntrancePosition(player);
- }
- }
-}
-
-// This function teleports player to entrance position, but it's not implemented correctly
-// It is also used on round swap; which should be handled by the following spells: 52365, 52528, 53464, 53465 (Split Teleport (FACTION) (Boat X))
-// This spell however cannot work with current system because of grid limitations.
-// On battleground start, this function should work fine, except that it is called to late and we need a NearTeleport to solve this.
-void BattlegroundSA::TeleportToEntrancePosition(Player* player) const
-{
- if (GetTeamIndexByTeamId(GetPlayerTeam(player->GetGUID())) == Attackers)
- {
- ObjectGuid const boatGUID = _boatGUIDs[Attackers][urand(0, 1)];
-
- if (GameObject* boat = GetBgMap()->GetGameObject(boatGUID))
- {
- if (TransportBase* transport = boat->ToTransportBase())
- {
- player->Relocate(spawnPositionOnTransport[Attackers]);
- transport->AddPassenger(player);
- player->m_movementInfo.transport.pos.Relocate(spawnPositionOnTransport[Attackers]);
- float x, y, z, o;
- spawnPositionOnTransport[Attackers].GetPosition(x, y, z, o);
- transport->CalculatePassengerPosition(x, y, z, &o);
- player->Relocate(x, y, z, o);
-
- if (player->IsInWorld())
- player->NearTeleportTo({ x, y, z, o });
- }
- }
- }
- else if (WorldSafeLocsEntry const* defenderSpawn = sObjectMgr->GetWorldSafeLoc(SPAWN_DEFENDERS))
- {
- if (player->IsInWorld())
- player->TeleportTo(defenderSpawn->Loc);
- else
- player->WorldRelocate(defenderSpawn->Loc);
- }
-}
-
-void BattlegroundSA::ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* invoker /*= nullptr*/)
-{
- switch (eventId)
- {
- case EVENT_ALLIANCE_ASSAULT_STARTED:
- for (ObjectGuid const& bombGuid : _staticBombGUIDs[TEAM_ALLIANCE])
- if (GameObject* bomb = GetBgMap()->GetGameObject(bombGuid))
- bomb->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
- break;
- case EVENT_HORDE_ASSAULT_STARTED:
- for (ObjectGuid const& bombGuid : _staticBombGUIDs[TEAM_HORDE])
- if (GameObject* bomb = GetBgMap()->GetGameObject(bombGuid))
- bomb->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
- break;
- default:
- break;
- }
-
- if (GameObject* go = Object::ToGameObject(obj))
- {
- switch (go->GetGoType())
- {
- case GAMEOBJECT_TYPE_GOOBER:
- if (invoker)
- if (eventId == EVENT_TITAN_RELIC_ACTIVATED)
- TitanRelicActivated(invoker->ToPlayer());
- break;
- case GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING:
- {
- if (GateInfo const* gate = GetGate(obj->GetEntry()))
- {
- uint32 gateId = gate->GameObjectId;
-
- // damaged
- if (eventId == go->GetGOInfo()->destructibleBuilding.DamagedEvent)
- {
- BG_SA_GateState gateState = Attackers == TEAM_HORDE ? BG_SA_ALLIANCE_GATE_DAMAGED : BG_SA_HORDE_GATE_DAMAGED;
-
- if (Creature* c = obj->FindNearestCreature(NPC_WORLD_TRIGGER, 500.0f))
- SendChatMessage(c, gate->DamagedText, invoker);
-
- PlaySoundToAll(Attackers == TEAM_ALLIANCE ? SOUND_WALL_ATTACKED_ALLIANCE : SOUND_WALL_ATTACKED_HORDE);
-
- UpdateWorldState(gate->WorldState, gateState);
- }
- // destroyed
- else if (eventId == go->GetGOInfo()->destructibleBuilding.DestroyedEvent)
- {
- BG_SA_GateState gateState = Attackers == TEAM_HORDE ? BG_SA_ALLIANCE_GATE_DESTROYED : BG_SA_HORDE_GATE_DESTROYED;
- if (Creature* c = obj->FindNearestCreature(NPC_WORLD_TRIGGER, 500.0f))
- SendChatMessage(c, gate->DestroyedText, invoker);
-
- PlaySoundToAll(Attackers == TEAM_ALLIANCE ? SOUND_WALL_DESTROYED_ALLIANCE : SOUND_WALL_DESTROYED_HORDE);
-
- // check if other gate from same line of defense is already destroyed for honor reward
- bool rewardHonor = true;
- switch (gateId)
- {
- case GO_GATE_OF_THE_GREEN_EMERALD:
- if (IsGateDestroyed(GetGate(GO_GATE_OF_THE_BLUE_SAPPHIRE)))
- rewardHonor = false;
- break;
- case GO_GATE_OF_THE_BLUE_SAPPHIRE:
- if (IsGateDestroyed(GetGate(GO_GATE_OF_THE_GREEN_EMERALD)))
- rewardHonor = false;
- break;
- case GO_GATE_OF_THE_RED_SUN:
- if (IsGateDestroyed(GetGate(GO_GATE_OF_THE_PURPLE_AMETHYST)))
- rewardHonor = false;
- break;
- case GO_GATE_OF_THE_PURPLE_AMETHYST:
- if (IsGateDestroyed(GetGate(GO_GATE_OF_THE_RED_SUN)))
- rewardHonor = false;
- break;
- default:
- break;
- }
-
- if (invoker)
- {
- if (Unit* unit = invoker->ToUnit())
- {
- if (Player* player = unit->GetCharmerOrOwnerPlayerOrPlayerItself())
- {
- UpdatePvpStat(player, PVP_STAT_GATES_DESTROYED, 1);
- if (rewardHonor)
- UpdatePlayerScore(player, SCORE_BONUS_HONOR, GetBonusHonorFromKill(1));
- }
- }
- }
-
- if (rewardHonor)
- MakeObjectsInteractable(gate->LineOfDefense);
-
- UpdateWorldState(gate->WorldState, gateState);
- GetBgMap()->UpdateSpawnGroupConditions();
- }
- }
- break;
- }
- default:
- break;
- }
- }
-}
-
-void BattlegroundSA::HandleKillUnit(Creature* creature, Unit* killer)
-{
- if (creature->GetEntry() == NPC_DEMOLISHER_SA)
- {
- if (Player* killerPlayer = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
- UpdatePvpStat(killerPlayer, PVP_STAT_DEMOLISHERS_DESTROYED, 1);
- int32 worldStateId = Attackers == TEAM_HORDE ? BG_SA_DESTROYED_HORDE_VEHICLES : BG_SA_DESTROYED_ALLIANCE_VEHICLES;
- int32 currentDestroyedVehicles = sWorldStateMgr->GetValue(worldStateId, GetBgMap());
- UpdateWorldState(worldStateId, currentDestroyedVehicles + 1);
- }
-}
-
-void BattlegroundSA::DestroyGate(Player* /*player*/, GameObject* /*go*/)
-{
-}
-
-void BattlegroundSA::CaptureGraveyard(StrandOfTheAncientsGraveyard graveyard, TeamId teamId)
-{
- switch (graveyard)
- {
- case StrandOfTheAncientsGraveyard::West:
- UpdateWorldState(BG_SA_LEFT_GY_ALLIANCE, teamId == TEAM_ALLIANCE);
- UpdateWorldState(BG_SA_LEFT_GY_HORDE, teamId == TEAM_HORDE);
- break;
- case StrandOfTheAncientsGraveyard::East:
- UpdateWorldState(BG_SA_RIGHT_GY_ALLIANCE, teamId == TEAM_ALLIANCE);
- UpdateWorldState(BG_SA_RIGHT_GY_HORDE, teamId == TEAM_HORDE);
- break;
- case StrandOfTheAncientsGraveyard::Central:
- UpdateWorldState(BG_SA_CENTER_GY_ALLIANCE, teamId == TEAM_ALLIANCE);
- UpdateWorldState(BG_SA_CENTER_GY_HORDE, teamId == TEAM_HORDE);
-
- CaptureGraveyard(StrandOfTheAncientsGraveyard::East, teamId);
- CaptureGraveyard(StrandOfTheAncientsGraveyard::West, teamId);
- break;
- default:
- break;
- }
-}
-
-void BattlegroundSA::TitanRelicActivated(Player* clicker)
-{
- if (!clicker)
- return;
-
- TeamId clickerTeamId = GetTeamIndexByTeamId(GetPlayerTeam(clicker->GetGUID()));
- if (clickerTeamId == Attackers)
- {
- if (clickerTeamId == TEAM_ALLIANCE)
- SendBroadcastText(BG_SA_TEXT_ALLIANCE_CAPTURED_TITAN_PORTAL, CHAT_MSG_BG_SYSTEM_ALLIANCE);
- else
- SendBroadcastText(BG_SA_TEXT_HORDE_CAPTURED_TITAN_PORTAL, CHAT_MSG_BG_SYSTEM_HORDE);
-
- if (Status == BG_SA_ROUND_ONE)
- {
- EndRound();
- // Achievement Storm the Beach (1310)
- for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
- {
- if (Player* player = ObjectAccessor::FindPlayer(itr->first))
- if (GetTeamIndexByTeamId(GetPlayerTeam(player->GetGUID())) == Attackers)
- player->UpdateCriteria(CriteriaType::BeSpellTarget, 65246);
- }
-
- if (Creature* c = FindKanrethad())
- SendChatMessage(c, TEXT_ROUND_1_FINISHED);
- }
- else if (Status == BG_SA_ROUND_TWO)
- {
- RoundScores[1].winner = Attackers;
- RoundScores[1].time = TotalTime;
- ToggleTimer();
- // Achievement Storm the Beach (1310)
- for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
- {
- if (Player* player = ObjectAccessor::FindPlayer(itr->first))
- if (GetTeamIndexByTeamId(GetPlayerTeam(player->GetGUID())) == Attackers && RoundScores[1].winner == Attackers)
- player->UpdateCriteria(CriteriaType::BeSpellTarget, 65246);
- }
-
- if (RoundScores[0].time == RoundScores[1].time)
- EndBattleground(TEAM_OTHER);
- else if (RoundScores[0].time < RoundScores[1].time)
- EndBattleground(RoundScores[0].winner == TEAM_ALLIANCE ? ALLIANCE : HORDE);
- else
- EndBattleground(RoundScores[1].winner == TEAM_ALLIANCE ? ALLIANCE : HORDE);
- }
- }
-}
-
-void BattlegroundSA::ToggleTimer()
-{
- TimerEnabled = !TimerEnabled;
- UpdateWorldState(BG_SA_ENABLE_TIMER, TimerEnabled);
-}
-
-void BattlegroundSA::EndBattleground(Team winner)
-{
- // honor reward for winning
- if (winner == ALLIANCE)
- RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
- else if (winner == HORDE)
- RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
-
- // complete map_end rewards (even if no team wins)
- RewardHonorToTeam(GetBonusHonorFromKill(2), ALLIANCE);
- RewardHonorToTeam(GetBonusHonorFromKill(2), HORDE);
-
- Battleground::EndBattleground(winner);
-}
-
-void BattlegroundSA::SendTransportInit(Player* player)
-{
- UpdateData transData(player->GetMapId());
- for (ObjectGuid const& boatGuid : _boatGUIDs[Attackers])
- if (GameObject const* boat = GetBgMap()->GetGameObject(boatGuid))
- boat->BuildCreateUpdateBlockForPlayer(&transData, player);
-
- WorldPacket packet;
- transData.BuildPacket(&packet);
- player->SendDirectMessage(&packet);
-}
-
-void BattlegroundSA::SendTransportsRemove(Player* player)
-{
- UpdateData transData(player->GetMapId());
- for (ObjectGuid const& boatGuid : _boatGUIDs[Attackers])
- if (GameObject const* boat = GetBgMap()->GetGameObject(boatGuid))
- boat->BuildOutOfRangeUpdateBlock(&transData);
-
- WorldPacket packet;
- transData.BuildPacket(&packet);
- player->SendDirectMessage(&packet);
-}
-
-bool BattlegroundSA::IsGateDestroyed(GateInfo const* gateInfo) const
-{
- if (!gateInfo)
- return false;
-
- int32 value = GetBgMap()->GetWorldStateValue(gateInfo->WorldState);
- return value == BG_SA_ALLIANCE_GATE_DESTROYED || value == BG_SA_HORDE_GATE_DESTROYED;
-}
-
-void BattlegroundSA::HandleCaptureGraveyardAction(GameObject* graveyardBanner, Player* player)
-{
- if (!graveyardBanner || !player)
- return;
-
- TeamId const teamId = GetTeamIndexByTeamId(GetPlayerTeam(player->GetGUID()));
- // Only attackers can capture graveyard by gameobject action
- if (teamId != Attackers)
- return;
-
- switch (graveyardBanner->GetEntry())
- {
- case GO_GRAVEYARD_WEST_A:
- case GO_GRAVEYARD_WEST_H:
- CaptureGraveyard(StrandOfTheAncientsGraveyard::West, teamId);
- break;
- case GO_GRAVEYARD_EAST_A:
- case GO_GRAVEYARD_EAST_H:
- CaptureGraveyard(StrandOfTheAncientsGraveyard::East, teamId);
- break;
- case GO_GRAVEYARD_CENTRAL_A:
- case GO_GRAVEYARD_CENTRAL_H:
- CaptureGraveyard(StrandOfTheAncientsGraveyard::Central, teamId);
- break;
- default:
- break;
- }
-}
-
-void BattlegroundSA::MakeObjectsInteractable(DefenseLine defenseLine)
-{
- auto makeInteractable = [&](ObjectGuid const& guid) -> void
- {
- if (GameObject* gameObject = GetBgMap()->GetGameObject(guid))
- gameObject->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
- };
-
- switch (defenseLine)
- {
- case DefenseLine::First:
- makeInteractable(_graveyardWest);
- makeInteractable(_graveyardEast);
- break;
- case DefenseLine::Second:
- makeInteractable(_graveyardCentral);
- break;
- case DefenseLine::Third:
- break;
- case DefenseLine::Last:
- // make titan orb interactable
- if (GameObject* door = GetBgMap()->GetGameObject(_collisionDoorGUID))
- door->UseDoorOrButton();
-
- makeInteractable(_titanRelicGUID);
- break;
- default:
- break;
- }
-}
-
-Creature* BattlegroundSA::FindKanrethad() const
-{
- return GetBgMap()->GetCreature(_kanrethadGUID);
-}
-
-void BattlegroundSA::EndRound()
-{
- RoundScores[0].winner = Attackers;
- RoundScores[0].time = std::min<uint32>(TotalTime, BG_SA_ROUNDLENGTH);
-
- Attackers = (Attackers == TEAM_ALLIANCE) ? TEAM_HORDE : TEAM_ALLIANCE;
- Status = BG_SA_SECOND_WARMUP;
- TotalTime = 0;
- ToggleTimer();
-
- UpdateWaitTimer = 5000;
- SignaledRoundTwo = false;
- SignaledRoundTwoHalfMin = false;
- InitSecondRound = true;
- ResetObjs();
- GetBgMap()->UpdateAreaDependentAuras();
-
- CastSpellOnTeam(SPELL_END_OF_ROUND, ALLIANCE);
- CastSpellOnTeam(SPELL_END_OF_ROUND, HORDE);
-
- RemoveAuraOnTeam(SPELL_CARRYING_SEAFORIUM_CHARGE, HORDE);
- RemoveAuraOnTeam(SPELL_CARRYING_SEAFORIUM_CHARGE, ALLIANCE);
-}
-
-void BattlegroundSA::OnGameObjectCreate(GameObject* gameobject)
-{
- Battleground::OnGameObjectCreate(gameobject);
-
- if (gameobject->GetGoType() == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
- _gateGUIDs.insert(gameobject->GetGUID());
-
- switch (gameobject->GetEntry())
- {
- case BG_SA_BOAT_ONE_A:
- _boatGUIDs[TEAM_ALLIANCE][0] = gameobject->GetGUID();
- break;
- case BG_SA_BOAT_TWO_A:
- _boatGUIDs[TEAM_ALLIANCE][1] = gameobject->GetGUID();
- break;
- case BG_SA_BOAT_ONE_H:
- _boatGUIDs[TEAM_HORDE][0] = gameobject->GetGUID();
- break;
- case BG_SA_BOAT_TWO_H:
- _boatGUIDs[TEAM_HORDE][1] = gameobject->GetGUID();
- break;
- case GO_SEAFORIUM_BOMB_A:
- _staticBombGUIDs[TEAM_ALLIANCE].insert(gameobject->GetGUID());
- if (Status != BG_SA_SECOND_WARMUP && Status != BG_SA_WARMUP)
- gameobject->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
- break;
- case GO_SEAFORIUM_BOMB_H:
- _staticBombGUIDs[TEAM_HORDE].insert(gameobject->GetGUID());
- if (Status != BG_SA_SECOND_WARMUP && Status != BG_SA_WARMUP)
- gameobject->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
- break;
- case GO_SEAFORIUM_CHARGE_A:
- case GO_SEAFORIUM_CHARGE_H:
- _dynamicBombGUIDs.insert(gameobject->GetGUID());
- break;
- case GO_GRAVEYARD_EAST_A:
- case GO_GRAVEYARD_EAST_H:
- _graveyardEast = gameobject->GetGUID();
- break;
- case GO_GRAVEYARD_WEST_A:
- case GO_GRAVEYARD_WEST_H:
- _graveyardWest = gameobject->GetGUID();
- break;
- case GO_GRAVEYARD_CENTRAL_A:
- case GO_GRAVEYARD_CENTRAL_H:
- _graveyardCentral = gameobject->GetGUID();
- break;
- case GO_COLLISION_DOOR:
- _collisionDoorGUID = gameobject->GetGUID();
- break;
- case GO_TITAN_RELIC_A:
- case GO_TITAN_RELIC_H:
- _titanRelicGUID = gameobject->GetGUID();
- break;
- default:
- break;
- }
-}
-
-void BattlegroundSA::DoAction(uint32 actionId, WorldObject* source, WorldObject* target)
-{
- switch (actionId)
- {
- case ACTION_SOTA_CAPTURE_GRAVEYARD:
- HandleCaptureGraveyardAction(Object::ToGameObject(target), Object::ToPlayer(source));
- break;
- default:
- break;
- }
-}
-
-void BattlegroundSA::OnCreatureCreate(Creature* creature)
-{
- Battleground::OnCreatureCreate(creature);
-
- switch (creature->GetEntry())
- {
- case NPC_DEMOLISHER:
- creature->SetFaction(BG_SA_Factions[Attackers]);
- break;
- case NPC_ANTIPERSONNEL_CANNON:
- creature->SetFaction(BG_SA_Factions[Attackers == TEAM_HORDE ? TEAM_ALLIANCE : TEAM_HORDE]);
- break;
- case NPC_KANRETHAD:
- _kanrethadGUID = creature->GetGUID();
- break;
- case NPC_RIGGER_SPARKLIGHT:
- case NPC_GORGRIL_RIGSPARK:
- creature->AI()->Talk(TEXT_SPARKLIGHT_RIGSPARK_SPAWN);
- break;
- default:
- break;
- }
-}
-
-void BattlegroundSA::OnMapSet(BattlegroundMap* map)
-{
- Battleground::OnMapSet(map);
- ResetObjs();
-}
-
-uint32 BattlegroundSA::GetData(uint32 dataId) const
-{
- switch (dataId)
- {
- case DATA_ATTACKERS:
- return Attackers;
- case DATA_STATUS:
- return Status;
- default:
- return Battleground::GetData(dataId);
- }
-}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h
deleted file mode 100644
index 179ceb0923b..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __BATTLEGROUNDSA_H
-#define __BATTLEGROUNDSA_H
-
-#include "Battleground.h"
-#include "Object.h"
-
-enum BG_SA_Status
-{
- BG_SA_NOT_STARTED = 0,
- BG_SA_WARMUP,
- BG_SA_ROUND_ONE,
- BG_SA_SECOND_WARMUP,
- BG_SA_ROUND_TWO,
- BG_SA_BONUS_ROUND
-};
-
-enum BG_SA_GateState
-{
- // alliance is defender
- BG_SA_ALLIANCE_GATE_OK = 1,
- BG_SA_ALLIANCE_GATE_DAMAGED = 2,
- BG_SA_ALLIANCE_GATE_DESTROYED = 3,
- // horde is defender
- BG_SA_HORDE_GATE_OK = 4,
- BG_SA_HORDE_GATE_DAMAGED = 5,
- BG_SA_HORDE_GATE_DESTROYED = 6,
-};
-
-enum StrandOfTheAncientsGameObjects
-{
- GO_SEAFORIUM_BOMB_H = 194086, // Used by horde players
- GO_SEAFORIUM_BOMB_A = 190753, // Used by alliance players
- GO_SEAFORIUM_CHARGE_H = 257572,
- GO_SEAFORIUM_CHARGE_A = 257565,
-
- GO_GRAVEYARD_WEST_H = 191307,
- GO_GRAVEYARD_WEST_A = 191308,
-
- GO_GRAVEYARD_EAST_H = 191305,
- GO_GRAVEYARD_EAST_A = 191306,
-
- GO_GRAVEYARD_CENTRAL_H = 191309,
- GO_GRAVEYARD_CENTRAL_A = 191310,
-
- GO_COLLISION_DOOR = 194162,
- GO_TITAN_RELIC_A = 194083,
- GO_TITAN_RELIC_H = 194082,
-
- GO_GATE_OF_THE_GREEN_EMERALD = 190722,
- GO_GATE_OF_THE_PURPLE_AMETHYST = 190723,
- GO_GATE_OF_THE_BLUE_SAPPHIRE = 190724,
- GO_GATE_OF_THE_RED_SUN = 190726,
- GO_GATE_OF_THE_YELLOW_MOON = 190727,
- GO_CHAMBER_OF_ANCIENT_RELICS = 192549
-};
-
-enum BG_SA_Timers
-{
- BG_SA_BOAT_START = 60 * IN_MILLISECONDS,
- BG_SA_WARMUPLENGTH = 120 * IN_MILLISECONDS,
- BG_SA_ROUNDLENGTH = 600 * IN_MILLISECONDS
-};
-
-enum SASounds
-{
- SOUND_GRAVEYARD_TAKEN_HORDE = 8174,
- SOUND_GRAVEYARD_TAKEN_ALLIANCE = 8212,
- SOUND_DEFEAT_HORDE = 15905,
- SOUND_VICTORY_HORDE = 15906,
- SOUND_VICTORY_ALLIANCE = 15907,
- SOUND_DEFEAT_ALLIANCE = 15908,
- SOUND_WALL_DESTROYED_ALLIANCE = 15909,
- SOUND_WALL_DESTROYED_HORDE = 15910,
- SOUND_WALL_ATTACKED_HORDE = 15911,
- SOUND_WALL_ATTACKED_ALLIANCE = 15912
-};
-
-enum SATexts
-{
- // Kanrethad
- TEXT_ROUND_STARTED = 1,
- TEXT_ROUND_1_FINISHED = 2,
-
- // Rigger Sparklight / Gorgril Rigspark
- TEXT_SPARKLIGHT_RIGSPARK_SPAWN = 1,
-
- // World Trigger
- TEXT_BLUE_GATE_UNDER_ATTACK = 1,
- TEXT_GREEN_GATE_UNDER_ATTACK = 2,
- TEXT_RED_GATE_UNDER_ATTACK = 3,
- TEXT_PURPLE_GATE_UNDER_ATTACK = 4,
- TEXT_YELLOW_GATE_UNDER_ATTACK = 5,
- TEXT_YELLOW_GATE_DESTROYED = 6,
- TEXT_PURPLE_GATE_DESTROYED = 7,
- TEXT_RED_GATE_DESTROYED = 8,
- TEXT_GREEN_GATE_DESTROYED = 9,
- TEXT_BLUE_GATE_DESTROYED = 10,
- TEXT_EAST_GRAVEYARD_CAPTURED_A = 11,
- TEXT_WEST_GRAVEYARD_CAPTURED_A = 12,
- TEXT_SOUTH_GRAVEYARD_CAPTURED_A = 13,
- TEXT_EAST_GRAVEYARD_CAPTURED_H = 14,
- TEXT_WEST_GRAVEYARD_CAPTURED_H = 15,
- TEXT_SOUTH_GRAVEYARD_CAPTURED_H = 16,
- TEXT_ANCIENT_GATE_UNDER_ATTACK = 17,
- TEXT_ANCIENT_GATE_DESTROYED = 18
-};
-
-enum SAWorldStates
-{
- BG_SA_TIMER = 3557,
- BG_SA_ALLY_ATTACKS = 4352,
- BG_SA_HORDE_ATTACKS = 4353,
- BG_SA_PURPLE_GATEWS = 3614,
- BG_SA_RED_GATEWS = 3617,
- BG_SA_BLUE_GATEWS = 3620,
- BG_SA_GREEN_GATEWS = 3623,
- BG_SA_YELLOW_GATEWS = 3638,
- BG_SA_ANCIENT_GATEWS = 3849,
-
- BG_SA_LEFT_GY_ALLIANCE = 3635,
- BG_SA_RIGHT_GY_ALLIANCE = 3636,
- BG_SA_CENTER_GY_ALLIANCE = 3637,
-
- BG_SA_RIGHT_ATT_TOKEN_ALL = 3627,
- BG_SA_LEFT_ATT_TOKEN_ALL = 3626,
- BG_SA_LEFT_ATT_TOKEN_HRD = 3629,
- BG_SA_RIGHT_ATT_TOKEN_HRD = 3628,
- BG_SA_HORDE_DEFENCE_TOKEN = 3631,
- BG_SA_ALLIANCE_DEFENCE_TOKEN = 3630,
-
- BG_SA_RIGHT_GY_HORDE = 3632,
- BG_SA_LEFT_GY_HORDE = 3633,
- BG_SA_CENTER_GY_HORDE = 3634,
-
- BG_SA_BONUS_TIMER = 3571,
-
- BG_SA_ENABLE_TIMER = 3564,
- BG_SA_ATTACKER_TEAM = 3690,
- BG_SA_DESTROYED_ALLIANCE_VEHICLES = 3955,
- BG_SA_DESTROYED_HORDE_VEHICLES = 3956,
-};
-
-enum BG_SA_Boat
-{
- BG_SA_BOAT_ONE_A = 208000,
- BG_SA_BOAT_TWO_H = 208001,
- BG_SA_BOAT_ONE_H = 193184,
- BG_SA_BOAT_TWO_A = 193185
-};
-
-uint32 const BG_SA_Factions[2] =
-{
- 1732,
- 1735,
-};
-
-enum class StrandOfTheAncientsGraveyard
-{
- West,
- East,
- Central
-};
-
-enum BG_SA_BroadcastTexts
-{
- BG_SA_TEXT_ALLIANCE_CAPTURED_TITAN_PORTAL = 28944,
- BG_SA_TEXT_HORDE_CAPTURED_TITAN_PORTAL = 28945,
-
- BG_SA_TEXT_ROUND_TWO_START_ONE_MINUTE = 29448,
- BG_SA_TEXT_ROUND_TWO_START_HALF_MINUTE = 29449
-};
-
-enum class DefenseLine
-{
- First,
- Second,
- Third,
- Last
-};
-
-struct GateInfo
-{
- uint32 GameObjectId;
- uint32 WorldState;
- uint8 DamagedText;
- uint8 DestroyedText;
- DefenseLine LineOfDefense;
-};
-
-GateInfo const Gates[] =
-{
- { GO_GATE_OF_THE_GREEN_EMERALD, BG_SA_GREEN_GATEWS, TEXT_GREEN_GATE_UNDER_ATTACK, TEXT_GREEN_GATE_DESTROYED, DefenseLine::First },
- { GO_GATE_OF_THE_YELLOW_MOON, BG_SA_YELLOW_GATEWS, TEXT_YELLOW_GATE_UNDER_ATTACK, TEXT_YELLOW_GATE_DESTROYED, DefenseLine::Third },
- { GO_GATE_OF_THE_BLUE_SAPPHIRE, BG_SA_BLUE_GATEWS, TEXT_BLUE_GATE_UNDER_ATTACK, TEXT_BLUE_GATE_DESTROYED, DefenseLine::First },
- { GO_GATE_OF_THE_RED_SUN, BG_SA_RED_GATEWS, TEXT_RED_GATE_UNDER_ATTACK, TEXT_RED_GATE_DESTROYED, DefenseLine::Second },
- { GO_GATE_OF_THE_PURPLE_AMETHYST, BG_SA_PURPLE_GATEWS, TEXT_PURPLE_GATE_UNDER_ATTACK, TEXT_PURPLE_GATE_DESTROYED, DefenseLine::Second },
- { GO_CHAMBER_OF_ANCIENT_RELICS, BG_SA_ANCIENT_GATEWS, TEXT_ANCIENT_GATE_UNDER_ATTACK, TEXT_ANCIENT_GATE_DESTROYED, DefenseLine::Last }
-};
-
-struct BG_SA_RoundScore
-{
- TeamId winner;
- uint32 time;
-};
-
-enum StrandOfTheAncientSharedActions
-{
- ACTION_SOTA_CAPTURE_GRAVEYARD
-};
-
-/// Class for manage Strand of Ancient battleground
-class BattlegroundSA : public Battleground
-{
- public:
- BattlegroundSA(BattlegroundTemplate const* battlegroundTemplate);
- ~BattlegroundSA();
-
- /**
- * \brief Called every time for update battle data
- * -Update timer
- * -Round switch
- */
- void PostUpdateImpl(uint32 diff) override;
-
- /* inherited from BattlegroundClass */
- /// Called when a player join battle
- void AddPlayer(Player* player, BattlegroundQueueTypeId queueId) override;
- /// Called for ini battleground, after that the first player be entered
- bool SetupBattleground() override;
- void Reset() override;
- /// Called when a player kill a unit in bg
- void HandleKillUnit(Creature* creature, Unit* killer) override;
- /// Called when someone activates an event
- void ProcessEvent(WorldObject* /*obj*/, uint32 /*eventId*/, WorldObject* /*invoker*/ = nullptr) override;
- /// Called when a player clicked on relic
- void TitanRelicActivated(Player* clicker);
-
- /// Return GateInfo, relative to bg data, according to gameobject entry
- GateInfo const* GetGate(uint32 entry)
- {
- for (GateInfo const& gate : Gates)
- if (gate.GameObjectId == entry)
- return &gate;
-
- return nullptr;
- }
-
- /// Called on battleground ending
- void EndBattleground(Team winner) override;
-
- /// Called when a player leave battleground
- void RemovePlayer(Player* player, ObjectGuid guid, uint32 team) override;
-
- void OnGameObjectCreate(GameObject* gameobject) override;
- void DoAction(uint32 actionId, WorldObject* source, WorldObject* target) override;
- void OnCreatureCreate(Creature* creature) override;
-
- void OnMapSet(BattlegroundMap* map) override;
- uint32 GetData(uint32 dataId) const override;
- private:
-
- /**
- * \brief Called on setup and between the two round
- * -Delete all gameobject / creature
- * -Respawn all gameobject / creature to have good faction
- */
- bool ResetObjs();
- /// Called for start ship movement
- void StartShips();
- /**
- * \brief Called between the two round
- * -Teleport all players to good location
- */
- void TeleportPlayers() const;
- void TeleportToEntrancePosition(Player* player) const;
- /**
- * \brief Called when a gate is destroy
- * -Give honor to player witch destroy it
- * -Update worldstate
- * -Delete gameobject in front of door (lighting object, with different colours for each door)
- */
- void DestroyGate(Player* player, GameObject* go) override;
- /**
- * \brief Called when a graveyard is capture
- * -Update spiritguide
- * -Update gameobject (flag)
- * -Update Worldstate
- * -Send warning for announce this
- * \param i : id of graveyard
- * \param Source : Player who capture gy
- */
- void CaptureGraveyard(StrandOfTheAncientsGraveyard graveyard, TeamId teamId);
- /// Switch on/off timer worldstate
- void ToggleTimer();
-
- /// Send packet to player for create boats (client part)
- void SendTransportInit(Player* player);
- /// Send packet to player for destroy boats (client part)
- void SendTransportsRemove(Player* player);
-
- bool IsGateDestroyed(GateInfo const* gateInfo) const;
-
- void HandleCaptureGraveyardAction(GameObject* graveyardBanner, Player* player);
-
- void MakeObjectsInteractable(DefenseLine defenseLine);
-
- Creature* FindKanrethad() const;
-
- void EndRound();
-
- /// Id of attacker team
- TeamId Attackers;
-
- /// Totale elapsed time of current round
- uint32 TotalTime;
- /// Max time of round
- uint32 EndRoundTimer;
- /// For know if boats has start moving or not yet
- bool ShipsStarted;
- /// Statu of battle (Start or not, and what round)
- BG_SA_Status Status;
- /// Score of each round
- BG_SA_RoundScore RoundScores[2];
- /// used for know we are in timer phase or not (used for worldstate update)
- bool TimerEnabled;
- /// 5secs before starting the 1min countdown for second round
- uint32 UpdateWaitTimer;
- /// for know if warning about second round start has been sent
- bool SignaledRoundTwo;
- /// for know if warning about second round start has been sent
- bool SignaledRoundTwoHalfMin;
- /// for know if second round has been init
- bool InitSecondRound;
-
- // [team][boat_idx]
- std::array<std::array<ObjectGuid, 2 /*BOAT_COUNT*/>, PVP_TEAMS_COUNT> _boatGUIDs;
- std::array<GuidUnorderedSet, PVP_TEAMS_COUNT> _staticBombGUIDs; // bombs ready to be picked up
- GuidUnorderedSet _dynamicBombGUIDs; // bombs thrown by players, ready to explode/disarm
-
- ObjectGuid _graveyardWest;
- ObjectGuid _graveyardEast;
- ObjectGuid _graveyardCentral;
- GuidUnorderedSet _gateGUIDs;
- ObjectGuid _collisionDoorGUID;
- ObjectGuid _kanrethadGUID;
- ObjectGuid _titanRelicGUID;
-};
-#endif
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
deleted file mode 100644
index 22cb9ce841c..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "BattlegroundWS.h"
-#include "AreaTrigger.h"
-#include "BattlegroundMgr.h"
-#include "DB2Stores.h"
-#include "GameObject.h"
-#include "GameTime.h"
-#include "Log.h"
-#include "Map.h"
-#include "Object.h"
-#include "ObjectAccessor.h"
-#include "ObjectMgr.h"
-#include "Player.h"
-#include "SpellAuras.h"
-#include "SpellInfo.h"
-
-// these variables aren't used outside of this file, so declare them only here
-enum BG_WSG_Rewards
-{
- BG_WSG_WIN = 0,
- BG_WSG_FLAG_CAP,
- BG_WSG_MAP_COMPLETE,
- BG_WSG_REWARD_NUM
-};
-
-uint32 BG_WSG_Honor[2][BG_WSG_REWARD_NUM] =
-{
- {20, 40, 40}, // normal honor
- {60, 40, 80} // holiday
-};
-
-enum WarsongGulchPvpStats
-{
- PVP_STAT_FLAG_CAPTURES = 928,
- PVP_STAT_FLAG_RETURNS = 929
-};
-
-BattlegroundWS::BattlegroundWS(BattlegroundTemplate const* battlegroundTemplate) : Battleground(battlegroundTemplate)
-{
- BgObjects.resize(0);
- BgCreatures.resize(0);
-
- StartMessageIds[BG_STARTING_EVENT_SECOND] = BG_WS_TEXT_START_ONE_MINUTE;
- StartMessageIds[BG_STARTING_EVENT_THIRD] = BG_WS_TEXT_START_HALF_MINUTE;
- StartMessageIds[BG_STARTING_EVENT_FOURTH] = BG_WS_TEXT_BATTLE_HAS_BEGUN;
-
- _bothFlagsKept = false;
-
- _lastFlagCaptureTeam = TEAM_OTHER;
- m_ReputationCapture = 0;
- m_HonorWinKills = 0;
- m_HonorEndKills = 0;
-
- _flags = { };
- _capturePointAreaTriggers = { };
-
- _flagAssaultTimer.Reset(FLAG_ASSAULT_TIMER);
- _assaultStackCount = 0;
-}
-
-BattlegroundWS::~BattlegroundWS() { }
-
-void BattlegroundWS::PostUpdateImpl(uint32 diff)
-{
- if (GetStatus() == STATUS_IN_PROGRESS)
- {
- if (GetElapsedTime() >= 17 * MINUTE * IN_MILLISECONDS)
- {
- if (GetTeamScore(TEAM_ALLIANCE) == 0)
- {
- if (GetTeamScore(TEAM_HORDE) == 0) // No one scored - result is tie
- EndBattleground(TEAM_OTHER);
- else // Horde has more points and thus wins
- EndBattleground(HORDE);
- }
- else if (GetTeamScore(TEAM_HORDE) == 0) // Alliance has > 0, Horde has 0, alliance wins
- EndBattleground(ALLIANCE);
- else if (GetTeamScore(TEAM_HORDE) == GetTeamScore(TEAM_ALLIANCE)) // Team score equal, winner is team that scored the last flag
- EndBattleground(_lastFlagCaptureTeam);
- else if (GetTeamScore(TEAM_HORDE) > GetTeamScore(TEAM_ALLIANCE)) // Last but not least, check who has the higher score
- EndBattleground(HORDE);
- else
- EndBattleground(ALLIANCE);
- }
-
- if (_bothFlagsKept)
- {
- _flagAssaultTimer.Update(diff);
- if (_flagAssaultTimer.Passed())
- {
- _flagAssaultTimer.Reset(FLAG_ASSAULT_TIMER);
- _assaultStackCount++;
-
- // update assault debuff stacks
- DoForFlagKeepers([&](Player* player) -> void
- {
- ApplyAssaultDebuffToPlayer(player);
- });
- }
- }
- }
-}
-
-void BattlegroundWS::DoForFlagKeepers(std::function<void(Player*)> action) const
-{
- for (ObjectGuid flagGUID : _flags)
- {
- if (GameObject* flag = GetBgMap()->GetGameObject(flagGUID))
- {
- if (Player* carrier = ObjectAccessor::FindPlayer(flag->GetFlagCarrierGUID()))
- action(carrier);
- }
- }
-}
-
-void BattlegroundWS::ResetAssaultDebuff()
-{
- _bothFlagsKept = false;
- _assaultStackCount = 0;
- _flagAssaultTimer.Reset(FLAG_ASSAULT_TIMER);
- DoForFlagKeepers([&](Player* player) -> void
- {
- RemoveAssaultDebuffFromPlayer(player);
- });
-}
-
-void BattlegroundWS::ApplyAssaultDebuffToPlayer(Player* player)
-{
- if (_assaultStackCount == 0)
- return;
-
- uint32 spellId = WS_SPELL_FOCUSED_ASSAULT;
- if (_assaultStackCount >= FLAG_BRUTAL_ASSAULT_STACK_COUNT)
- {
- player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
- spellId = WS_SPELL_BRUTAL_ASSAULT;
- }
-
- Aura* aura = player->GetAura(spellId);
- if (!aura)
- {
- player->CastSpell(player, spellId, true);
- aura = player->GetAura(spellId);
- }
-
- if (aura)
- aura->SetStackAmount(_assaultStackCount);
-}
-
-void BattlegroundWS::RemoveAssaultDebuffFromPlayer(Player* player)
-{
- player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
- player->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
-}
-
-void BattlegroundWS::StartingEventOpenDoors()
-{
- for (ObjectGuid door : _doors)
- {
- if (GameObject* gameObject = GetBgMap()->GetGameObject(door))
- {
- gameObject->UseDoorOrButton();
- gameObject->DespawnOrUnsummon(3s);
- }
- }
-
- UpdateWorldState(BG_WS_STATE_TIMER_ACTIVE, 1);
- UpdateWorldState(BG_WS_STATE_TIMER, GameTime::GetGameTime() + 15 * MINUTE);
-
- // players joining later are not eligibles
- TriggerGameEvent(WS_EVENT_START_BATTLE);
-}
-
-FlagState BattlegroundWS::GetFlagState(TeamId team) const
-{
- if (GameObject* gameObject = FindBgMap()->GetGameObject(_flags[team]))
- return gameObject->GetFlagState();
-
- return FlagState(0);
-}
-
-ObjectGuid const& BattlegroundWS::GetFlagCarrierGUID(TeamId team) const
-{
- if (GameObject* gameObject = FindBgMap()->GetGameObject(_flags[team]))
- return gameObject->GetFlagCarrierGUID();
-
- return ObjectGuid::Empty;
-}
-
-void BattlegroundWS::HandleFlagRoomCapturePoint()
-{
- DoForFlagKeepers([&](Player* player) -> void
- {
- TeamId team = GetTeamIndexByTeamId(GetPlayerTeam(player->GetGUID()));
- if (AreaTrigger* trigger = GetBgMap()->GetAreaTrigger(_capturePointAreaTriggers[team]))
- if (trigger->GetInsideUnits().contains(player->GetGUID()))
- if (CanCaptureFlag(trigger, player))
- OnCaptureFlag(trigger, player);
- });
-}
-
-void BattlegroundWS::UpdateFlagState(uint32 team, FlagState value)
-{
- auto transformValueToOtherTeamControlWorldState = [](FlagState value)
- {
- switch (value)
- {
- case FlagState::InBase:
- case FlagState::Dropped:
- case FlagState::Respawning:
- return 1;
- case FlagState::Taken:
- return 2;
- default:
- return 0;
- }
- };
-
- if (team == ALLIANCE)
- {
- UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, AsUnderlyingType(value));
- UpdateWorldState(BG_WS_FLAG_CONTROL_HORDE, transformValueToOtherTeamControlWorldState(value));
- }
- else
- {
- UpdateWorldState(BG_WS_FLAG_STATE_HORDE, AsUnderlyingType(value));
- UpdateWorldState(BG_WS_FLAG_CONTROL_ALLIANCE, transformValueToOtherTeamControlWorldState(value));
- }
-}
-
-void BattlegroundWS::UpdateTeamScore(TeamId team)
-{
- if (team == TEAM_ALLIANCE)
- UpdateWorldState(BG_WS_FLAG_CAPTURES_ALLIANCE, GetTeamScore(team));
- else
- UpdateWorldState(BG_WS_FLAG_CAPTURES_HORDE, GetTeamScore(team));
-}
-
-bool BattlegroundWS::SetupBattleground()
-{
- return true;
-}
-
-void BattlegroundWS::Reset()
-{
- //call parent's class reset
- Battleground::Reset();
-
- m_TeamScores[TEAM_ALLIANCE] = 0;
- m_TeamScores[TEAM_HORDE] = 0;
-
- if (sBattlegroundMgr->IsBGWeekend(GetTypeID()))
- {
- m_ReputationCapture = 45;
- m_HonorWinKills = 3;
- m_HonorEndKills = 4;
- }
- else
- {
- m_ReputationCapture = 35;
- m_HonorWinKills = 1;
- m_HonorEndKills = 2;
- }
- _lastFlagCaptureTeam = TEAM_OTHER;
- _bothFlagsKept = false;
-
- _doors.clear();
- _flags = { };
- _assaultStackCount = 0;
- _flagAssaultTimer.Reset(FLAG_ASSAULT_TIMER);
- _capturePointAreaTriggers = { };
-}
-
-void BattlegroundWS::EndBattleground(Team winner)
-{
- // Win reward
- if (winner == ALLIANCE)
- RewardHonorToTeam(GetBonusHonorFromKill(m_HonorWinKills), ALLIANCE);
- if (winner == HORDE)
- RewardHonorToTeam(GetBonusHonorFromKill(m_HonorWinKills), HORDE);
-
- // Complete map_end rewards (even if no team wins)
- RewardHonorToTeam(GetBonusHonorFromKill(m_HonorEndKills), ALLIANCE);
- RewardHonorToTeam(GetBonusHonorFromKill(m_HonorEndKills), HORDE);
-
- Battleground::EndBattleground(winner);
-}
-
-void BattlegroundWS::HandleKillPlayer(Player* player, Player* killer)
-{
- if (GetStatus() != STATUS_IN_PROGRESS)
- return;
-
- EventPlayerDroppedFlag(player);
-
- Battleground::HandleKillPlayer(player, killer);
-}
-
-WorldSafeLocsEntry const* BattlegroundWS::GetClosestGraveyard(Player* player)
-{
- return sObjectMgr->GetClosestGraveyard(*player, player->GetBGTeam(), player);
-}
-
-WorldSafeLocsEntry const* BattlegroundWS::GetExploitTeleportLocation(Team team)
-{
- return sObjectMgr->GetWorldSafeLoc(team == ALLIANCE ? WS_EXPLOIT_TELEPORT_LOCATION_ALLIANCE : WS_EXPLOIT_TELEPORT_LOCATION_HORDE);
-}
-
-Team BattlegroundWS::GetPrematureWinner()
-{
- if (GetTeamScore(TEAM_ALLIANCE) > GetTeamScore(TEAM_HORDE))
- return ALLIANCE;
- else if (GetTeamScore(TEAM_HORDE) > GetTeamScore(TEAM_ALLIANCE))
- return HORDE;
-
- return Battleground::GetPrematureWinner();
-}
-
-void BattlegroundWS::OnGameObjectCreate(GameObject* gameObject)
-{
- switch (gameObject->GetEntry())
- {
- case BG_WS_OBJECT_ALLIANCE_DOOR:
- case BG_WS_OBJECT_PORTCULLIS_009:
- case BG_WS_OBJECT_PORTCULLIS_002:
- case BG_WS_OBJECT_COLLISION_PC_SIZE:
- case BG_WS_OBJECT_HORDE_GATE_1:
- case BG_WS_OBJECT_HORDE_GATE_2:
- _doors.insert(gameObject->GetGUID());
- break;
- case BG_WS_OBJECT_ALLIANCE_FLAG_IN_BASE:
- _flags[TEAM_ALLIANCE] = gameObject->GetGUID();
- break;
- case BG_WS_OBJECT_HORDE_FLAG_IN_BASE:
- _flags[TEAM_HORDE] = gameObject->GetGUID();
- break;
- default:
- break;
- }
-}
-
-void BattlegroundWS::OnAreaTriggerCreate(AreaTrigger* areaTrigger)
-{
- if (!areaTrigger->IsStaticSpawn())
- return;
-
- switch (areaTrigger->GetEntry())
- {
- case AT_CAPTURE_POINT_ALLIANCE:
- _capturePointAreaTriggers[TEAM_ALLIANCE] = areaTrigger->GetGUID();
- break;
- case AT_CAPTURE_POINT_HORDE:
- _capturePointAreaTriggers[TEAM_HORDE] = areaTrigger->GetGUID();
- break;
- default:
- break;
- }
-}
-
-void BattlegroundWS::OnFlagStateChange(GameObject* flagInBase, FlagState /*oldValue*/, FlagState newValue, Player* player)
-{
- Team team = flagInBase->GetEntry() == BG_WS_OBJECT_HORDE_FLAG_IN_BASE ? HORDE : ALLIANCE;
- TeamId otherTeamId = GetTeamIndexByTeamId(GetOtherTeam(team));
-
- UpdateFlagState(team, newValue);
-
- switch (newValue)
- {
- case FlagState::InBase:
- {
- if (GetStatus() == STATUS_IN_PROGRESS)
- {
- ResetAssaultDebuff();
- if (player)
- {
- // flag got returned to base by player interaction
- UpdatePvpStat(player, PVP_STAT_FLAG_RETURNS, 1); // +1 flag returns
-
- if (team == ALLIANCE)
- {
- SendBroadcastText(BG_WS_TEXT_ALLIANCE_FLAG_RETURNED, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
- PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED);
- }
- else
- {
- SendBroadcastText(BG_WS_TEXT_HORDE_FLAG_RETURNED, CHAT_MSG_BG_SYSTEM_HORDE, player);
- PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED);
- }
- }
- // Flag respawned due to timeout/capture
- else if (GetFlagState(otherTeamId) != FlagState::Respawning)
- {
- // if other flag is respawning, we will let that one handle the message and sound to prevent double message/sound.
- SendBroadcastText(BG_WS_TEXT_FLAGS_PLACED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
- PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED);
- }
-
- HandleFlagRoomCapturePoint();
- }
- break;
- }
- case FlagState::Dropped:
- {
- player->RemoveAurasDueToSpell(BG_WS_SPELL_QUICK_CAP_TIMER);
- RemoveAssaultDebuffFromPlayer(player);
-
- uint32 recentlyDroppedSpellId = SPELL_RECENTLY_DROPPED_HORDE_FLAG;
- if (team == ALLIANCE)
- {
- recentlyDroppedSpellId = SPELL_RECENTLY_DROPPED_ALLIANCE_FLAG;
- SendBroadcastText(BG_WS_TEXT_ALLIANCE_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
- }
- else
- SendBroadcastText(BG_WS_TEXT_HORDE_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_HORDE, player);
-
- player->CastSpell(player, recentlyDroppedSpellId, true);
- break;
- }
- case FlagState::Taken:
- {
- if (team == HORDE)
- {
- SendBroadcastText(BG_WS_TEXT_HORDE_FLAG_PICKED_UP, CHAT_MSG_BG_SYSTEM_HORDE, player);
- PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
- }
- else
- {
- SendBroadcastText(BG_WS_TEXT_ALLIANCE_FLAG_PICKED_UP, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
- PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
- }
-
- if (GetFlagState(otherTeamId) == FlagState::Taken)
- _bothFlagsKept = true;
-
- ApplyAssaultDebuffToPlayer(player);
-
- flagInBase->CastSpell(player, BG_WS_SPELL_QUICK_CAP_TIMER, true);
- player->StartCriteria(CriteriaStartEvent::BeSpellTarget, BG_WS_SPELL_QUICK_CAP_TIMER, Seconds(GameTime::GetGameTime() - flagInBase->GetFlagTakenFromBaseTime()));
- break;
- }
- case FlagState::Respawning:
- ResetAssaultDebuff();
- break;
- default:
- break;
- }
-}
-
-bool BattlegroundWS::CanCaptureFlag(AreaTrigger* areaTrigger, Player* player)
-{
- if (GetStatus() != STATUS_IN_PROGRESS)
- return false;
-
- Team team = GetPlayerTeam(player->GetGUID());
- TeamId teamId = GetTeamIndexByTeamId(team);
- TeamId otherTeamId = GetTeamIndexByTeamId(GetOtherTeam(team));
-
- if (areaTrigger->GetGUID() != _capturePointAreaTriggers[teamId])
- return false;
-
- // check if enemy flag's carrier is this player
- if (GetFlagCarrierGUID(otherTeamId) != player->GetGUID())
- return false;
-
- // check that team's flag is in base
- return GetFlagState(teamId) == FlagState::InBase;
-}
-
-void BattlegroundWS::OnCaptureFlag(AreaTrigger* /*areaTrigger*/, Player* player)
-{
- Team winner = TEAM_OTHER;
-
- Team team = GetPlayerTeam(player->GetGUID());
- TeamId teamId = GetTeamIndexByTeamId(team);
- TeamId otherTeamId = GetTeamIndexByTeamId(GetOtherTeam(team));
-
- /*
- 1. Update flag states & score world states
- 2. udpate points
- 3. chat message & sound
- 4. update criterias & achievements
- 5. remove all related auras
- ?. Reward honor & reputation
- */
-
- // 1. update the flag states
- for (uint8 i = 0; i < _flags.size(); i++)
- if (GameObject* gameObject = GetBgMap()->GetGameObject(_flags[i]))
- gameObject->HandleCustomTypeCommand(GameObjectType::SetNewFlagState(FlagState::Respawning, player));
-
- // 2. update points
- if (GetTeamScore(teamId) < BG_WS_MAX_TEAM_SCORE)
- AddPoint(team, 1);
-
- UpdateTeamScore(teamId);
-
- // 3. chat message & sound
- if (team == ALLIANCE)
- {
- SendBroadcastText(BG_WS_TEXT_CAPTURED_HORDE_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, player);
- PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE);
- RewardReputationToTeam(890, m_ReputationCapture, ALLIANCE);
- player->CastSpell(player, SPELL_CAPTURED_ALLIANCE_COSMETIC_FX);
- }
- else
- {
- SendBroadcastText(BG_WS_TEXT_CAPTURED_ALLIANCE_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
- PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE);
- RewardReputationToTeam(889, m_ReputationCapture, HORDE);
- player->CastSpell(player, SPELL_CAPTURED_HORDE_COSMETIC_FX);
- }
-
- // 4. update criteria's for achievement, player score etc.
- UpdatePvpStat(player, PVP_STAT_FLAG_CAPTURES, 1); // +1 flag captures
-
- // 5. Remove all related auras
- RemoveAssaultDebuffFromPlayer(player);
-
- if (GameObject* gameObject = GetBgMap()->GetGameObject(_flags[otherTeamId]))
- player->RemoveAurasDueToSpell(gameObject->GetGOInfo()->newflag.pickupSpell, gameObject->GetGUID());
-
- player->RemoveAurasDueToSpell(BG_WS_SPELL_QUICK_CAP_TIMER);
-
- player->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::PvPActive);
-
- RewardHonorToTeam(GetBonusHonorFromKill(2), team);
-
- // update last flag capture to be used if teamscore is equal
- SetLastFlagCapture(team);
-
- if (GetTeamScore(teamId) == BG_WS_MAX_TEAM_SCORE)
- winner = team;
-
- if (winner)
- {
- UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, 1);
- UpdateWorldState(BG_WS_FLAG_STATE_HORDE, 1);
- UpdateWorldState(BG_WS_STATE_TIMER_ACTIVE, 0);
-
- RewardHonorToTeam(BG_WSG_Honor[BattlegroundMgr::IsBGWeekend(GetTypeID()) ? 1 : 0][BG_WSG_WIN], winner);
- EndBattleground(winner);
- }
-}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h
deleted file mode 100644
index 16f9b031472..00000000000
--- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __BATTLEGROUNDWS_H
-#define __BATTLEGROUNDWS_H
-
-#include "Battleground.h"
-#include "BattlegroundScore.h"
-#include "Timer.h"
-
-enum BG_WS_TimerOrScore
-{
- BG_WS_MAX_TEAM_SCORE = 3,
- BG_WS_FLAG_RESPAWN_TIME = 23000,
- BG_WS_FLAG_DROP_TIME = 10000,
- BG_WS_SPELL_FORCE_TIME = 600000,
- BG_WS_SPELL_BRUTAL_TIME = 900000
-};
-
-enum BG_WS_BroadcastTexts
-{
- BG_WS_TEXT_START_ONE_MINUTE = 10015,
- BG_WS_TEXT_START_HALF_MINUTE = 10016,
- BG_WS_TEXT_BATTLE_HAS_BEGUN = 10014,
-
- BG_WS_TEXT_CAPTURED_HORDE_FLAG = 9801,
- BG_WS_TEXT_CAPTURED_ALLIANCE_FLAG = 9802,
- BG_WS_TEXT_FLAGS_PLACED = 9803,
- BG_WS_TEXT_ALLIANCE_FLAG_PICKED_UP = 9804,
- BG_WS_TEXT_ALLIANCE_FLAG_DROPPED = 9805,
- BG_WS_TEXT_HORDE_FLAG_PICKED_UP = 9807,
- BG_WS_TEXT_HORDE_FLAG_DROPPED = 9806,
- BG_WS_TEXT_ALLIANCE_FLAG_RETURNED = 9808,
- BG_WS_TEXT_HORDE_FLAG_RETURNED = 9809,
-};
-
-enum BG_WS_Sound
-{
- BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE = 8173,
- BG_WS_SOUND_FLAG_CAPTURED_HORDE = 8213,
- BG_WS_SOUND_FLAG_PLACED = 8232,
- BG_WS_SOUND_FLAG_RETURNED = 8192,
- BG_WS_SOUND_HORDE_FLAG_PICKED_UP = 8212,
- BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP = 8174,
- BG_WS_SOUND_FLAGS_RESPAWNED = 8232
-};
-
-enum BG_WS_SpellId
-{
- BG_WS_SPELL_WARSONG_FLAG = 23333,
- BG_WS_SPELL_WARSONG_FLAG_DROPPED = 23334,
- //BG_WS_SPELL_WARSONG_FLAG_PICKED = 61266,
- BG_WS_SPELL_SILVERWING_FLAG = 23335,
- BG_WS_SPELL_SILVERWING_FLAG_DROPPED = 23336,
- //BG_WS_SPELL_SILVERWING_FLAG_PICKED = 61265,
- BG_WS_SPELL_FOCUSED_ASSAULT = 46392,
- BG_WS_SPELL_BRUTAL_ASSAULT = 46393,
- BG_WS_SPELL_QUICK_CAP_TIMER = 183317, // serverside
-};
-
-enum BG_WS_WorldStates
-{
- BG_WS_FLAG_STATE_ALLIANCE = 1545,
- BG_WS_FLAG_STATE_HORDE = 1546,
- BG_WS_FLAG_STATE_NEUTRAL = 1547, // unused
- BG_WS_HORDE_FLAG_COUNT_PICKED_UP = 17712, // brawl
- BG_WS_ALLIANCE_FLAG_COUNT_PICKED_UP = 17713, // brawl
- BG_WS_FLAG_CAPTURES_ALLIANCE = 1581,
- BG_WS_FLAG_CAPTURES_HORDE = 1582,
- BG_WS_FLAG_CAPTURES_MAX = 1601,
- BG_WS_FLAG_CAPTURES_MAX_NEW = 17303,
- BG_WS_FLAG_CONTROL_HORDE = 2338,
- BG_WS_FLAG_CONTROL_ALLIANCE = 2339,
- BG_WS_STATE_TIMER = 4248,
- BG_WS_STATE_TIMER_ACTIVE = 4247
-};
-
-// save the day
-// alliance criteria: BG_WS_FLAG_STATE_HORDE == 1 && BG_WS_FLAG_STATE_NEUTRAL == 0 && WS(1664) > 0
-// horde criteria: BG_WS_FLAG_STATE_ALLIANCE == 1 && BG_WS_FLAG_STATE_NEUTRAL == 0 && WS(1664) > 0
-
-enum BG_WS_ExploitTeleportLocations
-{
- WS_EXPLOIT_TELEPORT_LOCATION_ALLIANCE = 7051,
- WS_EXPLOIT_TELEPORT_LOCATION_HORDE = 7050
-};
-
-enum BG_WS_ObjectEntry
-{
- // doors
- BG_WS_OBJECT_ALLIANCE_DOOR = 309704,
- BG_WS_OBJECT_PORTCULLIS_009 = 309705, // Doodad_7NE_Blackrook_Portcullis009
- BG_WS_OBJECT_PORTCULLIS_002 = 309883, // Doodad_7NE_Blackrook_Portcullis002
- BG_WS_OBJECT_COLLISION_PC_SIZE = 242273,
- BG_WS_OBJECT_HORDE_GATE_1 = 352709,
- BG_WS_OBJECT_HORDE_GATE_2 = 352710,
-
- // flags
- BG_WS_OBJECT_ALLIANCE_FLAG_IN_BASE = 227741,
- BG_WS_OBJECT_HORDE_FLAG_IN_BASE = 227740
-};
-
-enum BG_WS_CarrierDebuffs
-{
- WS_SPELL_FOCUSED_ASSAULT = 46392,
- WS_SPELL_BRUTAL_ASSAULT = 46393,
-
- SPELL_CAPTURED_ALLIANCE_COSMETIC_FX = 262508,
- SPELL_CAPTURED_HORDE_COSMETIC_FX = 262512,
-};
-
-enum BG_WS_AreaTriggers
-{
- AT_CAPTURE_POINT_ALLIANCE = 30,
- AT_CAPTURE_POINT_HORDE = 31
-};
-
-static constexpr uint32 WS_EVENT_START_BATTLE = 35912;
-
-static constexpr Seconds FLAG_ASSAULT_TIMER = 30s;
-static constexpr uint16 FLAG_BRUTAL_ASSAULT_STACK_COUNT = 5;
-
-class BattlegroundWS : public Battleground
-{
- public:
- /* Construction */
- BattlegroundWS(BattlegroundTemplate const* battlegroundTemplate);
- ~BattlegroundWS();
-
- /* inherited from BattlegroundClass */
- void StartingEventOpenDoors() override;
-
- /* BG Flags */
- FlagState GetFlagState(TeamId team) const;
- ObjectGuid const& GetFlagCarrierGUID(TeamId team) const;
- void HandleFlagRoomCapturePoint();
-
- void HandleKillPlayer(Player* player, Player* killer) override;
- bool SetupBattleground() override;
- void Reset() override;
- void EndBattleground(Team winner) override;
- WorldSafeLocsEntry const* GetClosestGraveyard(Player* player) override;
- WorldSafeLocsEntry const* GetExploitTeleportLocation(Team team) override;
-
- void UpdateFlagState(uint32 team, FlagState value);
- void SetLastFlagCapture(Team team) { _lastFlagCaptureTeam = team; }
- void UpdateTeamScore(TeamId team);
-
- /* Scorekeeping */
- void AddPoint(Team team, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(team)] += Points; }
- void SetTeamPoint(Team team, uint32 Points = 0) { m_TeamScores[GetTeamIndexByTeamId(team)] = Points; }
- void RemovePoint(Team team, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(team)] -= Points; }
-
- Team GetPrematureWinner() override;
-
- void OnGameObjectCreate(GameObject* gameObject) override;
- void OnAreaTriggerCreate(AreaTrigger* areaTrigger) override;
- void OnFlagStateChange(GameObject* flagInBase, FlagState oldValue, FlagState newValue, Player* player) override;
-
- bool CanCaptureFlag(AreaTrigger* areatrigger, Player* player) override;
- void OnCaptureFlag(AreaTrigger* areatrigger, Player* player) override;
-
- protected:
- void PostUpdateImpl(uint32 diff) override;
- void DoForFlagKeepers(std::function<void(Player*)> action) const;
-
- // Focused & Brutal Assault debuffs
- void ResetAssaultDebuff();
- void ApplyAssaultDebuffToPlayer(Player* player);
- void RemoveAssaultDebuffFromPlayer(Player* player);
-
- private:
- Team _lastFlagCaptureTeam; // Winner is based on this if score is equal
-
- uint32 m_ReputationCapture;
- uint32 m_HonorWinKills;
- uint32 m_HonorEndKills;
- bool _bothFlagsKept;
-
- GuidSet _doors;
- std::array<ObjectGuid, 2> _flags;
-
- TimeTracker _flagAssaultTimer;
- uint16 _assaultStackCount;
- std::array<ObjectGuid, 2> _capturePointAreaTriggers;
-};
-#endif
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 3e016ae273b..914d38885cf 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -20,7 +20,7 @@
#include "AreaTrigger.h"
#include "AreaTriggerDataStore.h"
#include "BattlePetMgr.h"
-#include "Battleground.h"
+#include "BattlegroundScript.h"
#include "Containers.h"
#include "ConversationDataStore.h"
#include "DB2Stores.h"
@@ -232,7 +232,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const
}
else if (BattlegroundMap const* bgMap = map->ToBattlegroundMap())
{
- ZoneScript const* zoneScript = bgMap->GetBG();
+ ZoneScript const* zoneScript = bgMap->GetBattlegroundScript();
switch (ConditionValue3)
{
case INSTANCE_INFO_DATA:
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index ec3b687283e..a716b233621 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -2264,8 +2264,6 @@ bool GameObject::ActivateToQuest(Player const* target) const
|| LootTemplates_Gameobject.HaveQuestLootForPlayer(GetGOInfo()->chest.chestPersonalLoot, target)
|| LootTemplates_Gameobject.HaveQuestLootForPlayer(GetGOInfo()->chest.chestPushLoot, target))
{
- if (Battleground const* bg = target->GetBattleground())
- return bg->CanActivateGO(GetEntry(), bg->GetPlayerTeam(target->GetGUID()));
return true;
}
break;
@@ -2576,10 +2574,6 @@ void GameObject::Use(Unit* user)
if (!player)
return;
- if (Battleground* bg = player->GetBattleground())
- if (!bg->CanActivateGO(GetEntry(), bg->GetPlayerTeam(user->GetGUID())))
- return;
-
GameObjectTemplate const* info = GetGOInfo();
if (!m_loot && info->GetLootId())
{
@@ -3119,24 +3113,11 @@ void GameObject::Use(Unit* user)
if (player->CanUseBattlegroundObject(this))
{
- // in battleground check
- Battleground* bg = player->GetBattleground();
- if (!bg)
- return;
-
if (player->GetVehicle())
return;
player->RemoveAurasByType(SPELL_AURA_MOD_STEALTH);
player->RemoveAurasByType(SPELL_AURA_MOD_INVISIBILITY);
- // BG flag click
- // AB:
- // 15001
- // 15002
- // 15003
- // 15004
- // 15005
- bg->EventPlayerClickedOnFlag(player, this);
return; //we don;t need to delete flag ... it is despawned!
}
break;
@@ -3167,11 +3148,6 @@ void GameObject::Use(Unit* user)
if (player->CanUseBattlegroundObject(this))
{
- // in battleground check
- Battleground* bg = player->GetBattleground();
- if (!bg)
- return;
-
if (player->GetVehicle())
return;
@@ -3184,24 +3160,8 @@ void GameObject::Use(Unit* user)
// EotS:
// 184142 - Netherstorm Flag
GameObjectTemplate const* info = GetGOInfo();
- if (info)
- {
- switch (info->entry)
- {
- case 179785: // Silverwing Flag
- case 179786: // Warsong Flag
- if (bg->GetTypeID() == BATTLEGROUND_WS)
- bg->EventPlayerClickedOnFlag(player, this);
- break;
- case 184142: // Netherstorm Flag
- if (bg->GetTypeID() == BATTLEGROUND_EY)
- bg->EventPlayerClickedOnFlag(player, this);
- break;
- }
-
- if (info->flagDrop.eventID)
- GameEvents::Trigger(info->flagDrop.eventID, player, this);
- }
+ if (info->flagDrop.eventID)
+ GameEvents::Trigger(info->flagDrop.eventID, player, this);
//this cause to call return, all flags must be deleted here!!
spellId = 0;
Delete();
@@ -3705,10 +3665,6 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, WorldOb
GameEvents::Trigger(GetGOInfo()->destructibleBuilding.DestroyedEvent, attackerOrHealer, this);
AI()->Destroyed(attackerOrHealer, m_goInfo->destructibleBuilding.DestroyedEvent);
- if (Player* player = attackerOrHealer ? attackerOrHealer->GetCharmerOrOwnerPlayerOrPlayerItself() : nullptr)
- if (Battleground* bg = player->GetBattleground())
- bg->DestroyGate(player, this);
-
RemoveFlag(GO_FLAG_DAMAGED);
SetFlag(GO_FLAG_DESTROYED);
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 07d40b0c518..2906899aaaa 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -2010,7 +2010,7 @@ ZoneScript* WorldObject::FindZoneScript() const
if (InstanceMap* instanceMap = map->ToInstanceMap())
return reinterpret_cast<ZoneScript*>(instanceMap->GetInstanceScript());
if (BattlegroundMap* bgMap = map->ToBattlegroundMap())
- return reinterpret_cast<ZoneScript*>(bgMap->GetBG());
+ return reinterpret_cast<ZoneScript*>(bgMap->GetBattlegroundScript());
if (!map->IsBattlegroundOrArena())
{
if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(map, GetZoneId()))
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 49ce1431de5..484b18cd4a3 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -4403,12 +4403,6 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
UpdateZone(newzone, newarea);
sOutdoorPvPMgr->HandlePlayerResurrects(this, newzone);
- if (InBattleground())
- {
- if (Battleground* bg = GetBattleground())
- bg->HandlePlayerResurrect(this);
- }
-
// update visibility
UpdateObjectVisibility();
@@ -4796,9 +4790,7 @@ void Player::RepopAtGraveyard()
}
WorldSafeLocsEntry const* closestGrave = nullptr;
- if (Battleground* bg = GetBattleground())
- closestGrave = bg->GetClosestGraveyard(this);
- else if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(GetMap(), GetZoneId()))
+ if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(GetMap(), GetZoneId()))
closestGrave = bf->GetClosestGraveyard(this);
else if (InstanceScript* instance = GetInstanceScript())
closestGrave = sObjectMgr->GetWorldSafeLoc(instance->GetEntranceLocation());
@@ -24933,11 +24925,6 @@ void Player::SummonIfPossible(bool agree)
// stop taxi flight at summon
FinishTaxiFlight();
- // drop flag at summon
- // this code can be reached only when GM is summoning player who carries flag, because player should be immune to summoning spells when he carries flag
- if (Battleground* bg = GetBattleground())
- bg->EventPlayerDroppedFlag(this);
-
m_summon_expire = 0;
UpdateCriteria(CriteriaType::AcceptSummon, 1);
diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp
index 1d5a4abede9..f68486d7439 100644
--- a/src/server/game/Entities/Vehicle/Vehicle.cpp
+++ b/src/server/game/Entities/Vehicle/Vehicle.cpp
@@ -846,10 +846,6 @@ bool VehicleJoinEvent::Execute(uint64, uint32)
Player* player = Passenger->ToPlayer();
if (player)
{
- // drop flag
- if (Battleground* bg = player->GetBattleground())
- bg->EventPlayerDroppedFlag(player);
-
player->StopCastingCharm();
player->StopCastingBindSight();
player->SendOnCancelExpectedVehicleRideAura();
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index d67c146c2f2..dc2234584c2 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -573,9 +573,6 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPackets::AreaTrigger::AreaTrigge
return;
}
- if (Battleground* bg = player->GetBattleground())
- bg->HandleAreaTrigger(player, packet.AreaTriggerID, packet.Entered);
-
if (OutdoorPvP* pvp = player->GetOutdoorPvP())
if (pvp->HandleAreaTrigger(_player, packet.AreaTriggerID, packet.Entered))
return;
diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp
index 3c086d612ec..4b5909fcb39 100644
--- a/src/server/game/Handlers/QuestHandler.cpp
+++ b/src/server/game/Handlers/QuestHandler.cpp
@@ -378,9 +378,6 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPackets::Quest::Quest
{
if (_player->CanRewardQuest(quest, packet.Choice.LootItemType, packet.Choice.Item.ItemID, true)) // Then check if player can receive the reward item (if inventory is not full, if player doesn't have too many unique items, and so on). If not, the client will close the gossip window
{
- if (Battleground* bg = _player->GetBattleground())
- bg->HandleQuestComplete(packet.QuestID, _player);
-
_player->RewardQuest(quest, packet.Choice.LootItemType, packet.Choice.Item.ItemID, object);
}
}
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index b603d704f97..aa0f35abf15 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -17,6 +17,8 @@
#include "Map.h"
#include "Battleground.h"
+#include "BattlegroundMgr.h"
+#include "BattlegroundScript.h"
#include "CellImpl.h"
#include "CharacterPackets.h"
#include "Containers.h"
@@ -3385,7 +3387,7 @@ TeamId InstanceMap::GetTeamIdInInstance() const
/* ******* Battleground Instance Maps ******* */
BattlegroundMap::BattlegroundMap(uint32 id, time_t expiry, uint32 InstanceId, Difficulty spawnMode)
- : Map(id, expiry, InstanceId, spawnMode), m_bg(nullptr)
+ : Map(id, expiry, InstanceId, spawnMode), m_bg(nullptr), _battlegroundScript(nullptr), _scriptId(0)
{
//lets initialize visibility distance for BG/Arenas
BattlegroundMap::InitVisibilityDistance();
@@ -3408,6 +3410,36 @@ void BattlegroundMap::InitVisibilityDistance()
m_VisibilityNotifyPeriod = IsBattleArena() ? World::GetVisibilityNotifyPeriodInArenas() : World::GetVisibilityNotifyPeriodInBG();
}
+std::string const& BattlegroundMap::GetScriptName() const
+{
+ return sObjectMgr->GetScriptName(_scriptId);
+}
+
+void BattlegroundMap::InitScriptData()
+{
+ if (_battlegroundScript)
+ return;
+
+ ASSERT(GetBG(), "Battleground not set yet!");
+
+ if (BattlegroundScriptTemplate const* scriptTemplate = sBattlegroundMgr->FindBattlegroundScriptTemplate(GetId(), GetBG()->GetTypeID()))
+ {
+ _scriptId = scriptTemplate->ScriptId;
+ _battlegroundScript.reset(sScriptMgr->CreateBattlegroundData(this));
+ }
+
+ // Make sure every battleground has a default script
+ if (!_battlegroundScript)
+ {
+ if (IsBattleArena())
+ _battlegroundScript = std::make_unique<ArenaScript>(this);
+ else
+ _battlegroundScript = std::make_unique<BattlegroundScript>(this);
+ }
+
+ _battlegroundScript->OnInit();
+}
+
TransferAbortParams BattlegroundMap::CannotEnter(Player* player)
{
if (player->GetMapRef().getTarget() == this)
@@ -3451,6 +3483,12 @@ void BattlegroundMap::RemoveAllPlayers()
player->TeleportTo(player->GetBattlegroundEntryPoint());
}
+void BattlegroundMap::Update(uint32 diff)
+{
+ Map::Update(diff);
+ _battlegroundScript->OnUpdate(diff);
+}
+
AreaTrigger* Map::GetAreaTrigger(ObjectGuid const& guid)
{
return _objectsStore.Find<AreaTrigger>(guid);
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 0339d92a6ee..901e03e0264 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -46,6 +46,7 @@
class Battleground;
class BattlegroundMap;
+class BattlegroundScript;
class CreatureGroup;
class GameObjectModel;
class Group;
@@ -909,12 +910,22 @@ class TC_GAME_API BattlegroundMap : public Map
void SetUnload();
//void UnloadAll(bool pForce);
void RemoveAllPlayers() override;
+ void Update(uint32 diff) override;
virtual void InitVisibilityDistance() override;
Battleground* GetBG() const { return m_bg; }
void SetBG(Battleground* bg) { m_bg = bg; }
+
+ uint32 GetScriptId() const { return _scriptId; }
+ std::string const& GetScriptName() const;
+ BattlegroundScript* GetBattlegroundScript() { return _battlegroundScript.get(); }
+ BattlegroundScript const* GetBattlegroundScript() const { return _battlegroundScript.get(); }
+
+ void InitScriptData();
private:
Battleground* m_bg;
+ std::unique_ptr<BattlegroundScript> _battlegroundScript;
+ uint32 _scriptId;
};
template<class T, class CONTAINER>
diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp
index 87f2bbe160a..4f2153e6bee 100644
--- a/src/server/game/Maps/MapManager.cpp
+++ b/src/server/game/Maps/MapManager.cpp
@@ -127,6 +127,7 @@ BattlegroundMap* MapManager::CreateBattleground(uint32 mapId, uint32 instanceId,
ASSERT(map->IsBattlegroundOrArena());
map->SetBG(bg);
bg->SetBgMap(map);
+ map->InitScriptData();
map->InitSpawnGroupState();
if (sWorld->getBoolConfig(CONFIG_BATTLEGROUNDMAP_LOAD_GRIDS))
diff --git a/src/server/game/Maps/ZoneScript.h b/src/server/game/Maps/ZoneScript.h
index 370a2f6e239..3fd9e85aa19 100644
--- a/src/server/game/Maps/ZoneScript.h
+++ b/src/server/game/Maps/ZoneScript.h
@@ -92,7 +92,7 @@ class TC_GAME_API ZoneScript
virtual void SetData(uint32 /*DataId*/, uint32 /*Value*/) { }
virtual void TriggerGameEvent(uint32 gameEventId, WorldObject* source = nullptr, WorldObject* target = nullptr);
- virtual void ProcessEvent(WorldObject* /*obj*/, uint32 /*eventId*/, WorldObject* /*invoker*/) { }
+ virtual void ProcessEvent([[maybe_unused]] WorldObject* obj, [[maybe_unused]] uint32 eventId, [[maybe_unused]] WorldObject* invoker) { }
virtual void DoAction([[maybe_unused]] uint32 actionId, [[maybe_unused]] WorldObject* source = nullptr, [[maybe_unused]] WorldObject* target = nullptr) { }
virtual void OnFlagStateChange([[maybe_unused]] GameObject* flagInBase, [[maybe_unused]] FlagState oldValue, [[maybe_unused]] FlagState newValue, [[maybe_unused]] Player* player) { }
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index 76a51e0795f..e69b64a73fa 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -90,7 +90,7 @@ struct is_script_database_bound<BattlefieldScript>
: std::true_type { };
template<>
-struct is_script_database_bound<BattlegroundScript>
+struct is_script_database_bound<BattlegroundMapScript>
: std::true_type { };
template<>
@@ -754,11 +754,6 @@ template<typename Base>
class ScriptRegistrySwapHooks<BattlefieldScript, Base>
: public UnsupportedScriptRegistrySwapHooks<Base> { };
-/// This hook is responsible for swapping BattlegroundScript's
-template<typename Base>
-class ScriptRegistrySwapHooks<BattlegroundScript, Base>
- : public UnsupportedScriptRegistrySwapHooks<Base> { };
-
/// This hook is responsible for swapping OutdoorPvP's
template<typename Base>
class ScriptRegistrySwapHooks<OutdoorPvPScript, Base>
@@ -826,6 +821,35 @@ private:
bool swapped;
};
+/// This hook is responsible for swapping BattlegroundMapScript's
+template<typename Base>
+class ScriptRegistrySwapHooks<BattlegroundMapScript, Base>
+ : public ScriptRegistrySwapHookBase
+{
+public:
+ ScriptRegistrySwapHooks() : swapped(false) { }
+
+ void BeforeReleaseContext(std::string const& context) final override
+ {
+ auto const bounds = static_cast<Base*>(this)->_ids_of_contexts.equal_range(context);
+ if (bounds.first != bounds.second)
+ swapped = true;
+ }
+
+ void BeforeSwapContext(bool /*initialize*/) override
+ {
+ swapped = false;
+ }
+
+ void BeforeUnload() final override
+ {
+ ASSERT(!swapped);
+ }
+
+private:
+ bool swapped;
+};
+
/// This hook is responsible for swapping SceneScript's
template<typename Base>
class ScriptRegistrySwapHooks<SceneScript, Base>
@@ -1623,6 +1647,14 @@ InstanceScript* ScriptMgr::CreateInstanceData(InstanceMap* map)
return tmpscript->GetInstanceScript(map);
}
+BattlegroundScript* ScriptMgr::CreateBattlegroundData(BattlegroundMap* map)
+{
+ ASSERT(map);
+
+ GET_SCRIPT_RET(BattlegroundMapScript, map->GetScriptId(), tmpscript, NULL);
+ return tmpscript->GetBattlegroundScript(map);
+}
+
bool ScriptMgr::OnQuestAccept(Player* player, Item* item, Quest const* quest)
{
ASSERT(player);
@@ -1726,13 +1758,6 @@ Battlefield* ScriptMgr::CreateBattlefield(uint32 scriptId, Map* map)
return tmpscript->GetBattlefield(map);
}
-Battleground* ScriptMgr::CreateBattleground(BattlegroundTypeId /*typeId*/)
-{
- /// @todo Implement script-side battlegrounds.
- ABORT();
- return nullptr;
-}
-
OutdoorPvP* ScriptMgr::CreateOutdoorPvP(uint32 scriptId, Map* map)
{
GET_SCRIPT_RET(OutdoorPvPScript, scriptId, tmpscript, nullptr);
@@ -2582,6 +2607,11 @@ BattlegroundMapScript::BattlegroundMapScript(char const* name, uint32 mapId)
BattlegroundMapScript::~BattlegroundMapScript() = default;
+BattlegroundScript* BattlegroundMapScript::GetBattlegroundScript(BattlegroundMap* /*map*/) const
+{
+ return nullptr;
+}
+
ItemScript::ItemScript(char const* name)
: ScriptObject(name)
{
@@ -2702,14 +2732,6 @@ BattlefieldScript::BattlefieldScript(char const* name)
BattlefieldScript::~BattlefieldScript() = default;
-BattlegroundScript::BattlegroundScript(char const* name)
- : ScriptObject(name)
-{
- ScriptRegistry<BattlegroundScript>::Instance()->AddScript(this);
-}
-
-BattlegroundScript::~BattlegroundScript() = default;
-
OutdoorPvPScript::OutdoorPvPScript(char const* name)
: ScriptObject(name)
{
@@ -3247,7 +3269,6 @@ template class TC_GAME_API ScriptRegistry<CreatureScript>;
template class TC_GAME_API ScriptRegistry<GameObjectScript>;
template class TC_GAME_API ScriptRegistry<AreaTriggerScript>;
template class TC_GAME_API ScriptRegistry<BattlefieldScript>;
-template class TC_GAME_API ScriptRegistry<BattlegroundScript>;
template class TC_GAME_API ScriptRegistry<OutdoorPvPScript>;
template class TC_GAME_API ScriptRegistry<CommandScript>;
template class TC_GAME_API ScriptRegistry<WeatherScript>;
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index fe3fb48df79..31a5842a383 100644
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -35,6 +35,7 @@ class AuraScript;
class Battlefield;
class Battleground;
class BattlegroundMap;
+class BattlegroundScript;
class Channel;
class Conversation;
class Creature;
@@ -372,6 +373,9 @@ class TC_GAME_API BattlegroundMapScript : public ScriptObject, public MapScript<
public:
~BattlegroundMapScript();
+
+ // Gets an BattlegroundScript object for this battleground.
+ virtual BattlegroundScript* GetBattlegroundScript(BattlegroundMap* map) const;
};
class TC_GAME_API ItemScript : public ScriptObject
@@ -501,20 +505,6 @@ class TC_GAME_API BattlefieldScript : public ScriptObject
virtual Battlefield* GetBattlefield(Map* map) const = 0;
};
-class TC_GAME_API BattlegroundScript : public ScriptObject
-{
- protected:
-
- explicit BattlegroundScript(char const* name);
-
- public:
-
- ~BattlegroundScript();
-
- // Should return a fully valid Battleground object for the type ID.
- virtual Battleground* GetBattleground() const = 0;
-};
-
class TC_GAME_API OutdoorPvPScript : public ScriptObject
{
protected:
@@ -1151,7 +1141,7 @@ class TC_GAME_API ScriptMgr
public: /* BattlegroundScript */
- Battleground* CreateBattleground(BattlegroundTypeId typeId);
+ BattlegroundScript* CreateBattlegroundData(BattlegroundMap* map);
public: /* OutdoorPvPScript */
@@ -1415,6 +1405,16 @@ class GenericAreaTriggerEntityScript : public AreaTriggerEntityScript
};
#define RegisterAreaTriggerAI(ai_name) new GenericAreaTriggerEntityScript<ai_name>(#ai_name)
+template<class Script>
+class GenericBattlegroundMapScript : public BattlegroundMapScript
+{
+public:
+ GenericBattlegroundMapScript(char const* name, uint32 mapId) : BattlegroundMapScript(name, mapId) { }
+
+ BattlegroundScript* GetBattlegroundScript(BattlegroundMap* map) const override { return new Script(map); }
+};
+#define RegisterBattlegroundMapScript(script_name, mapId) new GenericBattlegroundMapScript<script_name>(#script_name, mapId)
+
#define sScriptMgr ScriptMgr::instance()
#endif
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index cfd10dda464..11f71181bd4 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -3396,12 +3396,7 @@ void AuraEffect::HandleAuraModEffectImmunity(AuraApplication const* aurApp, uint
Player* player = target->ToPlayer();
if (!apply && player && GetSpellInfo()->HasAuraInterruptFlag(SpellAuraInterruptFlags::StealthOrInvis))
{
- if (player->InBattleground())
- {
- if (Battleground* bg = player->GetBattleground())
- bg->EventPlayerDroppedFlag(player);
- }
- else
+ if (!player->InBattleground())
sOutdoorPvPMgr->HandleDropFlag(player, GetSpellInfo()->Id);
}
}
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index e3832c59130..635d0501417 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -1592,18 +1592,7 @@ void Spell::EffectOpenLock()
if (goInfo->GetNoDamageImmune() && player->HasUnitFlag(UNIT_FLAG_IMMUNE))
return;
- if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
- {
- //CanUseBattlegroundObject() already called in CheckCast()
- // in battleground check
- if (Battleground* bg = player->GetBattleground())
- {
- if (bg->GetTypeID() == BATTLEGROUND_EY)
- bg->EventPlayerClickedOnFlag(player, gameObjTarget);
- return;
- }
- }
- else if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP && gameObjTarget->GetOwner())
+ if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP && gameObjTarget->GetOwner())
{
gameObjTarget->SetLootState(GO_JUST_DEACTIVATED);
return;
@@ -2968,11 +2957,6 @@ void Spell::EffectSummonObjectWild()
// Wild object not have owner and check clickable by players
map->AddToMap(go);
- if (go->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP)
- if (Player* player = m_caster->ToPlayer())
- if (Battleground* bg = player->GetBattleground())
- bg->SetDroppedFlagGUID(go->GetGUID(), bg->GetPlayerTeam(player->GetGUID()) == ALLIANCE ? TEAM_HORDE: TEAM_ALLIANCE);
-
if (GameObject* linkedTrap = go->GetLinkedTrap())
{
PhasingHandler::InheritPhaseShift(linkedTrap , m_caster);
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 68373ed3ea4..e3c4ba51132 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -743,12 +743,6 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32
if (!player || (auraSpell > 0 && !player->HasAura(auraSpell)) || (auraSpell < 0 && player->HasAura(-auraSpell)))
return false;
- if (player)
- {
- if (Battleground* bg = player->GetBattleground())
- return bg->IsSpellAllowed(spellId, player);
- }
-
// Extra conditions
switch (spellId)
{
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 745a5e3b8a3..36b8120fa77 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -2465,6 +2465,7 @@ void World::SetInitialWorldSettings()
///- Initialize Battlegrounds
TC_LOG_INFO("server.loading", "Starting Battleground System");
sBattlegroundMgr->LoadBattlegroundTemplates();
+ sBattlegroundMgr->LoadBattlegroundScriptTemplate();
///- Initialize outdoor pvp
TC_LOG_INFO("server.loading", "Starting Outdoor PvP System");
diff --git a/src/server/scripts/EasternKingdoms/AlteracValley/alterac_valley.cpp b/src/server/scripts/Battlegrounds/AlteracValley/alterac_valley.cpp
index 629be86a525..94af6a25a53 100644
--- a/src/server/scripts/EasternKingdoms/AlteracValley/alterac_valley.cpp
+++ b/src/server/scripts/Battlegrounds/AlteracValley/alterac_valley.cpp
@@ -15,8 +15,9 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "alterac_valley.h"
#include "ScriptMgr.h"
-#include "BattlegroundAV.h"
+#include "Battleground.h"
#include "GameObject.h"
#include "GameObjectAI.h"
#include "Player.h"
@@ -192,10 +193,36 @@ public:
}
};
+template<AlteracValleySharedActions ActionId>
+class quest_alterac_valley : public QuestScript
+{
+public:
+ quest_alterac_valley(char const* scriptName) : QuestScript(scriptName) { }
+
+ void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override
+ {
+ if (newStatus != QUEST_STATUS_REWARDED)
+ return;
+
+ if (ZoneScript* zoneScript = player->FindZoneScript())
+ zoneScript->DoAction(ActionId, player, player);
+ }
+};
+
void AddSC_alterac_valley()
{
RegisterCreatureAI(npc_av_marshal_or_warmaster);
RegisterGameObjectAI(go_av_capturable_object);
RegisterGameObjectAI(go_av_contested_object);
new at_av_exploit();
+ new quest_alterac_valley<ACTION_TURN_IN_SCRAPS>("quest_alterac_valley_armor_scraps");
+ new quest_alterac_valley<ACTION_TURN_IN_COMMANDER_1>("quest_alterac_valley_call_of_air_slidore_guse");
+ new quest_alterac_valley<ACTION_TURN_IN_COMMANDER_2>("quest_alterac_valley_call_of_air_vipore_jeztor");
+ new quest_alterac_valley<ACTION_TURN_IN_COMMANDER_3>("quest_alterac_valley_call_of_air_ichman_mulverick");
+ new quest_alterac_valley<ACTION_TURN_IN_BOSS_1>("quest_alterac_valley_boss_5");
+ new quest_alterac_valley<ACTION_TURN_IN_BOSS_2>("quest_alterac_valley_boss_1");
+ new quest_alterac_valley<ACTION_TURN_IN_NEAR_MINE>("quest_alterac_valley_near_mine");
+ new quest_alterac_valley<ACTION_TURN_IN_OTHER_MINE>("quest_alterac_valley_other_mine");
+ new quest_alterac_valley<ACTION_TURN_IN_RIDER_HIDE>("quest_alterac_valley_ram_harnesses");
+ new quest_alterac_valley<ACTION_TURN_IN_RIDER_TAME>("quest_alterac_valley_empty_stables");
}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundBFG.cpp b/src/server/scripts/Battlegrounds/AlteracValley/alterac_valley.h
index 1d59b6a6b0d..4bd5dea255a 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundBFG.cpp
+++ b/src/server/scripts/Battlegrounds/AlteracValley/alterac_valley.h
@@ -15,12 +15,25 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "BattlegroundBFG.h"
+#ifndef __ALTERAC_VALLEY_H
+#define __ALTERAC_VALLEY_H
-BattlegroundBFG::BattlegroundBFG(BattlegroundTemplate const* battlegroundTemplate) : Battleground(battlegroundTemplate)
+enum AlteracValleySharedActions
{
-}
+ ACTION_BUFF_YELL = -30001,
+ ACTION_AV_INTERACT_CAPTURABLE_OBJECT = 1,
+ ACTION_AV_CAPTURE_CAPTURABLE_OBJECT = 2,
-BattlegroundBFG::~BattlegroundBFG()
-{
-}
+ ACTION_TURN_IN_SCRAPS = 3,
+ ACTION_TURN_IN_COMMANDER_1 = 4,
+ ACTION_TURN_IN_COMMANDER_2 = 5,
+ ACTION_TURN_IN_COMMANDER_3 = 6,
+ ACTION_TURN_IN_BOSS_1,
+ ACTION_TURN_IN_BOSS_2,
+ ACTION_TURN_IN_NEAR_MINE,
+ ACTION_TURN_IN_OTHER_MINE,
+ ACTION_TURN_IN_RIDER_HIDE,
+ ACTION_TURN_IN_RIDER_TAME
+};
+
+#endif
diff --git a/src/server/scripts/Battlegrounds/AlteracValley/battleground_alterac_valley.cpp b/src/server/scripts/Battlegrounds/AlteracValley/battleground_alterac_valley.cpp
new file mode 100644
index 00000000000..1616b77ec1e
--- /dev/null
+++ b/src/server/scripts/Battlegrounds/AlteracValley/battleground_alterac_valley.cpp
@@ -0,0 +1,1369 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "BattlegroundScript.h"
+#include "alterac_valley.h"
+#include "Battleground.h"
+#include "BattlegroundMgr.h"
+#include "BattlegroundPackets.h"
+#include "Creature.h"
+#include "CreatureAI.h"
+#include "GameObject.h"
+#include "GameTime.h"
+#include "Log.h"
+#include "Map.h"
+#include "Player.h"
+#include "ScriptMgr.h"
+
+constexpr uint32 BG_AV_SCORE_INITIAL_POINTS = 700;
+constexpr uint32 BG_AV_EVENT_START_BATTLE = 9166; // Achievement: The Alterac Blitz
+
+enum BG_AV_BroadcastTexts
+{
+ BG_AV_TEXT_START_ONE_MINUTE = 10638,
+ BG_AV_TEXT_START_HALF_MINUTE = 10639,
+ BG_AV_TEXT_BATTLE_HAS_BEGUN = 10640,
+
+ BG_AV_TEXT_ALLIANCE_NEAR_LOSE = 23210,
+ BG_AV_TEXT_HORDE_NEAR_LOSE = 23211
+};
+
+enum BG_AV_Sounds
+{
+ AV_SOUND_NEAR_VICTORY = 8456, /// @todo: Not confirmed yet
+
+ AV_SOUND_ALLIANCE_ASSAULTS = 8212, //tower, grave + enemy boss if someone tries to attack him
+ AV_SOUND_HORDE_ASSAULTS = 8174,
+ AV_SOUND_ALLIANCE_GOOD = 8173, //if something good happens for the team: wins(maybe only through killing the boss), captures mine or grave, destroys tower and defends grave
+ AV_SOUND_HORDE_GOOD = 8213,
+ AV_SOUND_BOTH_TOWER_DEFEND = 8192,
+
+ AV_SOUND_ALLIANCE_CAPTAIN = 8232, //gets called when someone attacks them and at the beginning after 5min+rand(x)*10sec (maybe buff)
+ AV_SOUND_HORDE_CAPTAIN = 8333
+};
+
+constexpr Seconds BG_AV_MINE_RESOURCE_TIMER = 45s;
+
+enum class AlteracValleyMine : uint8
+{
+ North = 0,
+ South
+};
+
+enum BG_AV_CreatureIds
+{
+ BG_AV_CREATURE_VANNDAR = 11948,
+ BG_AV_CREATURE_DREKTHAR = 11946,
+ BG_AV_CREATURE_BALINDA = 11949,
+ BG_AV_CREATURE_GALVANGAR = 11947,
+ BG_AV_CREATURE_MORLOCH = 11657,
+ BG_AV_CREATURE_UMI_THORSON = 13078,
+ BG_AV_CREATURE_KEETAR = 13079,
+ BG_AV_CREATURE_TASKMASTER_SNIVVLE = 11677,
+ BG_AV_CREATURE_AGI_RUMBLESTOMP = 13086,
+ BG_AV_CREATURE_MASHA_SWIFTCUT = 13088,
+ BG_AV_CREATURE_HERALD = 14848,
+
+ BG_AV_CREATURE_STORMPIKE_DEFENDER = 12050,
+ BG_AV_CREATURE_FROSTWOLF_GUARDIAN = 12053,
+ BG_AV_CREATURE_SEASONED_DEFENDER = 13326,
+ BG_AV_CREATURE_SEASONED_GUARDIAN = 13328,
+ BG_AV_CREATURE_VETERAN_DEFENDER = 13331,
+ BG_AV_CREATURE_VETERAN_GUARDIAN = 13332,
+ BG_AV_CREATURE_CHAMPION_DEFENDER = 13422,
+ BG_AV_CREATURE_CHAMPION_GUARDIAN = 13421
+};
+
+enum BG_AV_ObjectIds
+{
+ //cause the mangos-system is a bit different, we don't use the right go-ids for every node.. if we want to be 100% like another big server, we must take one object for every node
+ //snowfall 4flags as eyecandy 179424 (alliance neutral)
+ //Banners - stolen from battleground_AB.h ;-)
+ BG_AV_OBJECTID_BANNER_A = 178925, // can only be used by horde
+ BG_AV_OBJECTID_BANNER_H = 178943, // can only be used by alliance
+ BG_AV_OBJECTID_BANNER_CONT_A = 178940, // can only be used by horde
+ BG_AV_OBJECTID_BANNER_CONT_H = 179435, // can only be used by alliance
+
+ BG_AV_OBJECTID_BANNER_A_B = 178365,
+ BG_AV_OBJECTID_BANNER_H_B = 178364,
+ BG_AV_OBJECTID_BANNER_CONT_A_B = 179286,
+ BG_AV_OBJECTID_BANNER_CONT_H_B = 179287,
+ BG_AV_OBJECTID_BANNER_SNOWFALL_N = 180418,
+
+ //snowfall eyecandy banner:
+ BG_AV_OBJECTID_SNOWFALL_CANDY_A = 179044,
+ BG_AV_OBJECTID_SNOWFALL_CANDY_PA = 179424,
+ BG_AV_OBJECTID_SNOWFALL_CANDY_H = 179064,
+ BG_AV_OBJECTID_SNOWFALL_CANDY_PH = 179425,
+
+ //banners on top of towers:
+ BG_AV_OBJECTID_TOWER_BANNER_A = 178927, //[PH] Alliance A1 Tower Banner BIG
+ BG_AV_OBJECTID_TOWER_BANNER_H = 178955, //[PH] Horde H1 Tower Banner BIG
+ BG_AV_OBJECTID_TOWER_BANNER_PA = 179446, //[PH] Alliance H1 Tower Pre-Banner BIG
+ BG_AV_OBJECTID_TOWER_BANNER_PH = 179436, //[PH] Horde A1 Tower Pre-Banner BIG
+
+ //Auras
+ BG_AV_OBJECTID_AURA_A = 180421,
+ BG_AV_OBJECTID_AURA_H = 180422,
+ BG_AV_OBJECTID_AURA_N = 180423,
+ BG_AV_OBJECTID_AURA_A_S = 180100,
+ BG_AV_OBJECTID_AURA_H_S = 180101,
+ BG_AV_OBJECTID_AURA_N_S = 180102,
+
+ BG_AV_OBJECTID_GATE = 180424,
+ BG_AV_GHOST_GATE = 180322,
+
+ //mine supplies
+ BG_AV_OBJECTID_MINE_N = 178785,
+ BG_AV_OBJECTID_MINE_S = 178784,
+
+ BG_AV_OBJECTID_FIRE = 179065,
+ BG_AV_OBJECTID_SMOKE = 179066,
+
+ // Towers
+ BG_AV_OBJECTID_SOUTH_BUNKER_CONTROLLED_TOWER_BANNER = 178927,
+ BG_AV_OBJECTID_SOUTH_BUNKER_CONTROLLED_BANNER = 178925,
+ BG_AV_OBJECTID_SOUTH_BUNKER_CONTESTED_BANNER = 179435,
+ BG_AV_OBJECTID_SOUTH_BUNKER_CONTESTED_TOWER_BANNER = 179436,
+
+ BG_AV_OBJECTID_NORTH_BUNKER_CONTROLLED_TOWER_BANNER = 178932,
+ BG_AV_OBJECTID_NORTH_BUNKER_CONTROLLED_BANNER = 178929,
+ BG_AV_OBJECTID_NORTH_BUNKER_CONTESTED_BANNER = 179439,
+ BG_AV_OBJECTID_NORTH_BUNKER_CONTESTED_TOWER_BANNER = 179440,
+
+ BG_AV_OBJECTID_EAST_TOWER_CONTROLLED_TOWER_BANNER = 178956,
+ BG_AV_OBJECTID_EAST_TOWER_CONTROLLED_BANNER = 178944,
+ BG_AV_OBJECTID_EAST_TOWER_CONTESTED_BANNER = 179449,
+ BG_AV_OBJECTID_EAST_TOWER_CONTESTED_TOWER_BANNER = 179450,
+
+ BG_AV_OBJECTID_WEST_TOWER_CONTROLLED_TOWER_BANNER = 178955,
+ BG_AV_OBJECTID_WEST_TOWER_CONTROLLED_BANNER = 178943,
+ BG_AV_OBJECTID_WEST_TOWER_CONTESTED_BANNER = 179445,
+ BG_AV_OBJECTID_WEST_TOWER_CONTESTED_TOWER_BANNER = 179446,
+
+ BG_AV_OBJECTID_TOWER_POINT_CONTROLLED_TOWER_BANNER = 178957,
+ BG_AV_OBJECTID_TOWER_POINT_CONTROLLED_BANNER = 178945,
+ BG_AV_OBJECTID_TOWER_POINT_CONTESTED_BANNER = 179453,
+ BG_AV_OBJECTID_TOWER_POINT_CONTESTED_TOWER_BANNER = 179454,
+
+ BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTROLLED_TOWER_BANNER = 178958,
+ BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTROLLED_BANNER = 178946,
+ BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTESTED_BANNER = 178940,
+ BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTESTED_TOWER_BANNER = 179458,
+
+ BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTROLLED_TOWER_BANNER = 178948,
+ BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTROLLED_BANNER = 178936,
+ BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTESTED_BANNER = 179443,
+ BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTESTED_TOWER_BANNER = 179444,
+
+ BG_AV_OBJECTID_ICEWING_BUNKER_CONTROLLED_TOWER_BANNER = 178947,
+ BG_AV_OBJECTID_ICEWING_BUNKER_CONTROLLED_BANNER = 178935,
+ BG_AV_OBJECTID_ICEWING_BUNKER_CONTESTED_BANNER = 179441,
+ BG_AV_OBJECTID_ICEWING_BUNKER_CONTESTED_TOWER_BANNER = 179442,
+
+ // Graveyards
+ BG_AV_OBJECTID_AID_STATION_ALLIANCE_CONTROLLED = 179465,
+ BG_AV_OBJECTID_AID_STATION_HORDE_CONTESTED = 179468,
+ BG_AV_OBJECTID_AID_STATION_HORDE_CONTROLLED = 179467,
+ BG_AV_OBJECTID_AID_STATION_ALLIANCE_CONTESTED = 179466,
+
+ BG_AV_OBJECTID_STORMPIKE_ALLIANCE_CONTROLLED = 178389,
+ BG_AV_OBJECTID_STORMPIKE_HORDE_CONTESTED = 179287,
+ BG_AV_OBJECTID_STORMPIKE_HORDE_CONTROLLED = 178388,
+ BG_AV_OBJECTID_STORMPIKE_ALLIANCE_CONTESTED = 179286,
+
+ BG_AV_OBJECTID_STONEHEARTH_HORDE_CONTESTED = 179310,
+ BG_AV_OBJECTID_STONEHEARTH_HORDE_CONTROLLED = 179285,
+ BG_AV_OBJECTID_STONEHEARTH_ALLIANCE_CONTESTED = 179308,
+ BG_AV_OBJECTID_STONEHEARTH_ALLIANCE_CONTROLLED = 179284,
+
+ BG_AV_OBJECTID_SNOWFALL_NEUTRAL = 180418,
+ BG_AV_OBJECTID_SNOWFALL_HORDE_CONTESTED = 180420,
+ BG_AV_OBJECTID_SNOWFALL_ALLIANCE_CONTESTED = 180419,
+ BG_AV_OBJECTID_SNOWFALL_HORDE_CONTROLLED = 178364,
+ BG_AV_OBJECTID_SNOWFALL_ALLIANCE_CONTROLLED = 178365,
+
+ BG_AV_OBJECTID_ICEBLOOD_HORDE_CONTROLLED = 179483,
+ BG_AV_OBJECTID_ICEBLOOD_ALLIANCE_CONTESTED = 179482,
+ BG_AV_OBJECTID_ICEBLOOD_ALLIANCE_CONTROLLED = 179481,
+ BG_AV_OBJECTID_ICEBLOOD_HORDE_CONTESTED = 179484,
+
+ BG_AV_OBJECTID_FROSTWOLF_HORDE_CONTROLLED = 178393,
+ BG_AV_OBJECTID_FROSTWOLF_ALLIANCE_CONTESTED = 179304,
+ BG_AV_OBJECTID_FROSTWOLF_ALLIANCE_CONTROLLED = 178394,
+ BG_AV_OBJECTID_FROSTWOLF_HORDE_CONTESTED = 179305,
+
+ BG_AV_OBJECTID_FROSTWOLF_HUT_HORDE_CONTROLLED = 179472,
+ BG_AV_OBJECTID_FROSTWOLF_HUT_ALLIANCE_CONTESTED = 179471,
+ BG_AV_OBJECTID_FROSTWOLF_HUT_ALLIANCE_CONTROLLED = 179470,
+ BG_AV_OBJECTID_FROSTWOLF_HUT_HORDE_CONTESTED = 179473
+};
+
+enum BG_AV_Nodes
+{
+ BG_AV_NODES_FIRSTAID_STATION = 0,
+ BG_AV_NODES_STORMPIKE_GRAVE = 1,
+ BG_AV_NODES_STONEHEART_GRAVE = 2,
+ BG_AV_NODES_SNOWFALL_GRAVE = 3,
+ BG_AV_NODES_ICEBLOOD_GRAVE = 4,
+ BG_AV_NODES_FROSTWOLF_GRAVE = 5,
+ BG_AV_NODES_FROSTWOLF_HUT = 6,
+ BG_AV_NODES_DUNBALDAR_SOUTH = 7,
+ BG_AV_NODES_DUNBALDAR_NORTH = 8,
+ BG_AV_NODES_ICEWING_BUNKER = 9,
+ BG_AV_NODES_STONEHEART_BUNKER = 10,
+ BG_AV_NODES_ICEBLOOD_TOWER = 11,
+ BG_AV_NODES_TOWER_POINT = 12,
+ BG_AV_NODES_FROSTWOLF_ETOWER = 13,
+ BG_AV_NODES_FROSTWOLF_WTOWER = 14,
+
+ BG_AV_NODES_MAX = 15
+};
+
+enum BG_AV_BUFF
+{ /// @todo: Add all other buffs here
+ AV_BUFF_ARMOR = 21163,
+ AV_BUFF_A_CAPTAIN = 23693, //the buff which the alliance captain does
+ AV_BUFF_H_CAPTAIN = 22751 //the buff which the horde captain does
+};
+enum BG_AV_States
+{
+ POINT_NEUTRAL = 0,
+ POINT_ASSAULTED = 1,
+ POINT_DESTROYED = 2,
+ POINT_CONTROLED = 3
+};
+
+enum BG_AV_WorldStates
+{
+ AV_WS_ALLIANCE_REINFORCEMENTS = 3127,
+ AV_WS_HORDE_REINFORCEMENTS = 3128,
+ AV_WS_SHOW_HORDE_REINFORCEMENTS = 3133,
+ AV_WS_SHOW_ALLIANCE_REINFORCEMENTS = 3134,
+ AV_WS_MAX_REINFORCEMENTS = 3136,
+
+// Graves
+ // Alliance
+ //Stormpike first aid station
+ AV_WS_STORMPIKE_AID_STATION_ALLIANCE_CONTROLLED = 1325,
+ AV_WS_STORMPIKE_AID_STATION_IN_CONFLICT_ALLIANCE_ATTACKING = 1326,
+ AV_WS_STORMPIKE_AID_STATION_HORDE_CONTROLLED = 1327,
+ AV_WS_STORMPIKE_AID_STATION_IN_CONFLICT_HORDE_ATTACKING = 1328,
+ //Stormpike Graveyard
+ AV_WS_STORMPIKE_GRAVEYARD_ALLIANCE_CONTROLLED = 1333,
+ AV_WS_STORMPIKE_GRAVEYARD_IN_CONFLICT_ALLIANCE_ATTACKING = 1335,
+ AV_WS_STORMPIKE_GRAVEYARD_HORDE_CONTROLLED = 1334,
+ AV_WS_STORMPIKE_GRAVEYARD_IN_CONFLICT_HORDE_ATTACKING = 1336,
+ //Stoneheart Grave
+ AV_WS_STONEHEARTH_GRAVEYARD_ALLIANCE_CONTROLLED = 1302,
+ AV_WS_STONEHEARTH_GRAVEYARD_IN_CONFLICT_ALLIANCE_ATTACKING = 1304,
+ AV_WS_STONEHEARTH_GRAVEYARD_HORDE_CONTROLLED = 1301,
+ AV_WS_STONEHEARTH_GRAVEYARD_IN_CONFLICT_HORDE_ATTACKING = 1303,
+ //Neutral
+ //Snowfall Grave
+ AV_WS_SNOWFALL_GRAVEYARD_UNCONTROLLED = 1966,
+ AV_WS_SNOWFALL_GRAVEYARD_ALLIANCE_CONTROLLED = 1341,
+ AV_WS_SNOWFALL_GRAVEYARD_IN_CONFLICT_ALLIANCE_ATTACKING = 1343,
+ AV_WS_SNOWFALL_GRAVEYARD_HORDE_CONTROLLED = 1342,
+ AV_WS_SNOWFALL_GRAVEYARD_IN_CONFLICT_HORDE_ATTACKING = 1344,
+ //Horde
+ //Iceblood grave
+ AV_WS_ICEBLOOD_GRAVEYARD_ALLIANCE_CONTROLLED = 1346,
+ AV_WS_ICEBLOOD_GRAVEYARD_IN_CONFLICT_ALLIANCE_ATTACKING = 1348,
+ AV_WS_ICEBLOOD_GRAVEYARD_HORDE_CONTROLLED = 1347,
+ AV_WS_ICEBLOOD_GRAVEYARD_IN_CONFLICT_HORDE_ATTACKING = 1349,
+ //Frostwolf Grave
+ AV_WS_FROSTWOLF_GRAVEYARD_ALLIANCE_CONTROLLED = 1337,
+ AV_WS_FROSTWOLF_GRAVEYARD_IN_CONFLICT_ALLIANCE_ATTACKING = 1339,
+ AV_WS_FROSTWOLF_GRAVEYARD_HORDE_CONTROLLED = 1338,
+ AV_WS_FROSTWOLF_GRAVEYARD_IN_CONFLICT_HORDE_ATTACKING = 1340,
+ //Frostwolf Hut
+ AV_WS_FROSTWOLF_RELIEF_HUT_ALLIANCE_CONTROLLED = 1329,
+ AV_WS_FROSTWOLF_RELIEF_HUT_IN_CONFLICT_ALLIANCE_ATTACKING = 1331,
+ AV_WS_FROSTWOLF_RELIEF_HUT_HORDE_CONTROLLED = 1330,
+ AV_WS_FROSTWOLF_RELIEF_HUT_IN_CONFLICT_HORDE_ATTACKING = 1332,
+
+//Towers
+ //Alliance
+ //Dunbaldar South Bunker
+ AV_WS_DUN_BALDAR_SOUTH_BUNKER_OWNER = 1181,
+ AV_WS_DUN_BALDAR_SOUTH_BUNKER_ALLIANCE_CONTROLLED = 1361,
+ AV_WS_DUN_BALDAR_SOUTH_BUNKER_DESTROYED = 1370,
+ AV_WS_DUN_BALDAR_SOUTH_BUNKER_IN_CONFLICT_HORDE_ATTACKING = 1378,
+ AV_WS_DUN_BALDAR_SOUTH_BUNKER_IN_CONFLICT_ALLIANCE_ATTACKING = 1374, // unused
+ //Dunbaldar North Bunker
+ AV_WS_DUN_BALDAR_NORTH_BUNKER_OWNER = 1182,
+ AV_WS_DUN_BALDAR_NORTH_BUNKER_ALLIANCE_CONTROLLED = 1362,
+ AV_WS_DUN_BALDAR_NORTH_BUNKER_DESTROYED = 1371,
+ AV_WS_DUN_BALDAR_NORTH_BUNKER_IN_CONFLICT_HORDE_ATTACKING = 1379,
+ AV_WS_DUN_BALDAR_NORTH_BUNKER_IN_CONFLICT_ALLIANCE_ATTACKING = 1375, // unused
+ //Icewing Bunker
+ AV_WS_ICEWING_BUNKER_OWNER = 1183,
+ AV_WS_ICEWING_BUNKER_ALLIANCE_CONTROLLED = 1363,
+ AV_WS_ICEWING_BUNKER_DESTROYED = 1372,
+ AV_WS_ICEWING_BUNKER_IN_CONFLICT_HORDE_ATTACKING = 1380,
+ AV_WS_ICEWING_BUNKER_IN_CONFLICT_ALLIANCE_ATTACKING = 1376, // unused
+ //Stoneheart Bunker
+ AV_WS_STONEHEARTH_BUNKER_OWNER = 1184,
+ AV_WS_STONEHEARTH_BUNKER_ALLIANCE_CONTROLLED = 1364,
+ AV_WS_STONEHEARTH_BUNKER_DESTROYED = 1373,
+ AV_WS_STONEHEARTH_BUNKER_IN_CONFLICT_HORDE_ATTACKING = 1381,
+ AV_WS_STONEHEARTH_BUNKER_IN_CONFLICT_ALLIANCE_ATTACKING = 1377, // unused
+ //Horde
+ //Iceblood Tower
+ AV_WS_ICEBLOOD_TOWER_OWNER = 1187,
+ AV_WS_ICEBLOOD_TOWER_DESTROYED = 1368,
+ AV_WS_ICEBLOOD_TOWER_HORDE_CONTROLLED = 1385,
+ AV_WS_ICEBLOOD_TOWER_IN_CONFLICT_ALLIANCE_ATTACKING = 1390,
+ AV_WS_ICEBLOOD_TOWER_IN_CONFLICT_HORDE_ATTACKING = 1395, // unused
+ //Tower Point
+ AV_WS_TOWER_POINT_OWNER = 1188,
+ AV_WS_TOWER_POINT_DESTROYED = 1367,
+ AV_WS_TOWER_POINT_HORDE_CONTROLLED = 1384,
+ AV_WS_TOWER_POINT_IN_CONFLICT_ALLIANCE_ATTACKING = 1389,
+ AV_WS_TOWER_POINT_IN_CONFLICT_HORDE_ATTACKING = 1394, // unused
+ //Frostwolf West
+ AV_WS_WEST_FROSTWOLF_TOWER_OWNER = 1185,
+ AV_WS_WEST_FROSTWOLF_TOWER_DESTROYED = 1365,
+ AV_WS_WEST_FROSTWOLF_TOWER_HORDE_CONTROLLED = 1382,
+ AV_WS_WEST_FROSTWOLF_TOWER_IN_CONFLICT_ALLIANCE_ATTACKING = 1387,
+ AV_WS_WEST_FROSTWOLF_TOWER_IN_CONFLICT_HORDE_ATTACKING = 1392, // unused
+ //Frostwolf East
+ AV_WS_EAST_FROSTWOLF_TOWER_OWNER = 1186,
+ AV_WS_EAST_FROSTWOLF_TOWER_DESTROYED = 1366,
+ AV_WS_EAST_FROSTWOLF_TOWER_HORDE_CONTROLLED = 1383,
+ AV_WS_EAST_FROSTWOLF_TOWER_IN_CONFLICT_ALLIANCE_ATTACKING = 1388,
+ AV_WS_EAST_FROSTWOLF_TOWER_IN_CONFLICT_HORDE_ATTACKING = 1393, // unused
+
+//Mines
+ AV_WS_IRONDEEP_MINE_OWNER = 801,
+ AV_WS_IRONDEEP_MINE_TROGG_CONTROLLED = 1360,
+ AV_WS_IRONDEEP_MINE_ALLIANCE_CONTROLLED = 1358,
+ AV_WS_IRONDEEP_MINE_HORDE_CONTROLLED = 1359,
+
+ AV_WS_COLDTOOTH_MINE_OWNER = 804,
+ AV_WS_COLDTOOTH_MINE_KOBOLD_CONTROLLED = 1357,
+ AV_WS_COLDTOOTH_MINE_ALLIANCE_CONTROLLED = 1355,
+ AV_WS_COLDTOOTH_MINE_HORDE_CONTROLLED = 1356,
+
+//Turnins
+ AV_WS_IVUS_STORM_CRYSTAL_COUNT = 1043,
+ AV_WS_IVUS_STORM_CRYSTAL_MAX = 1044,
+ AV_WS_LOKHOLAR_STORMPIKE_SOLDIERS_BLOOD_COUNT = 923,
+ AV_WS_LOKHOLAR_STORMPIKE_SOLDIERS_BLOOD_MAX = 922,
+
+//Bosses
+ AV_WS_DREKTHAR_ALIVE = 601,
+ AV_WS_VANDAAR_ALIVE = 602,
+
+//Captains
+ AV_WS_GALVAGAR_ALIVE = 1352,
+ AV_WS_BALINDA_ALIVE = 1351,
+};
+
+struct StaticMineInfo
+{
+ int32 WorldStateOwner;
+ int32 WorldStateAllianceControlled;
+ int32 WorldStateHordeControlled;
+ int32 WorldStateNeutralControlled;
+ uint8 TextIdAlliance;
+ uint8 TextIdHorde;
+};
+
+struct AlteracValleyMineInfo
+{
+ Team Owner;
+
+ StaticMineInfo StaticInfo;
+};
+
+struct StaticNodeInfo
+{
+ BG_AV_Nodes NodeId;
+
+ struct
+ {
+ uint8 AllianceCapture;
+ uint8 AllianceAttack;
+ uint8 HordeCapture;
+ uint8 HordeAttack;
+ } TextIds;
+
+ struct
+ {
+ int32 AllianceControl;
+ int32 AllianceAssault;
+ int32 HordeControl;
+ int32 HordeAssault;
+ int32 Owner;
+ } WorldStateIds;
+
+ struct
+ {
+ std::string AllianceOrDefend;
+ std::string HordeOrDestroy;
+ } StringIds;
+};
+
+static StaticNodeInfo const BGAVNodeInfo[] =
+{
+ { BG_AV_NODES_FIRSTAID_STATION, { 47, 48, 45, 46 }, { 1325, 1326, 1327, 1328, 0 }, { "bg_av_herald_stormpike_aid_station_alliance", "bg_av_herald_stormpike_aid_station_horde" } }, // Stormpike First Aid Station
+ { BG_AV_NODES_STORMPIKE_GRAVE, { 1, 2, 3, 4 }, { 1333, 1335, 1334, 1336, 0 }, { "bg_av_herald_stormpike_alliance", "bg_av_herald_stormpike_horde" } }, // Stormpike Graveyard
+ { BG_AV_NODES_STONEHEART_GRAVE, { 55, 56, 53, 54 }, { 1302, 1304, 1301, 1303, 0 }, { "bg_av_herald_stonehearth_alliance", "bg_av_herald_stonehearth_horde" } }, // Stoneheart Graveyard
+ { BG_AV_NODES_SNOWFALL_GRAVE, { 5, 6, 7, 8 }, { 1341, 1343, 1342, 1344, 0 }, { "bg_av_herald_snowfall_alliance", "bg_av_herald_snowfall_horde" } }, // Snowfall Graveyard
+ { BG_AV_NODES_ICEBLOOD_GRAVE, { 59, 60, 57, 58 }, { 1346, 1348, 1347, 1349, 0 }, { "bg_av_herald_iceblood_alliance", "bg_av_herald_iceblood_horde" } }, // Iceblood Graveyard
+ { BG_AV_NODES_FROSTWOLF_GRAVE, { 9, 10, 11, 12 }, { 1337, 1339, 1338, 1340, 0 }, { "bg_av_herald_frostwolf_alliance", "bg_av_herald_frostwolf_horde" } }, // Frostwolf Graveyard
+ { BG_AV_NODES_FROSTWOLF_HUT, { 51, 52, 49, 50 }, { 1329, 1331, 1330, 1332, 0 }, { "bg_av_herald_frostwolf_hut_alliance", "bg_av_herald_frostwolf_hut_horde" } }, // Frostwolf Hut
+ { BG_AV_NODES_DUNBALDAR_SOUTH, { 16, 15, 14, 13 }, { 1361, 1375, 1370, 1378, 1181 }, { "bg_av_herald_south_bunker_defend", "bg_av_herald_south_bunker_attack" } }, // Dunbaldar South Bunker
+ { BG_AV_NODES_DUNBALDAR_NORTH, { 20, 19, 18, 17 }, { 1362, 1374, 1371, 1379, 1182 }, { "bg_av_herald_north_bunker_defend", "bg_av_herald_south_bunker_attack" } }, // Dunbaldar North Bunker
+ { BG_AV_NODES_ICEWING_BUNKER, { 24, 23, 22, 21 }, { 1363, 1376, 1372, 1380, 1183 }, { "bg_av_herald_icewing_bunker_defend", "bg_av_herald_icewing_bunker_attack" } }, // Icewing Bunker
+ { BG_AV_NODES_STONEHEART_BUNKER, { 28, 27, 26, 25 }, { 1364, 1377, 1373, 1381, 1184 }, { "bg_av_herald_stonehearth_bunker_defend", "bg_av_herald_stonehearth_bunker_attack" } }, // Stoneheart Bunker
+ { BG_AV_NODES_ICEBLOOD_TOWER, { 44, 43, 42, 41 }, { 1368, 1390, 1385, 1395, 1188 }, { "bg_av_herald_iceblood_tower_defend", "bg_av_herald_iceblood_tower_attack" } }, // Iceblood Tower
+ { BG_AV_NODES_TOWER_POINT, { 40, 39, 38, 37 }, { 1367, 1389, 1384, 1394, 1187 }, { "bg_av_herald_tower_point_defend", "bg_av_herald_tower_point_attack" } }, // Tower Point
+ { BG_AV_NODES_FROSTWOLF_ETOWER, { 36, 35, 34, 33 }, { 1366, 1388, 1383, 1393, 1186 }, { "bg_av_herald_east_tower_defend", "bg_av_herald_east_tower_attack" } }, // Frostwolf East Tower
+ { BG_AV_NODES_FROSTWOLF_WTOWER, { 32, 31, 30, 29 }, { 1365, 1387, 1382, 1392, 1185 }, { "bg_av_herald_west_tower_defend", "bg_av_herald_west_tower_attack" } }, // Frostwolf West Tower
+};
+
+enum Texts
+{
+ // Herold
+ // Towers/Graveyards = 1 - 60
+ TEXT_COLDTOOTH_MINE_ALLIANCE_TAKEN = 61,
+ TEXT_IRONDEEP_MINE_ALLIANCE_TAKEN = 62,
+ TEXT_COLDTOOTH_MINE_HORDE_TAKEN = 63,
+ TEXT_IRONDEEP_MINE_HORDE_TAKEN = 64,
+ TEXT_FROSTWOLF_GENERAL_DEAD = 65, /// @todo: sound is missing
+ TEXT_STORMPIKE_GENERAL_DEAD = 66, /// @todo: sound is missing
+ TEXT_ALLIANCE_WINS = 67, // NYI /// @todo: sound is missing
+ TEXT_HORDE_WINS = 68, // NYI /// @todo: sound is missing
+
+ // Taskmaster Snivvle
+ TEXT_SNIVVLE_RANDOM = 0
+};
+
+enum BG_AV_ExploitTeleportLocations
+{
+ AV_EXPLOIT_TELEPORT_LOCATION_ALLIANCE = 3664,
+ AV_EXPLOIT_TELEPORT_LOCATION_HORDE = 3665
+};
+
+struct BG_AV_NodeInfo
+{
+ BG_AV_States State;
+ BG_AV_States PrevState;
+ uint16 TotalOwner;
+ Team Owner;
+ uint16 PrevOwner;
+ bool Tower;
+};
+
+inline BG_AV_Nodes& operator++(BG_AV_Nodes& i) { return i = BG_AV_Nodes(i + 1); }
+
+struct battleground_alterac_valley : BattlegroundScript
+{
+ enum QuestIds
+ {
+ AV_QUEST_A_SCRAPS1 = 7223,
+ AV_QUEST_A_SCRAPS2 = 6781,
+ AV_QUEST_H_SCRAPS1 = 7224,
+ AV_QUEST_H_SCRAPS2 = 6741,
+ AV_QUEST_A_COMMANDER1 = 6942, //soldier
+ AV_QUEST_H_COMMANDER1 = 6825,
+ AV_QUEST_A_COMMANDER2 = 6941, //leutnant
+ AV_QUEST_H_COMMANDER2 = 6826,
+ AV_QUEST_A_COMMANDER3 = 6943, //commander
+ AV_QUEST_H_COMMANDER3 = 6827,
+ AV_QUEST_A_BOSS1 = 7386, // 5 cristal/blood
+ AV_QUEST_H_BOSS1 = 7385,
+ AV_QUEST_A_BOSS2 = 6881, // 1
+ AV_QUEST_H_BOSS2 = 6801,
+ AV_QUEST_A_NEAR_MINE = 5892, //the mine near start location of team
+ AV_QUEST_H_NEAR_MINE = 5893,
+ AV_QUEST_A_OTHER_MINE = 6982, //the other mine ;)
+ AV_QUEST_H_OTHER_MINE = 6985,
+ AV_QUEST_A_RIDER_HIDE = 7026,
+ AV_QUEST_H_RIDER_HIDE = 7002,
+ AV_QUEST_A_RIDER_TAME = 7027,
+ AV_QUEST_H_RIDER_TAME = 7001
+ };
+
+ enum Data : uint32
+ {
+ DATA_DEFENDER_TIER_HORDE = 1,
+ DATA_DEFENDER_TIER_ALLIANCE = 2,
+ };
+
+ enum DefenderTier : uint32
+ {
+ BG_AV_DEFENDER_TIER_DEFENDER,
+ BG_AV_DEFENDER_TIER_SEASONED,
+ BG_AV_DEFENDER_TIER_VETERAN,
+ BG_AV_DEFENDER_TIER_CHAMPION
+ };
+
+ enum PvpStats
+ {
+ PVP_STAT_TOWERS_ASSAULTED = 61,
+ PVP_STAT_GRAVEYARDS_ASSAULTED = 63,
+ PVP_STAT_TOWERS_DEFENDED = 64,
+ PVP_STAT_GRAVEYARDS_DEFENDED = 65,
+ PVP_STAT_SECONDARY_OBJECTIVES = 82
+ };
+
+ enum Misc
+ {
+ NEAR_LOSE_POINTS = 140
+ };
+
+ enum HonorKillBonus
+ {
+ HONOR_KILL_BONUS_BOSS = 4,
+ HONOR_KILL_BONUS_CAPTAIN = 3,
+ HONOR_KILL_BONUS_SURVIVING_TOWER = 2,
+ HONOR_KILL_BONUS_SURVIVING_CAPTAIN = 2,
+ HONOR_KILL_BONUS_DESTROY_TOWER = 3
+ };
+
+ enum ReputationGains
+ {
+ REP_GAIN_BOSS = 350,
+ REP_GAIN_CAPTAIN = 125,
+ REP_GAIN_DESTROY_TOWER = 12,
+ REP_GAIN_SURVIVING_TOWER = 12,
+ REP_GAIN_SURVIVING_CAPTAIN = 125
+ };
+
+ enum ResourceLoss
+ {
+ RESOURCE_LOSS_TOWER = -75,
+ RESOURCE_LOSS_CAPTAIN = -100
+ };
+
+ enum Spells
+ {
+ SPELL_COMPLETE_ALTERAC_VALLEY_QUEST = 23658,
+ };
+
+ enum Factions
+ {
+ FACTION_FROSTWOLF_CLAN = 729,
+ FACTION_STORMPIKE_GUARD = 730,
+ };
+
+ explicit battleground_alterac_valley(BattlegroundMap* map) : BattlegroundScript(map)
+ {
+ _teamResources = { BG_AV_SCORE_INITIAL_POINTS, BG_AV_SCORE_INITIAL_POINTS };
+ _isInformedNearVictory = { false, false };
+
+ for (uint8 i = 0; i < 2; i++) //forloop for both teams (it just make 0 == alliance and 1 == horde also for both mines 0=north 1=south
+ {
+ for (uint8 j = 0; j < 9; j++)
+ _teamQuestStatus[i][j] = 0;
+
+ _captainBuffTimer[i].Reset(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
+ }
+
+ _mineInfo[uint8(AlteracValleyMine::North)] = { TEAM_OTHER, { AV_WS_IRONDEEP_MINE_OWNER, AV_WS_IRONDEEP_MINE_ALLIANCE_CONTROLLED, AV_WS_IRONDEEP_MINE_HORDE_CONTROLLED, AV_WS_IRONDEEP_MINE_TROGG_CONTROLLED, TEXT_IRONDEEP_MINE_ALLIANCE_TAKEN, TEXT_IRONDEEP_MINE_HORDE_TAKEN } };
+ _mineInfo[uint8(AlteracValleyMine::South)] = { TEAM_OTHER, { AV_WS_COLDTOOTH_MINE_OWNER, AV_WS_COLDTOOTH_MINE_ALLIANCE_CONTROLLED, AV_WS_COLDTOOTH_MINE_HORDE_CONTROLLED, AV_WS_COLDTOOTH_MINE_KOBOLD_CONTROLLED, TEXT_COLDTOOTH_MINE_ALLIANCE_TAKEN, TEXT_COLDTOOTH_MINE_HORDE_TAKEN } };
+
+ for (BG_AV_Nodes i = BG_AV_NODES_FIRSTAID_STATION; i <= BG_AV_NODES_STONEHEART_GRAVE; ++i) //alliance graves
+ InitNode(i, ALLIANCE, false);
+ for (BG_AV_Nodes i = BG_AV_NODES_DUNBALDAR_SOUTH; i <= BG_AV_NODES_STONEHEART_BUNKER; ++i) //alliance towers
+ InitNode(i, ALLIANCE, true);
+ for (BG_AV_Nodes i = BG_AV_NODES_ICEBLOOD_GRAVE; i <= BG_AV_NODES_FROSTWOLF_HUT; ++i) //horde graves
+ InitNode(i, HORDE, false);
+ for (BG_AV_Nodes i = BG_AV_NODES_ICEBLOOD_TOWER; i <= BG_AV_NODES_FROSTWOLF_WTOWER; ++i) //horde towers
+ InitNode(i, HORDE, true);
+ InitNode(BG_AV_NODES_SNOWFALL_GRAVE, TEAM_OTHER, false); //give snowfall neutral owner
+
+ _mineResourceTimer.Reset(BG_AV_MINE_RESOURCE_TIMER);
+ }
+
+ void OnUpdate(uint32 diff) override
+ {
+ if (battleground->GetStatus() != STATUS_IN_PROGRESS)
+ return;
+
+ _mineResourceTimer.Update(diff);
+ if (_mineResourceTimer.Passed())
+ {
+ for (AlteracValleyMineInfo const& info : _mineInfo)
+ {
+ if (info.Owner == TEAM_OTHER)
+ continue;
+
+ UpdateScore(info.Owner, 1);
+ }
+
+ _mineResourceTimer.Reset(BG_AV_MINE_RESOURCE_TIMER);
+ }
+
+ for (uint8 i = TEAM_ALLIANCE; i <= TEAM_HORDE; i++)
+ {
+ if (!IsCaptainAlive(TeamId(i)))
+ continue;
+
+ _captainBuffTimer[i].Update(diff);
+ if (_captainBuffTimer[i].Passed())
+ {
+ if (i == 0)
+ {
+ battleground->CastSpellOnTeam(AV_BUFF_A_CAPTAIN, ALLIANCE);
+ if (Creature const* creature = battlegroundMap->GetCreature(_balindaGUID))
+ creature->AI()->DoAction(ACTION_BUFF_YELL);
+ }
+ else
+ {
+ battleground->CastSpellOnTeam(AV_BUFF_H_CAPTAIN, HORDE);
+ if (Creature const* creature = battlegroundMap->GetCreature(_galvangarGUID))
+ creature->AI()->DoAction(ACTION_BUFF_YELL);
+ }
+
+ _captainBuffTimer[i].Reset(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
+ }
+ }
+ }
+
+ void OnPlayerKilled(Player* victim, Player* /*killer*/) override
+ {
+ UpdateScore(battleground->GetPlayerTeam(victim->GetGUID()), -1);
+ }
+
+ void OnUnitKilled(Creature* victim, Unit* killer) override
+ {
+ switch (victim->GetEntry())
+ {
+ case BG_AV_CREATURE_VANNDAR:
+ {
+ UpdateWorldState(AV_WS_VANDAAR_ALIVE, 0);
+ battleground->CastSpellOnTeam(SPELL_COMPLETE_ALTERAC_VALLEY_QUEST, HORDE); //this is a spell which finishes a quest where a player has to kill the boss
+ battleground->RewardReputationToTeam(FACTION_FROSTWOLF_CLAN, REP_GAIN_BOSS, HORDE);
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(HONOR_KILL_BONUS_BOSS), HORDE);
+ battleground->EndBattleground(HORDE);
+ break;
+ }
+ case BG_AV_CREATURE_DREKTHAR:
+ {
+ UpdateWorldState(AV_WS_DREKTHAR_ALIVE, 0);
+ battleground->CastSpellOnTeam(SPELL_COMPLETE_ALTERAC_VALLEY_QUEST, ALLIANCE); //this is a spell which finishes a quest where a player has to kill the boss
+ battleground->RewardReputationToTeam(FACTION_STORMPIKE_GUARD, REP_GAIN_BOSS, ALLIANCE);
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(HONOR_KILL_BONUS_BOSS), ALLIANCE);
+ battleground->EndBattleground(ALLIANCE);
+ break;
+ }
+ case BG_AV_CREATURE_BALINDA:
+ {
+ UpdateWorldState(AV_WS_BALINDA_ALIVE, 0);
+ battleground->RewardReputationToTeam(FACTION_FROSTWOLF_CLAN, REP_GAIN_CAPTAIN, HORDE);
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(HONOR_KILL_BONUS_CAPTAIN), HORDE);
+ UpdateScore(ALLIANCE, RESOURCE_LOSS_CAPTAIN);
+ if (Creature const* herald = FindHerald("bg_av_herald_horde_win"))
+ herald->AI()->Talk(TEXT_STORMPIKE_GENERAL_DEAD);
+ break;
+ }
+ case BG_AV_CREATURE_GALVANGAR:
+ {
+ UpdateWorldState(AV_WS_GALVAGAR_ALIVE, 0);
+ battleground->RewardReputationToTeam(FACTION_STORMPIKE_GUARD, REP_GAIN_CAPTAIN, ALLIANCE);
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(HONOR_KILL_BONUS_CAPTAIN), ALLIANCE);
+ UpdateScore(HORDE, RESOURCE_LOSS_CAPTAIN);
+ if (Creature const* herald = FindHerald("bg_av_herald_alliance_win"))
+ herald->AI()->Talk(TEXT_FROSTWOLF_GENERAL_DEAD);
+ break;
+ }
+ case BG_AV_CREATURE_MORLOCH:
+ {
+ // if mine is not owned by morloch, then nothing happens
+ if (_mineInfo[uint8(AlteracValleyMine::North)].Owner != TEAM_OTHER)
+ break;
+
+ Team const killerTeam = battleground->GetPlayerTeam(Coalesce<Unit>(killer->GetCharmerOrOwnerPlayerOrPlayerItself(), killer)->GetGUID());
+ ChangeMineOwner(AlteracValleyMine::North, killerTeam);
+ break;
+ }
+ case BG_AV_CREATURE_TASKMASTER_SNIVVLE:
+ {
+ if (_mineInfo[uint8(AlteracValleyMine::South)].Owner != TEAM_OTHER)
+ break;
+
+ Team const killerTeam = battleground->GetPlayerTeam(Coalesce<Unit>(killer->GetCharmerOrOwnerPlayerOrPlayerItself(), killer)->GetGUID());
+ ChangeMineOwner(AlteracValleyMine::South, killerTeam);
+ break;
+ }
+ case BG_AV_CREATURE_UMI_THORSON:
+ case BG_AV_CREATURE_KEETAR:
+ {
+ Team const killerTeam = battleground->GetPlayerTeam(Coalesce<Unit>(killer->GetCharmerOrOwnerPlayerOrPlayerItself(), killer)->GetGUID());
+ ChangeMineOwner(AlteracValleyMine::North, killerTeam);
+ break;
+ }
+ case BG_AV_CREATURE_AGI_RUMBLESTOMP:
+ case BG_AV_CREATURE_MASHA_SWIFTCUT:
+ {
+ Team const killerTeam = battleground->GetPlayerTeam(Coalesce<Unit>(killer->GetCharmerOrOwnerPlayerOrPlayerItself(), killer)->GetGUID());
+ ChangeMineOwner(AlteracValleyMine::South, killerTeam);
+ break;
+ }
+ }
+ }
+
+ bool IsCaptainAlive(TeamId teamId) const
+ {
+ if (teamId == TEAM_HORDE)
+ return battlegroundMap->GetWorldStateValue(AV_WS_GALVAGAR_ALIVE) == 1;
+
+ if (teamId == TEAM_ALLIANCE)
+ return battlegroundMap->GetWorldStateValue(AV_WS_BALINDA_ALIVE) == 1;
+
+ return false;
+ }
+
+ void OnStart() override
+ {
+ UpdateWorldState(AV_WS_SHOW_HORDE_REINFORCEMENTS, 1);
+ UpdateWorldState(AV_WS_SHOW_ALLIANCE_REINFORCEMENTS, 1);
+
+ // Achievement: The Alterac Blitz
+ TriggerGameEvent(BG_AV_EVENT_START_BATTLE);
+
+ for (ObjectGuid const& guid : _doorGUIDs)
+ {
+ if (GameObject* gameObject = battlegroundMap->GetGameObject(guid))
+ {
+ gameObject->UseDoorOrButton();
+ Seconds delay = gameObject->GetEntry() == BG_AV_GHOST_GATE ? 0s : 3s;
+ gameObject->DespawnOrUnsummon(delay);
+ }
+ }
+ }
+
+ void OnEnd(Team winner) override
+ {
+ BattlegroundScript::OnEnd(winner);
+ //calculate bonuskills for both teams:
+ //first towers:
+ std::array<uint8, PVP_TEAMS_COUNT> kills = { 0, 0 };
+ std::array<uint8, PVP_TEAMS_COUNT> rep = { 0, 0 };
+
+ for (BG_AV_Nodes i = BG_AV_NODES_DUNBALDAR_SOUTH; i <= BG_AV_NODES_FROSTWOLF_WTOWER; ++i)
+ {
+ if (_nodes[i].State == POINT_CONTROLED)
+ {
+ if (_nodes[i].Owner == ALLIANCE)
+ {
+ rep[TEAM_ALLIANCE] += REP_GAIN_SURVIVING_TOWER;
+ kills[TEAM_ALLIANCE] += HONOR_KILL_BONUS_SURVIVING_TOWER;
+ }
+ else
+ {
+ rep[TEAM_HORDE] += REP_GAIN_SURVIVING_TOWER;
+ kills[TEAM_HORDE] += HONOR_KILL_BONUS_SURVIVING_TOWER;
+ }
+ }
+ }
+
+ for (uint8 i = TEAM_ALLIANCE; i <= TEAM_HORDE; ++i)
+ {
+ if (IsCaptainAlive(TeamId(i)))
+ {
+ kills[i] += HONOR_KILL_BONUS_SURVIVING_CAPTAIN;
+ rep[i] += REP_GAIN_SURVIVING_CAPTAIN;
+ }
+ if (rep[i] != 0)
+ battleground->RewardReputationToTeam(i == 0 ? FACTION_STORMPIKE_GUARD : FACTION_FROSTWOLF_CLAN, rep[i], i == 0 ? ALLIANCE : HORDE);
+ if (kills[i] != 0)
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(kills[i]), i == 0 ? ALLIANCE : HORDE);
+ }
+ }
+
+ void OnPlayerLeft(Player* player) override
+ {
+ BattlegroundScript::OnPlayerLeft(player);
+ if (!player)
+ return;
+
+ player->RemoveAurasDueToSpell(AV_BUFF_ARMOR);
+ }
+
+ void EventPlayerDestroyedPoint(GameObject* gameobject)
+ {
+ if (!gameobject)
+ return;
+
+ BG_AV_Nodes const node = GetNodeThroughObject(gameobject->GetEntry());
+ DestroyNode(node);
+ UpdateNodeWorldState(node);
+
+ Team const owner = _nodes[node].Owner;
+ if (IsTower(node))
+ {
+ UpdateScore((owner == ALLIANCE) ? HORDE : ALLIANCE, RESOURCE_LOSS_TOWER);
+ battleground->RewardReputationToTeam(owner == ALLIANCE ? FACTION_STORMPIKE_GUARD : FACTION_FROSTWOLF_CLAN, REP_GAIN_DESTROY_TOWER, owner);
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(HONOR_KILL_BONUS_DESTROY_TOWER), owner);
+ }
+
+ if (StaticNodeInfo const* nodeInfo = GetStaticNodeInfo(node))
+ if (Creature const* herald = FindHerald(nodeInfo->StringIds.HordeOrDestroy))
+ herald->AI()->Talk(owner == ALLIANCE ? nodeInfo->TextIds.AllianceCapture : nodeInfo->TextIds.HordeCapture);
+
+ battlegroundMap->UpdateSpawnGroupConditions();
+ }
+
+ void DoAction(uint32 actionId, WorldObject* source, WorldObject* target) override
+ {
+ Team const team = battleground->GetPlayerTeam(source->GetGUID());
+ TeamId const teamIndex = Battleground::GetTeamIndexByTeamId(team);
+
+ switch (actionId)
+ {
+ case ACTION_AV_CAPTURE_CAPTURABLE_OBJECT:
+ EventPlayerDestroyedPoint(source->ToGameObject());
+ break;
+ case ACTION_AV_INTERACT_CAPTURABLE_OBJECT:
+ if (target && source && source->IsPlayer())
+ HandleInteractCapturableObject(source->ToPlayer(), target->ToGameObject());
+ break;
+ case ACTION_TURN_IN_SCRAPS:
+ _teamQuestStatus[teamIndex][0] += 20;
+ break;
+ case ACTION_TURN_IN_COMMANDER_1:
+ _teamQuestStatus[teamIndex][1]++;
+ battleground->RewardReputationToTeam(teamIndex, 1, team);
+ if (_teamQuestStatus[teamIndex][1] == 30)
+ TC_LOG_DEBUG("bg.battleground", "BG_AV action {} completed (need to implement some events here", actionId);
+ break;
+ case ACTION_TURN_IN_COMMANDER_2:
+ _teamQuestStatus[teamIndex][2]++;
+ battleground->RewardReputationToTeam(teamIndex, 1, team);
+ if (_teamQuestStatus[teamIndex][2] == 60)
+ TC_LOG_DEBUG("bg.battleground", "BG_AV action {} completed (need to implement some events here", actionId);
+ break;
+ case ACTION_TURN_IN_COMMANDER_3:
+ _teamQuestStatus[teamIndex][3]++;
+ battleground->RewardReputationToTeam(teamIndex, 1, team);
+ if (_teamQuestStatus[teamIndex][3] == 120)
+ TC_LOG_DEBUG("bg.battleground", "BG_AV action {} completed (need to implement some events here", actionId);
+ break;
+ case ACTION_TURN_IN_BOSS_1:
+ _teamQuestStatus[teamIndex][4] += 4; //you can turn in 5 or 1 item..
+ [[fallthrough]];
+ case ACTION_TURN_IN_BOSS_2:
+ _teamQuestStatus[teamIndex][4]++;
+ if (_teamQuestStatus[teamIndex][4] >= 200)
+ TC_LOG_DEBUG("bg.battleground", "BG_AV action {} completed (need to implement some events here", actionId);
+ UpdateWorldState(teamIndex == TEAM_ALLIANCE ? AV_WS_IVUS_STORM_CRYSTAL_COUNT : AV_WS_LOKHOLAR_STORMPIKE_SOLDIERS_BLOOD_COUNT, _teamQuestStatus[teamIndex][4]);
+ break;
+ case ACTION_TURN_IN_NEAR_MINE:
+ _teamQuestStatus[teamIndex][5]++;
+ if (_teamQuestStatus[teamIndex][5] == 28)
+ {
+ TC_LOG_DEBUG("bg.battleground", "BG_AV action {} completed (need to implement some events here", actionId);
+ if (_teamQuestStatus[teamIndex][6] == 7)
+ TC_LOG_DEBUG("bg.battleground", "BG_AV action {} completed (need to implement some events here - ground assault ready", actionId);
+ }
+ break;
+ case ACTION_TURN_IN_OTHER_MINE:
+ _teamQuestStatus[teamIndex][6]++;
+ if (_teamQuestStatus[teamIndex][6] == 7)
+ {
+ TC_LOG_DEBUG("bg.battleground", "BG_AV action {} completed (need to implement some events here", actionId);
+ if (_teamQuestStatus[teamIndex][5] == 20)
+ TC_LOG_DEBUG("bg.battleground", "BG_AV action {} completed (need to implement some events here - ground assault ready", actionId);
+ }
+ break;
+ case ACTION_TURN_IN_RIDER_HIDE:
+ _teamQuestStatus[teamIndex][7]++;
+ if (_teamQuestStatus[teamIndex][7] == 25)
+ {
+ TC_LOG_DEBUG("bg.battleground", "BG_AV action {} completed (need to implement some events here", actionId);
+ if (_teamQuestStatus[teamIndex][8] == 25)
+ TC_LOG_DEBUG("bg.battleground", "BG_AV action {} completed (need to implement some events here - rider assault ready", actionId);
+ }
+ break;
+ case ACTION_TURN_IN_RIDER_TAME:
+ _teamQuestStatus[teamIndex][8]++;
+ if (_teamQuestStatus[teamIndex][8] == 25)
+ {
+ TC_LOG_DEBUG("bg.battleground", "BG_AV action {} completed (need to implement some events here", actionId);
+ if (_teamQuestStatus[teamIndex][7] == 25)
+ TC_LOG_DEBUG("bg.battleground", "BG_AV action {} completed (need to implement some events here - rider assault ready", actionId);
+ }
+ break;
+ default:
+ TC_LOG_ERROR("bg.battleground", "BattlegroundAV::DoAction: {}. Unhandled action.", actionId);
+ break;
+ }
+ }
+
+ void ChangeMineOwner(AlteracValleyMine mine, Team team, bool initial = false)
+ {
+ if (team != ALLIANCE && team != HORDE)
+ team = TEAM_OTHER;
+
+ AlteracValleyMineInfo& mineInfo = _mineInfo[uint8(mine)];
+
+ if (mineInfo.Owner == team && !initial)
+ return;
+
+ mineInfo.Owner = team;
+
+ SendMineWorldStates(mine);
+
+ uint8 const textId = team == ALLIANCE ? mineInfo.StaticInfo.TextIdAlliance : mineInfo.StaticInfo.TextIdHorde;
+
+ std::string const stringId = team == ALLIANCE ? "bg_av_herald_mine_alliance" : "bg_av_herald_mine_horde";
+
+ if (Creature const* herald = FindHerald(stringId))
+ herald->AI()->Talk(textId);
+ }
+
+ static BG_AV_Nodes GetNodeThroughObject(uint32 object)
+ {
+ switch (object)
+ {
+ case BG_AV_OBJECTID_AID_STATION_ALLIANCE_CONTROLLED:
+ case BG_AV_OBJECTID_AID_STATION_HORDE_CONTESTED:
+ case BG_AV_OBJECTID_AID_STATION_HORDE_CONTROLLED:
+ case BG_AV_OBJECTID_AID_STATION_ALLIANCE_CONTESTED:
+ return BG_AV_NODES_FIRSTAID_STATION;
+ case BG_AV_OBJECTID_STORMPIKE_ALLIANCE_CONTROLLED:
+ case BG_AV_OBJECTID_STORMPIKE_HORDE_CONTESTED:
+ case BG_AV_OBJECTID_STORMPIKE_HORDE_CONTROLLED:
+ case BG_AV_OBJECTID_STORMPIKE_ALLIANCE_CONTESTED:
+ return BG_AV_NODES_STORMPIKE_GRAVE;
+ case BG_AV_OBJECTID_STONEHEARTH_HORDE_CONTESTED:
+ case BG_AV_OBJECTID_STONEHEARTH_HORDE_CONTROLLED:
+ case BG_AV_OBJECTID_STONEHEARTH_ALLIANCE_CONTESTED:
+ case BG_AV_OBJECTID_STONEHEARTH_ALLIANCE_CONTROLLED:
+ return BG_AV_NODES_STONEHEART_GRAVE;
+ case BG_AV_OBJECTID_SNOWFALL_NEUTRAL:
+ case BG_AV_OBJECTID_SNOWFALL_HORDE_CONTESTED:
+ case BG_AV_OBJECTID_SNOWFALL_ALLIANCE_CONTESTED:
+ case BG_AV_OBJECTID_SNOWFALL_HORDE_CONTROLLED:
+ case BG_AV_OBJECTID_SNOWFALL_ALLIANCE_CONTROLLED:
+ return BG_AV_NODES_SNOWFALL_GRAVE;
+ case BG_AV_OBJECTID_ICEBLOOD_HORDE_CONTROLLED:
+ case BG_AV_OBJECTID_ICEBLOOD_ALLIANCE_CONTESTED:
+ case BG_AV_OBJECTID_ICEBLOOD_ALLIANCE_CONTROLLED:
+ case BG_AV_OBJECTID_ICEBLOOD_HORDE_CONTESTED:
+ return BG_AV_NODES_ICEBLOOD_GRAVE;
+ case BG_AV_OBJECTID_FROSTWOLF_HORDE_CONTROLLED:
+ case BG_AV_OBJECTID_FROSTWOLF_ALLIANCE_CONTESTED:
+ case BG_AV_OBJECTID_FROSTWOLF_ALLIANCE_CONTROLLED:
+ case BG_AV_OBJECTID_FROSTWOLF_HORDE_CONTESTED:
+ return BG_AV_NODES_FROSTWOLF_GRAVE;
+ case BG_AV_OBJECTID_FROSTWOLF_HUT_HORDE_CONTROLLED:
+ case BG_AV_OBJECTID_FROSTWOLF_HUT_ALLIANCE_CONTESTED:
+ case BG_AV_OBJECTID_FROSTWOLF_HUT_ALLIANCE_CONTROLLED:
+ case BG_AV_OBJECTID_FROSTWOLF_HUT_HORDE_CONTESTED:
+ return BG_AV_NODES_FROSTWOLF_HUT;
+ case BG_AV_OBJECTID_SOUTH_BUNKER_CONTROLLED_TOWER_BANNER:
+ case BG_AV_OBJECTID_SOUTH_BUNKER_CONTROLLED_BANNER:
+ case BG_AV_OBJECTID_SOUTH_BUNKER_CONTESTED_BANNER:
+ case BG_AV_OBJECTID_SOUTH_BUNKER_CONTESTED_TOWER_BANNER:
+ return BG_AV_NODES_DUNBALDAR_SOUTH;
+ case BG_AV_OBJECTID_NORTH_BUNKER_CONTROLLED_TOWER_BANNER:
+ case BG_AV_OBJECTID_NORTH_BUNKER_CONTROLLED_BANNER:
+ case BG_AV_OBJECTID_NORTH_BUNKER_CONTESTED_BANNER:
+ case BG_AV_OBJECTID_NORTH_BUNKER_CONTESTED_TOWER_BANNER:
+ return BG_AV_NODES_DUNBALDAR_NORTH;
+ case BG_AV_OBJECTID_EAST_TOWER_CONTROLLED_TOWER_BANNER:
+ case BG_AV_OBJECTID_EAST_TOWER_CONTROLLED_BANNER:
+ case BG_AV_OBJECTID_EAST_TOWER_CONTESTED_BANNER:
+ case BG_AV_OBJECTID_EAST_TOWER_CONTESTED_TOWER_BANNER:
+ return BG_AV_NODES_FROSTWOLF_ETOWER;
+ case BG_AV_OBJECTID_WEST_TOWER_CONTROLLED_TOWER_BANNER:
+ case BG_AV_OBJECTID_WEST_TOWER_CONTROLLED_BANNER:
+ case BG_AV_OBJECTID_WEST_TOWER_CONTESTED_BANNER:
+ case BG_AV_OBJECTID_WEST_TOWER_CONTESTED_TOWER_BANNER:
+ return BG_AV_NODES_FROSTWOLF_WTOWER;
+ case BG_AV_OBJECTID_TOWER_POINT_CONTROLLED_TOWER_BANNER:
+ case BG_AV_OBJECTID_TOWER_POINT_CONTROLLED_BANNER:
+ case BG_AV_OBJECTID_TOWER_POINT_CONTESTED_BANNER:
+ case BG_AV_OBJECTID_TOWER_POINT_CONTESTED_TOWER_BANNER:
+ return BG_AV_NODES_TOWER_POINT;
+ case BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTROLLED_TOWER_BANNER:
+ case BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTROLLED_BANNER:
+ case BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTESTED_BANNER:
+ case BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTESTED_TOWER_BANNER:
+ return BG_AV_NODES_ICEBLOOD_TOWER;
+ case BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTROLLED_TOWER_BANNER:
+ case BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTROLLED_BANNER:
+ case BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTESTED_BANNER:
+ case BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTESTED_TOWER_BANNER:
+ return BG_AV_NODES_STONEHEART_BUNKER;
+ case BG_AV_OBJECTID_ICEWING_BUNKER_CONTROLLED_TOWER_BANNER:
+ case BG_AV_OBJECTID_ICEWING_BUNKER_CONTROLLED_BANNER:
+ case BG_AV_OBJECTID_ICEWING_BUNKER_CONTESTED_BANNER:
+ case BG_AV_OBJECTID_ICEWING_BUNKER_CONTESTED_TOWER_BANNER:
+ return BG_AV_NODES_ICEWING_BUNKER;
+ default:
+ TC_LOG_ERROR("bg.battleground", "BattlegroundAV: ERROR! GetPlace got a wrong object :(");
+ ABORT();
+ return BG_AV_Nodes(0);
+ }
+ }
+
+ void HandleInteractCapturableObject(Player* player, GameObject* target)
+ {
+ if (!player || !target)
+ return;
+
+ switch (target->GetEntry())
+ {
+ // graveyards
+ case BG_AV_OBJECTID_AID_STATION_ALLIANCE_CONTROLLED:
+ case BG_AV_OBJECTID_AID_STATION_HORDE_CONTROLLED:
+ case BG_AV_OBJECTID_FROSTWOLF_ALLIANCE_CONTROLLED:
+ case BG_AV_OBJECTID_FROSTWOLF_HORDE_CONTROLLED:
+ case BG_AV_OBJECTID_FROSTWOLF_HUT_ALLIANCE_CONTROLLED:
+ case BG_AV_OBJECTID_FROSTWOLF_HUT_HORDE_CONTROLLED:
+ case BG_AV_OBJECTID_ICEBLOOD_ALLIANCE_CONTROLLED:
+ case BG_AV_OBJECTID_ICEBLOOD_HORDE_CONTROLLED:
+ case BG_AV_OBJECTID_STONEHEARTH_ALLIANCE_CONTROLLED:
+ case BG_AV_OBJECTID_STONEHEARTH_HORDE_CONTROLLED:
+ case BG_AV_OBJECTID_STORMPIKE_ALLIANCE_CONTROLLED:
+ case BG_AV_OBJECTID_STORMPIKE_HORDE_CONTROLLED:
+ // Snowfall
+ case BG_AV_OBJECTID_SNOWFALL_NEUTRAL:
+ case BG_AV_OBJECTID_SNOWFALL_ALLIANCE_CONTROLLED:
+ case BG_AV_OBJECTID_SNOWFALL_HORDE_CONTROLLED:
+ // towers
+ case BG_AV_OBJECTID_EAST_TOWER_CONTROLLED_BANNER:
+ case BG_AV_OBJECTID_WEST_TOWER_CONTROLLED_BANNER:
+ case BG_AV_OBJECTID_TOWER_POINT_CONTROLLED_BANNER:
+ case BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTROLLED_BANNER:
+ case BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTROLLED_BANNER:
+ case BG_AV_OBJECTID_ICEWING_BUNKER_CONTROLLED_BANNER:
+ case BG_AV_OBJECTID_SOUTH_BUNKER_CONTROLLED_BANNER:
+ case BG_AV_OBJECTID_NORTH_BUNKER_CONTROLLED_BANNER:
+ EventPlayerAssaultsPoint(player, target->GetEntry());
+ break;
+ // graveyards
+ case BG_AV_OBJECTID_AID_STATION_ALLIANCE_CONTESTED:
+ case BG_AV_OBJECTID_AID_STATION_HORDE_CONTESTED:
+ case BG_AV_OBJECTID_FROSTWOLF_ALLIANCE_CONTESTED:
+ case BG_AV_OBJECTID_FROSTWOLF_HORDE_CONTESTED:
+ case BG_AV_OBJECTID_FROSTWOLF_HUT_ALLIANCE_CONTESTED:
+ case BG_AV_OBJECTID_FROSTWOLF_HUT_HORDE_CONTESTED:
+ case BG_AV_OBJECTID_ICEBLOOD_ALLIANCE_CONTESTED:
+ case BG_AV_OBJECTID_ICEBLOOD_HORDE_CONTESTED:
+ case BG_AV_OBJECTID_STONEHEARTH_ALLIANCE_CONTESTED:
+ case BG_AV_OBJECTID_STONEHEARTH_HORDE_CONTESTED:
+ case BG_AV_OBJECTID_STORMPIKE_ALLIANCE_CONTESTED:
+ case BG_AV_OBJECTID_STORMPIKE_HORDE_CONTESTED:
+ // towers
+ case BG_AV_OBJECTID_EAST_TOWER_CONTESTED_BANNER:
+ case BG_AV_OBJECTID_WEST_TOWER_CONTESTED_BANNER:
+ case BG_AV_OBJECTID_TOWER_POINT_CONTESTED_BANNER:
+ case BG_AV_OBJECTID_ICEBLOOD_TOWER_CONTESTED_BANNER:
+ case BG_AV_OBJECTID_STONEHEARTH_BUNKER_CONTESTED_BANNER:
+ case BG_AV_OBJECTID_ICEWING_BUNKER_CONTESTED_BANNER:
+ case BG_AV_OBJECTID_SOUTH_BUNKER_CONTESTED_BANNER:
+ case BG_AV_OBJECTID_NORTH_BUNKER_CONTESTED_BANNER:
+ EventPlayerDefendsPoint(player, target->GetEntry());
+ break;
+ // Snowfall special cases (either defend/assault)
+ case BG_AV_OBJECTID_SNOWFALL_ALLIANCE_CONTESTED:
+ case BG_AV_OBJECTID_SNOWFALL_HORDE_CONTESTED:
+ {
+ BG_AV_Nodes const node = GetNodeThroughObject(target->GetEntry());
+ if (_nodes[node].TotalOwner == TEAM_OTHER)
+ EventPlayerAssaultsPoint(player, target->GetEntry());
+ else
+ EventPlayerDefendsPoint(player, target->GetEntry());
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ void EventPlayerDefendsPoint(Player* player, uint32 object)
+ {
+ BG_AV_Nodes node = GetNodeThroughObject(object);
+
+ Team const owner = _nodes[node].Owner;
+ Team const team = battleground->GetPlayerTeam(player->GetGUID());
+
+ if (owner == team || _nodes[node].State != POINT_ASSAULTED)
+ return;
+
+ TC_LOG_DEBUG("bg.battleground", "player defends point object: {} node: {}", object, node);
+ if (_nodes[node].PrevOwner != team)
+ {
+ TC_LOG_ERROR("bg.battleground", "BG_AV: player defends point which doesn't belong to his team {}", node);
+ return;
+ }
+
+ DefendNode(node, team);
+ UpdateNodeWorldState(node);
+
+ if (StaticNodeInfo const* nodeInfo = GetStaticNodeInfo(node))
+ {
+ std::string stringId;
+
+ if (IsTower(node))
+ stringId = nodeInfo->StringIds.AllianceOrDefend;
+ else
+ stringId = team == ALLIANCE ? nodeInfo->StringIds.AllianceOrDefend : nodeInfo->StringIds.HordeOrDestroy;
+
+ if (Creature const* herald = FindHerald(stringId))
+ herald->AI()->Talk(team == ALLIANCE ? nodeInfo->TextIds.AllianceCapture : nodeInfo->TextIds.HordeCapture);
+ }
+
+ // update the statistic for the defending player
+ battleground->UpdatePvpStat(player, IsTower(node) ? PVP_STAT_TOWERS_DEFENDED : PVP_STAT_GRAVEYARDS_DEFENDED, 1);
+ battlegroundMap->UpdateSpawnGroupConditions();
+ }
+
+ void EventPlayerAssaultsPoint(Player* player, uint32 object)
+ {
+ BG_AV_Nodes node = GetNodeThroughObject(object);
+ Team const owner = _nodes[node].Owner; //maybe name it prevowner
+ Team const team = battleground->GetPlayerTeam(player->GetGUID());
+
+ TC_LOG_DEBUG("bg.battleground", "bg_av: player assaults point object {} node {}", object, node);
+ if (owner == team || team == _nodes[node].TotalOwner)
+ return; //surely a gm used this object
+
+ AssaultNode(node, team);
+ UpdateNodeWorldState(node);
+
+ if (StaticNodeInfo const* nodeInfo = GetStaticNodeInfo(node))
+ {
+ std::string stringId;
+ if (IsTower(node))
+ stringId = nodeInfo->StringIds.HordeOrDestroy;
+ else
+ stringId = team == ALLIANCE ? nodeInfo->StringIds.AllianceOrDefend : nodeInfo->StringIds.HordeOrDestroy;
+
+ if (Creature const* herald = FindHerald(stringId))
+ herald->AI()->Talk(team == ALLIANCE ? nodeInfo->TextIds.AllianceAttack : nodeInfo->TextIds.HordeAttack);
+ }
+
+ // update the statistic for the assaulting player
+ battleground->UpdatePvpStat(player, (IsTower(node)) ? PVP_STAT_TOWERS_ASSAULTED : PVP_STAT_GRAVEYARDS_ASSAULTED, 1);
+ battlegroundMap->UpdateSpawnGroupConditions();
+ }
+
+ void UpdateNodeWorldState(BG_AV_Nodes node) const
+ {
+ if (StaticNodeInfo const* nodeInfo = GetStaticNodeInfo(node))
+ {
+ uint16 const owner = _nodes[node].Owner;
+ BG_AV_States const state = _nodes[node].State;
+
+ UpdateWorldState(nodeInfo->WorldStateIds.AllianceAssault, owner == ALLIANCE && state == POINT_ASSAULTED);
+ UpdateWorldState(nodeInfo->WorldStateIds.AllianceControl, owner == ALLIANCE && state >= POINT_DESTROYED);
+ UpdateWorldState(nodeInfo->WorldStateIds.HordeAssault, owner == HORDE && state == POINT_ASSAULTED);
+ UpdateWorldState(nodeInfo->WorldStateIds.HordeControl, owner == HORDE && state >= POINT_DESTROYED);
+ if (nodeInfo->WorldStateIds.Owner)
+ UpdateWorldState(nodeInfo->WorldStateIds.Owner, owner == HORDE ? 2 : owner == ALLIANCE ? 1 : 0);
+ }
+
+ if (node == BG_AV_NODES_SNOWFALL_GRAVE)
+ UpdateWorldState(AV_WS_SNOWFALL_GRAVEYARD_UNCONTROLLED, _nodes[node].Owner == TEAM_OTHER);
+ }
+
+ void SendMineWorldStates(AlteracValleyMine mine) const
+ {
+ AlteracValleyMineInfo const& mineInfo = _mineInfo[uint8(mine)];
+ UpdateWorldState(mineInfo.StaticInfo.WorldStateHordeControlled, mineInfo.Owner == HORDE);
+ UpdateWorldState(mineInfo.StaticInfo.WorldStateAllianceControlled, mineInfo.Owner == ALLIANCE);
+ UpdateWorldState(mineInfo.StaticInfo.WorldStateNeutralControlled, mineInfo.Owner == TEAM_OTHER);
+ UpdateWorldState(mineInfo.StaticInfo.WorldStateOwner, mineInfo.Owner == HORDE ? 2 : mineInfo.Owner == ALLIANCE ? 1 : 0);
+ }
+
+ void AssaultNode(BG_AV_Nodes node, Team team)
+ {
+ _nodes[node].PrevOwner = _nodes[node].Owner;
+ _nodes[node].Owner = team;
+ _nodes[node].PrevState = _nodes[node].State;
+ _nodes[node].State = POINT_ASSAULTED;
+ }
+
+ void DestroyNode(BG_AV_Nodes node)
+ {
+ _nodes[node].TotalOwner = _nodes[node].Owner;
+ _nodes[node].PrevOwner = _nodes[node].Owner;
+ _nodes[node].PrevState = _nodes[node].State;
+ _nodes[node].State = (_nodes[node].Tower) ? POINT_DESTROYED : POINT_CONTROLED;
+ }
+
+ void InitNode(BG_AV_Nodes node, Team team, bool tower)
+ {
+ _nodes[node].TotalOwner = team;
+ _nodes[node].Owner = team;
+ _nodes[node].PrevOwner = 0;
+ _nodes[node].State = POINT_CONTROLED;
+ _nodes[node].PrevState = _nodes[node].State;
+ _nodes[node].State = POINT_CONTROLED;
+ _nodes[node].Tower = tower;
+ }
+
+ void DefendNode(BG_AV_Nodes node, Team team)
+ {
+ _nodes[node].PrevOwner = _nodes[node].Owner;
+ _nodes[node].Owner = team;
+ _nodes[node].PrevState = _nodes[node].State;
+ _nodes[node].State = POINT_CONTROLED;
+ }
+
+ Team GetPrematureWinner() override
+ {
+ uint32 const allianceScore = _teamResources[Battleground::GetTeamIndexByTeamId(ALLIANCE)];
+ uint32 const hordeScore = _teamResources[Battleground::GetTeamIndexByTeamId(HORDE)];
+
+ if (allianceScore > hordeScore)
+ return ALLIANCE;
+ if (hordeScore > allianceScore)
+ return HORDE;
+
+ return BattlegroundScript::GetPrematureWinner();
+ }
+
+ void OnGameObjectCreate(GameObject* gameObject) override
+ {
+ switch (gameObject->GetEntry())
+ {
+ case BG_AV_GHOST_GATE:
+ case BG_AV_OBJECTID_GATE:
+ _doorGUIDs.insert(gameObject->GetGUID());
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnCreatureCreate(Creature* creature) override
+ {
+ switch (creature->GetEntry())
+ {
+ case BG_AV_CREATURE_GALVANGAR:
+ _galvangarGUID = creature->GetGUID();
+ break;
+ case BG_AV_CREATURE_BALINDA:
+ _balindaGUID = creature->GetGUID();
+ break;
+ case BG_AV_CREATURE_HERALD:
+ _heraldGUIDs.insert(creature->GetGUID());
+ break;
+ default:
+ break;
+ }
+ }
+
+ uint32 GetData(uint32 dataId) const override
+ {
+ auto getDefenderTierForTeam = [&](TeamId teamId) -> DefenderTier
+ {
+ if (_teamQuestStatus[teamId][0] < 500)
+ return BG_AV_DEFENDER_TIER_DEFENDER;
+
+ if (_teamQuestStatus[teamId][0] < 1000)
+ return BG_AV_DEFENDER_TIER_SEASONED;
+
+ if (_teamQuestStatus[teamId][0] < 1500)
+ return BG_AV_DEFENDER_TIER_VETERAN;
+
+ return BG_AV_DEFENDER_TIER_CHAMPION;
+ };
+
+ switch (dataId)
+ {
+ case DATA_DEFENDER_TIER_ALLIANCE:
+ return getDefenderTierForTeam(TEAM_ALLIANCE);
+ case DATA_DEFENDER_TIER_HORDE:
+ return getDefenderTierForTeam(TEAM_HORDE);
+ default:
+ return BattlegroundScript::GetData(dataId);
+ }
+ }
+
+ Creature* FindHerald(std::string_view stringId) const
+ {
+ for (ObjectGuid const& guid : _heraldGUIDs)
+ if (Creature* creature = battlegroundMap->GetCreature(guid))
+ if (creature->HasStringId(stringId))
+ return creature;
+
+ return nullptr;
+ }
+
+ static StaticNodeInfo const* GetStaticNodeInfo(BG_AV_Nodes node)
+ {
+ for (const auto& nodeInfo : BGAVNodeInfo)
+ if (nodeInfo.NodeId == node)
+ return &nodeInfo;
+
+ return nullptr;
+ }
+
+ bool IsTower(BG_AV_Nodes node) const { return _nodes[node].Tower; }
+
+ void UpdateScore(Team team, int16 points)
+ {
+ ASSERT(team == ALLIANCE || team == HORDE);
+ TeamId const teamindex = Battleground::GetTeamIndexByTeamId(team);
+ _teamResources[teamindex] += points;
+
+ UpdateWorldState(teamindex == TEAM_HORDE ? AV_WS_HORDE_REINFORCEMENTS : AV_WS_ALLIANCE_REINFORCEMENTS, _teamResources[teamindex]);
+ if (points < 0)
+ {
+ if (_teamResources[teamindex] < 1)
+ {
+ _teamResources[teamindex] = 0;
+ battleground->EndBattleground(teamindex == TEAM_HORDE ? ALLIANCE : HORDE);
+ }
+ else if (!_isInformedNearVictory[teamindex] && _teamResources[teamindex] < NEAR_LOSE_POINTS)
+ {
+ if (teamindex == TEAM_ALLIANCE)
+ battleground->SendBroadcastText(BG_AV_TEXT_ALLIANCE_NEAR_LOSE, CHAT_MSG_BG_SYSTEM_ALLIANCE);
+ else
+ battleground->SendBroadcastText(BG_AV_TEXT_HORDE_NEAR_LOSE, CHAT_MSG_BG_SYSTEM_HORDE);
+ battleground->PlaySoundToAll(AV_SOUND_NEAR_VICTORY);
+ _isInformedNearVictory[teamindex] = true;
+ }
+ }
+ }
+
+private:
+ /*variables */
+ std::array<int32, PVP_TEAMS_COUNT> _teamResources;
+ uint32 _teamQuestStatus[PVP_TEAMS_COUNT][9]; //[x][y] x=team y=questcounter
+
+ std::array<BG_AV_NodeInfo, BG_AV_NODES_MAX> _nodes;
+
+ TimeTracker _mineResourceTimer; //ticks for both teams
+
+ std::array<AlteracValleyMineInfo, 2> _mineInfo;
+
+ std::array<TimeTracker, PVP_TEAMS_COUNT> _captainBuffTimer;
+
+ std::array<bool, PVP_TEAMS_COUNT> _isInformedNearVictory;
+ GuidUnorderedSet _doorGUIDs;
+ ObjectGuid _balindaGUID;
+ ObjectGuid _galvangarGUID;
+ GuidUnorderedSet _heraldGUIDs;
+};
+
+void AddSC_battleground_alterac_valley()
+{
+ RegisterBattlegroundMapScript(battleground_alterac_valley, 30);
+}
diff --git a/src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp b/src/server/scripts/Battlegrounds/AlteracValley/boss_balinda.cpp
index 38987c82428..38987c82428 100644
--- a/src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp
+++ b/src/server/scripts/Battlegrounds/AlteracValley/boss_balinda.cpp
diff --git a/src/server/scripts/EasternKingdoms/AlteracValley/boss_drekthar.cpp b/src/server/scripts/Battlegrounds/AlteracValley/boss_drekthar.cpp
index f7ec0bb3da9..f7ec0bb3da9 100644
--- a/src/server/scripts/EasternKingdoms/AlteracValley/boss_drekthar.cpp
+++ b/src/server/scripts/Battlegrounds/AlteracValley/boss_drekthar.cpp
diff --git a/src/server/scripts/EasternKingdoms/AlteracValley/boss_galvangar.cpp b/src/server/scripts/Battlegrounds/AlteracValley/boss_galvangar.cpp
index 741387ec033..741387ec033 100644
--- a/src/server/scripts/EasternKingdoms/AlteracValley/boss_galvangar.cpp
+++ b/src/server/scripts/Battlegrounds/AlteracValley/boss_galvangar.cpp
diff --git a/src/server/scripts/EasternKingdoms/AlteracValley/boss_vanndar.cpp b/src/server/scripts/Battlegrounds/AlteracValley/boss_vanndar.cpp
index 83c1fcc813e..83c1fcc813e 100644
--- a/src/server/scripts/EasternKingdoms/AlteracValley/boss_vanndar.cpp
+++ b/src/server/scripts/Battlegrounds/AlteracValley/boss_vanndar.cpp
diff --git a/src/server/scripts/EasternKingdoms/ArathiBasin/arathi_basin.cpp b/src/server/scripts/Battlegrounds/ArathiBasin/arathi_basin.cpp
index 4a30195833f..4a30195833f 100644
--- a/src/server/scripts/EasternKingdoms/ArathiBasin/arathi_basin.cpp
+++ b/src/server/scripts/Battlegrounds/ArathiBasin/arathi_basin.cpp
diff --git a/src/server/scripts/Battlegrounds/ArathiBasin/battleground_arathi_basin.cpp b/src/server/scripts/Battlegrounds/ArathiBasin/battleground_arathi_basin.cpp
new file mode 100644
index 00000000000..f30216bf067
--- /dev/null
+++ b/src/server/scripts/Battlegrounds/ArathiBasin/battleground_arathi_basin.cpp
@@ -0,0 +1,605 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "BattlegroundScript.h"
+#include "Battleground.h"
+#include "BattlegroundMgr.h"
+#include "BattlegroundPackets.h"
+#include "Creature.h"
+#include "GameObject.h"
+#include "GameTime.h"
+#include "Log.h"
+#include "Map.h"
+#include "ScriptMgr.h"
+
+struct battleground_arathi_basin : BattlegroundScript
+{
+ // Tick intervals and given points: case 0, 1, 2, 3, 4, 5 captured nodes
+ static constexpr uint32 BG_AB_TickInterval = 2000;
+ static constexpr uint32 BG_AB_TickPoints[6] = { 0, 2, 3, 4, 7, 60 };
+ static constexpr uint32 NORMAL_HONOR_TICKS = 160;
+ static constexpr uint32 WEEKEND_HONOR_TICKS = 260;
+ static constexpr uint32 NORMAL_REPUTATION_TICKS = 120;
+ static constexpr uint32 WEEKEND_REPUTATION_TICKS = 160;
+
+ enum PvpStats
+ {
+ PVP_STAT_BASES_ASSAULTED = 926,
+ PVP_STAT_BASES_DEFENDED = 927,
+ };
+
+ enum Events
+ {
+ AB_EVENT_START_BATTLE = 9158, // Achievement: Let's Get This Done
+
+ AB_EVENT_CONTESTED_STABLES_HORDE = 28523,
+ AB_EVENT_CAPTURE_STABLES_HORDE = 28527,
+ AB_EVENT_DEFENDED_STABLES_HORDE = 28525,
+ AB_EVENT_CONTESTED_STABLES_ALLIANCE = 28522,
+ AB_EVENT_CAPTURE_STABLES_ALLIANCE = 28526,
+ AB_EVENT_DEFENDED_STABLES_ALLIANCE = 28524,
+
+ AB_EVENT_CONTESTED_BLACKSMITH_HORDE = 8876,
+ AB_EVENT_CAPTURE_BLACKSMITH_HORDE = 8773,
+ AB_EVENT_DEFENDED_BLACKSMITH_HORDE = 8770,
+ AB_EVENT_CONTESTED_BLACKSMITH_ALLIANCE = 8874,
+ AB_EVENT_CAPTURE_BLACKSMITH_ALLIANCE = 8769,
+ AB_EVENT_DEFENDED_BLACKSMITH_ALLIANCE = 8774,
+
+ AB_EVENT_CONTESTED_FARM_HORDE = 39398,
+ AB_EVENT_CAPTURE_FARM_HORDE = 39399,
+ AB_EVENT_DEFENDED_FARM_HORDE = 39400,
+ AB_EVENT_CONTESTED_FARM_ALLIANCE = 39401,
+ AB_EVENT_CAPTURE_FARM_ALLIANCE = 39402,
+ AB_EVENT_DEFENDED_FARM_ALLIANCE = 39403,
+
+ AB_EVENT_CONTESTED_GOLD_MINE_HORDE = 39404,
+ AB_EVENT_CAPTURE_GOLD_MINE_HORDE = 39405,
+ AB_EVENT_DEFENDED_GOLD_MINE_HORDE = 39406,
+ AB_EVENT_CONTESTED_GOLD_MINE_ALLIANCE = 39407,
+ AB_EVENT_CAPTURE_GOLD_MINE_ALLIANCE = 39408,
+ AB_EVENT_DEFENDED_GOLD_MINE_ALLIANCE = 39409,
+
+ AB_EVENT_CONTESTED_LUMBER_MILL_HORDE = 39387,
+ AB_EVENT_CAPTURE_LUMBER_MILL_HORDE = 39388,
+ AB_EVENT_DEFENDED_LUMBER_MILL_HORDE = 39389,
+ AB_EVENT_CONTESTED_LUMBER_MILL_ALLIANCE = 39390,
+ AB_EVENT_CAPTURE_LUMBER_MILL_ALLIANCE = 39391,
+ AB_EVENT_DEFENDED_LUMBER_MILL_ALLIANCE = 39392
+ };
+
+ enum Sounds
+ {
+ BG_AB_SOUND_NODE_CLAIMED = 8192,
+ BG_AB_SOUND_NODE_CAPTURED_ALLIANCE = 8173,
+ BG_AB_SOUND_NODE_CAPTURED_HORDE = 8213,
+ BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE = 8212,
+ BG_AB_SOUND_NODE_ASSAULTED_HORDE = 8174,
+ BG_AB_SOUND_NEAR_VICTORY_ALLIANCE = 8456,
+ BG_AB_SOUND_NEAR_VICTORY_HORDE = 8457
+ };
+
+ enum BroadcastTexts
+ {
+ BG_AB_TEXT_ALLIANCE_NEAR_VICTORY = 10598,
+ BG_AB_TEXT_HORDE_NEAR_VICTORY = 10599,
+ };
+
+ enum Score
+ {
+ BG_AB_WARNING_NEAR_VICTORY_SCORE = 1200,
+ BG_AB_MAX_TEAM_SCORE = 1500
+ };
+
+ enum Creatures
+ {
+ BG_AB_NPC_THE_BLACK_BRIDE = 150501,
+ BG_AB_NPC_RADULF_LEDER = 150505
+ };
+
+ enum ObjectTypes
+ {
+ BG_AB_OBJECTID_CAPTURE_POINT_STABLES = 227420,
+ BG_AB_OBJECTID_CAPTURE_POINT_BLACKSMITH = 227522,
+ BG_AB_OBJECTID_CAPTURE_POINT_FARM = 227536,
+ BG_AB_OBJECTID_CAPTURE_POINT_GOLD_MINE = 227538,
+ BG_AB_OBJECTID_CAPTURE_POINT_LUMBER_MILL = 227544,
+
+ BG_AB_OBJECTID_GHOST_GATE = 180322,
+ BG_AB_OBJECTID_ALLIANCE_DOOR = 322273,
+ BG_AB_OBJECTID_HORDE_DOOR = 322274
+ };
+
+ enum WorldStates
+ {
+ BG_AB_WS_OCCUPIED_BASES_HORDE = 1778,
+ BG_AB_WS_OCCUPIED_BASES_ALLY = 1779,
+ BG_AB_WS_RESOURCES_ALLY = 1776,
+ BG_AB_WS_RESOURCES_HORDE = 1777,
+ BG_AB_WS_RESOURCES_MAX = 1780,
+ BG_AB_WS_RESOURCES_WARNING = 1955,
+
+ BG_AB_WS_STABLE_ICON = 1842, // Stable map icon (NONE)
+ BG_AB_WS_STABLE_STATE_ALIENCE = 1767, // Stable map state (ALIENCE)
+ BG_AB_WS_STABLE_STATE_HORDE = 1768, // Stable map state (HORDE)
+ BG_AB_WS_STABLE_STATE_CON_ALI = 1769, // Stable map state (CON ALIENCE)
+ BG_AB_WS_STABLE_STATE_CON_HOR = 1770, // Stable map state (CON HORDE)
+ BG_AB_WS_FARM_ICON = 1845, // Farm map icon (NONE)
+ BG_AB_WS_FARM_STATE_ALIENCE = 1772, // Farm state (ALIENCE)
+ BG_AB_WS_FARM_STATE_HORDE = 1773, // Farm state (HORDE)
+ BG_AB_WS_FARM_STATE_CON_ALI = 1774, // Farm state (CON ALIENCE)
+ BG_AB_WS_FARM_STATE_CON_HOR = 1775, // Farm state (CON HORDE)
+ BG_AB_WS_BLACKSMITH_ICON = 1846, // Blacksmith map icon (NONE)
+ BG_AB_WS_BLACKSMITH_STATE_ALIENCE = 1782, // Blacksmith map state (ALIENCE)
+ BG_AB_WS_BLACKSMITH_STATE_HORDE = 1783, // Blacksmith map state (HORDE)
+ BG_AB_WS_BLACKSMITH_STATE_CON_ALI = 1784, // Blacksmith map state (CON ALIENCE)
+ BG_AB_WS_BLACKSMITH_STATE_CON_HOR = 1785, // Blacksmith map state (CON HORDE)
+ BG_AB_WS_LUMBERMILL_ICON = 1844, // Lumber Mill map icon (NONE)
+ BG_AB_WS_LUMBERMILL_STATE_ALIENCE = 1792, // Lumber Mill map state (ALIENCE)
+ BG_AB_WS_LUMBERMILL_STATE_HORDE = 1793, // Lumber Mill map state (HORDE)
+ BG_AB_WS_LUMBERMILL_STATE_CON_ALI = 1794, // Lumber Mill map state (CON ALIENCE)
+ BG_AB_WS_LUMBERMILL_STATE_CON_HOR = 1795, // Lumber Mill map state (CON HORDE)
+ BG_AB_WS_GOLDMINE_ICON = 1843, // Gold Mine map icon (NONE)
+ BG_AB_WS_GOLDMINE_STATE_ALIENCE = 1787, // Gold Mine map state (ALIENCE)
+ BG_AB_WS_GOLDMINE_STATE_HORDE = 1788, // Gold Mine map state (HORDE)
+ BG_AB_WS_GOLDMINE_STATE_CON_ALI = 1789, // Gold Mine map state (CON ALIENCE
+ BG_AB_WS_GOLDMINE_STATE_CON_HOR = 1790, // Gold Mine map state (CON HORDE)
+
+ BG_AB_WS_HAD_500_DISADVANTAGE_ALLIANCE = 3644,
+ BG_AB_WS_HAD_500_DISADVANTAGE_HORDE = 3645,
+
+ BG_AB_WS_FARM_ICON_NEW = 8808, // Farm map icon
+ BG_AB_WS_LUMBER_MILL_ICON_NEW = 8805, // Lumber Mill map icon
+ BG_AB_WS_BLACKSMITH_ICON_NEW = 8799, // Blacksmith map icon
+ BG_AB_WS_GOLD_MINE_ICON_NEW = 8809, // Gold Mine map icon
+ BG_AB_WS_STABLES_ICON_NEW = 5834, // Stable map icon
+
+ BG_AB_WS_FARM_HORDE_CONTROL_STATE = 17328,
+ BG_AB_WS_FARM_ALLIANCE_CONTROL_STATE = 17325,
+ BG_AB_WS_LUMBER_MILL_HORDE_CONTROL_STATE = 17330,
+ BG_AB_WS_LUMBER_MILL_ALLIANCE_CONTROL_STATE = 17326,
+ BG_AB_WS_BLACKSMITH_HORDE_CONTROL_STATE = 17327,
+ BG_AB_WS_BLACKSMITH_ALLIANCE_CONTROL_STATE = 17324,
+ BG_AB_WS_GOLD_MINE_HORDE_CONTROL_STATE = 17329,
+ BG_AB_WS_GOLD_MINE_ALLIANCE_CONTROL_STATE = 17323,
+ BG_AB_WS_STABLES_HORDE_CONTROL_STATE = 17331,
+ BG_AB_WS_STABLES_ALLIANCE_CONTROL_STATE = 17322,
+ };
+
+ explicit battleground_arathi_basin(BattlegroundMap* map) : BattlegroundScript(map), _lastTick(0), _isInformedNearVictory(false)
+ {
+ bool const isBGWeekend = sBattlegroundMgr->IsBGWeekend(battleground->GetTypeID());
+
+ _honorTics = (isBGWeekend) ? WEEKEND_HONOR_TICKS : NORMAL_HONOR_TICKS;
+ _reputationTics = (isBGWeekend) ? WEEKEND_REPUTATION_TICKS : NORMAL_REPUTATION_TICKS;
+ _honorScoreTics = { { 0, 0 } };
+ _reputationScoreTics = { { 0, 0 } };
+ }
+
+ void OnInit() override
+ {
+ BattlegroundScript::OnInit();
+
+ UpdateWorldState(BG_AB_WS_RESOURCES_MAX, BG_AB_MAX_TEAM_SCORE);
+ UpdateWorldState(BG_AB_WS_RESOURCES_WARNING, BG_AB_WARNING_NEAR_VICTORY_SCORE);
+ }
+
+ void OnUpdate(uint32 diff) override
+ {
+ if (battleground->GetStatus() != STATUS_IN_PROGRESS)
+ return;
+
+ // Accumulate points
+ _lastTick += diff;
+ if (_lastTick > BG_AB_TickInterval)
+ {
+ _lastTick -= BG_AB_TickInterval;
+
+ uint8 ally = 0, horde = 0;
+ _CalculateTeamNodes(ally, horde);
+ uint8 points[PVP_TEAMS_COUNT] = { ally, horde };
+
+ for (uint8 team = 0; team < PVP_TEAMS_COUNT; ++team)
+ {
+ if (!points[team])
+ continue;
+
+ battleground->AddPoint(team == TEAM_HORDE ? HORDE : ALLIANCE, BG_AB_TickPoints[points[team]]);
+ _honorScoreTics[team] += BG_AB_TickPoints[points[team]];
+ _reputationScoreTics[team] += BG_AB_TickPoints[points[team]];
+
+ if (_reputationScoreTics[team] >= _reputationTics)
+ {
+ (team == TEAM_ALLIANCE) ? battleground->RewardReputationToTeam(509, 10, ALLIANCE) : battleground->RewardReputationToTeam(510, 10, HORDE);
+ _reputationScoreTics[team] -= _reputationTics;
+ }
+
+ if (_honorScoreTics[team] >= _honorTics)
+ {
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), (team == TEAM_ALLIANCE) ? ALLIANCE : HORDE);
+ _honorScoreTics[team] -= _honorTics;
+ }
+
+ const uint32 teamScore = battleground->GetTeamScore(static_cast<TeamId>(team));
+ if (!_isInformedNearVictory && teamScore > BG_AB_WARNING_NEAR_VICTORY_SCORE)
+ {
+ if (team == TEAM_ALLIANCE)
+ {
+ battleground->SendBroadcastText(BG_AB_TEXT_ALLIANCE_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NEAR_VICTORY_ALLIANCE);
+ }
+ else
+ {
+ battleground->SendBroadcastText(BG_AB_TEXT_HORDE_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NEAR_VICTORY_HORDE);
+ }
+ _isInformedNearVictory = true;
+ }
+
+ if (teamScore > BG_AB_MAX_TEAM_SCORE)
+ battleground->SetTeamPoint(team == TEAM_HORDE ? HORDE : ALLIANCE, BG_AB_MAX_TEAM_SCORE);
+
+ if (team == TEAM_ALLIANCE)
+ UpdateWorldState(BG_AB_WS_RESOURCES_ALLY, teamScore);
+ else
+ UpdateWorldState(BG_AB_WS_RESOURCES_HORDE, teamScore);
+
+ // update achievement flags
+ // we increased m_TeamScores[team] so we just need to check if it is 500 more than other teams resources
+ uint8 otherTeam = (team + 1) % PVP_TEAMS_COUNT;
+ if (teamScore > battleground->GetTeamScore(static_cast<TeamId>(otherTeam)) + 500)
+ {
+ if (team == TEAM_ALLIANCE)
+ UpdateWorldState(BG_AB_WS_HAD_500_DISADVANTAGE_HORDE, 1);
+ else
+ UpdateWorldState(BG_AB_WS_HAD_500_DISADVANTAGE_ALLIANCE, 1);
+ }
+ }
+
+ UpdateWorldState(BG_AB_WS_OCCUPIED_BASES_ALLY, ally);
+ UpdateWorldState(BG_AB_WS_OCCUPIED_BASES_HORDE, horde);
+ }
+
+ // Test win condition
+ if (battleground->GetTeamScore(TEAM_ALLIANCE) >= BG_AB_MAX_TEAM_SCORE && battleground->GetTeamScore(TEAM_HORDE) >= BG_AB_MAX_TEAM_SCORE)
+ battleground->EndBattleground(TEAM_OTHER); // draw
+ else if (battleground->GetTeamScore(TEAM_ALLIANCE) >= BG_AB_MAX_TEAM_SCORE)
+ battleground->EndBattleground(ALLIANCE);
+ else if (battleground->GetTeamScore(TEAM_HORDE) >= BG_AB_MAX_TEAM_SCORE)
+ battleground->EndBattleground(HORDE);
+ }
+
+ void OnStart() override
+ {
+ // Achievement: Let's Get This Done
+ TriggerGameEvent(AB_EVENT_START_BATTLE);
+ }
+
+ void _CalculateTeamNodes(uint8& alliance, uint8& horde) const
+ {
+ alliance = 0;
+ horde = 0;
+
+ for (ObjectGuid const& guid : _capturePoints)
+ {
+ if (GameObject const* capturePoint = battlegroundMap->GetGameObject(guid))
+ {
+ int32 const wsValue = battlegroundMap->GetWorldStateValue(capturePoint->GetGOInfo()->capturePoint.worldState1);
+ switch (WorldPackets::Battleground::BattlegroundCapturePointState(wsValue))
+ {
+ case WorldPackets::Battleground::BattlegroundCapturePointState::AllianceCaptured:
+ ++alliance;
+ break;
+ case WorldPackets::Battleground::BattlegroundCapturePointState::HordeCaptured:
+ ++horde;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ Team GetPrematureWinner() override
+ {
+ // How many bases each team owns
+ uint8 ally = 0, horde = 0;
+ _CalculateTeamNodes(ally, horde);
+
+ if (ally > horde)
+ return ALLIANCE;
+ if (horde > ally)
+ return HORDE;
+
+ // If the values are equal, fall back to the original result (based on number of players on each team)
+ return BattlegroundScript::GetPrematureWinner();
+ }
+
+ void ProcessEvent(WorldObject* /*source*/, uint32 eventId, WorldObject* invoker) override
+ {
+ switch (eventId)
+ {
+ case AB_EVENT_START_BATTLE:
+ {
+ for (ObjectGuid const& guid : _creaturesToRemoveOnMatchStart)
+ if (Creature* creature = battlegroundMap->GetCreature(guid))
+ creature->DespawnOrUnsummon();
+
+ for (ObjectGuid const& guid : _gameobjectsToRemoveOnMatchStart)
+ if (GameObject* gameObject = battlegroundMap->GetGameObject(guid))
+ gameObject->DespawnOrUnsummon();
+
+ for (ObjectGuid const& guid : _doors)
+ {
+ if (GameObject* gameObject = battlegroundMap->GetGameObject(guid))
+ {
+ gameObject->UseDoorOrButton();
+ gameObject->DespawnOrUnsummon(3s);
+ }
+ }
+ break;
+ }
+ case AB_EVENT_CONTESTED_BLACKSMITH_ALLIANCE:
+ UpdateWorldState(BG_AB_WS_BLACKSMITH_ALLIANCE_CONTROL_STATE, 1);
+ UpdateWorldState(BG_AB_WS_BLACKSMITH_HORDE_CONTROL_STATE, 0);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
+ break;
+ case AB_EVENT_DEFENDED_BLACKSMITH_ALLIANCE:
+ UpdateWorldState(BG_AB_WS_BLACKSMITH_ALLIANCE_CONTROL_STATE, 2);
+ UpdateWorldState(BG_AB_WS_BLACKSMITH_HORDE_CONTROL_STATE, 0);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
+ break;
+ case AB_EVENT_CAPTURE_BLACKSMITH_ALLIANCE:
+ UpdateWorldState(BG_AB_WS_BLACKSMITH_ALLIANCE_CONTROL_STATE, 2);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
+ break;
+ case AB_EVENT_CONTESTED_BLACKSMITH_HORDE:
+ UpdateWorldState(BG_AB_WS_BLACKSMITH_ALLIANCE_CONTROL_STATE, 0);
+ UpdateWorldState(BG_AB_WS_BLACKSMITH_HORDE_CONTROL_STATE, 1);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_HORDE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
+ break;
+ case AB_EVENT_DEFENDED_BLACKSMITH_HORDE:
+ UpdateWorldState(BG_AB_WS_BLACKSMITH_ALLIANCE_CONTROL_STATE, 0);
+ UpdateWorldState(BG_AB_WS_BLACKSMITH_HORDE_CONTROL_STATE, 2);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
+ break;
+ case AB_EVENT_CAPTURE_BLACKSMITH_HORDE:
+ UpdateWorldState(BG_AB_WS_BLACKSMITH_HORDE_CONTROL_STATE, 2);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
+ break;
+ case AB_EVENT_CONTESTED_FARM_ALLIANCE:
+ UpdateWorldState(BG_AB_WS_FARM_ALLIANCE_CONTROL_STATE, 1);
+ UpdateWorldState(BG_AB_WS_FARM_HORDE_CONTROL_STATE, 0);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
+ break;
+ case AB_EVENT_DEFENDED_FARM_ALLIANCE:
+ UpdateWorldState(BG_AB_WS_FARM_ALLIANCE_CONTROL_STATE, 2);
+ UpdateWorldState(BG_AB_WS_FARM_HORDE_CONTROL_STATE, 0);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
+ break;
+ case AB_EVENT_CAPTURE_FARM_ALLIANCE:
+ UpdateWorldState(BG_AB_WS_FARM_ALLIANCE_CONTROL_STATE, 2);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
+ break;
+ case AB_EVENT_CONTESTED_FARM_HORDE:
+ UpdateWorldState(BG_AB_WS_FARM_ALLIANCE_CONTROL_STATE, 0);
+ UpdateWorldState(BG_AB_WS_FARM_HORDE_CONTROL_STATE, 1);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_HORDE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
+ break;
+ case AB_EVENT_DEFENDED_FARM_HORDE:
+ UpdateWorldState(BG_AB_WS_FARM_ALLIANCE_CONTROL_STATE, 0);
+ UpdateWorldState(BG_AB_WS_FARM_HORDE_CONTROL_STATE, 2);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
+ break;
+ case AB_EVENT_CAPTURE_FARM_HORDE:
+ UpdateWorldState(BG_AB_WS_FARM_HORDE_CONTROL_STATE, 2);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
+ break;
+ case AB_EVENT_CONTESTED_GOLD_MINE_ALLIANCE:
+ UpdateWorldState(BG_AB_WS_GOLD_MINE_ALLIANCE_CONTROL_STATE, 1);
+ UpdateWorldState(BG_AB_WS_GOLD_MINE_HORDE_CONTROL_STATE, 0);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
+ break;
+ case AB_EVENT_DEFENDED_GOLD_MINE_ALLIANCE:
+ UpdateWorldState(BG_AB_WS_GOLD_MINE_ALLIANCE_CONTROL_STATE, 2);
+ UpdateWorldState(BG_AB_WS_GOLD_MINE_HORDE_CONTROL_STATE, 0);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
+ break;
+ case AB_EVENT_CAPTURE_GOLD_MINE_ALLIANCE:
+ UpdateWorldState(BG_AB_WS_GOLD_MINE_ALLIANCE_CONTROL_STATE, 2);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
+ break;
+ case AB_EVENT_CONTESTED_GOLD_MINE_HORDE:
+ UpdateWorldState(BG_AB_WS_GOLD_MINE_ALLIANCE_CONTROL_STATE, 0);
+ UpdateWorldState(BG_AB_WS_GOLD_MINE_HORDE_CONTROL_STATE, 1);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_HORDE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
+ break;
+ case AB_EVENT_DEFENDED_GOLD_MINE_HORDE:
+ UpdateWorldState(BG_AB_WS_GOLD_MINE_ALLIANCE_CONTROL_STATE, 0);
+ UpdateWorldState(BG_AB_WS_GOLD_MINE_HORDE_CONTROL_STATE, 2);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
+ break;
+ case AB_EVENT_CAPTURE_GOLD_MINE_HORDE:
+ UpdateWorldState(BG_AB_WS_GOLD_MINE_HORDE_CONTROL_STATE, 2);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
+ break;
+ case AB_EVENT_CONTESTED_LUMBER_MILL_ALLIANCE:
+ UpdateWorldState(BG_AB_WS_LUMBER_MILL_ALLIANCE_CONTROL_STATE, 1);
+ UpdateWorldState(BG_AB_WS_LUMBER_MILL_HORDE_CONTROL_STATE, 0);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
+ break;
+ case AB_EVENT_DEFENDED_LUMBER_MILL_ALLIANCE:
+ UpdateWorldState(BG_AB_WS_LUMBER_MILL_ALLIANCE_CONTROL_STATE, 2);
+ UpdateWorldState(BG_AB_WS_LUMBER_MILL_HORDE_CONTROL_STATE, 0);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
+ break;
+ case AB_EVENT_CAPTURE_LUMBER_MILL_ALLIANCE:
+ UpdateWorldState(BG_AB_WS_LUMBER_MILL_ALLIANCE_CONTROL_STATE, 2);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
+ break;
+ case AB_EVENT_CONTESTED_LUMBER_MILL_HORDE:
+ UpdateWorldState(BG_AB_WS_LUMBER_MILL_ALLIANCE_CONTROL_STATE, 0);
+ UpdateWorldState(BG_AB_WS_LUMBER_MILL_HORDE_CONTROL_STATE, 1);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_HORDE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
+ break;
+ case AB_EVENT_DEFENDED_LUMBER_MILL_HORDE:
+ UpdateWorldState(BG_AB_WS_LUMBER_MILL_ALLIANCE_CONTROL_STATE, 0);
+ UpdateWorldState(BG_AB_WS_LUMBER_MILL_HORDE_CONTROL_STATE, 2);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
+ break;
+ case AB_EVENT_CAPTURE_LUMBER_MILL_HORDE:
+ UpdateWorldState(BG_AB_WS_LUMBER_MILL_HORDE_CONTROL_STATE, 2);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
+ break;
+ case AB_EVENT_CONTESTED_STABLES_ALLIANCE:
+ UpdateWorldState(BG_AB_WS_STABLES_ALLIANCE_CONTROL_STATE, 1);
+ UpdateWorldState(BG_AB_WS_STABLES_HORDE_CONTROL_STATE, 0);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
+ break;
+ case AB_EVENT_DEFENDED_STABLES_ALLIANCE:
+ UpdateWorldState(BG_AB_WS_STABLES_ALLIANCE_CONTROL_STATE, 2);
+ UpdateWorldState(BG_AB_WS_STABLES_HORDE_CONTROL_STATE, 0);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
+ break;
+ case AB_EVENT_CAPTURE_STABLES_ALLIANCE:
+ UpdateWorldState(BG_AB_WS_STABLES_ALLIANCE_CONTROL_STATE, 2);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
+ break;
+ case AB_EVENT_CONTESTED_STABLES_HORDE:
+ UpdateWorldState(BG_AB_WS_STABLES_ALLIANCE_CONTROL_STATE, 0);
+ UpdateWorldState(BG_AB_WS_STABLES_HORDE_CONTROL_STATE, 1);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_HORDE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
+ break;
+ case AB_EVENT_DEFENDED_STABLES_HORDE:
+ UpdateWorldState(BG_AB_WS_STABLES_ALLIANCE_CONTROL_STATE, 0);
+ UpdateWorldState(BG_AB_WS_STABLES_HORDE_CONTROL_STATE, 2);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
+ if (Player* player = invoker->ToPlayer())
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
+ break;
+ case AB_EVENT_CAPTURE_STABLES_HORDE:
+ UpdateWorldState(BG_AB_WS_STABLES_HORDE_CONTROL_STATE, 2);
+ battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
+ break;
+ default:
+ TC_LOG_WARN("bg.events", "BattlegroundAB::ProcessEvent: Unhandled event %u.", eventId);
+ break;
+ }
+ }
+
+ void OnCreatureCreate(Creature* creature) override
+ {
+ switch (creature->GetEntry())
+ {
+ case BG_AB_NPC_THE_BLACK_BRIDE:
+ case BG_AB_NPC_RADULF_LEDER:
+ _creaturesToRemoveOnMatchStart.push_back(creature->GetGUID());
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnGameObjectCreate(GameObject* gameObject) override
+ {
+ if (gameObject->GetGOInfo()->type == GAMEOBJECT_TYPE_CAPTURE_POINT)
+ _capturePoints.push_back(gameObject->GetGUID());
+
+ switch (gameObject->GetEntry())
+ {
+ case BG_AB_OBJECTID_GHOST_GATE:
+ _gameobjectsToRemoveOnMatchStart.push_back(gameObject->GetGUID());
+ break;
+ case BG_AB_OBJECTID_ALLIANCE_DOOR:
+ case BG_AB_OBJECTID_HORDE_DOOR:
+ _doors.push_back(gameObject->GetGUID());
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnEnd(Team winner) override
+ {
+ BattlegroundScript::OnEnd(winner);
+
+ // Win reward
+ if (winner == ALLIANCE)
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), ALLIANCE);
+ if (winner == HORDE)
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), HORDE);
+ // Complete map_end rewards (even if no team wins)
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), HORDE);
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), ALLIANCE);
+ }
+
+private:
+ uint32 _lastTick;
+ std::array<uint32, PVP_TEAMS_COUNT> _honorScoreTics;
+ std::array<uint32, PVP_TEAMS_COUNT> _reputationScoreTics;
+ bool _isInformedNearVictory;
+ uint32 _honorTics;
+ uint32 _reputationTics;
+
+ GuidVector _gameobjectsToRemoveOnMatchStart;
+ GuidVector _creaturesToRemoveOnMatchStart;
+ GuidVector _doors;
+ GuidVector _capturePoints;
+};
+
+void AddSC_battleground_arathi_basin()
+{
+ RegisterBattlegroundMapScript(battleground_arathi_basin, 2107);
+}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundTP.h b/src/server/scripts/Battlegrounds/BattleForGilneas/battleground_battle_for_gilneas.cpp
index 0b1654a616d..ff049d2dd11 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundTP.h
+++ b/src/server/scripts/Battlegrounds/BattleForGilneas/battleground_battle_for_gilneas.cpp
@@ -15,23 +15,21 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef __BATTLEGROUNDTP_H
-#define __BATTLEGROUNDTP_H
+#include "BattlegroundScript.h"
+#include "ScriptMgr.h"
-#include "Battleground.h"
-#include "BattlegroundScore.h"
-
-enum BG_TP_Objectives
+struct battleground_battle_for_gilneas : BattlegroundScript
{
- BG_TP_FLAG_CAPTURES = 290,
- BG_TP_FLAG_RETURNS = 291
-};
+ enum PvpStats : uint32
+ {
+ BFG_OBJECTIVE_BASES_ASSAULTED = 370,
+ BFG_OBJECTIVE_BASES_DEFENDED = 371
+ };
-class BattlegroundTP : public Battleground
-{
- public:
- BattlegroundTP(BattlegroundTemplate const* battlegroundTemplate);
- ~BattlegroundTP();
+ explicit battleground_battle_for_gilneas(BattlegroundMap* map) : BattlegroundScript(map) { }
};
-#endif
+void AddSC_battleground_battle_for_gilneas()
+{
+ RegisterBattlegroundMapScript(battleground_battle_for_gilneas, 761);
+}
diff --git a/src/server/scripts/Battlegrounds/BladesEdge/arena_blades_edge.cpp b/src/server/scripts/Battlegrounds/BladesEdge/arena_blades_edge.cpp
new file mode 100644
index 00000000000..f0ac3bfc212
--- /dev/null
+++ b/src/server/scripts/Battlegrounds/BladesEdge/arena_blades_edge.cpp
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Battleground.h"
+#include "BattlegroundScript.h"
+#include "GameObject.h"
+#include "Map.h"
+#include "ScriptMgr.h"
+#include "TaskScheduler.h"
+
+struct arena_blades_edge : ArenaScript
+{
+ enum GameObjects
+ {
+ BG_BE_OBJECT_TYPE_DOOR_1 = 183971,
+ BG_BE_OBJECT_TYPE_DOOR_2 = 183973,
+ BG_BE_OBJECT_TYPE_DOOR_3 = 183970,
+ BG_BE_OBJECT_TYPE_DOOR_4 = 183972,
+ BG_BE_OBJECT_TYPE_BUFF_1 = 184663,
+ BG_BE_OBJECT_TYPE_BUFF_2 = 184664
+ };
+
+ explicit arena_blades_edge(BattlegroundMap* map) : ArenaScript(map) { }
+
+ void OnUpdate(uint32 diff) override
+ {
+ _scheduler.Update(diff);
+ }
+
+ void OnInit() override
+ {
+ AddDoor(BG_BE_OBJECT_TYPE_DOOR_1, 6287.277f, 282.1877f, 3.810925f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f);
+ AddDoor(BG_BE_OBJECT_TYPE_DOOR_2, 6189.546f, 241.7099f, 3.101481f, 0.8813917f, 0, 0, 0.4265689f, 0.9044551f);
+ AddDoor(BG_BE_OBJECT_TYPE_DOOR_3, 6299.116f, 296.5494f, 3.308032f, 0.8813917f, 0, 0, 0.4265689f, 0.9044551f);
+ AddDoor(BG_BE_OBJECT_TYPE_DOOR_4, 6177.708f, 227.3481f, 3.604374f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f);
+ }
+
+ void OnStart() override
+ {
+ for (ObjectGuid const& guid : _doorGUIDs)
+ {
+ if (GameObject* door = battlegroundMap->GetGameObject(guid))
+ {
+ door->UseDoorOrButton();
+ door->DespawnOrUnsummon(5s);
+ }
+ }
+
+ _scheduler.Schedule(1min, [&](TaskContext)
+ {
+ CreateObject(BG_BE_OBJECT_TYPE_BUFF_1, 6249.042f, 275.3239f, 11.22033f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f);
+ CreateObject(BG_BE_OBJECT_TYPE_BUFF_2, 6228.26f, 249.566f, 11.21812f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f);
+ });
+ }
+
+ void AddDoor(uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, GOState goState = GO_STATE_READY)
+ {
+ if (GameObject const* go = CreateObject(entry, x, y, z, o, rotation0, rotation1, rotation2, rotation3, goState))
+ _doorGUIDs.emplace_back(go->GetGUID());
+ }
+
+private:
+ GuidVector _doorGUIDs;
+ TaskScheduler _scheduler;
+};
+
+void AddSC_arena_blades_edge()
+{
+ RegisterBattlegroundMapScript(arena_blades_edge, 1672);
+}
diff --git a/src/server/scripts/Battlegrounds/DalaranSewers/arena_dalaran_sewers.cpp b/src/server/scripts/Battlegrounds/DalaranSewers/arena_dalaran_sewers.cpp
new file mode 100644
index 00000000000..bbdf5d4ab3b
--- /dev/null
+++ b/src/server/scripts/Battlegrounds/DalaranSewers/arena_dalaran_sewers.cpp
@@ -0,0 +1,266 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Battleground.h"
+#include "BattlegroundScript.h"
+#include "Creature.h"
+#include "Duration.h"
+#include "EventMap.h"
+#include "GameObject.h"
+#include "Map.h"
+#include "ObjectAccessor.h"
+#include "Player.h"
+#include "ScriptMgr.h"
+#include "TaskScheduler.h"
+
+struct arena_dalaran_sewers : ArenaScript
+{
+ enum GameObjects
+ {
+ BG_DS_OBJECT_TYPE_DOOR_1 = 192642,
+ BG_DS_OBJECT_TYPE_DOOR_2 = 192643,
+ BG_DS_OBJECT_TYPE_WATER_1 = 194395, // Collision
+ BG_DS_OBJECT_TYPE_WATER_2 = 191877,
+ BG_DS_OBJECT_TYPE_BUFF_1 = 184663,
+ BG_DS_OBJECT_TYPE_BUFF_2 = 184664
+ };
+
+ enum Events
+ {
+ BG_DS_EVENT_WATERFALL_WARNING = 1, // Water starting to fall, but no LoS Blocking nor movement blocking
+ BG_DS_EVENT_WATERFALL_ON = 2, // LoS and Movement blocking active
+ BG_DS_EVENT_WATERFALL_OFF = 3,
+ BG_DS_EVENT_WATERFALL_KNOCKBACK = 4,
+
+ BG_DS_EVENT_PIPE_KNOCKBACK = 5
+ };
+
+ enum Creatures
+ {
+ BG_DS_NPC_TYPE_WATER_SPOUT = 28567
+ };
+
+ enum Spells
+ {
+ BG_DS_SPELL_FLUSH = 57405, // Visual and target selector for the starting knockback from the pipe
+ BG_DS_SPELL_FLUSH_KNOCKBACK = 61698, // Knockback effect for previous spell (triggered, not needed to be cast)
+ BG_DS_SPELL_WATER_SPOUT = 58873, // Knockback effect of the central waterfall
+
+ SPELL_WARL_DEMONIC_CIRCLE = 48018 // Demonic Circle Summon
+ };
+
+ enum Data
+ {
+ // These values are NOT blizzlike... need the correct data!
+ BG_DS_PIPE_KNOCKBACK_FIRST_DELAY = 5000,
+ BG_DS_PIPE_KNOCKBACK_DELAY = 3000
+ };
+
+ // These values are NOT blizzlike... need the correct data!
+ static constexpr Seconds BG_DS_WATERFALL_TIMER_MIN = 30s;
+ static constexpr Seconds BG_DS_WATERFALL_TIMER_MAX = 60s;
+ static constexpr Seconds BG_DS_WATERFALL_WARNING_DURATION = 5s;
+ static constexpr Seconds BG_DS_WATERFALL_DURATION = 30s;
+ static constexpr Milliseconds BG_DS_WATERFALL_KNOCKBACK_TIMER = 1500ms;
+ static constexpr uint32 BG_DS_DATA_PIPE_KNOCKBACK_COUNT = 1;
+ static constexpr uint32 BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT = 2;
+
+ explicit arena_dalaran_sewers(BattlegroundMap* map) : ArenaScript(map), _pipeKnockBackTimer(BG_DS_PIPE_KNOCKBACK_FIRST_DELAY), _pipeKnockBackCount(0) { }
+
+ void OnUpdate(uint32 diff) override
+ {
+ if (battleground->GetStatus() != STATUS_IN_PROGRESS)
+ return;
+
+ _events.Update(diff);
+ _scheduler.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case BG_DS_EVENT_WATERFALL_WARNING:
+ // Add the water
+ if (GameObject* go = battlegroundMap->GetGameObject(_water2GUID))
+ go->ResetDoorOrButton();
+ _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_ON, BG_DS_WATERFALL_WARNING_DURATION);
+ break;
+ case BG_DS_EVENT_WATERFALL_ON:
+ // Active collision and start knockback timer
+ if (GameObject* go = battlegroundMap->GetGameObject(_water1GUID))
+ go->ResetDoorOrButton();
+ _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_OFF, BG_DS_WATERFALL_DURATION);
+ _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_KNOCKBACK, BG_DS_WATERFALL_KNOCKBACK_TIMER);
+ break;
+ case BG_DS_EVENT_WATERFALL_OFF:
+ // Remove collision and water
+ if (GameObject* go = battlegroundMap->GetGameObject(_water1GUID))
+ go->UseDoorOrButton();
+ if (GameObject* go = battlegroundMap->GetGameObject(_water2GUID))
+ go->UseDoorOrButton();
+ _events.CancelEvent(BG_DS_EVENT_WATERFALL_KNOCKBACK);
+ _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_WARNING, BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX);
+ break;
+ case BG_DS_EVENT_WATERFALL_KNOCKBACK:
+ // Repeat knockback while the waterfall still active
+ if (Creature* waterSpout = battlegroundMap->GetCreature(_waterfallCreatureGUID))
+ waterSpout->CastSpell(waterSpout, BG_DS_SPELL_WATER_SPOUT, true);
+ _events.ScheduleEvent(eventId, BG_DS_WATERFALL_KNOCKBACK_TIMER);
+ break;
+ case BG_DS_EVENT_PIPE_KNOCKBACK:
+ for (ObjectGuid const& guid : _pipeCreatureGUIDs)
+ if (Creature* waterSpout = battlegroundMap->GetCreature(guid))
+ waterSpout->CastSpell(waterSpout, BG_DS_SPELL_FLUSH, true);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (_pipeKnockBackCount < BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT)
+ {
+ if (_pipeKnockBackTimer < diff)
+ {
+ for (ObjectGuid const& guid : _pipeCreatureGUIDs)
+ if (Creature* waterSpout = battlegroundMap->GetCreature(guid))
+ waterSpout->CastSpell(waterSpout, BG_DS_SPELL_FLUSH, true);
+
+ ++_pipeKnockBackCount;
+ _pipeKnockBackTimer = BG_DS_PIPE_KNOCKBACK_DELAY;
+ }
+ else
+ _pipeKnockBackTimer -= diff;
+ }
+
+ }
+
+ void OnInit() override
+ {
+ AddObject(BG_DS_OBJECT_TYPE_DOOR_1, 1350.95f, 817.2f, 20.8096f, 3.15f, 0, 0, 0.99627f, 0.0862864f, GO_STATE_READY, _doorGUIDs);
+ AddObject(BG_DS_OBJECT_TYPE_DOOR_2, 1232.65f, 764.913f, 20.0729f, 6.3f, 0, 0, 0.0310211f, -0.999519f, GO_STATE_READY, _doorGUIDs);
+
+ if (GameObject const* go = CreateObject(BG_DS_OBJECT_TYPE_WATER_1, 1291.56f, 790.837f, 7.1f, 3.14238f, 0, 0, 0.694215f, -0.719768f, GO_STATE_READY))
+ _water1GUID = go->GetGUID();
+
+ if (GameObject const* go = CreateObject(BG_DS_OBJECT_TYPE_WATER_2, 1291.56f, 790.837f, 7.1f, 3.14238f, 0, 0, 0.694215f, -0.719768f, GO_STATE_READY))
+ _water2GUID = go->GetGUID();
+ }
+
+ void OnStart() override
+ {
+ for (ObjectGuid const& guid : _doorGUIDs)
+ {
+ if (GameObject* door = battlegroundMap->GetGameObject(guid))
+ {
+ door->UseDoorOrButton();
+ door->DespawnOrUnsummon(5s);
+ }
+ }
+
+ _scheduler.Schedule(1min, [&](TaskContext)
+ {
+ CreateObject(BG_DS_OBJECT_TYPE_BUFF_1, 1291.7f, 813.424f, 7.11472f, 4.64562f, 0, 0, 0.730314f, -0.683111f);
+ CreateObject(BG_DS_OBJECT_TYPE_BUFF_2, 1291.7f, 768.911f, 7.11472f, 1.55194f, 0, 0, 0.700409f, 0.713742f);
+ });
+ _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_WARNING, BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX);
+ _pipeKnockBackTimer = BG_DS_PIPE_KNOCKBACK_FIRST_DELAY;
+
+ // Remove collision and water
+ if (GameObject* go = battlegroundMap->GetGameObject(_water1GUID))
+ go->UseDoorOrButton();
+ if (GameObject* go = battlegroundMap->GetGameObject(_water2GUID))
+ go->UseDoorOrButton();
+
+ for (const auto& [playerGuid, _] : battleground->GetPlayers())
+ if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
+ player->RemoveAurasDueToSpell(SPELL_WARL_DEMONIC_CIRCLE);
+ }
+
+ void AddObject(uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, GOState goState, GuidVector guidVector) const
+ {
+ if (GameObject const* go = CreateObject(entry, x, y, z, o, rotation0, rotation1, rotation2, rotation3, goState))
+ guidVector.emplace_back(go->GetGUID());
+ }
+
+ void SetData(uint32 dataId, uint32 value) override
+ {
+ ArenaScript::SetData(dataId, value);
+ if (dataId == BG_DS_DATA_PIPE_KNOCKBACK_COUNT)
+ _pipeKnockBackCount = value;
+ }
+
+ uint32 GetData(uint32 dataId) const override
+ {
+ if (dataId == BG_DS_DATA_PIPE_KNOCKBACK_COUNT)
+ return _pipeKnockBackCount;
+
+ return ArenaScript::GetData(dataId);
+ }
+
+private:
+ GuidVector _doorGUIDs;
+ ObjectGuid _water1GUID;
+ ObjectGuid _water2GUID;
+ ObjectGuid _waterfallCreatureGUID;
+ GuidVector _pipeCreatureGUIDs;
+ TaskScheduler _scheduler;
+ EventMap _events;
+
+ uint32 _pipeKnockBackTimer;
+ uint8 _pipeKnockBackCount;
+};
+
+class at_ds_pipe_knockback : public AreaTriggerScript
+{
+public:
+ at_ds_pipe_knockback() : AreaTriggerScript("at_ds_pipe_knockback") { }
+
+ void Trigger(Player* player) const
+ {
+ if (Battleground const* battleground = player->GetBattleground())
+ {
+ if (battleground->GetStatus() != STATUS_IN_PROGRESS)
+ return;
+
+ // Remove effects of Demonic Circle Summon
+ player->RemoveAurasDueToSpell(arena_dalaran_sewers::SPELL_WARL_DEMONIC_CIRCLE);
+
+ // Someone has get back into the pipes and the knockback has already been performed,
+ // so we reset the knockback count for kicking the player again into the arena.
+ if (battleground->GetBgMap()->GetBattlegroundScript()->GetData(arena_dalaran_sewers::BG_DS_DATA_PIPE_KNOCKBACK_COUNT) >= arena_dalaran_sewers::BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT)
+ battleground->GetBgMap()->GetBattlegroundScript()->SetData(arena_dalaran_sewers::BG_DS_DATA_PIPE_KNOCKBACK_COUNT, 0);
+ }
+ }
+
+ bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/) override
+ {
+ Trigger(player);
+ return true;
+ }
+
+ bool OnExit(Player* player, AreaTriggerEntry const* /*trigger*/) override
+ {
+ Trigger(player);
+ return true;
+ }
+};
+
+void AddSC_arena_dalaran_sewers()
+{
+ RegisterBattlegroundMapScript(arena_dalaran_sewers, 617);
+ new at_ds_pipe_knockback();
+}
diff --git a/src/server/scripts/Battlegrounds/EyeOfTheStorm/battleground_eye_of_the_storm.cpp b/src/server/scripts/Battlegrounds/EyeOfTheStorm/battleground_eye_of_the_storm.cpp
new file mode 100644
index 00000000000..3c8ef48438e
--- /dev/null
+++ b/src/server/scripts/Battlegrounds/EyeOfTheStorm/battleground_eye_of_the_storm.cpp
@@ -0,0 +1,677 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "AreaTrigger.h"
+#include "BattlegroundScript.h"
+#include "Battleground.h"
+#include "BattlegroundMgr.h"
+#include "GameObject.h"
+#include "GameTime.h"
+#include "Map.h"
+#include "ObjectAccessor.h"
+#include "Player.h"
+#include "ScriptMgr.h"
+#include "SpellAuras.h"
+#include "Timer.h"
+
+enum EyeOfTheStormWorldStates
+{
+ EY_ALLIANCE_RESOURCES = 1776,
+ EY_HORDE_RESOURCES = 1777,
+ EY_MAX_RESOURCES = 1780,
+ EY_ALLIANCE_BASE = 2752,
+ EY_HORDE_BASE = 2753,
+ DRAENEI_RUINS_HORDE_CONTROL = 2733,
+ DRAENEI_RUINS_ALLIANCE_CONTROL = 2732,
+ DRAENEI_RUINS_UNCONTROL = 2731,
+ MAGE_TOWER_ALLIANCE_CONTROL = 2730,
+ MAGE_TOWER_HORDE_CONTROL = 2729,
+ MAGE_TOWER_UNCONTROL = 2728,
+ FEL_REAVER_HORDE_CONTROL = 2727,
+ FEL_REAVER_ALLIANCE_CONTROL = 2726,
+ FEL_REAVER_UNCONTROL = 2725,
+ BLOOD_ELF_HORDE_CONTROL = 2724,
+ BLOOD_ELF_ALLIANCE_CONTROL = 2723,
+ BLOOD_ELF_UNCONTROL = 2722,
+ PROGRESS_BAR_PERCENT_GREY = 2720, //100 = empty (only grey), 0 = blue|red (no grey)
+ PROGRESS_BAR_STATUS = 2719, //50 init!, 48 ... hordak bere .. 33 .. 0 = full 100% hordacky, 100 = full alliance
+ PROGRESS_BAR_SHOW = 2718, //1 init, 0 druhy send - bez messagu, 1 = controlled aliance
+ NETHERSTORM_FLAG = 8863,
+ //set to 2 when flag is picked up, and to 1 if it is dropped
+ NETHERSTORM_FLAG_STATE_ALLIANCE = 9808,
+ NETHERSTORM_FLAG_STATE_HORDE = 9809,
+
+ DRAENEI_RUINS_HORDE_CONTROL_STATE = 17362,
+ DRAENEI_RUINS_ALLIANCE_CONTROL_STATE = 17366,
+ MAGE_TOWER_HORDE_CONTROL_STATE = 17361,
+ MAGE_TOWER_ALLIANCE_CONTROL_STATE = 17368,
+ FEL_REAVER_HORDE_CONTROL_STATE = 17364,
+ FEL_REAVER_ALLIANCE_CONTROL_STATE = 17367,
+ BLOOD_ELF_HORDE_CONTROL_STATE = 17363,
+ BLOOD_ELF_ALLIANCE_CONTROL_STATE = 17365,
+};
+
+enum EyeOfTheStormSounds
+{
+ //strange ids, but sure about them
+ BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE = 8212,
+ BG_EY_SOUND_FLAG_CAPTURED_HORDE = 8213,
+ BG_EY_SOUND_FLAG_PICKED_UP_HORDE = 8174,
+ BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE = 8173,
+ BG_EY_SOUND_FLAG_RESET = 8192
+};
+
+enum EyeOfTheStormSpells
+{
+ BG_EY_NETHERSTORM_FLAG_SPELL = 34976,
+ BG_EY_PLAYER_DROPPED_FLAG_SPELL = 34991,
+
+ // Focused/Brutal Assault
+ BG_EY_FOCUSED_ASSAULT_SPELL = 46392,
+ BG_EY_BRUTAL_ASSAULT_SPELL = 46393
+};
+
+enum EyeOfTheStormObjectEntry
+{
+ BG_OBJECT_A_DOOR_EY_ENTRY = 184719, //Alliance door
+ BG_OBJECT_H_DOOR_EY_ENTRY = 184720, //Horde door
+ BG_OBJECT_FLAG2_EY_ENTRY = 208977, //Netherstorm flag (flagstand)
+ BG_OBJECT_BE_TOWER_CAP_EY_ENTRY = 184080, //BE Tower Cap Pt
+ BG_OBJECT_FR_TOWER_CAP_EY_ENTRY = 184081, //Fel Reaver Cap Pt
+ BG_OBJECT_HU_TOWER_CAP_EY_ENTRY = 184082, //Human Tower Cap Pt
+ BG_OBJECT_DR_TOWER_CAP_EY_ENTRY = 184083, //Draenei Tower Cap Pt
+};
+
+enum EyeOfTheStormPointsTrigger
+{
+ AREATRIGGER_CAPTURE_FLAG = 33
+};
+
+enum EyeOfTheStormPoints
+{
+ FEL_REAVER = 0,
+ BLOOD_ELF = 1,
+ DRAENEI_RUINS = 2,
+ MAGE_TOWER = 3,
+
+ EY_PLAYERS_OUT_OF_POINTS = 4,
+ EY_POINTS_MAX = 4
+};
+
+constexpr uint32 BG_EY_NotEYWeekendHonorTicks = 260;
+constexpr uint32 BG_EY_EYWeekendHonorTicks = 160;
+
+enum BG_EY_Score
+{
+ BG_EY_WARNING_NEAR_VICTORY_SCORE = 1200,
+ BG_EY_MAX_TEAM_SCORE = 1500
+};
+
+enum BG_EY_FlagState
+{
+ BG_EY_FLAG_STATE_ON_BASE = 0,
+ BG_EY_FLAG_STATE_WAIT_RESPAWN = 1,
+ BG_EY_FLAG_STATE_ON_PLAYER = 2,
+ BG_EY_FLAG_STATE_ON_GROUND = 3
+};
+
+enum EYBattlegroundPointState
+{
+ EY_POINT_NO_OWNER = 0,
+ EY_POINT_STATE_UNCONTROLLED = 0,
+ EY_POINT_UNDER_CONTROL = 3
+};
+
+enum BG_EY_ExploitTeleportLocations
+{
+ EY_EXPLOIT_TELEPORT_LOCATION_ALLIANCE = 3773,
+ EY_EXPLOIT_TELEPORT_LOCATION_HORDE = 3772
+};
+
+enum EyeOFtheStormBroadcastTexts
+{
+ BG_EY_TEXT_ALLIANCE_TAKEN_FEL_REAVER_RUINS = 17828,
+ BG_EY_TEXT_HORDE_TAKEN_FEL_REAVER_RUINS = 17829,
+ BG_EY_TEXT_ALLIANCE_LOST_FEL_REAVER_RUINS = 91961,
+ BG_EY_TEXT_HORDE_LOST_FEL_REAVER_RUINS = 91962,
+
+ BG_EY_TEXT_ALLIANCE_TAKEN_BLOOD_ELF_TOWER = 17819,
+ BG_EY_TEXT_HORDE_TAKEN_BLOOD_ELF_TOWER = 17823,
+ BG_EY_TEXT_ALLIANCE_LOST_BLOOD_ELF_TOWER = 91957,
+ BG_EY_TEXT_HORDE_LOST_BLOOD_ELF_TOWER = 91958,
+
+ BG_EY_TEXT_ALLIANCE_TAKEN_DRAENEI_RUINS = 17827,
+ BG_EY_TEXT_HORDE_TAKEN_DRAENEI_RUINS = 91917,
+ BG_EY_TEXT_ALLIANCE_LOST_DRAENEI_RUINS = 91959,
+ BG_EY_TEXT_HORDE_LOST_DRAENEI_RUINS = 91960,
+
+ BG_EY_TEXT_ALLIANCE_TAKEN_MAGE_TOWER = 17824,
+ BG_EY_TEXT_HORDE_TAKEN_MAGE_TOWER = 17825,
+ BG_EY_TEXT_ALLIANCE_LOST_MAGE_TOWER = 91963,
+ BG_EY_TEXT_HORDE_LOST_MAGE_TOWER = 91964,
+
+ BG_EY_TEXT_TAKEN_FLAG = 18359,
+ BG_EY_TEXT_FLAG_DROPPED = 18361,
+ BG_EY_TEXT_FLAG_RESET = 18364,
+ BG_EY_TEXT_ALLIANCE_CAPTURED_FLAG = 18375,
+ BG_EY_TEXT_HORDE_CAPTURED_FLAG = 18384,
+};
+
+struct BattlegroundEYPointIconsStruct
+{
+ BattlegroundEYPointIconsStruct(uint32 _WorldStateControlIndex, uint32 _WorldStateAllianceControlledIndex, uint32 _WorldStateHordeControlledIndex,
+ uint32 worldStateAllianceStatusBarIcon, uint32 worldStateHordeStatusBarIcon)
+ : WorldStateControlIndex(_WorldStateControlIndex), WorldStateAllianceControlledIndex(_WorldStateAllianceControlledIndex), WorldStateHordeControlledIndex(_WorldStateHordeControlledIndex),
+ WorldStateAllianceStatusBarIcon(worldStateAllianceStatusBarIcon), WorldStateHordeStatusBarIcon(worldStateHordeStatusBarIcon) { }
+ uint32 WorldStateControlIndex;
+ uint32 WorldStateAllianceControlledIndex;
+ uint32 WorldStateHordeControlledIndex;
+ uint32 WorldStateAllianceStatusBarIcon;
+ uint32 WorldStateHordeStatusBarIcon;
+};
+
+struct BattlegroundEYLosingPointStruct
+{
+ BattlegroundEYLosingPointStruct(uint32 _MessageIdAlliance, uint32 _MessageIdHorde)
+ : MessageIdAlliance(_MessageIdAlliance), MessageIdHorde(_MessageIdHorde)
+ { }
+
+ uint32 MessageIdAlliance;
+ uint32 MessageIdHorde;
+};
+
+struct BattlegroundEYCapturingPointStruct
+{
+ BattlegroundEYCapturingPointStruct(uint32 _MessageIdAlliance, uint32 _MessageIdHorde)
+ : MessageIdAlliance(_MessageIdAlliance), MessageIdHorde(_MessageIdHorde)
+ { }
+
+ uint32 MessageIdAlliance;
+ uint32 MessageIdHorde;
+};
+
+class BattlegroundEYControlZoneHandler : public ControlZoneHandler
+{
+public:
+ explicit BattlegroundEYControlZoneHandler(uint32 point) : _point(point) { }
+
+ uint32 GetPoint() const { return _point; }
+
+private:
+ uint32 _point;
+};
+
+const std::array<BattlegroundEYPointIconsStruct, EY_POINTS_MAX> m_PointsIconStruct =
+{
+ BattlegroundEYPointIconsStruct(FEL_REAVER_UNCONTROL, FEL_REAVER_ALLIANCE_CONTROL, FEL_REAVER_HORDE_CONTROL, FEL_REAVER_ALLIANCE_CONTROL_STATE, FEL_REAVER_HORDE_CONTROL_STATE),
+ BattlegroundEYPointIconsStruct(BLOOD_ELF_UNCONTROL, BLOOD_ELF_ALLIANCE_CONTROL, BLOOD_ELF_HORDE_CONTROL, BLOOD_ELF_ALLIANCE_CONTROL_STATE, BLOOD_ELF_HORDE_CONTROL_STATE),
+ BattlegroundEYPointIconsStruct(DRAENEI_RUINS_UNCONTROL, DRAENEI_RUINS_ALLIANCE_CONTROL, DRAENEI_RUINS_HORDE_CONTROL, DRAENEI_RUINS_ALLIANCE_CONTROL_STATE, DRAENEI_RUINS_HORDE_CONTROL_STATE),
+ BattlegroundEYPointIconsStruct(MAGE_TOWER_UNCONTROL, MAGE_TOWER_ALLIANCE_CONTROL, MAGE_TOWER_HORDE_CONTROL, MAGE_TOWER_ALLIANCE_CONTROL_STATE, MAGE_TOWER_HORDE_CONTROL_STATE)
+};
+
+const std::array<BattlegroundEYLosingPointStruct, EY_POINTS_MAX> m_LosingPointTypes =
+{
+ BattlegroundEYLosingPointStruct(BG_EY_TEXT_ALLIANCE_LOST_FEL_REAVER_RUINS, BG_EY_TEXT_HORDE_LOST_FEL_REAVER_RUINS),
+ BattlegroundEYLosingPointStruct(BG_EY_TEXT_ALLIANCE_LOST_BLOOD_ELF_TOWER, BG_EY_TEXT_HORDE_LOST_BLOOD_ELF_TOWER),
+ BattlegroundEYLosingPointStruct(BG_EY_TEXT_ALLIANCE_LOST_DRAENEI_RUINS, BG_EY_TEXT_HORDE_LOST_DRAENEI_RUINS),
+ BattlegroundEYLosingPointStruct(BG_EY_TEXT_ALLIANCE_LOST_MAGE_TOWER, BG_EY_TEXT_HORDE_LOST_MAGE_TOWER)
+};
+
+const std::array<BattlegroundEYCapturingPointStruct, EY_POINTS_MAX> m_CapturingPointTypes =
+{
+ BattlegroundEYCapturingPointStruct(BG_EY_TEXT_ALLIANCE_TAKEN_FEL_REAVER_RUINS, BG_EY_TEXT_HORDE_TAKEN_FEL_REAVER_RUINS),
+ BattlegroundEYCapturingPointStruct(BG_EY_TEXT_ALLIANCE_TAKEN_BLOOD_ELF_TOWER, BG_EY_TEXT_HORDE_TAKEN_BLOOD_ELF_TOWER),
+ BattlegroundEYCapturingPointStruct(BG_EY_TEXT_ALLIANCE_TAKEN_DRAENEI_RUINS, BG_EY_TEXT_HORDE_TAKEN_DRAENEI_RUINS),
+ BattlegroundEYCapturingPointStruct(BG_EY_TEXT_ALLIANCE_TAKEN_MAGE_TOWER, BG_EY_TEXT_HORDE_TAKEN_MAGE_TOWER)
+};
+
+struct battleground_eye_of_the_storm : BattlegroundScript
+{
+ enum PvpStats
+ {
+ PVP_STAT_FLAG_CAPTURES = 183
+ };
+
+ static constexpr Seconds POINTS_TICK_TIME = 2s;
+ static constexpr Seconds BG_EY_FLAG_ASSAULT_TIMER = 30s;
+ static constexpr uint16 BG_EY_FLAG_BRUTAL_ASSAULT_STACK_COUNT = 5;
+ static constexpr uint32 BG_EY_EVENT_START_BATTLE = 13180;
+
+ static constexpr std::array<uint8, EY_POINTS_MAX> BG_EY_TickPoints = { 1, 2, 5, 10 };
+ static constexpr std::array<uint32, EY_POINTS_MAX> BG_EY_FlagPoints = { 75, 85, 100, 500 };
+
+ explicit battleground_eye_of_the_storm(BattlegroundMap* map) : BattlegroundScript(map)
+ {
+ _honorScoreTics = { 0, 0 };
+ _honorTics = 0;
+ _pointsTimer.Reset(POINTS_TICK_TIME);
+ _assaultEnabled = false;
+ _assaultStackCount = 0;
+ _flagAssaultTimer.Reset(BG_EY_FLAG_ASSAULT_TIMER);
+
+ _controlZoneHandlers[BG_OBJECT_FR_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(FEL_REAVER);
+ _controlZoneHandlers[BG_OBJECT_BE_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(BLOOD_ELF);
+ _controlZoneHandlers[BG_OBJECT_DR_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(DRAENEI_RUINS);
+ _controlZoneHandlers[BG_OBJECT_HU_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(MAGE_TOWER);
+
+ bool isBGWeekend = sBattlegroundMgr->IsBGWeekend(battleground->GetTypeID());
+ _honorTics = (isBGWeekend) ? BG_EY_EYWeekendHonorTicks : BG_EY_NotEYWeekendHonorTicks;
+ }
+
+ void OnInit() override
+ {
+ UpdateWorldState(EY_MAX_RESOURCES, BG_EY_MAX_TEAM_SCORE);
+ }
+
+ void OnUpdate(uint32 diff) override
+ {
+ if (battleground->GetStatus() != STATUS_IN_PROGRESS)
+ return;
+
+ _pointsTimer.Update(diff);
+ if (_pointsTimer.Passed())
+ {
+ _pointsTimer.Reset(POINTS_TICK_TIME);
+
+ uint8 baseCountAlliance = GetControlledBaseCount(TEAM_ALLIANCE);
+ uint8 baseCountHorde = GetControlledBaseCount(TEAM_HORDE);
+ if (baseCountAlliance > 0)
+ AddPoint(ALLIANCE, BG_EY_TickPoints[baseCountAlliance - 1]);
+ if (baseCountHorde > 0)
+ AddPoint(HORDE, BG_EY_TickPoints[baseCountHorde - 1]);
+ }
+
+ if (_assaultEnabled)
+ {
+ _flagAssaultTimer.Update(diff);
+ if (_flagAssaultTimer.Passed())
+ {
+ _flagAssaultTimer.Reset(BG_EY_FLAG_ASSAULT_TIMER);
+ if (_assaultStackCount < std::numeric_limits<uint8>::max())
+ {
+ _assaultStackCount++;
+
+ // update assault debuff stacks
+ DoForFlagKeepers([&](Player* player) -> void
+ {
+ ApplyAssaultDebuffToPlayer(player);
+ });
+ }
+ }
+ }
+ }
+
+ void OnStart() override
+ {
+ for (ObjectGuid const& door : _doorGUIDs)
+ {
+ if (GameObject* gameObject = battlegroundMap->GetGameObject(door))
+ {
+ gameObject->UseDoorOrButton();
+ gameObject->DespawnOrUnsummon(3s);
+ }
+ }
+
+ // Achievement: Flurry
+ TriggerGameEvent(BG_EY_EVENT_START_BATTLE);
+ }
+
+ void AddPoint(Team team, uint32 points)
+ {
+ battleground->AddPoint(team, points);
+ TeamId const team_index = Battleground::GetTeamIndexByTeamId(team);
+ _honorScoreTics[team_index] += points;
+ if (_honorScoreTics[team_index] >= _honorTics)
+ {
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), team);
+ _honorScoreTics[team_index] -= _honorTics;
+ }
+
+ UpdateTeamScore(team_index);
+ }
+
+ uint8 GetControlledBaseCount(TeamId teamId) const
+ {
+ uint8 baseCount = 0;
+ for (auto const& controlZoneHandler : _controlZoneHandlers)
+ {
+ uint32 point = controlZoneHandler.second->GetPoint();
+ switch (teamId)
+ {
+ case TEAM_ALLIANCE:
+ if (battlegroundMap->GetWorldStateValue(m_PointsIconStruct[point].WorldStateAllianceControlledIndex) == 1)
+ baseCount++;
+ break;
+ case TEAM_HORDE:
+ if (battlegroundMap->GetWorldStateValue(m_PointsIconStruct[point].WorldStateHordeControlledIndex) == 1)
+ baseCount++;
+ break;
+ default:
+ break;
+ }
+ }
+ return baseCount;
+ }
+
+ void DoForFlagKeepers(std::function<void(Player*)> const& action) const
+ {
+ if (GameObject const* flag = battlegroundMap->GetGameObject(_flagGUID))
+ if (Player* carrier = ObjectAccessor::FindPlayer(flag->GetFlagCarrierGUID()))
+ action(carrier);
+ }
+
+ void ResetAssaultDebuff()
+ {
+ _assaultEnabled = false;
+ _assaultStackCount = 0;
+ _flagAssaultTimer.Reset(BG_EY_FLAG_ASSAULT_TIMER);
+ DoForFlagKeepers([&](Player* player) -> void
+ {
+ RemoveAssaultDebuffFromPlayer(player);
+ });
+ }
+
+ void ApplyAssaultDebuffToPlayer(Player* player)
+ {
+ if (_assaultStackCount == 0)
+ return;
+
+ uint32 spellId = BG_EY_FOCUSED_ASSAULT_SPELL;
+ if (_assaultStackCount >= BG_EY_FLAG_BRUTAL_ASSAULT_STACK_COUNT)
+ {
+ player->RemoveAurasDueToSpell(BG_EY_FOCUSED_ASSAULT_SPELL);
+ spellId = BG_EY_BRUTAL_ASSAULT_SPELL;
+ }
+
+ Aura* aura = player->GetAura(spellId);
+ if (!aura)
+ {
+ player->CastSpell(player, spellId, true);
+ aura = player->GetAura(spellId);
+ }
+
+ if (aura)
+ aura->SetStackAmount(_assaultStackCount);
+ }
+
+ void RemoveAssaultDebuffFromPlayer(Player* player)
+ {
+ player->RemoveAurasDueToSpell(BG_EY_FOCUSED_ASSAULT_SPELL);
+ player->RemoveAurasDueToSpell(BG_EY_BRUTAL_ASSAULT_SPELL);
+ }
+
+ void UpdateTeamScore(TeamId Team) const
+ {
+ uint32 score = battleground->GetTeamScore(Team);
+
+ if (score >= BG_EY_MAX_TEAM_SCORE)
+ {
+ score = BG_EY_MAX_TEAM_SCORE;
+ if (Team == TEAM_ALLIANCE)
+ battleground->EndBattleground(ALLIANCE);
+ else
+ battleground->EndBattleground(HORDE);
+ }
+
+ if (Team == TEAM_ALLIANCE)
+ UpdateWorldState(EY_ALLIANCE_RESOURCES, score);
+ else
+ UpdateWorldState(EY_HORDE_RESOURCES, score);
+ }
+
+ void OnEnd(Team winner) override
+ {
+ BattlegroundScript::OnEnd(winner);
+ // Win reward
+ if (winner == ALLIANCE)
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), ALLIANCE);
+ if (winner == HORDE)
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), HORDE);
+
+ // Complete map reward
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), ALLIANCE);
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), HORDE);
+ }
+
+ void UpdatePointsCount(TeamId teamId) const
+ {
+ if (teamId == TEAM_ALLIANCE)
+ UpdateWorldState(EY_ALLIANCE_BASE, GetControlledBaseCount(TEAM_ALLIANCE));
+ else
+ UpdateWorldState(EY_HORDE_BASE, GetControlledBaseCount(TEAM_HORDE));
+ }
+
+ void OnGameObjectCreate(GameObject* gameObject) override
+ {
+ switch (gameObject->GetEntry())
+ {
+ case BG_OBJECT_A_DOOR_EY_ENTRY:
+ case BG_OBJECT_H_DOOR_EY_ENTRY:
+ _doorGUIDs.insert(gameObject->GetGUID());
+ break;
+ case BG_OBJECT_FLAG2_EY_ENTRY:
+ _flagGUID = gameObject->GetGUID();
+ break;
+ default:
+ break;
+ }
+ }
+
+ bool CanCaptureFlag(AreaTrigger* areaTrigger, Player* player) override
+ {
+ if (areaTrigger->GetEntry() != AREATRIGGER_CAPTURE_FLAG)
+ return false;
+
+ if (GameObject const* flag = battlegroundMap->GetGameObject(_flagGUID))
+ {
+ if (flag->GetFlagCarrierGUID() != player->GetGUID())
+ return false;
+ }
+
+ if (GameObject const* controlzone = player->FindNearestGameObjectWithOptions(40.0f, { .StringId = "bg_eye_of_the_storm_control_zone" }))
+ {
+ uint32 const point = _controlZoneHandlers[controlzone->GetEntry()]->GetPoint();
+ switch (battleground->GetPlayerTeam(player->GetGUID()))
+ {
+ case ALLIANCE:
+ return battlegroundMap->GetWorldStateValue(m_PointsIconStruct[point].WorldStateAllianceControlledIndex) == 1;
+ case HORDE:
+ return battlegroundMap->GetWorldStateValue(m_PointsIconStruct[point].WorldStateHordeControlledIndex) == 1;
+ default:
+ return false;
+ }
+ }
+
+ return false;
+ }
+
+ void OnCaptureFlag(AreaTrigger* areaTrigger, Player* player) override
+ {
+ if (areaTrigger->GetEntry() != AREATRIGGER_CAPTURE_FLAG)
+ return;
+
+ uint32 const baseCount = GetControlledBaseCount(Battleground::GetTeamIndexByTeamId(battleground->GetPlayerTeam(player->GetGUID())));
+
+ if (GameObject const* gameObject = battlegroundMap->GetGameObject(_flagGUID))
+ gameObject->HandleCustomTypeCommand(GameObjectType::SetNewFlagState(FlagState::Respawning, player));
+
+ Team const team = Team(battleground->GetPlayerTeam(player->GetGUID()));
+ if (team == ALLIANCE)
+ {
+ battleground->SendBroadcastText(BG_EY_TEXT_ALLIANCE_CAPTURED_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ battleground->PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE);
+ }
+ else
+ {
+ battleground->SendBroadcastText(BG_EY_TEXT_HORDE_CAPTURED_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, player);
+ battleground->PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_HORDE);
+ }
+
+ if (baseCount > 0)
+ AddPoint(team, BG_EY_FlagPoints[baseCount - 1]);
+
+ UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_ON_BASE);
+ UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_ON_BASE);
+
+ battleground->UpdatePvpStat(player, PVP_STAT_FLAG_CAPTURES, 1);
+
+ ResetAssaultDebuff();
+ player->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
+ player->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::PvPActive);
+ }
+
+ void OnFlagStateChange(GameObject* /*flagInBase*/, FlagState /*oldValue*/, FlagState newValue, Player* player) override
+ {
+ switch (newValue)
+ {
+ case FlagState::InBase:
+ ResetAssaultDebuff();
+ break;
+ case FlagState::Dropped:
+ player->CastSpell(player, SPELL_RECENTLY_DROPPED_NEUTRAL_FLAG, true);
+ RemoveAssaultDebuffFromPlayer(player);
+
+ UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
+ UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
+
+ if (battleground->GetPlayerTeam(player->GetGUID()) == ALLIANCE)
+ battleground->SendBroadcastText(BG_EY_TEXT_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_ALLIANCE);
+ else
+ battleground->SendBroadcastText(BG_EY_TEXT_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_HORDE);
+ break;
+ case FlagState::Taken:
+ if (battleground->GetPlayerTeam(player->GetGUID()) == ALLIANCE)
+ {
+ UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_ON_PLAYER);
+ battleground->PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE);
+ battleground->SendBroadcastText(BG_EY_TEXT_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ }
+ else
+ {
+ UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_ON_PLAYER);
+ battleground->PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_HORDE);
+ battleground->SendBroadcastText(BG_EY_TEXT_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, player);
+ }
+
+ ApplyAssaultDebuffToPlayer(player);
+ _assaultEnabled = true;
+
+ player->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::PvPActive);
+ break;
+ case FlagState::Respawning:
+ ResetAssaultDebuff();
+ break;
+ default:
+ break;
+ }
+
+ UpdateWorldState(NETHERSTORM_FLAG, AsUnderlyingType(newValue));
+ }
+
+ void EventTeamLostPoint(TeamId teamId, uint32 point, GameObject* controlZone) const
+ {
+ if (teamId == TEAM_ALLIANCE)
+ {
+ battleground->SendBroadcastText(m_LosingPointTypes[point].MessageIdAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE, controlZone);
+ UpdateWorldState(m_PointsIconStruct[point].WorldStateAllianceControlledIndex, 0);
+ }
+ else if (teamId == TEAM_HORDE)
+ {
+ battleground->SendBroadcastText(m_LosingPointTypes[point].MessageIdHorde, CHAT_MSG_BG_SYSTEM_HORDE, controlZone);
+ UpdateWorldState(m_PointsIconStruct[point].WorldStateHordeControlledIndex, 0);
+ }
+
+ UpdateWorldState(m_PointsIconStruct[point].WorldStateControlIndex, 1);
+ UpdatePointsCount(teamId);
+ }
+
+ void EventTeamCapturedPoint(TeamId teamId, uint32 point, GameObject* controlZone) const
+ {
+ if (teamId == TEAM_ALLIANCE)
+ {
+ battleground->SendBroadcastText(m_CapturingPointTypes[point].MessageIdAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE, controlZone);
+ UpdateWorldState(m_PointsIconStruct[point].WorldStateAllianceControlledIndex, 1);
+ }
+ else if (teamId == TEAM_HORDE)
+ {
+ battleground->SendBroadcastText(m_CapturingPointTypes[point].MessageIdHorde, CHAT_MSG_BG_SYSTEM_HORDE, controlZone);
+ UpdateWorldState(m_PointsIconStruct[point].WorldStateHordeControlledIndex, 1);
+ }
+
+ UpdateWorldState(m_PointsIconStruct[point].WorldStateControlIndex, 0);
+ UpdatePointsCount(teamId);
+ }
+
+ Team GetPrematureWinner() override
+ {
+ if (battleground->GetTeamScore(TEAM_ALLIANCE) > battleground->GetTeamScore(TEAM_HORDE))
+ return ALLIANCE;
+
+ if (battleground->GetTeamScore(TEAM_HORDE) > battleground->GetTeamScore(TEAM_ALLIANCE))
+ return HORDE;
+
+ return BattlegroundScript::GetPrematureWinner();
+ }
+
+ void ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* invoker) override
+ {
+ BattlegroundScript::ProcessEvent(obj, eventId, invoker);
+
+ if (invoker)
+ {
+ if (GameObject* gameobject = invoker->ToGameObject())
+ {
+ if (gameobject->GetGoType() == GAMEOBJECT_TYPE_CONTROL_ZONE)
+ {
+ if (!_controlZoneHandlers.contains(gameobject->GetEntry()))
+ return;
+
+ auto controlzone = gameobject->GetGOInfo()->controlZone;
+ BattlegroundEYControlZoneHandler& handler = *_controlZoneHandlers[invoker->GetEntry()];
+ if (eventId == controlzone.NeutralEventAlliance)
+ EventTeamLostPoint(TEAM_ALLIANCE, handler.GetPoint(), gameobject);
+ else if (eventId == controlzone.NeutralEventHorde)
+ EventTeamLostPoint(TEAM_HORDE, handler.GetPoint(), gameobject);
+ else if (eventId == controlzone.ProgressEventAlliance)
+ EventTeamCapturedPoint(TEAM_ALLIANCE, handler.GetPoint(), gameobject);
+ else if (eventId == controlzone.ProgressEventHorde)
+ EventTeamCapturedPoint(TEAM_HORDE, handler.GetPoint(), gameobject);
+ }
+ }
+ }
+ }
+
+private:
+ std::array<uint32, PVP_TEAMS_COUNT> _honorScoreTics;
+
+ TimeTracker _pointsTimer;
+ uint32 _honorTics;
+
+ std::unordered_map<uint32, std::unique_ptr<BattlegroundEYControlZoneHandler>> _controlZoneHandlers;
+ GuidUnorderedSet _doorGUIDs;
+ ObjectGuid _flagGUID;
+
+ // Focused/Brutal Assault
+ bool _assaultEnabled;
+ TimeTracker _flagAssaultTimer;
+ uint8 _assaultStackCount;
+};
+
+void AddSC_battleground_eye_of_the_storm()
+{
+ RegisterBattlegroundMapScript(battleground_eye_of_the_storm, 566);
+}
diff --git a/src/server/scripts/Battlegrounds/IsleOfConquest/battleground_isle_of_conquest.cpp b/src/server/scripts/Battlegrounds/IsleOfConquest/battleground_isle_of_conquest.cpp
new file mode 100644
index 00000000000..5d55df8d6b7
--- /dev/null
+++ b/src/server/scripts/Battlegrounds/IsleOfConquest/battleground_isle_of_conquest.cpp
@@ -0,0 +1,902 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "BattlegroundScript.h"
+#include "Battleground.h"
+#include "BattlegroundMgr.h"
+#include "GameTime.h"
+#include "isle_of_conquest.h"
+#include "Map.h"
+#include "Player.h"
+#include "ScriptMgr.h"
+#include "TaskScheduler.h"
+#include "TemporarySummon.h"
+#include "Timer.h"
+#include "Transport.h"
+#include "TransportMgr.h"
+#include "Vehicle.h"
+
+inline constexpr uint16 MAX_REINFORCEMENTS = 400;
+
+enum BannersTypes
+{
+ BANNER_A_CONTROLLED,
+ BANNER_A_CONTESTED,
+ BANNER_H_CONTROLLED,
+ BANNER_H_CONTESTED
+};
+
+enum BG_IC_ExploitTeleportLocations
+{
+ IC_EXPLOIT_TELEPORT_LOCATION_ALLIANCE = 3986,
+ IC_EXPLOIT_TELEPORT_LOCATION_HORDE = 3983
+};
+
+enum BG_IC_GateState
+{
+ BG_IC_GATE_OK = 1,
+ BG_IC_GATE_DAMAGED = 2,
+ BG_IC_GATE_DESTROYED = 3
+};
+
+enum ICDoorList
+{
+ BG_IC_H_FRONT,
+ BG_IC_H_WEST,
+ BG_IC_H_EAST,
+ BG_IC_A_FRONT,
+ BG_IC_A_WEST,
+ BG_IC_A_EAST,
+ BG_IC_MAXDOOR
+};
+
+enum ICNodePointType
+{
+ NODE_TYPE_REFINERY,
+ NODE_TYPE_QUARRY,
+ NODE_TYPE_DOCKS,
+ NODE_TYPE_HANGAR,
+ NODE_TYPE_WORKSHOP,
+
+ // Graveyards
+ NODE_TYPE_GRAVEYARD_A,
+ NODE_TYPE_GRAVEYARD_H,
+
+ MAX_NODE_TYPES
+};
+
+enum class IsleOfConquestNodeState
+{
+ Neutral,
+ ConflictA,
+ ConflictH,
+ ControlledA,
+ ControlledH
+};
+
+enum ICBroadcastTexts
+{
+ BG_IC_TEXT_FRONT_GATE_HORDE_DESTROYED = 35409,
+ BG_IC_TEXT_FRONT_GATE_ALLIANCE_DESTROYED = 35410,
+ BG_IC_TEXT_WEST_GATE_HORDE_DESTROYED = 35411,
+ BG_IC_TEXT_WEST_GATE_ALLIANCE_DESTROYED = 35412,
+ BG_IC_TEXT_EAST_GATE_HORDE_DESTROYED = 35413,
+ BG_IC_TEXT_EAST_GATE_ALLIANCE_DESTROYED = 35414
+};
+
+// I.E: Hangar, Quarry, Graveyards .. etc
+struct IoCStaticNodeInfo
+{
+ ICNodePointType NodeType;
+
+ struct
+ {
+ uint32 Assaulted;
+ uint32 Defended;
+ uint32 AllianceTaken;
+ uint32 HordeTaken;
+ } TextIds;
+
+ struct
+ {
+ int32 Uncontrolled;
+ int32 ConflictA;
+ int32 ConflictH;
+ int32 ControlledA;
+ int32 ControlledH;
+ } WorldStateIds;
+};
+
+class ICNodePoint
+{
+public:
+ explicit ICNodePoint(IsleOfConquestNodeState state, IoCStaticNodeInfo const& nodeInfo) : _state(state), _nodeInfo(nodeInfo)
+ {
+ switch (state)
+ {
+ case IsleOfConquestNodeState::ControlledH:
+ _lastControlled = TEAM_HORDE;
+ break;
+ case IsleOfConquestNodeState::ControlledA:
+ _lastControlled = TEAM_ALLIANCE;
+ break;
+ case IsleOfConquestNodeState::ConflictA:
+ case IsleOfConquestNodeState::ConflictH:
+ case IsleOfConquestNodeState::Neutral:
+ _lastControlled = TEAM_NEUTRAL;
+ break;
+ }
+ }
+
+ IsleOfConquestNodeState GetState() const { return _state; }
+
+ bool IsContested() const
+ {
+ return _state == IsleOfConquestNodeState::ConflictA || _state == IsleOfConquestNodeState::ConflictH;
+ }
+
+ TeamId GetLastControlledTeam() const { return _lastControlled; }
+
+ IoCStaticNodeInfo const& GetNodeInfo() const { return _nodeInfo; }
+
+ void UpdateState(IsleOfConquestNodeState state)
+ {
+ switch (state)
+ {
+ case IsleOfConquestNodeState::ControlledA:
+ _lastControlled = TEAM_ALLIANCE;
+ break;
+ case IsleOfConquestNodeState::ControlledH:
+ _lastControlled = TEAM_HORDE;
+ break;
+ case IsleOfConquestNodeState::Neutral:
+ _lastControlled = TEAM_NEUTRAL;
+ break;
+ case IsleOfConquestNodeState::ConflictA:
+ case IsleOfConquestNodeState::ConflictH:
+ break;
+ }
+
+ _state = state;
+ }
+private:
+ IsleOfConquestNodeState _state;
+ TeamId _lastControlled;
+ IoCStaticNodeInfo _nodeInfo;
+};
+
+const IoCStaticNodeInfo nodePointInitial[MAX_NODE_TYPES] =
+{
+ { NODE_TYPE_REFINERY, { 35377, 35378, 35379, 35380 }, { BG_IC_REFINERY_UNCONTROLLED, BG_IC_REFINERY_CONFLICT_A, BG_IC_REFINERY_CONFLICT_H, BG_IC_REFINERY_CONTROLLED_A, BG_IC_REFINERY_CONTROLLED_H } },
+ { NODE_TYPE_QUARRY, { 35373, 35374, 35375, 35376 }, { BG_IC_QUARRY_UNCONTROLLED, BG_IC_QUARRY_CONFLICT_A, BG_IC_QUARRY_CONFLICT_H, BG_IC_QUARRY_CONTROLLED_A, BG_IC_QUARRY_CONTROLLED_H } },
+ { NODE_TYPE_DOCKS, { 35365, 35366, 35367, 35368 }, { BG_IC_DOCKS_UNCONTROLLED, BG_IC_DOCKS_CONFLICT_A, BG_IC_DOCKS_CONFLICT_H, BG_IC_DOCKS_CONTROLLED_A, BG_IC_DOCKS_CONTROLLED_H } },
+ { NODE_TYPE_HANGAR, { 35369, 35370, 35371, 35372 }, { BG_IC_HANGAR_UNCONTROLLED, BG_IC_HANGAR_CONFLICT_A, BG_IC_HANGAR_CONFLICT_H, BG_IC_HANGAR_CONTROLLED_A, BG_IC_HANGAR_CONTROLLED_H } },
+ { NODE_TYPE_WORKSHOP, { 35278, 35286, 35279, 35280 }, { BG_IC_WORKSHOP_UNCONTROLLED, BG_IC_WORKSHOP_CONFLICT_A, BG_IC_WORKSHOP_CONFLICT_H, BG_IC_WORKSHOP_CONTROLLED_A, BG_IC_WORKSHOP_CONTROLLED_H } },
+ { NODE_TYPE_GRAVEYARD_A, { 35461, 35459, 35463, 35466 }, { BG_IC_ALLIANCE_KEEP_UNCONTROLLED, BG_IC_ALLIANCE_KEEP_CONFLICT_A, BG_IC_ALLIANCE_KEEP_CONFLICT_H, BG_IC_ALLIANCE_KEEP_CONTROLLED_A, BG_IC_ALLIANCE_KEEP_CONTROLLED_H } },
+ { NODE_TYPE_GRAVEYARD_H, { 35462, 35460, 35464, 35465 }, { BG_IC_HORDE_KEEP_UNCONTROLLED, BG_IC_HORDE_KEEP_CONFLICT_A, BG_IC_HORDE_KEEP_CONFLICT_H, BG_IC_HORDE_KEEP_CONTROLLED_A, BG_IC_HORDE_KEEP_CONTROLLED_H } }
+};
+
+enum HonorRewards
+{
+ RESOURCE_HONOR_AMOUNT = 12,
+ WINNER_HONOR_AMOUNT = 500
+};
+
+enum IsleOfConquestPvpStats
+{
+ PVP_STAT_BASES_ASSAULTED = 245,
+ PVP_STAT_BASES_DEFENDED = 246
+};
+
+enum IsleOfConquestGameObjects
+{
+ GO_TELEPORTER_1 = 195314, // 195314 H-OUT 66549
+ GO_TELEPORTER_2 = 195313, // 195313 H-IN 66548
+
+ GO_TELEPORTER_3 = 195315, // 195315 A-OUT 66549
+ GO_TELEPORTER_4 = 195316, // 195316 A-IN 66548
+
+ GO_TELEPORTER_EFFECTS_A = 195701,
+ GO_TELEPORTER_EFFECTS_H = 195702,
+
+ GO_DOODAD_HU_PORTCULLIS01 = 195436,
+ GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01 = 195703,
+ GO_DOODAD_PORTCULLISACTIVE02 = 195452,
+ GO_DOODAD_VR_PORTCULLIS01 = 195437,
+
+ GO_HORDE_GATE_1 = 195494,
+ GO_HORDE_GATE_2 = 195495,
+ GO_HORDE_GATE_3 = 195496,
+
+ GO_ALLIANCE_GATE_1 = 195699,
+ GO_ALLIANCE_GATE_2 = 195700,
+ GO_ALLIANCE_GATE_3 = 195698,
+
+ GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01 = 195491,
+
+ // banners
+ GO_BANNER_WORKSHOP_CONTROLLED_H = 195130,
+ GO_BANNER_WORKSHOP_CONTROLLED_A = 195132,
+ GO_BANNER_WORKSHOP_CONTROLLED_N = 195133,
+ GO_BANNER_WORKSHOP_CONTESTED_A = 195144,
+ GO_BANNER_WORKSHOP_CONTESTED_H = 195145,
+
+ GO_BANNER_DOCKS_CONTROLLED_A = 195149,
+ GO_BANNER_DOCKS_CONTESTED_A = 195150,
+ GO_BANNER_DOCKS_CONTROLLED_H = 195151,
+ GO_BANNER_DOCKS_CONTESTED_H = 195152,
+ GO_BANNER_DOCKS_CONTROLLED_N = 195157,
+
+ GO_BANNER_HANGAR_CONTROLLED_A = 195153,
+ GO_BANNER_HANGAR_CONTESTED_A = 195154,
+ GO_BANNER_HANGAR_CONTROLLED_H = 195155,
+ GO_BANNER_HANGAR_CONTESTED_H = 195156,
+ GO_BANNER_HANGAR_CONTROLLED_N = 195158,
+
+ GO_BANNER_QUARRY_CONTROLLED_A = 195334,
+ GO_BANNER_QUARRY_CONTROLLED_H = 195336,
+ GO_BANNER_QUARRY_CONTESTED_A = 195335,
+ GO_BANNER_QUARRY_CONTESTED_H = 195337,
+ GO_BANNER_QUARRY_CONTROLLED_N = 195338,
+
+ GO_BANNER_REFINERY_CONTROLLED_A = 195339,
+ GO_BANNER_REFINERY_CONTROLLED_H = 195341,
+ GO_BANNER_REFINERY_CONTESTED_A = 195340,
+ GO_BANNER_REFINERY_CONTESTED_H = 195342,
+ GO_BANNER_REFINERY_CONTROLLED_N = 195343,
+
+ GO_BANNER_HORDE_KEEP_CONTROLLED_A = 195391,
+ GO_BANNER_HORDE_KEEP_CONTROLLED_H = 195393,
+ GO_BANNER_HORDE_KEEP_CONTESTED_A = 195392,
+ GO_BANNER_HORDE_KEEP_CONTESTED_H = 195394,
+
+ GO_BANNER_ALLIANCE_KEEP_CONTROLLED_A = 195396,
+ GO_BANNER_ALLIANCE_KEEP_CONTROLLED_H = 195398,
+ GO_BANNER_ALLIANCE_KEEP_CONTESTED_A = 195397,
+ GO_BANNER_ALLIANCE_KEEP_CONTESTED_H = 195399,
+
+ GO_KEEP_GATE_H = 195223,
+ GO_KEEP_GATE_A = 195451,
+ GO_KEEP_GATE_2_A = 195452,
+
+ GO_HORDE_GUNSHIP = 195276,
+ GO_ALLIANCE_GUNSHIP = 195121
+};
+
+static constexpr Seconds IOC_RESOURCE_TIMER = 45s;
+
+static constexpr Position GunshipTeleportTriggerPosition[2] =
+{
+ { 11.69964981079101562f, 0.034145999699831008f, 20.62075996398925781f, 3.211405754089355468f },
+ { 7.30560922622680664f, -0.09524600207805633f, 34.51021575927734375f, 3.159045934677124023f }
+};
+
+struct battleground_isle_of_conquest : BattlegroundScript
+{
+ explicit battleground_isle_of_conquest(BattlegroundMap* map) : BattlegroundScript(map)
+ {
+ _factionReinforcements = { MAX_REINFORCEMENTS, MAX_REINFORCEMENTS };
+
+ _gateStatus = { BG_IC_GATE_OK, BG_IC_GATE_OK, BG_IC_GATE_OK, BG_IC_GATE_OK, BG_IC_GATE_OK, BG_IC_GATE_OK };
+
+ _gunshipGUIDs = { };
+ _cannonGUIDs = { };
+ _nodePoints = { };
+ _keepGateGUIDs = { };
+ _keepBannerGUIDs = { };
+
+ _nodePoints[NODE_TYPE_REFINERY] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::Neutral, nodePointInitial[NODE_TYPE_REFINERY]);
+ _nodePoints[NODE_TYPE_QUARRY] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::Neutral, nodePointInitial[NODE_TYPE_QUARRY]);
+ _nodePoints[NODE_TYPE_DOCKS] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::Neutral, nodePointInitial[NODE_TYPE_DOCKS]);
+ _nodePoints[NODE_TYPE_HANGAR] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::Neutral, nodePointInitial[NODE_TYPE_HANGAR]);
+ _nodePoints[NODE_TYPE_WORKSHOP] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::Neutral, nodePointInitial[NODE_TYPE_WORKSHOP]);
+ _nodePoints[NODE_TYPE_GRAVEYARD_A] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::ControlledA, nodePointInitial[NODE_TYPE_GRAVEYARD_A]);
+ _nodePoints[NODE_TYPE_GRAVEYARD_H] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::ControlledH, nodePointInitial[NODE_TYPE_GRAVEYARD_H]);
+
+ _resourceTimer.Reset(IOC_RESOURCE_TIMER);
+ }
+
+ void OnUpdate(uint32 diff) override
+ {
+ BattlegroundScript::OnUpdate(diff);
+
+ if (battleground->GetStatus() != STATUS_IN_PROGRESS)
+ return;
+
+ _scheduler.Update(diff);
+ _resourceTimer.Update(diff);
+ if (_resourceTimer.Passed())
+ {
+ for (uint8 i = 0; i < NODE_TYPE_DOCKS; ++i)
+ {
+ if (_nodePoints[i]->GetLastControlledTeam() != TEAM_NEUTRAL && !_nodePoints[i]->IsContested())
+ {
+ _factionReinforcements[_nodePoints[i]->GetLastControlledTeam()] += 1;
+ battleground->RewardHonorToTeam(RESOURCE_HONOR_AMOUNT, _nodePoints[i]->GetLastControlledTeam() == TEAM_ALLIANCE ? ALLIANCE : HORDE);
+ UpdateWorldState((_nodePoints[i]->GetLastControlledTeam() == TEAM_ALLIANCE ? BG_IC_ALLIANCE_REINFORCEMENTS : BG_IC_HORDE_REINFORCEMENTS), _factionReinforcements[_nodePoints[i]->GetLastControlledTeam()]);
+ }
+ }
+
+ _resourceTimer.Reset(IOC_RESOURCE_TIMER);
+ }
+ }
+
+ void OnStart() override
+ {
+ BattlegroundScript::OnStart();
+
+ auto gameobjectAction = [&](GuidVector const& guids, std::function<void(GameObject*)> const& action) -> void
+ {
+ for (ObjectGuid const& guid : guids)
+ if (GameObject* gameObject = battlegroundMap->GetGameObject(guid))
+ action(gameObject);
+ };
+
+ gameobjectAction(_mainGateDoorGUIDs, [&](GameObject* gameobject) -> void
+ {
+ gameobject->UseDoorOrButton();
+ gameobject->DespawnOrUnsummon(20s);
+ });
+
+ gameobjectAction(_portcullisGUIDs, [&](GameObject* gameobject) -> void
+ {
+ gameobject->UseDoorOrButton();
+ });
+
+ gameobjectAction(_teleporterGUIDs, [&](GameObject* gameobject) -> void
+ {
+ gameobject->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
+ });
+
+ gameobjectAction(_teleporterEffectGUIDs, [&](GameObject* gameobject) -> void
+ {
+ gameobject->SetGoState(GO_STATE_ACTIVE);
+ });
+
+ _scheduler.Schedule(20s, [&](TaskContext)
+ {
+ for (ObjectGuid const& guid : _wallGUIDs)
+ if (GameObject* gameobject = battlegroundMap->GetGameObject(guid))
+ gameobject->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED);
+ });
+ }
+
+ void OnUnitKilled(Creature* unit, Unit* killer) override
+ {
+ BattlegroundScript::OnUnitKilled(unit, killer);
+
+ if (battleground->GetStatus() != STATUS_IN_PROGRESS)
+ return;
+
+ uint32 entry = unit->GetEntry();
+ if (entry == NPC_HIGH_COMMANDER_HALFORD_WYRMBANE)
+ {
+ battleground->RewardHonorToTeam(WINNER_HONOR_AMOUNT, HORDE);
+ battleground->EndBattleground(HORDE);
+ }
+ else if (entry == NPC_OVERLORD_AGMAR)
+ {
+ battleground->RewardHonorToTeam(WINNER_HONOR_AMOUNT, ALLIANCE);
+ battleground->EndBattleground(ALLIANCE);
+ }
+
+ //Achievement Mowed Down
+ // TO-DO: This should be done on the script of each vehicle of the BG.
+ if (unit->IsVehicle())
+ {
+ if (Player* killerPlayer = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
+ killerPlayer->CastSpell(killerPlayer, SPELL_DESTROYED_VEHICLE_ACHIEVEMENT, true);
+ }
+ }
+
+ void OnPlayerKilled(Player* player, Player* killer) override
+ {
+ BattlegroundScript::OnPlayerKilled(player, killer);
+
+ if (battleground->GetStatus() != STATUS_IN_PROGRESS)
+ return;
+
+ TeamId const victimTeamId = Battleground::GetTeamIndexByTeamId(battleground->GetPlayerTeam(player->GetGUID()));
+ _factionReinforcements[victimTeamId] -= 1;
+
+ UpdateWorldState((battleground->GetPlayerTeam(player->GetGUID()) == ALLIANCE ? BG_IC_ALLIANCE_REINFORCEMENTS : BG_IC_HORDE_REINFORCEMENTS), _factionReinforcements[victimTeamId]);
+
+ // we must end the battleground
+ if (_factionReinforcements[victimTeamId] < 1)
+ battleground->EndBattleground(battleground->GetPlayerTeam(killer->GetGUID()));
+ }
+
+ static uint32 GetGateIDFromEntry(uint32 id)
+ {
+ switch (id)
+ {
+ case GO_HORDE_GATE_1:
+ return BG_IC_H_FRONT;
+ case GO_HORDE_GATE_2:
+ return BG_IC_H_WEST;
+ case GO_HORDE_GATE_3:
+ return BG_IC_H_EAST;
+ case GO_ALLIANCE_GATE_3:
+ return BG_IC_A_FRONT;
+ case GO_ALLIANCE_GATE_1:
+ return BG_IC_A_WEST;
+ case GO_ALLIANCE_GATE_2:
+ return BG_IC_A_EAST;
+ default:
+ return 0;
+ }
+ }
+
+ static int32 GetWorldStateFromGateEntry(uint32 id, bool open)
+ {
+ int32 uws = 0;
+
+ switch (id)
+ {
+ case GO_HORDE_GATE_1:
+ uws = (open ? BG_IC_GATE_FRONT_H_WS_OPEN : BG_IC_GATE_FRONT_H_WS_CLOSED);
+ break;
+ case GO_HORDE_GATE_2:
+ uws = (open ? BG_IC_GATE_WEST_H_WS_OPEN : BG_IC_GATE_WEST_H_WS_CLOSED);
+ break;
+ case GO_HORDE_GATE_3:
+ uws = (open ? BG_IC_GATE_EAST_H_WS_OPEN : BG_IC_GATE_EAST_H_WS_CLOSED);
+ break;
+ case GO_ALLIANCE_GATE_3:
+ uws = (open ? BG_IC_GATE_FRONT_A_WS_OPEN : BG_IC_GATE_FRONT_A_WS_CLOSED);
+ break;
+ case GO_ALLIANCE_GATE_1:
+ uws = (open ? BG_IC_GATE_WEST_A_WS_OPEN : BG_IC_GATE_WEST_A_WS_CLOSED);
+ break;
+ case GO_ALLIANCE_GATE_2:
+ uws = (open ? BG_IC_GATE_EAST_A_WS_OPEN : BG_IC_GATE_EAST_A_WS_CLOSED);
+ break;
+ default:
+ break;
+ }
+ return uws;
+ }
+
+ void UpdateNodeWorldState(ICNodePoint const& node) const
+ {
+ UpdateWorldState(node.GetNodeInfo().WorldStateIds.ConflictA, node.GetState() == IsleOfConquestNodeState::ConflictA);
+ UpdateWorldState(node.GetNodeInfo().WorldStateIds.ConflictH, node.GetState() == IsleOfConquestNodeState::ConflictH);
+ UpdateWorldState(node.GetNodeInfo().WorldStateIds.ControlledA, node.GetState() == IsleOfConquestNodeState::ControlledA);
+ UpdateWorldState(node.GetNodeInfo().WorldStateIds.ControlledH, node.GetState() == IsleOfConquestNodeState::ControlledH);
+ UpdateWorldState(node.GetNodeInfo().WorldStateIds.Uncontrolled, node.GetState() == IsleOfConquestNodeState::Neutral);
+ }
+
+ static ICNodePointType BannerToNodeType(uint32 bannerId)
+ {
+ switch (bannerId)
+ {
+ case GO_BANNER_ALLIANCE_KEEP_CONTESTED_A:
+ case GO_BANNER_ALLIANCE_KEEP_CONTESTED_H:
+ case GO_BANNER_ALLIANCE_KEEP_CONTROLLED_A:
+ case GO_BANNER_ALLIANCE_KEEP_CONTROLLED_H:
+ return NODE_TYPE_GRAVEYARD_A;
+ case GO_BANNER_HORDE_KEEP_CONTESTED_A:
+ case GO_BANNER_HORDE_KEEP_CONTESTED_H:
+ case GO_BANNER_HORDE_KEEP_CONTROLLED_A:
+ case GO_BANNER_HORDE_KEEP_CONTROLLED_H:
+ return NODE_TYPE_GRAVEYARD_H;
+ case GO_BANNER_DOCKS_CONTESTED_A:
+ case GO_BANNER_DOCKS_CONTESTED_H:
+ case GO_BANNER_DOCKS_CONTROLLED_A:
+ case GO_BANNER_DOCKS_CONTROLLED_H:
+ case GO_BANNER_DOCKS_CONTROLLED_N:
+ return NODE_TYPE_DOCKS;
+ case GO_BANNER_HANGAR_CONTESTED_A:
+ case GO_BANNER_HANGAR_CONTESTED_H:
+ case GO_BANNER_HANGAR_CONTROLLED_A:
+ case GO_BANNER_HANGAR_CONTROLLED_H:
+ case GO_BANNER_HANGAR_CONTROLLED_N:
+ return NODE_TYPE_HANGAR;
+ case GO_BANNER_WORKSHOP_CONTESTED_A:
+ case GO_BANNER_WORKSHOP_CONTESTED_H:
+ case GO_BANNER_WORKSHOP_CONTROLLED_A:
+ case GO_BANNER_WORKSHOP_CONTROLLED_H:
+ case GO_BANNER_WORKSHOP_CONTROLLED_N:
+ return NODE_TYPE_WORKSHOP;
+ case GO_BANNER_QUARRY_CONTESTED_A:
+ case GO_BANNER_QUARRY_CONTESTED_H:
+ case GO_BANNER_QUARRY_CONTROLLED_A:
+ case GO_BANNER_QUARRY_CONTROLLED_H:
+ case GO_BANNER_QUARRY_CONTROLLED_N:
+ return NODE_TYPE_QUARRY;
+ case GO_BANNER_REFINERY_CONTESTED_A:
+ case GO_BANNER_REFINERY_CONTESTED_H:
+ case GO_BANNER_REFINERY_CONTROLLED_A:
+ case GO_BANNER_REFINERY_CONTROLLED_H:
+ case GO_BANNER_REFINERY_CONTROLLED_N:
+ return NODE_TYPE_REFINERY;
+ default:
+ break;
+ }
+
+ return MAX_NODE_TYPES;
+ }
+
+ void HandleCapturedNodes(ICNodePoint& node)
+ {
+ if (node.GetLastControlledTeam() == TEAM_NEUTRAL)
+ return;
+
+ switch (node.GetNodeInfo().NodeType)
+ {
+ case NODE_TYPE_QUARRY:
+ case NODE_TYPE_REFINERY:
+ battlegroundMap->UpdateAreaDependentAuras();
+ break;
+ case NODE_TYPE_HANGAR:
+ if (Transport* transport = battlegroundMap->GetTransport(_gunshipGUIDs[node.GetLastControlledTeam()]))
+ {
+ // Can't have this in spawngroup, creature is on a transport
+ if (TempSummon* trigger = transport->SummonPassenger(NPC_WORLD_TRIGGER_NOT_FLOATING, GunshipTeleportTriggerPosition[node.GetLastControlledTeam()], TEMPSUMMON_MANUAL_DESPAWN))
+ _gunshipTeleportTarget = trigger->GetGUID();
+
+ transport->EnableMovement(true);
+ }
+
+ for (ObjectGuid const& guid : _cannonGUIDs[node.GetLastControlledTeam()])
+ if (Creature* cannon = battlegroundMap->GetCreature(guid))
+ cannon->SetUninteractible(false);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnCreatureCreate(Creature* creature) override
+ {
+ BattlegroundScript::OnCreatureCreate(creature);
+
+ if (creature->HasStringId("bg_ioc_faction_1735"))
+ creature->SetFaction(FACTION_HORDE_GENERIC_WG);
+ else if (creature->HasStringId("bg_ioc_faction_1732"))
+ creature->SetFaction(FACTION_ALLIANCE_GENERIC_WG);
+
+ switch (creature->GetEntry())
+ {
+ case NPC_ALLIANCE_GUNSHIP_CANNON:
+ _cannonGUIDs[TEAM_ALLIANCE].emplace_back(creature->GetGUID());
+ creature->SetUninteractible(true);
+ creature->SetControlled(true, UNIT_STATE_ROOT);
+ break;
+ case NPC_HORDE_GUNSHIP_CANNON:
+ _cannonGUIDs[TEAM_HORDE].emplace_back(creature->GetGUID());
+ creature->SetUninteractible(true);
+ creature->SetControlled(true, UNIT_STATE_ROOT);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnGameObjectCreate(GameObject* gameobject) override
+ {
+ BattlegroundScript::OnGameObjectCreate(gameobject);
+
+ if (gameobject->IsDestructibleBuilding())
+ _wallGUIDs.emplace_back(gameobject->GetGUID());
+
+ if (gameobject->HasStringId("bg_ioc_faction_1735"))
+ gameobject->SetFaction(FACTION_HORDE_GENERIC_WG);
+ else if (gameobject->HasStringId("bg_ioc_faction_1732"))
+ gameobject->SetFaction(FACTION_ALLIANCE_GENERIC_WG);
+
+ switch (gameobject->GetEntry())
+ {
+ case GO_TELEPORTER_1:
+ case GO_TELEPORTER_2:
+ case GO_TELEPORTER_3:
+ case GO_TELEPORTER_4:
+ _teleporterGUIDs.emplace_back(gameobject->GetGUID());
+ break;
+ case GO_TELEPORTER_EFFECTS_A:
+ case GO_TELEPORTER_EFFECTS_H:
+ _teleporterEffectGUIDs.emplace_back(gameobject->GetGUID());
+ break;
+ case GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01:
+ case GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01:
+ _mainGateDoorGUIDs.emplace_back(gameobject->GetGUID());
+ break;
+ case GO_DOODAD_HU_PORTCULLIS01:
+ case GO_DOODAD_VR_PORTCULLIS01:
+ _portcullisGUIDs.emplace_back(gameobject->GetGUID());
+ break;
+ case GO_KEEP_GATE_H:
+ _keepGateGUIDs[TEAM_HORDE].emplace_back(gameobject->GetGUID());
+ break;
+ case GO_KEEP_GATE_A:
+ case GO_KEEP_GATE_2_A:
+ _keepGateGUIDs[TEAM_ALLIANCE].emplace_back(gameobject->GetGUID());
+ break;
+ case GO_BANNER_ALLIANCE_KEEP_CONTROLLED_A:
+ _keepBannerGUIDs[TEAM_ALLIANCE] = gameobject->GetGUID();
+ break;
+ case GO_BANNER_HORDE_KEEP_CONTROLLED_H:
+ _keepBannerGUIDs[TEAM_HORDE] = gameobject->GetGUID();
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnInit() override
+ {
+ BattlegroundScript::OnInit();
+
+ if (Transport* transport = sTransportMgr->CreateTransport(GO_HORDE_GUNSHIP, battlegroundMap))
+ {
+ _gunshipGUIDs[TEAM_HORDE] = transport->GetGUID();
+ transport->EnableMovement(false);
+ }
+
+ if (Transport* transport = sTransportMgr->CreateTransport(GO_ALLIANCE_GUNSHIP, battlegroundMap))
+ {
+ _gunshipGUIDs[TEAM_ALLIANCE] = transport->GetGUID();
+ transport->EnableMovement(false);
+ }
+ }
+
+ void DoAction(uint32 actionId, WorldObject* source, WorldObject* target) override
+ {
+ BattlegroundScript::DoAction(actionId, source, target);
+
+ switch (actionId)
+ {
+ case ACTION_IOC_INTERACT_CAPTURABLE_OBJECT:
+ OnPlayerInteractWithBanner(WorldObject::ToPlayer(source), WorldObject::ToGameObject(target));
+ break;
+ case ACTION_IOC_CAPTURE_CAPTURABLE_OBJECT:
+ HandleCaptureNodeAction(WorldObject::ToGameObject(target));
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnPlayerInteractWithBanner(Player* player, GameObject* banner)
+ {
+ if (!player || !banner)
+ return;
+
+ Team const playerTeam = battleground->GetPlayerTeam(player->GetGUID());
+ TeamId const playerTeamId = Battleground::GetTeamIndexByTeamId(playerTeam);
+ ICNodePointType const nodeType = BannerToNodeType(banner->GetEntry());
+ if (nodeType == MAX_NODE_TYPES)
+ return;
+
+ ICNodePoint& node = *_nodePoints[nodeType];
+
+ bool assault = false;
+ bool defend = false;
+
+ switch (node.GetState())
+ {
+ case IsleOfConquestNodeState::Neutral:
+ assault = true;
+ break;
+ case IsleOfConquestNodeState::ControlledH:
+ assault = playerTeamId != TEAM_HORDE;
+ break;
+ case IsleOfConquestNodeState::ControlledA:
+ assault = playerTeamId != TEAM_ALLIANCE;
+ break;
+ case IsleOfConquestNodeState::ConflictA:
+ defend = playerTeamId == node.GetLastControlledTeam();
+ assault = !defend && playerTeamId == TEAM_HORDE;
+ break;
+ case IsleOfConquestNodeState::ConflictH:
+ defend = playerTeamId == node.GetLastControlledTeam();
+ assault = !defend && playerTeamId == TEAM_ALLIANCE;
+ break;
+ }
+
+ if (assault)
+ OnPlayerAssaultNode(player, node);
+ else if (defend)
+ OnPlayerDefendNode(player, node);
+
+ battlegroundMap->UpdateSpawnGroupConditions();
+ }
+
+ void OnPlayerAssaultNode(Player* player, ICNodePoint& node)
+ {
+ if (!player)
+ return;
+
+ Team const playerTeam = battleground->GetPlayerTeam(player->GetGUID());
+ TeamId const playerTeamId = Battleground::GetTeamIndexByTeamId(playerTeam);
+
+ IsleOfConquestNodeState const newState = playerTeamId == TEAM_HORDE ? IsleOfConquestNodeState::ConflictH : IsleOfConquestNodeState::ConflictA;
+ node.UpdateState(newState);
+
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
+
+ ChatMsg const messageType = playerTeamId == TEAM_ALLIANCE ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE;
+ battleground->SendBroadcastText(node.GetNodeInfo().TextIds.Assaulted, messageType, player);
+ UpdateNodeWorldState(node);
+
+ // apply side effects of each node, only if it wasn't neutral before
+ if (node.GetLastControlledTeam() == TEAM_NEUTRAL)
+ return;
+
+ switch (node.GetNodeInfo().NodeType)
+ {
+ case NODE_TYPE_HANGAR:
+ if (Transport* transport = battlegroundMap->GetTransport(_gunshipGUIDs[node.GetLastControlledTeam()]))
+ transport->EnableMovement(false);
+
+ for (ObjectGuid const& guid : _cannonGUIDs[node.GetLastControlledTeam()])
+ {
+ if (Creature* cannon = battlegroundMap->GetCreature(guid))
+ {
+ cannon->GetVehicleKit()->RemoveAllPassengers();
+ cannon->SetUninteractible(true);
+ }
+ }
+
+ // Despawn teleport trigger target
+ if (Creature* creature = battlegroundMap->GetCreature(_gunshipTeleportTarget))
+ creature->DespawnOrUnsummon();
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnPlayerDefendNode(Player* player, ICNodePoint& node)
+ {
+ if (!player)
+ return;
+
+ Team const playerTeam = battleground->GetPlayerTeam(player->GetGUID());
+ TeamId const playerTeamId = Battleground::GetTeamIndexByTeamId(playerTeam);
+
+ node.UpdateState(playerTeamId == TEAM_HORDE ? IsleOfConquestNodeState::ControlledH : IsleOfConquestNodeState::ControlledA);
+ HandleCapturedNodes(node);
+ battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
+
+ ChatMsg const messageType = playerTeamId == TEAM_ALLIANCE ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE;
+ battleground->SendBroadcastText(node.GetNodeInfo().TextIds.Defended, messageType, player);
+ UpdateNodeWorldState(node);
+ }
+
+ void ProcessEvent(WorldObject* target, uint32 eventId, WorldObject* invoker) override
+ {
+ BattlegroundScript::ProcessEvent(target, eventId, invoker);
+
+ if (GameObject* obj = Object::ToGameObject(target))
+ if (obj->GetGoType() == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
+ if (obj->GetGOInfo()->destructibleBuilding.DestroyedEvent == eventId)
+ OnGateDestroyed(obj, invoker);
+ }
+
+ void HandleCaptureNodeAction(GameObject* banner)
+ {
+ if (!banner)
+ return;
+
+ ICNodePointType const nodeType = BannerToNodeType(banner->GetEntry());
+ if (nodeType == MAX_NODE_TYPES)
+ return;
+
+ ICNodePoint& node = *_nodePoints[nodeType];
+ if (node.GetState() == IsleOfConquestNodeState::ConflictH)
+ node.UpdateState(IsleOfConquestNodeState::ControlledH);
+ else if (node.GetState() == IsleOfConquestNodeState::ConflictA)
+ node.UpdateState(IsleOfConquestNodeState::ControlledA);
+
+ HandleCapturedNodes(node);
+
+ ChatMsg const messageType = node.GetLastControlledTeam() == TEAM_ALLIANCE ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE;
+ uint32 const textId = node.GetLastControlledTeam() == TEAM_ALLIANCE ? node.GetNodeInfo().TextIds.AllianceTaken : node.GetNodeInfo().TextIds.HordeTaken;
+ battleground->SendBroadcastText(textId, messageType);
+ UpdateNodeWorldState(node);
+ }
+
+ void OnGateDestroyed(GameObject* gate, WorldObject* destroyer)
+ {
+ _gateStatus[GetGateIDFromEntry(gate->GetEntry())] = BG_IC_GATE_DESTROYED;
+ int32 const wsGateOpen = GetWorldStateFromGateEntry(gate->GetEntry(), true);
+ int32 const wsGateClosed = GetWorldStateFromGateEntry(gate->GetEntry(), false);
+ if (wsGateOpen)
+ {
+ UpdateWorldState(wsGateClosed, 0);
+ UpdateWorldState(wsGateOpen, 1);
+ }
+
+ TeamId teamId = TEAM_NEUTRAL;
+ uint32 textId;
+ ChatMsg msgType;
+ switch (gate->GetEntry())
+ {
+ case GO_HORDE_GATE_1:
+ textId = BG_IC_TEXT_FRONT_GATE_HORDE_DESTROYED;
+ msgType = CHAT_MSG_BG_SYSTEM_ALLIANCE;
+ teamId = TEAM_HORDE;
+ break;
+ case GO_HORDE_GATE_2:
+ textId = BG_IC_TEXT_WEST_GATE_HORDE_DESTROYED;
+ msgType = CHAT_MSG_BG_SYSTEM_ALLIANCE;
+ teamId = TEAM_HORDE;
+ break;
+ case GO_HORDE_GATE_3:
+ textId = BG_IC_TEXT_EAST_GATE_HORDE_DESTROYED;
+ msgType = CHAT_MSG_BG_SYSTEM_ALLIANCE;
+ teamId = TEAM_HORDE;
+ break;
+ case GO_ALLIANCE_GATE_1:
+ textId = BG_IC_TEXT_WEST_GATE_ALLIANCE_DESTROYED;
+ msgType = CHAT_MSG_BG_SYSTEM_HORDE;
+ teamId = TEAM_ALLIANCE;
+ break;
+ case GO_ALLIANCE_GATE_2:
+ textId = BG_IC_TEXT_EAST_GATE_ALLIANCE_DESTROYED;
+ msgType = CHAT_MSG_BG_SYSTEM_HORDE;
+ teamId = TEAM_ALLIANCE;
+ break;
+ case GO_ALLIANCE_GATE_3:
+ textId = BG_IC_TEXT_FRONT_GATE_ALLIANCE_DESTROYED;
+ msgType = CHAT_MSG_BG_SYSTEM_HORDE;
+ teamId = TEAM_ALLIANCE;
+ break;
+ default:
+ return;
+ }
+
+ if (teamId != TEAM_NEUTRAL)
+ {
+ GuidVector const keepGates = _keepGateGUIDs[teamId];
+ ObjectGuid const bannerGuid = _keepBannerGUIDs[teamId];
+
+ for (ObjectGuid const& guid : keepGates)
+ if (GameObject* keepGate = battlegroundMap->GetGameObject(guid))
+ keepGate->UseDoorOrButton();
+
+ if (GameObject* banner = battlegroundMap->GetGameObject(bannerGuid))
+ banner->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
+ }
+
+ battleground->SendBroadcastText(textId, msgType, destroyer);
+ }
+
+private:
+ std::array<uint16, PVP_TEAMS_COUNT> _factionReinforcements;
+ std::array<BG_IC_GateState, 6> _gateStatus;
+ std::array<std::unique_ptr<ICNodePoint>, 7> _nodePoints;
+ std::array<ObjectGuid, PVP_TEAMS_COUNT> _gunshipGUIDs;
+ GuidVector _teleporterGUIDs;
+ GuidVector _teleporterEffectGUIDs;
+ GuidVector _mainGateDoorGUIDs;
+ GuidVector _portcullisGUIDs;
+ GuidVector _wallGUIDs;
+ std::array<GuidVector, PVP_TEAMS_COUNT> _cannonGUIDs;
+ std::array<GuidVector, PVP_TEAMS_COUNT> _keepGateGUIDs;
+ std::array<ObjectGuid, PVP_TEAMS_COUNT> _keepBannerGUIDs;
+ ObjectGuid _gunshipTeleportTarget;
+
+ TaskScheduler _scheduler;
+ TimeTracker _resourceTimer;
+};
+
+void AddSC_battleground_isle_of_conquest()
+{
+ RegisterBattlegroundMapScript(battleground_isle_of_conquest, 628);
+}
diff --git a/src/server/scripts/Northrend/IsleOfConquest/boss_ioc_horde_alliance.cpp b/src/server/scripts/Battlegrounds/IsleOfConquest/boss_ioc_horde_alliance.cpp
index 77f5e53207e..05a13de842b 100644
--- a/src/server/scripts/Northrend/IsleOfConquest/boss_ioc_horde_alliance.cpp
+++ b/src/server/scripts/Battlegrounds/IsleOfConquest/boss_ioc_horde_alliance.cpp
@@ -16,7 +16,7 @@
*/
#include "ScriptMgr.h"
-#include "BattlegroundIC.h"
+#include "isle_of_conquest.h"
#include "ScriptedCreature.h"
enum BossSpells
diff --git a/src/server/scripts/Northrend/IsleOfConquest/isle_of_conquest.cpp b/src/server/scripts/Battlegrounds/IsleOfConquest/isle_of_conquest.cpp
index 1492335ce15..2c9fdce6596 100644
--- a/src/server/scripts/Northrend/IsleOfConquest/isle_of_conquest.cpp
+++ b/src/server/scripts/Battlegrounds/IsleOfConquest/isle_of_conquest.cpp
@@ -15,8 +15,9 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "isle_of_conquest.h"
#include "ScriptMgr.h"
-#include "BattlegroundIC.h"
+#include "Battleground.h"
#include "GameObject.h"
#include "GameObjectAI.h"
#include "Map.h"
diff --git a/src/server/scripts/Battlegrounds/IsleOfConquest/isle_of_conquest.h b/src/server/scripts/Battlegrounds/IsleOfConquest/isle_of_conquest.h
new file mode 100644
index 00000000000..ab4c92abae6
--- /dev/null
+++ b/src/server/scripts/Battlegrounds/IsleOfConquest/isle_of_conquest.h
@@ -0,0 +1,132 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TRINITYCORE_ISLE_OF_CONQUEST_H
+#define TRINITYCORE_ISLE_OF_CONQUEST_H
+
+enum CreaturesIC
+{
+ NPC_HIGH_COMMANDER_HALFORD_WYRMBANE = 34924, // Alliance Boss
+ NPC_OVERLORD_AGMAR = 34922, // Horde Boss
+ NPC_KOR_KRON_GUARD = 34918, // horde guard
+ NPC_SEVEN_TH_LEGION_INFANTRY = 34919, // alliance guard
+ NPC_KEEP_CANNON = 34944,
+ NPC_DEMOLISHER = 34775,
+ NPC_SIEGE_ENGINE_H = 35069,
+ NPC_SIEGE_ENGINE_A = 34776,
+ NPC_GLAIVE_THROWER_A = 34802,
+ NPC_GLAIVE_THROWER_H = 35273,
+ NPC_CATAPULT = 34793,
+ NPC_HORDE_GUNSHIP_CANNON = 34935,
+ NPC_ALLIANCE_GUNSHIP_CANNON = 34929,
+ NPC_HORDE_GUNSHIP_CAPTAIN = 35003,
+ NPC_ALLIANCE_GUNSHIP_CAPTAIN = 34960,
+ NPC_WORLD_TRIGGER_NOT_FLOATING = 34984,
+ NPC_WORLD_TRIGGER_ALLIANCE_FRIENDLY = 20213,
+ NPC_WORLD_TRIGGER_HORDE_FRIENDLY = 20212
+};
+
+enum Actions
+{
+ ACTION_GUNSHIP_READY = 1,
+ ACTION_IOC_INTERACT_CAPTURABLE_OBJECT = 2,
+ ACTION_IOC_CAPTURE_CAPTURABLE_OBJECT = 3
+};
+
+enum Spells
+{
+ SPELL_OIL_REFINERY = 68719,
+ SPELL_QUARRY = 68720,
+ SPELL_PARACHUTE = 66656,
+ SPELL_SLOW_FALL = 12438,
+ SPELL_DESTROYED_VEHICLE_ACHIEVEMENT = 68357,
+ SPELL_BACK_DOOR_JOB_ACHIEVEMENT = 68502,
+ SPELL_DRIVING_CREDIT_DEMOLISHER = 68365,
+ SPELL_DRIVING_CREDIT_GLAIVE = 68363,
+ SPELL_DRIVING_CREDIT_SIEGE = 68364,
+ SPELL_DRIVING_CREDIT_CATAPULT = 68362,
+ SPELL_SIMPLE_TELEPORT = 12980,
+ SPELL_TELEPORT_VISUAL_ONLY = 51347,
+ SPELL_PARACHUTE_IC = 66657,
+ SPELL_LAUNCH_NO_FALLING_DAMAGE = 66251
+};
+
+enum ICWorldStates
+{
+ BG_IC_ALLIANCE_REINFORCEMENTS_SET = 4221,
+ BG_IC_HORDE_REINFORCEMENTS_SET = 4222,
+ BG_IC_ALLIANCE_REINFORCEMENTS = 4226,
+ BG_IC_HORDE_REINFORCEMENTS = 4227,
+ BG_IC_MAX_REINFORCEMENTS = 17377,
+
+ BG_IC_GATE_FRONT_H_WS_CLOSED = 4317,
+ BG_IC_GATE_WEST_H_WS_CLOSED = 4318,
+ BG_IC_GATE_EAST_H_WS_CLOSED = 4319,
+ BG_IC_GATE_FRONT_A_WS_CLOSED = 4328,
+ BG_IC_GATE_WEST_A_WS_CLOSED = 4327,
+ BG_IC_GATE_EAST_A_WS_CLOSED = 4326,
+ BG_IC_GATE_FRONT_H_WS_OPEN = 4322,
+ BG_IC_GATE_WEST_H_WS_OPEN = 4321,
+ BG_IC_GATE_EAST_H_WS_OPEN = 4320,
+ BG_IC_GATE_FRONT_A_WS_OPEN = 4323,
+ BG_IC_GATE_WEST_A_WS_OPEN = 4324,
+ BG_IC_GATE_EAST_A_WS_OPEN = 4325,
+
+ BG_IC_DOCKS_UNCONTROLLED = 4301,
+ BG_IC_DOCKS_CONFLICT_A = 4305,
+ BG_IC_DOCKS_CONFLICT_H = 4302,
+ BG_IC_DOCKS_CONTROLLED_A = 4304,
+ BG_IC_DOCKS_CONTROLLED_H = 4303,
+
+ BG_IC_HANGAR_UNCONTROLLED = 4296,
+ BG_IC_HANGAR_CONFLICT_A = 4300,
+ BG_IC_HANGAR_CONFLICT_H = 4297,
+ BG_IC_HANGAR_CONTROLLED_A = 4299,
+ BG_IC_HANGAR_CONTROLLED_H = 4298,
+
+ BG_IC_QUARRY_UNCONTROLLED = 4306,
+ BG_IC_QUARRY_CONFLICT_A = 4310,
+ BG_IC_QUARRY_CONFLICT_H = 4307,
+ BG_IC_QUARRY_CONTROLLED_A = 4309,
+ BG_IC_QUARRY_CONTROLLED_H = 4308,
+
+ BG_IC_REFINERY_UNCONTROLLED = 4311,
+ BG_IC_REFINERY_CONFLICT_A = 4315,
+ BG_IC_REFINERY_CONFLICT_H = 4312,
+ BG_IC_REFINERY_CONTROLLED_A = 4314,
+ BG_IC_REFINERY_CONTROLLED_H = 4313,
+
+ BG_IC_WORKSHOP_UNCONTROLLED = 4294,
+ BG_IC_WORKSHOP_CONFLICT_A = 4228,
+ BG_IC_WORKSHOP_CONFLICT_H = 4293,
+ BG_IC_WORKSHOP_CONTROLLED_A = 4229,
+ BG_IC_WORKSHOP_CONTROLLED_H = 4230,
+
+ BG_IC_ALLIANCE_KEEP_UNCONTROLLED = 4341,
+ BG_IC_ALLIANCE_KEEP_CONFLICT_A = 4342,
+ BG_IC_ALLIANCE_KEEP_CONFLICT_H = 4343,
+ BG_IC_ALLIANCE_KEEP_CONTROLLED_A = 4339,
+ BG_IC_ALLIANCE_KEEP_CONTROLLED_H = 4340,
+
+ BG_IC_HORDE_KEEP_UNCONTROLLED = 4346,
+ BG_IC_HORDE_KEEP_CONFLICT_A = 4347,
+ BG_IC_HORDE_KEEP_CONFLICT_H = 4348,
+ BG_IC_HORDE_KEEP_CONTROLLED_A = 4344,
+ BG_IC_HORDE_KEEP_CONTROLLED_H = 4345
+};
+
+#endif
diff --git a/src/server/scripts/Battlegrounds/NagrandArena/arena_nagrand_arena.cpp b/src/server/scripts/Battlegrounds/NagrandArena/arena_nagrand_arena.cpp
new file mode 100644
index 00000000000..e3f83c6acb2
--- /dev/null
+++ b/src/server/scripts/Battlegrounds/NagrandArena/arena_nagrand_arena.cpp
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Battleground.h"
+#include "BattlegroundScript.h"
+#include "GameObject.h"
+#include "Map.h"
+#include "ScriptMgr.h"
+#include "TaskScheduler.h"
+
+struct arena_nagrand : ArenaScript
+{
+ enum GameObjects
+ {
+ BG_NA_OBJECT_TYPE_DOOR_1 = 183978,
+ BG_NA_OBJECT_TYPE_DOOR_2 = 183980,
+ BG_NA_OBJECT_TYPE_DOOR_3 = 183977,
+ BG_NA_OBJECT_TYPE_DOOR_4 = 183979,
+ BG_NA_OBJECT_TYPE_BUFF_1 = 184663,
+ BG_NA_OBJECT_TYPE_BUFF_2 = 184664
+ };
+
+ explicit arena_nagrand(BattlegroundMap* map) : ArenaScript(map) { }
+
+ void OnUpdate(uint32 diff) override
+ {
+ _scheduler.Update(diff);
+ }
+
+ void OnInit() override
+ {
+ AddDoor(BG_NA_OBJECT_TYPE_DOOR_1, 4031.854f, 2966.833f, 12.6462f, -2.648788f, 0, 0, 0.9697962f, -0.2439165f);
+ AddDoor(BG_NA_OBJECT_TYPE_DOOR_2, 4081.179f, 2874.97f, 12.39171f, 0.4928045f, 0, 0, 0.2439165f, 0.9697962f);
+ AddDoor(BG_NA_OBJECT_TYPE_DOOR_3, 4023.709f, 2981.777f, 10.70117f, -2.648788f, 0, 0, 0.9697962f, -0.2439165f);
+ AddDoor(BG_NA_OBJECT_TYPE_DOOR_4, 4090.064f, 2858.438f, 10.23631f, 0.4928045f, 0, 0, 0.2439165f, 0.9697962f);
+ }
+
+ void OnStart() override
+ {
+ for (ObjectGuid const& guid : _doorGUIDs)
+ {
+ if (GameObject* door = battlegroundMap->GetGameObject(guid))
+ {
+ door->UseDoorOrButton();
+ door->DespawnOrUnsummon(5s);
+ }
+ }
+
+ _scheduler.Schedule(1min, [&](TaskContext)
+ {
+ CreateObject(BG_NA_OBJECT_TYPE_BUFF_1, 4009.189941f, 2895.250000f, 13.052700f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f);
+ CreateObject(BG_NA_OBJECT_TYPE_BUFF_2, 4103.330078f, 2946.350098f, 13.051300f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f);
+ });
+ }
+
+ void AddDoor(uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, GOState goState = GO_STATE_READY)
+ {
+ if (GameObject const* go = CreateObject(entry, x, y, z, o, rotation0, rotation1, rotation2, rotation3, goState))
+ _doorGUIDs.emplace_back(go->GetGUID());
+ }
+
+private:
+ GuidVector _doorGUIDs;
+ TaskScheduler _scheduler;
+};
+
+void AddSC_arena_nagrand()
+{
+ RegisterBattlegroundMapScript(arena_nagrand, 1505);
+}
diff --git a/src/server/scripts/Battlegrounds/RingOfValor/arena_ring_of_valor.cpp b/src/server/scripts/Battlegrounds/RingOfValor/arena_ring_of_valor.cpp
new file mode 100644
index 00000000000..3c2dbdc473a
--- /dev/null
+++ b/src/server/scripts/Battlegrounds/RingOfValor/arena_ring_of_valor.cpp
@@ -0,0 +1,302 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Battleground.h"
+#include "BattlegroundScript.h"
+#include "GameObject.h"
+#include "Map.h"
+#include "ObjectAccessor.h"
+#include "ScriptMgr.h"
+#include "TaskScheduler.h"
+
+struct arena_ring_of_valor : ArenaScript
+{
+ enum BattlegroundRVGameObjects
+ {
+ BG_RV_OBJECT_TYPE_BUFF_1 = 184663,
+ BG_RV_OBJECT_TYPE_BUFF_2 = 184664,
+ BG_RV_OBJECT_TYPE_FIRE_1 = 192704,
+ BG_RV_OBJECT_TYPE_FIRE_2 = 192705,
+
+ BG_RV_OBJECT_TYPE_FIREDOOR_2 = 192387,
+ BG_RV_OBJECT_TYPE_FIREDOOR_1 = 192388,
+ BG_RV_OBJECT_TYPE_PULLEY_1 = 192389,
+ BG_RV_OBJECT_TYPE_PULLEY_2 = 192390,
+ BG_RV_OBJECT_TYPE_GEAR_1 = 192393,
+ BG_RV_OBJECT_TYPE_GEAR_2 = 192394,
+ BG_RV_OBJECT_TYPE_ELEVATOR_1 = 194582,
+ BG_RV_OBJECT_TYPE_ELEVATOR_2 = 194586,
+
+ BG_RV_OBJECT_TYPE_PILAR_COLLISION_1 = 194580, // axe
+ BG_RV_OBJECT_TYPE_PILAR_COLLISION_2 = 194579, // arena // big
+ BG_RV_OBJECT_TYPE_PILAR_COLLISION_3 = 194581, // lightning
+ BG_RV_OBJECT_TYPE_PILAR_COLLISION_4 = 194578, // ivory // big
+
+ BG_RV_OBJECT_TYPE_PILAR_1 = 194583, // axe
+ BG_RV_OBJECT_TYPE_PILAR_2 = 194584, // arena
+ BG_RV_OBJECT_TYPE_PILAR_3 = 194585, // lightning
+ BG_RV_OBJECT_TYPE_PILAR_4 = 194587 // ivory
+ };
+
+ enum BattlegroundRVData
+ {
+ BG_RV_STATE_OPEN_FENCES,
+ BG_RV_STATE_SWITCH_PILLARS,
+ BG_RV_STATE_CLOSE_FIRE,
+
+ BG_RV_PILLAR_SWITCH_TIMER = 25000,
+ BG_RV_FIRE_TO_PILLAR_TIMER = 20000,
+ BG_RV_CLOSE_FIRE_TIMER = 5000,
+ BG_RV_FIRST_TIMER = 20133,
+ };
+
+ explicit arena_ring_of_valor(BattlegroundMap* map) : ArenaScript(map), _timer(0), _state(0), _pillarCollision(false) { }
+
+ void OnUpdate(uint32 diff) override
+ {
+ if (battleground->GetStatus() != STATUS_IN_PROGRESS)
+ return;
+
+ _scheduler.Update(diff);
+
+ if (_timer < diff)
+ {
+ switch (_state)
+ {
+ case BG_RV_STATE_OPEN_FENCES:
+ // Open fire (only at game start)
+ for (ObjectGuid const& guid : _fireGUIDs)
+ if (GameObject* go = battlegroundMap->GetGameObject(guid))
+ go->UseDoorOrButton();
+ for (ObjectGuid const& guid : _firedoorGUIDs)
+ if (GameObject* go = battlegroundMap->GetGameObject(guid))
+ go->UseDoorOrButton();
+ _timer = BG_RV_CLOSE_FIRE_TIMER;
+ _state = BG_RV_STATE_CLOSE_FIRE;
+ break;
+ case BG_RV_STATE_CLOSE_FIRE:
+ for (ObjectGuid const& guid : _fireGUIDs)
+ if (GameObject* go = battlegroundMap->GetGameObject(guid))
+ go->ResetDoorOrButton();
+ for (ObjectGuid const& guid : _firedoorGUIDs)
+ if (GameObject* go = battlegroundMap->GetGameObject(guid))
+ go->ResetDoorOrButton();
+ // Fire got closed after five seconds, leaves twenty seconds before toggling pillars
+ _timer = BG_RV_FIRE_TO_PILLAR_TIMER;
+ _state = BG_RV_STATE_SWITCH_PILLARS;
+ break;
+ case BG_RV_STATE_SWITCH_PILLARS:
+ TogglePillarCollision();
+ _timer = BG_RV_PILLAR_SWITCH_TIMER;
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ _timer -= diff;
+ }
+
+ void OnInit() override
+ {
+ CreateObject(BG_RV_OBJECT_TYPE_ELEVATOR_1, 763.536377f, -294.535767f, 0.505383f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
+ CreateObject(BG_RV_OBJECT_TYPE_ELEVATOR_2, 763.506348f, -273.873352f, 0.505383f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
+
+ CreateObject(BG_RV_OBJECT_TYPE_FIRE_1, 743.543457f, -283.799469f, 28.286655f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
+ CreateObject(BG_RV_OBJECT_TYPE_FIRE_2, 782.971802f, -283.799469f, 28.286655f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
+ CreateObject(BG_RV_OBJECT_TYPE_FIREDOOR_1, 743.711060f, -284.099609f, 27.542587f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
+ CreateObject(BG_RV_OBJECT_TYPE_FIREDOOR_2, 783.221252f, -284.133362f, 27.535686f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
+
+ CreateObject(BG_RV_OBJECT_TYPE_GEAR_1, 763.664551f, -261.872986f, 26.686588f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
+ CreateObject(BG_RV_OBJECT_TYPE_GEAR_2, 763.578979f, -306.146149f, 26.665222f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
+ CreateObject(BG_RV_OBJECT_TYPE_PULLEY_1, 700.722290f, -283.990662f, 39.517582f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
+ CreateObject(BG_RV_OBJECT_TYPE_PULLEY_2, 826.303833f, -283.996429f, 39.517582f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
+ CreateObject(BG_RV_OBJECT_TYPE_PILAR_1, 763.632385f, -306.162384f, 25.909504f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
+ CreateObject(BG_RV_OBJECT_TYPE_PILAR_2, 723.644287f, -284.493256f, 24.648525f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
+ CreateObject(BG_RV_OBJECT_TYPE_PILAR_3, 763.611145f, -261.856750f, 25.909504f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
+ CreateObject(BG_RV_OBJECT_TYPE_PILAR_4, 802.211609f, -284.493256f, 24.648525f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
+ CreateObject(BG_RV_OBJECT_TYPE_PILAR_COLLISION_1, 763.632385f, -306.162384f, 30.639660f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
+ CreateObject(BG_RV_OBJECT_TYPE_PILAR_COLLISION_2, 723.644287f, -284.493256f, 32.382710f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
+ CreateObject(BG_RV_OBJECT_TYPE_PILAR_COLLISION_3, 763.611145f, -261.856750f, 30.639660f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
+ CreateObject(BG_RV_OBJECT_TYPE_PILAR_COLLISION_4, 802.211609f, -284.493256f, 32.382710f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
+ }
+
+ void OnStart() override
+ {
+ for (ObjectGuid const& guid : _elevatorGUIDs)
+ {
+ if (GameObject* door = battlegroundMap->GetGameObject(guid))
+ {
+ door->UseDoorOrButton();
+ door->DespawnOrUnsummon(5s);
+ }
+ }
+
+ _state = BG_RV_STATE_OPEN_FENCES;
+ _timer = BG_RV_FIRST_TIMER;
+
+ // Should be false at first, TogglePillarCollision will do it.
+ _pillarCollision = true;
+ TogglePillarCollision();
+
+ _scheduler.Schedule(1min, [&](TaskContext)
+ {
+ CreateObject(BG_RV_OBJECT_TYPE_BUFF_1, 735.551819f, -284.794678f, 28.276682f, 0.034906f, 0.0f, 0.0f, 0.0f, 0.0f);
+ CreateObject(BG_RV_OBJECT_TYPE_BUFF_2, 791.224487f, -284.794464f, 28.276682f, 2.600535f, 0.0f, 0.0f, 0.0f, 0.0f);
+ });
+ }
+
+ void TogglePillarCollision()
+ {
+ // Toggle visual pillars, pulley, gear, and collision based on previous state
+
+ GuidVector smallPillarGuids;
+ smallPillarGuids.insert(std::end(smallPillarGuids), std::begin(_pillarSmallGUIDs), std::end(_pillarSmallGUIDs));
+ smallPillarGuids.insert(std::end(smallPillarGuids), std::begin(_gearGUIDs), std::end(_gearGUIDs));
+
+ for (ObjectGuid const& guid : smallPillarGuids)
+ {
+ if (GameObject* go = battlegroundMap->GetGameObject(guid))
+ {
+ if (_pillarCollision)
+ go->UseDoorOrButton();
+ else
+ go->ResetDoorOrButton();
+ }
+ }
+
+ GuidVector bigPillarGuids;
+ bigPillarGuids.insert(std::end(bigPillarGuids), std::begin(_pillarBigGUIDs), std::end(_pillarBigGUIDs));
+ bigPillarGuids.insert(std::end(bigPillarGuids), std::begin(_pulleyGUIDs), std::end(_pulleyGUIDs));
+
+ for (ObjectGuid const& guid : bigPillarGuids)
+ {
+ if (GameObject* go = battlegroundMap->GetGameObject(guid))
+ {
+ if (_pillarCollision)
+ go->ResetDoorOrButton();
+ else
+ go->UseDoorOrButton();
+ }
+ }
+
+ GuidVector allObjects;
+ allObjects.insert(std::end(allObjects), std::begin(smallPillarGuids), std::end(smallPillarGuids));
+ allObjects.insert(std::end(allObjects), std::begin(bigPillarGuids), std::end(bigPillarGuids));
+ allObjects.insert(std::end(allObjects), std::begin(_pillarSmallCollisionGUIDs), std::end(_pillarSmallCollisionGUIDs));
+ allObjects.insert(std::end(allObjects), std::begin(_pillarBigCollisionGUIDs), std::end(_pillarBigCollisionGUIDs));
+
+ for (ObjectGuid const& guid : allObjects)
+ {
+ if (GameObject* go = battlegroundMap->GetGameObject(guid))
+ {
+ bool isCollision = false;
+ switch (go->GetEntry())
+ {
+ case BG_RV_OBJECT_TYPE_PILAR_COLLISION_1:
+ case BG_RV_OBJECT_TYPE_PILAR_COLLISION_2:
+ case BG_RV_OBJECT_TYPE_PILAR_COLLISION_3:
+ case BG_RV_OBJECT_TYPE_PILAR_COLLISION_4:
+ isCollision = true;
+ break;
+ default:
+ break;
+ }
+
+ if (isCollision)
+ {
+ GOState state = ((go->GetGOInfo()->door.startOpen != 0) == _pillarCollision) ? GO_STATE_ACTIVE : GO_STATE_READY;
+ go->SetGoState(state);
+ }
+
+ for (auto const& [playerGuid, _]: battleground->GetPlayers())
+ if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
+ go->SendUpdateToPlayer(player);
+ }
+ }
+
+ _pillarCollision = !_pillarCollision;
+ }
+
+ void OnGameObjectCreate(GameObject* gameobject) override
+ {
+ ArenaScript::OnGameObjectCreate(gameobject);
+
+ switch (gameobject->GetEntry())
+ {
+ case BG_RV_OBJECT_TYPE_ELEVATOR_1:
+ case BG_RV_OBJECT_TYPE_ELEVATOR_2:
+ _elevatorGUIDs.emplace_back(gameobject->GetGUID());
+ break;
+ case BG_RV_OBJECT_TYPE_FIRE_1:
+ case BG_RV_OBJECT_TYPE_FIRE_2:
+ _fireGUIDs.emplace_back(gameobject->GetGUID());
+ break;
+ case BG_RV_OBJECT_TYPE_FIREDOOR_1:
+ case BG_RV_OBJECT_TYPE_FIREDOOR_2:
+ _firedoorGUIDs.emplace_back(gameobject->GetGUID());
+ break;
+ case BG_RV_OBJECT_TYPE_GEAR_1:
+ case BG_RV_OBJECT_TYPE_GEAR_2:
+ _gearGUIDs.emplace_back(gameobject->GetGUID());
+ break;
+ case BG_RV_OBJECT_TYPE_PILAR_1:
+ case BG_RV_OBJECT_TYPE_PILAR_3:
+ _pillarSmallGUIDs.emplace_back(gameobject->GetGUID());
+ break;
+ case BG_RV_OBJECT_TYPE_PILAR_2:
+ case BG_RV_OBJECT_TYPE_PILAR_4:
+ _pillarBigGUIDs.emplace_back(gameobject->GetGUID());
+ break;
+ case BG_RV_OBJECT_TYPE_PILAR_COLLISION_1:
+ case BG_RV_OBJECT_TYPE_PILAR_COLLISION_3:
+ _pillarSmallCollisionGUIDs.emplace_back(gameobject->GetGUID());
+ break;
+ case BG_RV_OBJECT_TYPE_PILAR_COLLISION_2:
+ case BG_RV_OBJECT_TYPE_PILAR_COLLISION_4:
+ _pillarBigCollisionGUIDs.emplace_back(gameobject->GetGUID());
+ break;
+ case BG_RV_OBJECT_TYPE_PULLEY_1:
+ case BG_RV_OBJECT_TYPE_PULLEY_2:
+ _pulleyGUIDs.emplace_back(gameobject->GetGUID());
+ break;
+ default:
+ break;
+ }
+ }
+
+private:
+ GuidVector _elevatorGUIDs;
+ GuidVector _gearGUIDs;
+ GuidVector _fireGUIDs;
+ GuidVector _firedoorGUIDs;
+ GuidVector _pillarSmallCollisionGUIDs;
+ GuidVector _pillarBigCollisionGUIDs;
+ GuidVector _pillarSmallGUIDs;
+ GuidVector _pillarBigGUIDs;
+ GuidVector _pulleyGUIDs;
+ TaskScheduler _scheduler;
+
+ uint32 _timer;
+ uint32 _state;
+ bool _pillarCollision;
+};
+
+void AddSC_arena_ring_of_valor()
+{
+ RegisterBattlegroundMapScript(arena_ring_of_valor, 618);
+}
diff --git a/src/server/scripts/Battlegrounds/RuinsOfLordaeron/arena_ruins_of_lordaeron.cpp b/src/server/scripts/Battlegrounds/RuinsOfLordaeron/arena_ruins_of_lordaeron.cpp
new file mode 100644
index 00000000000..75f9c6caef1
--- /dev/null
+++ b/src/server/scripts/Battlegrounds/RuinsOfLordaeron/arena_ruins_of_lordaeron.cpp
@@ -0,0 +1,80 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Battleground.h"
+#include "BattlegroundScript.h"
+#include "GameObject.h"
+#include "Map.h"
+#include "ScriptMgr.h"
+#include "TaskScheduler.h"
+
+struct arena_ruins_of_lordaeron : ArenaScript
+{
+ enum BattlegroundRLGameObjects
+ {
+ BG_RL_OBJECT_TYPE_DOOR_1 = 185918,
+ BG_RL_OBJECT_TYPE_DOOR_2 = 185917,
+ BG_RL_OBJECT_TYPE_BUFF_1 = 184663,
+ BG_RL_OBJECT_TYPE_BUFF_2 = 184664
+ };
+
+ explicit arena_ruins_of_lordaeron(BattlegroundMap* map) : ArenaScript(map) { }
+
+ void OnUpdate(uint32 diff) override
+ {
+ _scheduler.Update(diff);
+ }
+
+ void OnInit() override
+ {
+ AddDoor(BG_RL_OBJECT_TYPE_DOOR_1, 1293.561f, 1601.938f, 31.60557f, -1.457349f, 0, 0, -0.6658813f, 0.7460576f);
+ AddDoor(BG_RL_OBJECT_TYPE_DOOR_2, 1278.648f, 1730.557f, 31.60557f, 1.684245f, 0, 0, 0.7460582f, 0.6658807f);
+ }
+
+ void OnStart() override
+ {
+ for (ObjectGuid const& guid : _doorGUIDs)
+ {
+ if (GameObject* door = battlegroundMap->GetGameObject(guid))
+ {
+ door->UseDoorOrButton();
+ door->DespawnOrUnsummon(5s);
+ }
+ }
+
+ _scheduler.Schedule(1min, [&](TaskContext)
+ {
+ CreateObject(BG_RL_OBJECT_TYPE_BUFF_1, 1328.719971f, 1632.719971f, 36.730400f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f);
+ CreateObject(BG_RL_OBJECT_TYPE_BUFF_2, 1243.300049f, 1699.170044f, 34.872601f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f);
+ });
+ }
+
+ void AddDoor(uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, GOState goState = GO_STATE_READY)
+ {
+ if (GameObject const* go = CreateObject(entry, x, y, z, o, rotation0, rotation1, rotation2, rotation3, goState))
+ _doorGUIDs.emplace_back(go->GetGUID());
+ }
+
+private:
+ GuidVector _doorGUIDs;
+ TaskScheduler _scheduler;
+};
+
+void AddSC_arena_ruins_of_lordaeron()
+{
+ RegisterBattlegroundMapScript(arena_ruins_of_lordaeron, 572);
+}
diff --git a/src/server/scripts/Battlegrounds/StrandOfTheAncients/battleground_strand_of_the_ancients.cpp b/src/server/scripts/Battlegrounds/StrandOfTheAncients/battleground_strand_of_the_ancients.cpp
new file mode 100644
index 00000000000..dba78903864
--- /dev/null
+++ b/src/server/scripts/Battlegrounds/StrandOfTheAncients/battleground_strand_of_the_ancients.cpp
@@ -0,0 +1,1059 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "BattlegroundScript.h"
+#include "Battleground.h"
+#include "BattlegroundMgr.h"
+#include "BattlegroundScore.h"
+#include "Creature.h"
+#include "CreatureAI.h"
+#include "GameObject.h"
+#include "GameTime.h"
+#include "Map.h"
+#include "ObjectAccessor.h"
+#include "ObjectMgr.h"
+#include "Player.h"
+#include "ScriptMgr.h"
+#include "strand_of_the_ancients.h"
+#include "VehicleDefines.h"
+#include "WorldStateMgr.h"
+
+enum BG_SA_Status
+{
+ BG_SA_NOT_STARTED = 0,
+ BG_SA_WARMUP,
+ BG_SA_ROUND_ONE,
+ BG_SA_SECOND_WARMUP,
+ BG_SA_ROUND_TWO,
+ BG_SA_BONUS_ROUND
+};
+
+enum BG_SA_GateState
+{
+ // alliance is defender
+ BG_SA_ALLIANCE_GATE_OK = 1,
+ BG_SA_ALLIANCE_GATE_DAMAGED = 2,
+ BG_SA_ALLIANCE_GATE_DESTROYED = 3,
+ // horde is defender
+ BG_SA_HORDE_GATE_OK = 4,
+ BG_SA_HORDE_GATE_DAMAGED = 5,
+ BG_SA_HORDE_GATE_DESTROYED = 6,
+};
+
+enum StrandOfTheAncientsGameObjects
+{
+ GO_SEAFORIUM_BOMB_H = 194086, // Used by horde players
+ GO_SEAFORIUM_BOMB_A = 190753, // Used by alliance players
+ GO_SEAFORIUM_CHARGE_H = 257572,
+ GO_SEAFORIUM_CHARGE_A = 257565,
+
+ GO_GRAVEYARD_WEST_H = 191307,
+ GO_GRAVEYARD_WEST_A = 191308,
+
+ GO_GRAVEYARD_EAST_H = 191305,
+ GO_GRAVEYARD_EAST_A = 191306,
+
+ GO_GRAVEYARD_CENTRAL_H = 191309,
+ GO_GRAVEYARD_CENTRAL_A = 191310,
+
+ GO_COLLISION_DOOR = 194162,
+ GO_TITAN_RELIC_A = 194083,
+ GO_TITAN_RELIC_H = 194082,
+
+ GO_GATE_OF_THE_GREEN_EMERALD = 190722,
+ GO_GATE_OF_THE_PURPLE_AMETHYST = 190723,
+ GO_GATE_OF_THE_BLUE_SAPPHIRE = 190724,
+ GO_GATE_OF_THE_RED_SUN = 190726,
+ GO_GATE_OF_THE_YELLOW_MOON = 190727,
+ GO_CHAMBER_OF_ANCIENT_RELICS = 192549
+};
+
+enum BG_SA_Timers
+{
+ BG_SA_BOAT_START = 60 * IN_MILLISECONDS,
+ BG_SA_WARMUPLENGTH = 120 * IN_MILLISECONDS,
+ BG_SA_ROUNDLENGTH = 600 * IN_MILLISECONDS
+};
+
+enum SASounds
+{
+ SOUND_GRAVEYARD_TAKEN_HORDE = 8174,
+ SOUND_GRAVEYARD_TAKEN_ALLIANCE = 8212,
+ SOUND_DEFEAT_HORDE = 15905,
+ SOUND_VICTORY_HORDE = 15906,
+ SOUND_VICTORY_ALLIANCE = 15907,
+ SOUND_DEFEAT_ALLIANCE = 15908,
+ SOUND_WALL_DESTROYED_ALLIANCE = 15909,
+ SOUND_WALL_DESTROYED_HORDE = 15910,
+ SOUND_WALL_ATTACKED_HORDE = 15911,
+ SOUND_WALL_ATTACKED_ALLIANCE = 15912
+};
+
+enum SATexts
+{
+ // Kanrethad
+ TEXT_ROUND_STARTED = 1,
+ TEXT_ROUND_1_FINISHED = 2,
+
+ // Rigger Sparklight / Gorgril Rigspark
+ TEXT_SPARKLIGHT_RIGSPARK_SPAWN = 1,
+
+ // World Trigger
+ TEXT_BLUE_GATE_UNDER_ATTACK = 1,
+ TEXT_GREEN_GATE_UNDER_ATTACK = 2,
+ TEXT_RED_GATE_UNDER_ATTACK = 3,
+ TEXT_PURPLE_GATE_UNDER_ATTACK = 4,
+ TEXT_YELLOW_GATE_UNDER_ATTACK = 5,
+ TEXT_YELLOW_GATE_DESTROYED = 6,
+ TEXT_PURPLE_GATE_DESTROYED = 7,
+ TEXT_RED_GATE_DESTROYED = 8,
+ TEXT_GREEN_GATE_DESTROYED = 9,
+ TEXT_BLUE_GATE_DESTROYED = 10,
+ TEXT_EAST_GRAVEYARD_CAPTURED_A = 11,
+ TEXT_WEST_GRAVEYARD_CAPTURED_A = 12,
+ TEXT_SOUTH_GRAVEYARD_CAPTURED_A = 13,
+ TEXT_EAST_GRAVEYARD_CAPTURED_H = 14,
+ TEXT_WEST_GRAVEYARD_CAPTURED_H = 15,
+ TEXT_SOUTH_GRAVEYARD_CAPTURED_H = 16,
+ TEXT_ANCIENT_GATE_UNDER_ATTACK = 17,
+ TEXT_ANCIENT_GATE_DESTROYED = 18
+};
+
+enum SAWorldStates
+{
+ BG_SA_TIMER = 3557,
+ BG_SA_ALLY_ATTACKS = 4352,
+ BG_SA_HORDE_ATTACKS = 4353,
+ BG_SA_PURPLE_GATEWS = 3614,
+ BG_SA_RED_GATEWS = 3617,
+ BG_SA_BLUE_GATEWS = 3620,
+ BG_SA_GREEN_GATEWS = 3623,
+ BG_SA_YELLOW_GATEWS = 3638,
+ BG_SA_ANCIENT_GATEWS = 3849,
+
+ BG_SA_LEFT_GY_ALLIANCE = 3635,
+ BG_SA_RIGHT_GY_ALLIANCE = 3636,
+ BG_SA_CENTER_GY_ALLIANCE = 3637,
+
+ BG_SA_RIGHT_ATT_TOKEN_ALL = 3627,
+ BG_SA_LEFT_ATT_TOKEN_ALL = 3626,
+ BG_SA_LEFT_ATT_TOKEN_HRD = 3629,
+ BG_SA_RIGHT_ATT_TOKEN_HRD = 3628,
+ BG_SA_HORDE_DEFENCE_TOKEN = 3631,
+ BG_SA_ALLIANCE_DEFENCE_TOKEN = 3630,
+
+ BG_SA_RIGHT_GY_HORDE = 3632,
+ BG_SA_LEFT_GY_HORDE = 3633,
+ BG_SA_CENTER_GY_HORDE = 3634,
+
+ BG_SA_BONUS_TIMER = 3571,
+
+ BG_SA_ENABLE_TIMER = 3564,
+ BG_SA_ATTACKER_TEAM = 3690,
+ BG_SA_DESTROYED_ALLIANCE_VEHICLES = 3955,
+ BG_SA_DESTROYED_HORDE_VEHICLES = 3956,
+};
+
+enum BG_SA_Boat
+{
+ BG_SA_BOAT_ONE_A = 208000,
+ BG_SA_BOAT_TWO_H = 208001,
+ BG_SA_BOAT_ONE_H = 193184,
+ BG_SA_BOAT_TWO_A = 193185
+};
+
+static constexpr uint32 BG_SA_Factions[2] =
+{
+ 1732,
+ 1735,
+};
+
+enum class StrandOfTheAncientsGraveyard
+{
+ West,
+ East,
+ Central
+};
+
+enum BG_SA_BroadcastTexts
+{
+ BG_SA_TEXT_ALLIANCE_CAPTURED_TITAN_PORTAL = 28944,
+ BG_SA_TEXT_HORDE_CAPTURED_TITAN_PORTAL = 28945,
+
+ BG_SA_TEXT_ROUND_TWO_START_ONE_MINUTE = 29448,
+ BG_SA_TEXT_ROUND_TWO_START_HALF_MINUTE = 29449
+};
+
+enum class DefenseLine
+{
+ First,
+ Second,
+ Third,
+ Last
+};
+
+struct GateInfo
+{
+ uint32 GameObjectId;
+ uint32 WorldState;
+ uint8 DamagedText;
+ uint8 DestroyedText;
+ DefenseLine LineOfDefense;
+};
+
+GateInfo const Gates[] =
+{
+ { GO_GATE_OF_THE_GREEN_EMERALD, BG_SA_GREEN_GATEWS, TEXT_GREEN_GATE_UNDER_ATTACK, TEXT_GREEN_GATE_DESTROYED, DefenseLine::First },
+ { GO_GATE_OF_THE_YELLOW_MOON, BG_SA_YELLOW_GATEWS, TEXT_YELLOW_GATE_UNDER_ATTACK, TEXT_YELLOW_GATE_DESTROYED, DefenseLine::Third },
+ { GO_GATE_OF_THE_BLUE_SAPPHIRE, BG_SA_BLUE_GATEWS, TEXT_BLUE_GATE_UNDER_ATTACK, TEXT_BLUE_GATE_DESTROYED, DefenseLine::First },
+ { GO_GATE_OF_THE_RED_SUN, BG_SA_RED_GATEWS, TEXT_RED_GATE_UNDER_ATTACK, TEXT_RED_GATE_DESTROYED, DefenseLine::Second },
+ { GO_GATE_OF_THE_PURPLE_AMETHYST, BG_SA_PURPLE_GATEWS, TEXT_PURPLE_GATE_UNDER_ATTACK, TEXT_PURPLE_GATE_DESTROYED, DefenseLine::Second },
+ { GO_CHAMBER_OF_ANCIENT_RELICS, BG_SA_ANCIENT_GATEWS, TEXT_ANCIENT_GATE_UNDER_ATTACK, TEXT_ANCIENT_GATE_DESTROYED, DefenseLine::Last }
+};
+
+struct BG_SA_RoundScore
+{
+ TeamId winner;
+ uint32 time;
+};
+
+enum StrandOfTheAncientsPvpStats
+{
+ PVP_STAT_GATES_DESTROYED = 231,
+ PVP_STAT_DEMOLISHERS_DESTROYED = 232
+};
+
+enum StrandOfTheAncientsEvents
+{
+ EVENT_HORDE_ASSAULT_STARTED = 21702,
+ EVENT_ALLIANCE_ASSAULT_STARTED = 23748,
+ EVENT_TITAN_RELIC_ACTIVATED = 20572
+};
+
+enum StrandOfTheAncientsCreatures
+{
+ NPC_KANRETHAD = 29,
+ NPC_DEMOLISHER = 28781,
+ NPC_ANTIPERSONNEL_CANNON = 27894,
+ NPC_RIGGER_SPARKLIGHT = 29260,
+ NPC_GORGRIL_RIGSPARK = 29262,
+ NPC_WORLD_TRIGGER = 22515,
+ NPC_DEMOLISHER_SA = 28781
+};
+
+enum StrandOfTheAncientsSpawnPositions
+{
+ SPAWN_DEFENDERS = 1399
+};
+
+enum StrandOfTheAncientsData
+{
+ DATA_ATTACKERS = 1,
+ DATA_STATUS = 2
+};
+
+enum StrandOfTheAncientSpells
+{
+ SPELL_TELEPORT_DEFENDER = 52364,
+ SPELL_TELEPORT_ATTACKERS = 60178,
+ SPELL_END_OF_ROUND = 52459,
+ SPELL_REMOVE_SEAFORIUM = 59077,
+ SPELL_ALLIANCE_CONTROL_PHASE_SHIFT = 60027,
+ SPELL_HORDE_CONTROL_PHASE_SHIFT = 60028,
+ SPELL_CARRYING_SEAFORIUM_CHARGE = 52415
+};
+
+static constexpr Position spawnPositionOnTransport[] =
+{
+ { 0.0f, 5.0f, 9.6f, 3.14f },
+ { -6.0f, -3.0f, 8.6f, 0.0f }
+};
+
+struct battleground_strand_of_the_ancients : BattlegroundScript
+{
+ explicit battleground_strand_of_the_ancients(BattlegroundMap* map) : BattlegroundScript(map)
+ {
+ _timerEnabled = false;
+ _updateWaitTimer = 0;
+ _signaledRoundTwo = false;
+ _signaledRoundTwoHalfMin = false;
+ _initSecondRound = false;
+ _attackers = static_cast<TeamId>(urand(TEAM_ALLIANCE, TEAM_HORDE));
+ _totalTime = 0;
+ _endRoundTimer = 0;
+ _shipsStarted = false;
+ _status = BG_SA_NOT_STARTED;
+
+ _roundScores = { };
+
+ for (BG_SA_RoundScore& roundScore : _roundScores)
+ {
+ roundScore.winner = TEAM_ALLIANCE;
+ roundScore.time = 0;
+ }
+
+ _boatGUIDs = { };
+ _staticBombGUIDs = { };
+ }
+
+ void OnInit() override
+ {
+ BattlegroundScript::OnInit();
+ _status = BG_SA_WARMUP;
+ ResetObjs();
+ }
+
+ void OnUpdate(uint32 diff) override
+ {
+ BattlegroundScript::OnUpdate(diff);
+ if (_initSecondRound)
+ {
+ if (_updateWaitTimer < diff)
+ {
+ if (!_signaledRoundTwo)
+ {
+ _signaledRoundTwo = true;
+ _initSecondRound = false;
+ battleground->SendBroadcastText(BG_SA_TEXT_ROUND_TWO_START_ONE_MINUTE, CHAT_MSG_BG_SYSTEM_NEUTRAL);
+ }
+ }
+ else
+ {
+ _updateWaitTimer -= diff;
+ return;
+ }
+ }
+ _totalTime += diff;
+
+ if (_status == BG_SA_WARMUP)
+ {
+ _endRoundTimer = BG_SA_ROUNDLENGTH;
+ UpdateWorldState(BG_SA_TIMER, GameTime::GetGameTime() + (_endRoundTimer / 1000));
+ if (_totalTime >= BG_SA_WARMUPLENGTH)
+ {
+ if (Creature* c = FindKanrethad())
+ battleground->SendChatMessage(c, TEXT_ROUND_STARTED);
+
+ _totalTime = 0;
+ ToggleTimer();
+ _status = BG_SA_ROUND_ONE;
+ TriggerGameEvent((_attackers == TEAM_ALLIANCE) ? EVENT_ALLIANCE_ASSAULT_STARTED : EVENT_HORDE_ASSAULT_STARTED);
+ }
+ if (_totalTime >= BG_SA_BOAT_START)
+ StartShips();
+ return;
+ }
+ else if (_status == BG_SA_SECOND_WARMUP)
+ {
+ if (_roundScores[0].time < BG_SA_ROUNDLENGTH)
+ _endRoundTimer = _roundScores[0].time;
+ else
+ _endRoundTimer = BG_SA_ROUNDLENGTH;
+
+ UpdateWorldState(BG_SA_TIMER, GameTime::GetGameTime() + (_endRoundTimer / 1000));
+ if (_totalTime >= 60000)
+ {
+ if (Creature* c = FindKanrethad())
+ battleground->SendChatMessage(c, TEXT_ROUND_STARTED);
+
+ _totalTime = 0;
+ ToggleTimer();
+ _status = BG_SA_ROUND_TWO;
+ TriggerGameEvent((_attackers == TEAM_ALLIANCE) ? EVENT_ALLIANCE_ASSAULT_STARTED : EVENT_HORDE_ASSAULT_STARTED);
+ // status was set to STATUS_WAIT_JOIN manually for Preparation, set it back now
+ battleground->SetStatus(STATUS_IN_PROGRESS);
+ for (const auto& [playerGuid, bp] : battleground->GetPlayers())
+ if (Player* p = ObjectAccessor::FindPlayer(playerGuid))
+ p->RemoveAurasDueToSpell(SPELL_PREPARATION);
+ }
+ if (_totalTime >= 30000)
+ {
+ if (!_signaledRoundTwoHalfMin)
+ {
+ _signaledRoundTwoHalfMin = true;
+ battleground->SendBroadcastText(BG_SA_TEXT_ROUND_TWO_START_HALF_MINUTE, CHAT_MSG_BG_SYSTEM_NEUTRAL);
+ }
+ }
+ StartShips();
+ return;
+ }
+ else if (battleground->GetStatus() == STATUS_IN_PROGRESS)
+ {
+ if (_status == BG_SA_ROUND_ONE)
+ {
+ if (_totalTime >= BG_SA_ROUNDLENGTH)
+ {
+ EndRound();
+ return;
+ }
+ }
+ else if (_status == BG_SA_ROUND_TWO)
+ {
+ if (_totalTime >= _endRoundTimer)
+ {
+ battleground->CastSpellOnTeam(SPELL_END_OF_ROUND, ALLIANCE);
+ battleground->CastSpellOnTeam(SPELL_END_OF_ROUND, HORDE);
+ _roundScores[1].time = BG_SA_ROUNDLENGTH;
+ _roundScores[1].winner = (_attackers == TEAM_ALLIANCE) ? TEAM_HORDE : TEAM_ALLIANCE;
+ if (_roundScores[0].time == _roundScores[1].time)
+ battleground->EndBattleground(TEAM_OTHER);
+ else if (_roundScores[0].time < _roundScores[1].time)
+ battleground->EndBattleground(_roundScores[0].winner == TEAM_ALLIANCE ? ALLIANCE : HORDE);
+ else
+ battleground->EndBattleground(_roundScores[1].winner == TEAM_ALLIANCE ? ALLIANCE : HORDE);
+ return;
+ }
+ }
+ }
+ }
+
+ void Reset()
+ {
+ _totalTime = 0;
+ _shipsStarted = false;
+ _status = BG_SA_WARMUP;
+ }
+
+ void ResetObjs()
+ {
+ for (ObjectGuid const& bombGuid : _dynamicBombGUIDs)
+ if (GameObject* bomb = battlegroundMap->GetGameObject(bombGuid))
+ bomb->Delete();
+
+ _dynamicBombGUIDs.clear();
+
+ TeamId const defenders = _attackers == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE;
+
+ _totalTime = 0;
+ _shipsStarted = false;
+
+ UpdateWorldState(BG_SA_ALLY_ATTACKS, _attackers == TEAM_ALLIANCE);
+ UpdateWorldState(BG_SA_HORDE_ATTACKS, _attackers == TEAM_HORDE);
+
+ UpdateWorldState(BG_SA_RIGHT_ATT_TOKEN_ALL, _attackers == TEAM_ALLIANCE);
+ UpdateWorldState(BG_SA_LEFT_ATT_TOKEN_ALL, _attackers == TEAM_ALLIANCE);
+
+ UpdateWorldState(BG_SA_RIGHT_ATT_TOKEN_HRD, _attackers == TEAM_HORDE);
+ UpdateWorldState(BG_SA_LEFT_ATT_TOKEN_HRD, _attackers == TEAM_HORDE);
+
+ UpdateWorldState(BG_SA_HORDE_DEFENCE_TOKEN, defenders == TEAM_HORDE);
+ UpdateWorldState(BG_SA_ALLIANCE_DEFENCE_TOKEN, defenders == TEAM_ALLIANCE);
+
+ CaptureGraveyard(StrandOfTheAncientsGraveyard::Central, defenders);
+ CaptureGraveyard(StrandOfTheAncientsGraveyard::West, defenders);
+ CaptureGraveyard(StrandOfTheAncientsGraveyard::East, defenders);
+
+ UpdateWorldState(BG_SA_ATTACKER_TEAM, _attackers);
+
+ for (ObjectGuid const& guid : _gateGUIDs)
+ if (GameObject* gate = battlegroundMap->GetGameObject(guid))
+ gate->SetDestructibleState(GO_DESTRUCTIBLE_INTACT, nullptr, true);
+
+ BG_SA_GateState const state = _attackers == TEAM_ALLIANCE ? BG_SA_HORDE_GATE_OK : BG_SA_ALLIANCE_GATE_OK;
+ UpdateWorldState(BG_SA_PURPLE_GATEWS, state);
+ UpdateWorldState(BG_SA_RED_GATEWS, state);
+ UpdateWorldState(BG_SA_BLUE_GATEWS, state);
+ UpdateWorldState(BG_SA_GREEN_GATEWS, state);
+ UpdateWorldState(BG_SA_YELLOW_GATEWS, state);
+ UpdateWorldState(BG_SA_ANCIENT_GATEWS, state);
+
+ battlegroundMap->UpdateSpawnGroupConditions();
+
+ if (GameObject* door = battlegroundMap->GetGameObject(_collisionDoorGUID))
+ door->ResetDoorOrButton();
+
+ battleground->SetStatus(STATUS_WAIT_JOIN);
+ battlegroundMap->DoOnPlayers([&](Player* player)
+ {
+ SendTransportInit(player);
+ });
+
+ TeleportPlayers();
+ }
+
+ void StartShips()
+ {
+ if (_shipsStarted)
+ return;
+
+ for (ObjectGuid const& guid : _boatGUIDs[_attackers])
+ {
+ if (GameObject* boat = battlegroundMap->GetGameObject(guid))
+ {
+ boat->SetGoState(GO_STATE_TRANSPORT_STOPPED);
+
+ // make sure every player knows the transport exists & is moving
+ for (auto const& [playerGuid, _] : battleground->GetPlayers())
+ if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
+ boat->SendUpdateToPlayer(player);
+ }
+ }
+
+ _shipsStarted = true;
+ }
+
+ void OnPlayerJoined(Player* player, bool inBattleground) override
+ {
+ BattlegroundScript::OnPlayerJoined(player, inBattleground);
+ SendTransportInit(player);
+ if (!inBattleground)
+ TeleportToEntrancePosition(player);
+ }
+
+ void TeleportPlayers() const
+ {
+ for (auto const& [playerGuid, bp] : battleground->GetPlayers())
+ {
+ if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
+ {
+ // should remove spirit of redemption
+ if (player->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
+ player->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT);
+
+ if (!player->IsAlive())
+ {
+ player->ResurrectPlayer(1.0f);
+ player->SpawnCorpseBones();
+ }
+
+ player->ResetAllPowers();
+ player->CombatStopWithPets(true);
+
+ player->CastSpell(player, SPELL_PREPARATION, true);
+
+ TeleportToEntrancePosition(player);
+ }
+ }
+ }
+
+ // This function teleports player to entrance position, but it's not implemented correctly
+ // It is also used on round swap; which should be handled by the following spells: 52365, 52528, 53464, 53465 (Split Teleport (FACTION) (Boat X))
+ // This spell however cannot work with current system because of grid limitations.
+ // On battleground start, this function should work fine, except that it is called to late and we need a NearTeleport to solve this.
+ void TeleportToEntrancePosition(Player* player) const
+ {
+ if (Battleground::GetTeamIndexByTeamId(battleground->GetPlayerTeam(player->GetGUID())) == _attackers)
+ {
+ ObjectGuid const boatGUID = _boatGUIDs[_attackers][urand(0, 1)];
+
+ if (GameObject* boat = battlegroundMap->GetGameObject(boatGUID))
+ {
+ if (TransportBase* transport = boat->ToTransportBase())
+ {
+ player->Relocate(spawnPositionOnTransport[_attackers]);
+ transport->AddPassenger(player);
+ player->m_movementInfo.transport.pos.Relocate(spawnPositionOnTransport[_attackers]);
+ float x, y, z, o;
+ spawnPositionOnTransport[_attackers].GetPosition(x, y, z, o);
+ transport->CalculatePassengerPosition(x, y, z, &o);
+ player->Relocate(x, y, z, o);
+
+ if (player->IsInWorld())
+ player->NearTeleportTo({ x, y, z, o });
+ }
+ }
+ }
+ else if (WorldSafeLocsEntry const* defenderSpawn = sObjectMgr->GetWorldSafeLoc(SPAWN_DEFENDERS))
+ {
+ if (player->IsInWorld())
+ player->TeleportTo(defenderSpawn->Loc);
+ else
+ player->WorldRelocate(defenderSpawn->Loc);
+ }
+ }
+
+ void ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* invoker) override
+ {
+ BattlegroundScript::ProcessEvent(obj, eventId, invoker);
+
+ switch (eventId)
+ {
+ case EVENT_ALLIANCE_ASSAULT_STARTED:
+ for (ObjectGuid const& bombGuid : _staticBombGUIDs[TEAM_ALLIANCE])
+ if (GameObject* bomb = battlegroundMap->GetGameObject(bombGuid))
+ bomb->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
+ break;
+ case EVENT_HORDE_ASSAULT_STARTED:
+ for (ObjectGuid const& bombGuid : _staticBombGUIDs[TEAM_HORDE])
+ if (GameObject* bomb = battlegroundMap->GetGameObject(bombGuid))
+ bomb->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
+ break;
+ default:
+ break;
+ }
+
+ if (GameObject* go = Object::ToGameObject(obj))
+ {
+ switch (go->GetGoType())
+ {
+ case GAMEOBJECT_TYPE_GOOBER:
+ if (invoker)
+ if (eventId == EVENT_TITAN_RELIC_ACTIVATED)
+ TitanRelicActivated(invoker->ToPlayer());
+ break;
+ case GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING:
+ {
+ if (GateInfo const* gate = GetGate(obj->GetEntry()))
+ {
+ uint32 gateId = gate->GameObjectId;
+
+ // damaged
+ if (eventId == go->GetGOInfo()->destructibleBuilding.DamagedEvent)
+ {
+ BG_SA_GateState gateState = _attackers == TEAM_HORDE ? BG_SA_ALLIANCE_GATE_DAMAGED : BG_SA_HORDE_GATE_DAMAGED;
+
+ if (Creature* c = obj->FindNearestCreature(NPC_WORLD_TRIGGER, 500.0f))
+ battleground->SendChatMessage(c, gate->DamagedText, invoker);
+
+ battleground->PlaySoundToAll(_attackers == TEAM_ALLIANCE ? SOUND_WALL_ATTACKED_ALLIANCE : SOUND_WALL_ATTACKED_HORDE);
+
+ UpdateWorldState(gate->WorldState, gateState);
+ }
+ // destroyed
+ else if (eventId == go->GetGOInfo()->destructibleBuilding.DestroyedEvent)
+ {
+ BG_SA_GateState gateState = _attackers == TEAM_HORDE ? BG_SA_ALLIANCE_GATE_DESTROYED : BG_SA_HORDE_GATE_DESTROYED;
+ if (Creature* c = obj->FindNearestCreature(NPC_WORLD_TRIGGER, 500.0f))
+ battleground->SendChatMessage(c, gate->DestroyedText, invoker);
+
+ battleground->PlaySoundToAll(_attackers == TEAM_ALLIANCE ? SOUND_WALL_DESTROYED_ALLIANCE : SOUND_WALL_DESTROYED_HORDE);
+
+ // check if other gate from same line of defense is already destroyed for honor reward
+ bool rewardHonor = true;
+ switch (gateId)
+ {
+ case GO_GATE_OF_THE_GREEN_EMERALD:
+ if (IsGateDestroyed(GetGate(GO_GATE_OF_THE_BLUE_SAPPHIRE)))
+ rewardHonor = false;
+ break;
+ case GO_GATE_OF_THE_BLUE_SAPPHIRE:
+ if (IsGateDestroyed(GetGate(GO_GATE_OF_THE_GREEN_EMERALD)))
+ rewardHonor = false;
+ break;
+ case GO_GATE_OF_THE_RED_SUN:
+ if (IsGateDestroyed(GetGate(GO_GATE_OF_THE_PURPLE_AMETHYST)))
+ rewardHonor = false;
+ break;
+ case GO_GATE_OF_THE_PURPLE_AMETHYST:
+ if (IsGateDestroyed(GetGate(GO_GATE_OF_THE_RED_SUN)))
+ rewardHonor = false;
+ break;
+ default:
+ break;
+ }
+
+ if (invoker)
+ {
+ if (Unit* unit = invoker->ToUnit())
+ {
+ if (Player* player = unit->GetCharmerOrOwnerPlayerOrPlayerItself())
+ {
+ battleground->UpdatePvpStat(player, PVP_STAT_GATES_DESTROYED, 1);
+ if (rewardHonor)
+ battleground->UpdatePlayerScore(player, SCORE_BONUS_HONOR, battleground->GetBonusHonorFromKill(1));
+ }
+ }
+ }
+
+ if (rewardHonor)
+ MakeObjectsInteractable(gate->LineOfDefense);
+
+ UpdateWorldState(gate->WorldState, gateState);
+ battlegroundMap->UpdateSpawnGroupConditions();
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+
+ void OnUnitKilled(Creature* victim, Unit* killer) override
+ {
+ if (victim->GetEntry() == NPC_DEMOLISHER_SA)
+ {
+ if (Player* killerPlayer = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
+ battleground->UpdatePvpStat(killerPlayer, PVP_STAT_DEMOLISHERS_DESTROYED, 1);
+ int32 worldStateId = _attackers == TEAM_HORDE ? BG_SA_DESTROYED_HORDE_VEHICLES : BG_SA_DESTROYED_ALLIANCE_VEHICLES;
+ int32 currentDestroyedVehicles = sWorldStateMgr->GetValue(worldStateId, battlegroundMap);
+ UpdateWorldState(worldStateId, currentDestroyedVehicles + 1);
+ }
+ }
+
+ void CaptureGraveyard(StrandOfTheAncientsGraveyard graveyard, TeamId teamId)
+ {
+ switch (graveyard)
+ {
+ case StrandOfTheAncientsGraveyard::West:
+ UpdateWorldState(BG_SA_LEFT_GY_ALLIANCE, teamId == TEAM_ALLIANCE);
+ UpdateWorldState(BG_SA_LEFT_GY_HORDE, teamId == TEAM_HORDE);
+ break;
+ case StrandOfTheAncientsGraveyard::East:
+ UpdateWorldState(BG_SA_RIGHT_GY_ALLIANCE, teamId == TEAM_ALLIANCE);
+ UpdateWorldState(BG_SA_RIGHT_GY_HORDE, teamId == TEAM_HORDE);
+ break;
+ case StrandOfTheAncientsGraveyard::Central:
+ UpdateWorldState(BG_SA_CENTER_GY_ALLIANCE, teamId == TEAM_ALLIANCE);
+ UpdateWorldState(BG_SA_CENTER_GY_HORDE, teamId == TEAM_HORDE);
+
+ CaptureGraveyard(StrandOfTheAncientsGraveyard::East, teamId);
+ CaptureGraveyard(StrandOfTheAncientsGraveyard::West, teamId);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void TitanRelicActivated(Player const* clicker)
+ {
+ if (!clicker)
+ return;
+
+ TeamId const clickerTeamId = Battleground::GetTeamIndexByTeamId(battleground->GetPlayerTeam(clicker->GetGUID()));
+ if (clickerTeamId == _attackers)
+ {
+ if (clickerTeamId == TEAM_ALLIANCE)
+ battleground->SendBroadcastText(BG_SA_TEXT_ALLIANCE_CAPTURED_TITAN_PORTAL, CHAT_MSG_BG_SYSTEM_ALLIANCE);
+ else
+ battleground->SendBroadcastText(BG_SA_TEXT_HORDE_CAPTURED_TITAN_PORTAL, CHAT_MSG_BG_SYSTEM_HORDE);
+
+ if (_status == BG_SA_ROUND_ONE)
+ {
+ EndRound();
+ // Achievement Storm the Beach (1310)
+ for (auto itr = battleground->GetPlayers().begin(); itr != battleground->GetPlayers().end(); ++itr)
+ {
+ if (Player* player = ObjectAccessor::FindPlayer(itr->first))
+ if (Battleground::GetTeamIndexByTeamId(battleground->GetPlayerTeam(player->GetGUID())) == _attackers)
+ player->UpdateCriteria(CriteriaType::BeSpellTarget, 65246);
+ }
+
+ if (Creature* c = FindKanrethad())
+ battleground->SendChatMessage(c, TEXT_ROUND_1_FINISHED);
+ }
+ else if (_status == BG_SA_ROUND_TWO)
+ {
+ _roundScores[1].winner = _attackers;
+ _roundScores[1].time = _totalTime;
+ ToggleTimer();
+ // Achievement Storm the Beach (1310)
+ for (auto itr = battleground->GetPlayers().begin(); itr != battleground->GetPlayers().end(); ++itr)
+ {
+ if (Player* player = ObjectAccessor::FindPlayer(itr->first))
+ if (Battleground::GetTeamIndexByTeamId(battleground->GetPlayerTeam(player->GetGUID())) == _attackers && _roundScores[1].winner == _attackers)
+ player->UpdateCriteria(CriteriaType::BeSpellTarget, 65246);
+ }
+
+ if (_roundScores[0].time == _roundScores[1].time)
+ battleground->EndBattleground(TEAM_OTHER);
+ else if (_roundScores[0].time < _roundScores[1].time)
+ battleground->EndBattleground(_roundScores[0].winner == TEAM_ALLIANCE ? ALLIANCE : HORDE);
+ else
+ battleground->EndBattleground(_roundScores[1].winner == TEAM_ALLIANCE ? ALLIANCE : HORDE);
+ }
+ }
+ }
+
+ void ToggleTimer()
+ {
+ _timerEnabled = !_timerEnabled;
+ UpdateWorldState(BG_SA_ENABLE_TIMER, _timerEnabled);
+ }
+
+ void OnEnd(Team winner) override
+ {
+ BattlegroundScript::OnEnd(winner);
+
+ // honor reward for winning
+ if (winner == ALLIANCE)
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), ALLIANCE);
+ else if (winner == HORDE)
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), HORDE);
+
+ // complete map_end rewards (even if no team wins)
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(2), ALLIANCE);
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(2), HORDE);
+ }
+
+ void SendTransportInit(Player* player) const
+ {
+ for (ObjectGuid const& boatGuid : _boatGUIDs[_attackers])
+ if (GameObject* boat = battlegroundMap->GetGameObject(boatGuid))
+ boat->SendUpdateToPlayer(player);
+ }
+
+ bool IsGateDestroyed(GateInfo const* gateInfo) const
+ {
+ if (!gateInfo)
+ return false;
+
+ int32 value = battlegroundMap->GetWorldStateValue(gateInfo->WorldState);
+ return value == BG_SA_ALLIANCE_GATE_DESTROYED || value == BG_SA_HORDE_GATE_DESTROYED;
+ }
+
+ void HandleCaptureGraveyardAction(GameObject const* graveyardBanner, Player const* player)
+ {
+ if (!graveyardBanner || !player)
+ return;
+
+ TeamId const teamId = Battleground::GetTeamIndexByTeamId(battleground->GetPlayerTeam(player->GetGUID()));
+ // Only attackers can capture graveyard by gameobject action
+ if (teamId != _attackers)
+ return;
+
+ switch (graveyardBanner->GetEntry())
+ {
+ case GO_GRAVEYARD_WEST_A:
+ case GO_GRAVEYARD_WEST_H:
+ CaptureGraveyard(StrandOfTheAncientsGraveyard::West, teamId);
+ break;
+ case GO_GRAVEYARD_EAST_A:
+ case GO_GRAVEYARD_EAST_H:
+ CaptureGraveyard(StrandOfTheAncientsGraveyard::East, teamId);
+ break;
+ case GO_GRAVEYARD_CENTRAL_A:
+ case GO_GRAVEYARD_CENTRAL_H:
+ CaptureGraveyard(StrandOfTheAncientsGraveyard::Central, teamId);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void MakeObjectsInteractable(DefenseLine defenseLine) const
+ {
+ auto makeInteractable = [&](ObjectGuid const& guid) -> void
+ {
+ if (GameObject* gameObject = battlegroundMap->GetGameObject(guid))
+ gameObject->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
+ };
+
+ switch (defenseLine)
+ {
+ case DefenseLine::First:
+ makeInteractable(_graveyardWest);
+ makeInteractable(_graveyardEast);
+ break;
+ case DefenseLine::Second:
+ makeInteractable(_graveyardCentral);
+ break;
+ case DefenseLine::Third:
+ break;
+ case DefenseLine::Last:
+ // make titan orb interactable
+ if (GameObject* door = battlegroundMap->GetGameObject(_collisionDoorGUID))
+ door->UseDoorOrButton();
+
+ makeInteractable(_titanRelicGUID);
+ break;
+ default:
+ break;
+ }
+ }
+
+ Creature* FindKanrethad() const
+ {
+ return battlegroundMap->GetCreature(_kanrethadGUID);
+ }
+
+ void EndRound()
+ {
+ _roundScores[0].winner = _attackers;
+ _roundScores[0].time = std::min<uint32>(_totalTime, BG_SA_ROUNDLENGTH);
+
+ _attackers = (_attackers == TEAM_ALLIANCE) ? TEAM_HORDE : TEAM_ALLIANCE;
+ _status = BG_SA_SECOND_WARMUP;
+ _totalTime = 0;
+ ToggleTimer();
+
+ _updateWaitTimer = 5000;
+ _signaledRoundTwo = false;
+ _signaledRoundTwoHalfMin = false;
+ _initSecondRound = true;
+ ResetObjs();
+ battlegroundMap->UpdateAreaDependentAuras();
+
+ battleground->CastSpellOnTeam(SPELL_END_OF_ROUND, ALLIANCE);
+ battleground->CastSpellOnTeam(SPELL_END_OF_ROUND, HORDE);
+
+ battleground->RemoveAuraOnTeam(SPELL_CARRYING_SEAFORIUM_CHARGE, HORDE);
+ battleground->RemoveAuraOnTeam(SPELL_CARRYING_SEAFORIUM_CHARGE, ALLIANCE);
+ }
+
+ void OnGameObjectCreate(GameObject* gameobject) override
+ {
+ BattlegroundScript::OnGameObjectCreate(gameobject);
+
+ if (gameobject->GetGoType() == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
+ _gateGUIDs.insert(gameobject->GetGUID());
+
+ switch (gameobject->GetEntry())
+ {
+ case BG_SA_BOAT_ONE_A:
+ _boatGUIDs[TEAM_ALLIANCE][0] = gameobject->GetGUID();
+ break;
+ case BG_SA_BOAT_TWO_A:
+ _boatGUIDs[TEAM_ALLIANCE][1] = gameobject->GetGUID();
+ break;
+ case BG_SA_BOAT_ONE_H:
+ _boatGUIDs[TEAM_HORDE][0] = gameobject->GetGUID();
+ break;
+ case BG_SA_BOAT_TWO_H:
+ _boatGUIDs[TEAM_HORDE][1] = gameobject->GetGUID();
+ break;
+ case GO_SEAFORIUM_BOMB_A:
+ _staticBombGUIDs[TEAM_ALLIANCE].insert(gameobject->GetGUID());
+ if (_status != BG_SA_SECOND_WARMUP && _status != BG_SA_WARMUP)
+ gameobject->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
+ break;
+ case GO_SEAFORIUM_BOMB_H:
+ _staticBombGUIDs[TEAM_HORDE].insert(gameobject->GetGUID());
+ if (_status != BG_SA_SECOND_WARMUP && _status != BG_SA_WARMUP)
+ gameobject->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
+ break;
+ case GO_SEAFORIUM_CHARGE_A:
+ case GO_SEAFORIUM_CHARGE_H:
+ _dynamicBombGUIDs.insert(gameobject->GetGUID());
+ break;
+ case GO_GRAVEYARD_EAST_A:
+ case GO_GRAVEYARD_EAST_H:
+ _graveyardEast = gameobject->GetGUID();
+ break;
+ case GO_GRAVEYARD_WEST_A:
+ case GO_GRAVEYARD_WEST_H:
+ _graveyardWest = gameobject->GetGUID();
+ break;
+ case GO_GRAVEYARD_CENTRAL_A:
+ case GO_GRAVEYARD_CENTRAL_H:
+ _graveyardCentral = gameobject->GetGUID();
+ break;
+ case GO_COLLISION_DOOR:
+ _collisionDoorGUID = gameobject->GetGUID();
+ break;
+ case GO_TITAN_RELIC_A:
+ case GO_TITAN_RELIC_H:
+ _titanRelicGUID = gameobject->GetGUID();
+ break;
+ default:
+ break;
+ }
+ }
+
+ void DoAction(uint32 actionId, WorldObject* source, WorldObject* target) override
+ {
+ BattlegroundScript::DoAction(actionId, source, target);
+
+ switch (actionId)
+ {
+ case ACTION_SOTA_CAPTURE_GRAVEYARD:
+ HandleCaptureGraveyardAction(Object::ToGameObject(target), Object::ToPlayer(source));
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnCreatureCreate(Creature* creature) override
+ {
+ BattlegroundScript::OnCreatureCreate(creature);
+ switch (creature->GetEntry())
+ {
+ case NPC_DEMOLISHER:
+ creature->SetFaction(BG_SA_Factions[_attackers]);
+ break;
+ case NPC_ANTIPERSONNEL_CANNON:
+ creature->SetFaction(BG_SA_Factions[_attackers == TEAM_HORDE ? TEAM_ALLIANCE : TEAM_HORDE]);
+ break;
+ case NPC_KANRETHAD:
+ _kanrethadGUID = creature->GetGUID();
+ break;
+ case NPC_RIGGER_SPARKLIGHT:
+ case NPC_GORGRIL_RIGSPARK:
+ creature->AI()->Talk(TEXT_SPARKLIGHT_RIGSPARK_SPAWN);
+ break;
+ default:
+ break;
+ }
+ }
+
+ uint32 GetData(uint32 dataId) const override
+ {
+ switch (dataId)
+ {
+ case DATA_ATTACKERS:
+ return _attackers;
+ case DATA_STATUS:
+ return _status;
+ default:
+ return BattlegroundScript::GetData(dataId);
+ }
+ }
+
+ static GateInfo const* GetGate(uint32 entry)
+ {
+ for (GateInfo const& gate : Gates)
+ if (gate.GameObjectId == entry)
+ return &gate;
+
+ return nullptr;
+ }
+
+private:
+ /// Id of attacker team
+ TeamId _attackers;
+
+ /// Totale elapsed time of current round
+ uint32 _totalTime;
+ /// Max time of round
+ uint32 _endRoundTimer;
+ /// For know if boats has start moving or not yet
+ bool _shipsStarted;
+ /// Statu of battle (Start or not, and what round)
+ BG_SA_Status _status;
+ /// Score of each round
+ std::array<BG_SA_RoundScore, 2> _roundScores;
+ /// used for know we are in timer phase or not (used for worldstate update)
+ bool _timerEnabled;
+ /// 5secs before starting the 1min countdown for second round
+ uint32 _updateWaitTimer;
+ /// for know if warning about second round start has been sent
+ bool _signaledRoundTwo;
+ /// for know if warning about second round start has been sent
+ bool _signaledRoundTwoHalfMin;
+ /// for know if second round has been init
+ bool _initSecondRound;
+
+ // [team][boat_idx]
+ std::array<std::array<ObjectGuid, 2 /*BOAT_COUNT*/>, PVP_TEAMS_COUNT> _boatGUIDs;
+ std::array<GuidUnorderedSet, PVP_TEAMS_COUNT> _staticBombGUIDs; // bombs ready to be picked up
+ GuidUnorderedSet _dynamicBombGUIDs; // bombs thrown by players, ready to explode/disarm
+
+ ObjectGuid _graveyardWest;
+ ObjectGuid _graveyardEast;
+ ObjectGuid _graveyardCentral;
+ GuidUnorderedSet _gateGUIDs;
+ ObjectGuid _collisionDoorGUID;
+ ObjectGuid _kanrethadGUID;
+ ObjectGuid _titanRelicGUID;
+};
+
+void AddSC_battleground_strand_of_the_ancients()
+{
+ RegisterBattlegroundMapScript(battleground_strand_of_the_ancients, 607);
+}
diff --git a/src/server/scripts/Northrend/StrandOfTheAncients/strand_of_the_ancients.cpp b/src/server/scripts/Battlegrounds/StrandOfTheAncients/strand_of_the_ancients.cpp
index ed268327760..0ad0c7381e2 100644
--- a/src/server/scripts/Northrend/StrandOfTheAncients/strand_of_the_ancients.cpp
+++ b/src/server/scripts/Battlegrounds/StrandOfTheAncients/strand_of_the_ancients.cpp
@@ -15,8 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "strand_of_the_ancients.h"
#include "ScriptMgr.h"
-#include "BattlegroundSA.h"
#include "GameObject.h"
#include "GameObjectAI.h"
#include "Player.h"
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundTP.cpp b/src/server/scripts/Battlegrounds/StrandOfTheAncients/strand_of_the_ancients.h
index 8cbdd141c5d..4d86099136d 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundTP.cpp
+++ b/src/server/scripts/Battlegrounds/StrandOfTheAncients/strand_of_the_ancients.h
@@ -15,12 +15,12 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "BattlegroundTP.h"
+#ifndef TRINITYCORE_STRAND_OF_THE_ANCIENTS_H
+#define TRINITYCORE_STRAND_OF_THE_ANCIENTS_H
-BattlegroundTP::BattlegroundTP(BattlegroundTemplate const* battlegroundTemplate) : Battleground(battlegroundTemplate)
+enum StrandOfTheAncientSharedActions
{
-}
+ ACTION_SOTA_CAPTURE_GRAVEYARD
+};
-BattlegroundTP::~BattlegroundTP()
-{
-}
+#endif
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundBFG.h b/src/server/scripts/Battlegrounds/TwinPeaks/battleground_twin_peaks.cpp
index 58210788737..73f8db98aab 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundBFG.h
+++ b/src/server/scripts/Battlegrounds/TwinPeaks/battleground_twin_peaks.cpp
@@ -15,22 +15,21 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef __BATTLEGROUNDBFG_H
-#define __BATTLEGROUNDBFG_H
+#include "BattlegroundScript.h"
+#include "ScriptMgr.h"
-#include "Battleground.h"
-
-enum BG_BFG_Objectives
+struct battleground_twin_peaks : BattlegroundScript
{
- BFG_OBJECTIVE_BASES_ASSAULTED = 370,
- BFG_OBJECTIVE_BASES_DEFENDED = 371
-};
+ enum PvpStats : uint32
+ {
+ BG_TP_FLAG_CAPTURES = 290,
+ BG_TP_FLAG_RETURNS = 291
+ };
-class BattlegroundBFG : public Battleground
-{
- public:
- BattlegroundBFG(BattlegroundTemplate const* battlegroundTemplate);
- ~BattlegroundBFG();
+ explicit battleground_twin_peaks(BattlegroundMap* map) : BattlegroundScript(map) { }
};
-#endif
+void AddSC_battleground_twin_peaks()
+{
+ RegisterBattlegroundMapScript(battleground_twin_peaks, 726);
+}
diff --git a/src/server/scripts/Battlegrounds/WarsongGulch/battleground_warsong_gulch.cpp b/src/server/scripts/Battlegrounds/WarsongGulch/battleground_warsong_gulch.cpp
new file mode 100644
index 00000000000..be76b69abf1
--- /dev/null
+++ b/src/server/scripts/Battlegrounds/WarsongGulch/battleground_warsong_gulch.cpp
@@ -0,0 +1,608 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "AreaTrigger.h"
+#include "BattlegroundScript.h"
+#include "Battleground.h"
+#include "BattlegroundMgr.h"
+#include "GameObject.h"
+#include "GameTime.h"
+#include "Map.h"
+#include "ObjectAccessor.h"
+#include "Player.h"
+#include "ScriptMgr.h"
+#include "SpellAuras.h"
+#include "Timer.h"
+
+struct battleground_warsong_gulch : BattlegroundScript
+{
+ static constexpr Seconds FLAG_ASSAULT_TIMER = 30s;
+
+ enum Misc
+ {
+ MAX_TEAM_SCORE = 3,
+ FLAG_BRUTAL_ASSAULT_STACK_COUNT = 5
+ };
+
+ enum Spells : uint32
+ {
+ SPELL_FOCUSED_ASSAULT = 46392,
+ SPELL_BRUTAL_ASSAULT = 46393,
+ SPELL_CAPTURED_ALLIANCE_COSMETIC_FX = 262508,
+ SPELL_CAPTURED_HORDE_COSMETIC_FX = 262512,
+ SPELL_WARSONG_FLAG = 23333,
+ SPELL_WARSONG_FLAG_DROPPED = 23334,
+ SPELL_SILVERWING_FLAG = 23335,
+ SPELL_SILVERWING_FLAG_DROPPED = 23336,
+ SPELL_QUICK_CAP_TIMER = 183317,
+ };
+
+ enum AreaTriggers : uint32
+ {
+ AT_CAPTURE_POINT_ALLIANCE = 30,
+ AT_CAPTURE_POINT_HORDE = 31
+ };
+
+ enum Events : uint32
+ {
+ EVENT_START_BATTLE = 35912
+ };
+
+ enum PvpStats : uint32
+ {
+ PVP_STAT_FLAG_CAPTURES = 928,
+ PVP_STAT_FLAG_RETURNS = 929
+ };
+
+ enum WorldStates : int32
+ {
+ WORLD_STATE_FLAG_STATE_ALLIANCE = 1545,
+ WORLD_STATE_FLAG_STATE_HORDE = 1546,
+ WORLD_STATE_FLAG_STATE_NEUTRAL = 1547,
+ WORLD_STATE_HORDE_FLAG_COUNT_PICKED_UP = 17712,
+ WORLD_STATE_ALLIANCE_FLAG_COUNT_PICKED_UP = 17713,
+ WORLD_STATE_FLAG_CAPTURES_ALLIANCE = 1581,
+ WORLD_STATE_FLAG_CAPTURES_HORDE = 1582,
+ WORLD_STATE_FLAG_CAPTURES_MAX = 1601,
+ WORLD_STATE_FLAG_CAPTURES_MAX_NEW = 17303,
+ WORLD_STATE_FLAG_CONTROL_HORDE = 2338,
+ WORLD_STATE_FLAG_CONTROL_ALLIANCE = 2339,
+ WORLD_STATE_STATE_TIMER = 4248,
+ WORLD_STATE_STATE_TIMER_ACTIVE = 4247
+ };
+
+ enum Texts
+ {
+ TEXT_START_ONE_MINUTE = 10015,
+ TEXT_START_HALF_MINUTE = 10016,
+ TEXT_BATTLE_HAS_BEGUN = 10014,
+ TEXT_CAPTURED_HORDE_FLAG = 9801,
+ TEXT_CAPTURED_ALLIANCE_FLAG = 9802,
+ TEXT_FLAGS_PLACED = 9803,
+ TEXT_ALLIANCE_FLAG_PICKED_UP = 9804,
+ TEXT_ALLIANCE_FLAG_DROPPED = 9805,
+ TEXT_HORDE_FLAG_PICKED_UP = 9807,
+ TEXT_HORDE_FLAG_DROPPED = 9806,
+ TEXT_ALLIANCE_FLAG_RETURNED = 9808,
+ TEXT_HORDE_FLAG_RETURNED = 9809
+ };
+
+ enum Sounds
+ {
+ SOUND_FLAG_CAPTURED_ALLIANCE = 8173,
+ SOUND_FLAG_CAPTURED_HORDE = 8213,
+ SOUND_FLAG_PLACED = 8232,
+ SOUND_FLAG_RETURNED = 8192,
+ SOUND_HORDE_FLAG_PICKED_UP = 8212,
+ SOUND_ALLIANCE_FLAG_PICKED_UP = 8174,
+ SOUND_FLAGS_RESPAWNED = 8232
+ };
+
+ enum GameObjects
+ {
+ OBJECT_ALLIANCE_DOOR = 309704,
+ OBJECT_PORTCULLIS_009 = 309705,
+ OBJECT_PORTCULLIS_002 = 309883,
+ OBJECT_COLLISION_PC_SIZE = 242273,
+ OBJECT_HORDE_GATE_1 = 352709,
+ OBJECT_HORDE_GATE_2 = 352710,
+ OBJECT_ALLIANCE_FLAG_IN_BASE = 227741,
+ OBJECT_HORDE_FLAG_IN_BASE = 227740
+ };
+
+ static constexpr std::array<std::array<uint32, 3>, 2> HONOR_REWARDS =
+ {{
+ { 20, 40, 40 },
+ { 60, 40, 80 }
+ }};
+
+ explicit battleground_warsong_gulch(BattlegroundMap* map) : BattlegroundScript(map), _lastFlagCaptureTeam(TEAM_OTHER), _bothFlagsKept(false), _flags({ }), _assaultStackCount(0), _capturePointAreaTriggers({ })
+ {
+ _flagAssaultTimer.Reset(FLAG_ASSAULT_TIMER);
+
+ if (sBattlegroundMgr->IsBGWeekend(battleground->GetTypeID()))
+ {
+ _reputationCapture = 45;
+ _honorWinKills = 3;
+ _honorEndKills = 4;
+ }
+ else
+ {
+ _reputationCapture = 35;
+ _honorWinKills = 1;
+ _honorEndKills = 2;
+ }
+ }
+
+ void OnUpdate(uint32 diff) override
+ {
+ BattlegroundScript::OnUpdate(diff);
+
+ if (battleground->GetStatus() == STATUS_IN_PROGRESS)
+ {
+ if (battleground->GetElapsedTime() >= 17 * MINUTE * IN_MILLISECONDS)
+ {
+ if (battleground->GetTeamScore(TEAM_ALLIANCE) == 0)
+ {
+ if (battleground->GetTeamScore(TEAM_HORDE) == 0) // No one scored - result is tie
+ battleground->EndBattleground(TEAM_OTHER);
+ else // Horde has more points and thus wins
+ battleground->EndBattleground(HORDE);
+ }
+ else if (battleground->GetTeamScore(TEAM_HORDE) == 0) // Alliance has > 0, Horde has 0, alliance wins
+ battleground->EndBattleground(ALLIANCE);
+ else if (battleground->GetTeamScore(TEAM_HORDE) == battleground->GetTeamScore(TEAM_ALLIANCE)) // Team score equal, winner is team that scored the last flag
+ battleground->EndBattleground(_lastFlagCaptureTeam);
+ else if (battleground->GetTeamScore(TEAM_HORDE) > battleground->GetTeamScore(TEAM_ALLIANCE)) // Last but not least, check who has the higher score
+ battleground->EndBattleground(HORDE);
+ else
+ battleground->EndBattleground(ALLIANCE);
+ }
+ }
+
+ if (_bothFlagsKept)
+ {
+ _flagAssaultTimer.Update(diff);
+ if (_flagAssaultTimer.Passed())
+ {
+ _flagAssaultTimer.Reset(FLAG_ASSAULT_TIMER);
+ if (_assaultStackCount < std::numeric_limits<uint8>::max())
+ {
+ _assaultStackCount++;
+
+ // update assault debuff stacks
+ DoForFlagKeepers([&](Player* player) -> void
+ {
+ ApplyAssaultDebuffToPlayer(player);
+ });
+ }
+ }
+ }
+ }
+
+ void OnStart() override
+ {
+ BattlegroundScript::OnStart();
+ for (ObjectGuid door : _doors)
+ {
+ if (GameObject* gameObject = battlegroundMap->GetGameObject(door))
+ {
+ gameObject->UseDoorOrButton();
+ gameObject->DespawnOrUnsummon(3s);
+ }
+ }
+
+ UpdateWorldState(WORLD_STATE_STATE_TIMER_ACTIVE, 1);
+ UpdateWorldState(WORLD_STATE_STATE_TIMER, std::chrono::system_clock::to_time_t(GameTime::GetSystemTime() + 15min));
+
+ // players joining later are not eligibles
+ TriggerGameEvent(EVENT_START_BATTLE);
+ }
+
+ void OnEnd(Team winner) override
+ {
+ BattlegroundScript::OnEnd(winner);
+ // Win reward
+ if (winner == ALLIANCE)
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(_honorWinKills), ALLIANCE);
+ if (winner == HORDE)
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(_honorWinKills), HORDE);
+
+ // Complete map_end rewards (even if no team wins)
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(_honorEndKills), ALLIANCE);
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(_honorEndKills), HORDE);
+ }
+
+ void DoForFlagKeepers(std::function<void(Player*)> const& action) const
+ {
+ for (ObjectGuid flagGUID : _flags)
+ if (GameObject const* flag = battlegroundMap->GetGameObject(flagGUID))
+ if (Player* carrier = ObjectAccessor::FindPlayer(flag->GetFlagCarrierGUID()))
+ action(carrier);
+ }
+
+ void ResetAssaultDebuff()
+ {
+ _bothFlagsKept = false;
+ _assaultStackCount = 0;
+ _flagAssaultTimer.Reset(FLAG_ASSAULT_TIMER);
+ DoForFlagKeepers([&](Player* player) -> void
+ {
+ RemoveAssaultDebuffFromPlayer(player);
+ });
+ }
+
+ void ApplyAssaultDebuffToPlayer(Player* player) const
+ {
+ if (_assaultStackCount == 0)
+ return;
+
+ uint32 spellId = SPELL_FOCUSED_ASSAULT;
+ if (_assaultStackCount >= FLAG_BRUTAL_ASSAULT_STACK_COUNT)
+ {
+ player->RemoveAurasDueToSpell(SPELL_FOCUSED_ASSAULT);
+ spellId = SPELL_BRUTAL_ASSAULT;
+ }
+
+ Aura* aura = player->GetAura(spellId);
+ if (!aura)
+ {
+ player->CastSpell(player, spellId, true);
+ aura = player->GetAura(spellId);
+ }
+
+ if (aura)
+ aura->SetStackAmount(_assaultStackCount);
+ }
+
+ void RemoveAssaultDebuffFromPlayer(Player* player) const
+ {
+ player->RemoveAurasDueToSpell(SPELL_FOCUSED_ASSAULT);
+ player->RemoveAurasDueToSpell(SPELL_BRUTAL_ASSAULT);
+ }
+
+ FlagState GetFlagState(TeamId team) const
+ {
+ if (GameObject const* flag = battlegroundMap->GetGameObject(_flags[team]))
+ return flag->GetFlagState();
+
+ return FlagState(0);
+ }
+
+ ObjectGuid const& GetFlagCarrierGUID(TeamId team) const
+ {
+ if (GameObject const* flag = battlegroundMap->GetGameObject(_flags[team]))
+ return flag->GetFlagCarrierGUID();
+
+ return ObjectGuid::Empty;
+ }
+
+ void HandleFlagRoomCapturePoint()
+ {
+ DoForFlagKeepers([&](Player* player) -> void
+ {
+ TeamId const team = Battleground::GetTeamIndexByTeamId(battleground->GetPlayerTeam(player->GetGUID()));
+ if (AreaTrigger* trigger = battlegroundMap->GetAreaTrigger(_capturePointAreaTriggers[team]))
+ if (trigger->GetInsideUnits().contains(player->GetGUID()))
+ if (CanCaptureFlag(trigger, player))
+ OnCaptureFlag(trigger, player);
+ });
+ }
+
+ void UpdateFlagState(uint32 team, FlagState value) const
+ {
+ auto transformValueToOtherTeamControlWorldState = [](FlagState state)
+ {
+ switch (state)
+ {
+ case FlagState::InBase:
+ case FlagState::Dropped:
+ case FlagState::Respawning:
+ return 1;
+ case FlagState::Taken:
+ return 2;
+ default:
+ return 0;
+ }
+ };
+
+ if (team == ALLIANCE)
+ {
+ UpdateWorldState(WORLD_STATE_FLAG_STATE_ALLIANCE, AsUnderlyingType(value));
+ UpdateWorldState(WORLD_STATE_FLAG_CONTROL_HORDE, transformValueToOtherTeamControlWorldState(value));
+ }
+ else
+ {
+ UpdateWorldState(WORLD_STATE_FLAG_STATE_HORDE, AsUnderlyingType(value));
+ UpdateWorldState(WORLD_STATE_FLAG_CONTROL_ALLIANCE, transformValueToOtherTeamControlWorldState(value));
+ }
+ }
+
+ void UpdateTeamScore(TeamId team) const
+ {
+ if (team == TEAM_ALLIANCE)
+ UpdateWorldState(WORLD_STATE_FLAG_CAPTURES_ALLIANCE, battleground->GetTeamScore(team));
+ else
+ UpdateWorldState(WORLD_STATE_FLAG_CAPTURES_HORDE, battleground->GetTeamScore(team));
+ }
+
+ void OnGameObjectCreate(GameObject* gameObject) override
+ {
+ BattlegroundScript::OnGameObjectCreate(gameObject);
+ switch (gameObject->GetEntry())
+ {
+ case OBJECT_ALLIANCE_DOOR:
+ case OBJECT_PORTCULLIS_009:
+ case OBJECT_PORTCULLIS_002:
+ case OBJECT_COLLISION_PC_SIZE:
+ case OBJECT_HORDE_GATE_1:
+ case OBJECT_HORDE_GATE_2:
+ _doors.insert(gameObject->GetGUID());
+ break;
+ case OBJECT_ALLIANCE_FLAG_IN_BASE:
+ _flags[TEAM_ALLIANCE] = gameObject->GetGUID();
+ break;
+ case OBJECT_HORDE_FLAG_IN_BASE:
+ _flags[TEAM_HORDE] = gameObject->GetGUID();
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnAreaTriggerCreate(AreaTrigger* areaTrigger) override
+ {
+ BattlegroundScript::OnAreaTriggerCreate(areaTrigger);
+ if (!areaTrigger->IsStaticSpawn())
+ return;
+
+ switch (areaTrigger->GetEntry())
+ {
+ case AT_CAPTURE_POINT_ALLIANCE:
+ _capturePointAreaTriggers[TEAM_ALLIANCE] = areaTrigger->GetGUID();
+ break;
+ case AT_CAPTURE_POINT_HORDE:
+ _capturePointAreaTriggers[TEAM_HORDE] = areaTrigger->GetGUID();
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnFlagStateChange(GameObject* flagInBase, FlagState oldValue, FlagState newValue, Player* player) override
+ {
+ BattlegroundScript::OnFlagStateChange(flagInBase, oldValue, newValue, player);
+
+ Team const team = flagInBase->GetEntry() == OBJECT_HORDE_FLAG_IN_BASE ? HORDE : ALLIANCE;
+ TeamId const otherTeamId = Battleground::GetTeamIndexByTeamId(GetOtherTeam(team));
+
+ UpdateFlagState(team, newValue);
+
+ switch (newValue)
+ {
+ case FlagState::InBase:
+ {
+ if (battleground->GetStatus() == STATUS_IN_PROGRESS)
+ {
+ ResetAssaultDebuff();
+ if (player)
+ {
+ // flag got returned to base by player interaction
+ battleground->UpdatePvpStat(player, PVP_STAT_FLAG_RETURNS, 1); // +1 flag returns
+
+ if (team == ALLIANCE)
+ {
+ battleground->SendBroadcastText(TEXT_ALLIANCE_FLAG_RETURNED, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ battleground->PlaySoundToAll(SOUND_FLAG_RETURNED);
+ }
+ else
+ {
+ battleground->SendBroadcastText(TEXT_HORDE_FLAG_RETURNED, CHAT_MSG_BG_SYSTEM_HORDE, player);
+ battleground->PlaySoundToAll(SOUND_FLAG_RETURNED);
+ }
+ }
+ // Flag respawned due to timeout/capture
+ else if (GetFlagState(otherTeamId) != FlagState::Respawning)
+ {
+ // if other flag is respawning, we will let that one handle the message and sound to prevent double message/sound.
+ battleground->SendBroadcastText(TEXT_FLAGS_PLACED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
+ battleground->PlaySoundToAll(SOUND_FLAGS_RESPAWNED);
+ }
+
+ HandleFlagRoomCapturePoint();
+ }
+ break;
+ }
+ case FlagState::Dropped:
+ {
+ player->RemoveAurasDueToSpell(SPELL_QUICK_CAP_TIMER);
+ RemoveAssaultDebuffFromPlayer(player);
+
+ uint32 recentlyDroppedSpellId = SPELL_RECENTLY_DROPPED_HORDE_FLAG;
+ if (team == ALLIANCE)
+ {
+ recentlyDroppedSpellId = SPELL_RECENTLY_DROPPED_ALLIANCE_FLAG;
+ battleground->SendBroadcastText(TEXT_ALLIANCE_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ }
+ else
+ battleground->SendBroadcastText(TEXT_HORDE_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_HORDE, player);
+
+ player->CastSpell(player, recentlyDroppedSpellId, true);
+ break;
+ }
+ case FlagState::Taken:
+ {
+ if (team == HORDE)
+ {
+ battleground->SendBroadcastText(TEXT_HORDE_FLAG_PICKED_UP, CHAT_MSG_BG_SYSTEM_HORDE, player);
+ battleground->PlaySoundToAll(SOUND_HORDE_FLAG_PICKED_UP);
+ }
+ else
+ {
+ battleground->SendBroadcastText(TEXT_ALLIANCE_FLAG_PICKED_UP, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ battleground->PlaySoundToAll(SOUND_ALLIANCE_FLAG_PICKED_UP);
+ }
+
+ if (GetFlagState(otherTeamId) == FlagState::Taken)
+ _bothFlagsKept = true;
+
+ ApplyAssaultDebuffToPlayer(player);
+
+ flagInBase->CastSpell(player, SPELL_QUICK_CAP_TIMER, true);
+ player->StartCriteria(CriteriaStartEvent::BeSpellTarget, SPELL_QUICK_CAP_TIMER, Seconds(GameTime::GetGameTime() - flagInBase->GetFlagTakenFromBaseTime()));
+ break;
+ }
+ case FlagState::Respawning:
+ ResetAssaultDebuff();
+ break;
+ default:
+ break;
+ }
+ }
+
+ bool CanCaptureFlag(AreaTrigger* areaTrigger, Player* player) override
+ {
+ if (battleground->GetStatus() != STATUS_IN_PROGRESS)
+ return false;
+
+ Team const team = battleground->GetPlayerTeam(player->GetGUID());
+ TeamId const teamId = Battleground::GetTeamIndexByTeamId(team);
+ TeamId const otherTeamId = Battleground::GetTeamIndexByTeamId(GetOtherTeam(team));
+
+ if (areaTrigger->GetGUID() != _capturePointAreaTriggers[teamId])
+ return false;
+
+ // check if enemy flag's carrier is this player
+ if (GetFlagCarrierGUID(otherTeamId) != player->GetGUID())
+ return false;
+
+ // check that team's flag is in base
+ return GetFlagState(teamId) == FlagState::InBase;
+ }
+
+ void OnCaptureFlag(AreaTrigger* areaTrigger, Player* player) override
+ {
+ BattlegroundScript::OnCaptureFlag(areaTrigger, player);
+
+ Team winner = TEAM_OTHER;
+
+ Team const team = battleground->GetPlayerTeam(player->GetGUID());
+ TeamId const teamId = Battleground::GetTeamIndexByTeamId(team);
+ TeamId const otherTeamId = Battleground::GetTeamIndexByTeamId(GetOtherTeam(team));
+
+ /*
+ 1. Update flag states & score world states
+ 2. update points
+ 3. chat message & sound
+ 4. update criterias & achievements
+ 5. remove all related auras
+ ?. Reward honor & reputation
+ */
+
+ // 1. update the flag states
+ for (ObjectGuid const& flagGuid: _flags)
+ if (GameObject const* flag = battlegroundMap->GetGameObject(flagGuid))
+ flag->HandleCustomTypeCommand(GameObjectType::SetNewFlagState(FlagState::Respawning, player));
+
+ // 2. update points
+ if (battleground->GetTeamScore(teamId) < MAX_TEAM_SCORE)
+ battleground->AddPoint(team, 1);
+
+ UpdateTeamScore(teamId);
+
+ // 3. chat message & sound
+ if (team == ALLIANCE)
+ {
+ battleground->SendBroadcastText(TEXT_CAPTURED_HORDE_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, player);
+ battleground->PlaySoundToAll(SOUND_FLAG_CAPTURED_ALLIANCE);
+ battleground->RewardReputationToTeam(890, _reputationCapture, ALLIANCE);
+ player->CastSpell(player, SPELL_CAPTURED_ALLIANCE_COSMETIC_FX);
+ }
+ else
+ {
+ battleground->SendBroadcastText(TEXT_CAPTURED_ALLIANCE_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ battleground->PlaySoundToAll(SOUND_FLAG_CAPTURED_HORDE);
+ battleground->RewardReputationToTeam(889, _reputationCapture, HORDE);
+ player->CastSpell(player, SPELL_CAPTURED_HORDE_COSMETIC_FX);
+ }
+
+ // 4. update criteria's for achievement, player score etc.
+ battleground->UpdatePvpStat(player, PVP_STAT_FLAG_CAPTURES, 1); // +1 flag captures
+
+ // 5. Remove all related auras
+ RemoveAssaultDebuffFromPlayer(player);
+
+ if (GameObject const* flag = battlegroundMap->GetGameObject(_flags[otherTeamId]))
+ player->RemoveAurasDueToSpell(flag->GetGOInfo()->newflag.pickupSpell, flag->GetGUID());
+
+ player->RemoveAurasDueToSpell(SPELL_QUICK_CAP_TIMER);
+
+ player->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::PvPActive);
+
+ battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(2), team);
+
+ // update last flag capture to be used if teamscore is equal
+ SetLastFlagCapture(team);
+
+ if (battleground->GetTeamScore(teamId) == MAX_TEAM_SCORE)
+ winner = team;
+
+ if (winner)
+ {
+ UpdateWorldState(WORLD_STATE_FLAG_STATE_ALLIANCE, 1);
+ UpdateWorldState(WORLD_STATE_FLAG_STATE_HORDE, 1);
+ UpdateWorldState(WORLD_STATE_STATE_TIMER_ACTIVE, 0);
+
+ battleground->RewardHonorToTeam(HONOR_REWARDS[BattlegroundMgr::IsBGWeekend(battleground->GetTypeID()) ? 1 : 0][0], winner);
+ battleground->EndBattleground(winner);
+ }
+ }
+
+ Team GetPrematureWinner() override
+ {
+ if (battleground->GetTeamScore(TEAM_ALLIANCE) > battleground->GetTeamScore(TEAM_HORDE))
+ return ALLIANCE;
+ if (battleground->GetTeamScore(TEAM_HORDE) > battleground->GetTeamScore(TEAM_ALLIANCE))
+ return HORDE;
+
+ return BattlegroundScript::GetPrematureWinner();
+ }
+
+ void SetLastFlagCapture(Team team)
+ {
+ _lastFlagCaptureTeam = team;
+ }
+
+private:
+ Team _lastFlagCaptureTeam;
+ bool _bothFlagsKept;
+ GuidSet _doors;
+ std::array<ObjectGuid, PVP_TEAMS_COUNT> _flags;
+
+ TimeTracker _flagAssaultTimer;
+ uint8 _assaultStackCount;
+ std::array<ObjectGuid, PVP_TEAMS_COUNT> _capturePointAreaTriggers;
+
+ uint32 _honorWinKills;
+ uint32 _honorEndKills;
+ uint32 _reputationCapture;
+};
+
+void AddSC_battleground_warsong_gulch()
+{
+ RegisterBattlegroundMapScript(battleground_warsong_gulch, 2106);
+}
diff --git a/src/server/scripts/Battlegrounds/battlegrounds_script_loader.cpp b/src/server/scripts/Battlegrounds/battlegrounds_script_loader.cpp
new file mode 100644
index 00000000000..da8062fee38
--- /dev/null
+++ b/src/server/scripts/Battlegrounds/battlegrounds_script_loader.cpp
@@ -0,0 +1,95 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// This is where scripts' loading functions should be declared:
+// Alterac Valley
+void AddSC_alterac_valley();
+void AddSC_boss_balinda();
+void AddSC_boss_drekthar();
+void AddSC_boss_galvangar();
+void AddSC_boss_vanndar();
+void AddSC_battleground_alterac_valley();
+
+// Arathi Basin
+void AddSC_arathi_basin();
+void AddSC_battleground_arathi_basin();
+
+// Eye of the storm
+void AddSC_battleground_eye_of_the_storm();
+
+// Warsong Gulch
+void AddSC_battleground_warsong_gulch();
+
+// Isle of Conquest
+void AddSC_battleground_isle_of_conquest();
+void AddSC_isle_of_conquest();
+void AddSC_boss_ioc_horde_alliance();
+
+// Strand of the Ancients
+void AddSC_battleground_strand_of_the_ancients();
+void AddSC_strand_of_the_ancients();
+
+// Blade's Edge Arena
+void AddSC_arena_blades_edge();
+void AddSC_arena_dalaran_sewers();
+void AddSC_arena_nagrand();
+void AddSC_arena_ruins_of_lordaeron();
+void AddSC_arena_ring_of_valor();
+
+void AddSC_battleground_twin_peaks();
+void AddSC_battleground_battle_for_gilneas();
+
+// The name of this function should match:
+// void Add${NameOfDirectory}Scripts()
+void AddBattlegroundsScripts()
+{
+ // Alterac Valley
+ AddSC_alterac_valley();
+ AddSC_boss_balinda();
+ AddSC_boss_drekthar();
+ AddSC_boss_galvangar();
+ AddSC_boss_vanndar();
+ AddSC_battleground_alterac_valley();
+
+ // Arathi Basin
+ AddSC_arathi_basin();
+ AddSC_battleground_arathi_basin();
+
+ // Eye of the Storm
+ AddSC_battleground_eye_of_the_storm();
+
+ // Warsong Gulch
+ AddSC_battleground_warsong_gulch();
+
+ // Isle of Conquest
+ AddSC_battleground_isle_of_conquest();
+ AddSC_isle_of_conquest();
+ AddSC_boss_ioc_horde_alliance();
+
+ // Strand of the Ancients
+ AddSC_battleground_strand_of_the_ancients();
+ AddSC_strand_of_the_ancients();
+
+ AddSC_arena_blades_edge();
+ AddSC_arena_dalaran_sewers();
+ AddSC_arena_nagrand();
+ AddSC_arena_ruins_of_lordaeron();
+ AddSC_arena_ring_of_valor();
+
+ AddSC_battleground_twin_peaks();
+ AddSC_battleground_battle_for_gilneas();
+}
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index d03dd7b96cb..7f4468dbdb9 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -1418,15 +1418,11 @@ public:
if (linked)
{
- if (Battleground* bg = player->GetBattleground())
- nearestLoc = bg->GetClosestGraveyard(player);
+
+ if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetMap(), player->GetZoneId()))
+ nearestLoc = bf->GetClosestGraveyard(player);
else
- {
- if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetMap(), player->GetZoneId()))
- nearestLoc = bf->GetClosestGraveyard(player);
- else
- nearestLoc = sObjectMgr->GetClosestGraveyard(*player, player->GetTeam(), player);
- }
+ nearestLoc = sObjectMgr->GetClosestGraveyard(*player, player->GetTeam(), player);
}
else
{
diff --git a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp
index 673f1e9bfad..b818c1e6f10 100644
--- a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp
+++ b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp
@@ -16,12 +16,6 @@
*/
// This is where scripts' loading functions should be declared:
-void AddSC_alterac_valley(); //Alterac Valley
-void AddSC_boss_balinda();
-void AddSC_boss_drekthar();
-void AddSC_boss_galvangar();
-void AddSC_boss_vanndar();
-void AddSC_arathi_basin(); //Arathi Basin
void AddSC_boss_alizabal(); //Baradin Hold
void AddSC_boss_occuthar();
void AddSC_boss_argaloth();
@@ -211,12 +205,6 @@ void AddSC_undercity();
// void Add${NameOfDirectory}Scripts()
void AddEasternKingdomsScripts()
{
- AddSC_alterac_valley(); //Alterac Valley
- AddSC_boss_balinda();
- AddSC_boss_drekthar();
- AddSC_boss_galvangar();
- AddSC_boss_vanndar();
- AddSC_arathi_basin(); //Arathi Basin
AddSC_boss_alizabal(); //Baradin Hold
AddSC_boss_occuthar();
AddSC_boss_argaloth();
diff --git a/src/server/scripts/Northrend/northrend_script_loader.cpp b/src/server/scripts/Northrend/northrend_script_loader.cpp
index fe2514d804e..639aa223fa8 100644
--- a/src/server/scripts/Northrend/northrend_script_loader.cpp
+++ b/src/server/scripts/Northrend/northrend_script_loader.cpp
@@ -194,9 +194,6 @@ void AddSC_boss_baltharus_the_warborn();
void AddSC_boss_saviana_ragefire();
void AddSC_boss_general_zarithrian();
void AddSC_boss_halion();
-// Isle of Conquest
-void AddSC_isle_of_conquest();
-void AddSC_boss_ioc_horde_alliance();
void AddSC_dalaran();
void AddSC_borean_tundra();
@@ -210,8 +207,6 @@ void AddSC_wintergrasp();
void AddSC_zuldrak();
void AddSC_crystalsong_forest();
-void AddSC_strand_of_the_ancients();
-
// The name of this function should match:
// void Add${NameOfDirectory}Scripts()
void AddNorthrendScripts()
@@ -394,9 +389,6 @@ void AddNorthrendScripts()
AddSC_boss_saviana_ragefire();
AddSC_boss_general_zarithrian();
AddSC_boss_halion();
- // Isle of Conquest
- AddSC_isle_of_conquest();
- AddSC_boss_ioc_horde_alliance();
AddSC_dalaran();
AddSC_borean_tundra();
@@ -408,6 +400,4 @@ void AddNorthrendScripts()
AddSC_storm_peaks();
AddSC_wintergrasp();
AddSC_zuldrak();
-
- AddSC_strand_of_the_ancients();
}
diff --git a/src/server/scripts/Northrend/zone_dalaran.cpp b/src/server/scripts/Northrend/zone_dalaran.cpp
index 46460521b6b..92fc14b2c64 100644
--- a/src/server/scripts/Northrend/zone_dalaran.cpp
+++ b/src/server/scripts/Northrend/zone_dalaran.cpp
@@ -24,7 +24,6 @@ SDCategory: Dalaran
Script Data End */
#include "ScriptMgr.h"
-#include "BattlegroundDS.h"
#include "Containers.h"
#include "DatabaseEnv.h"
#include "Mail.h"
@@ -254,44 +253,8 @@ private:
EventMap events;
};
-class at_ds_pipe_knockback : public AreaTriggerScript
-{
-public:
- at_ds_pipe_knockback() : AreaTriggerScript("at_ds_pipe_knockback") { }
-
- void Trigger(Player* player) const
- {
- if (Battleground* battleground = player->GetBattleground())
- {
- if (battleground->GetStatus() != STATUS_IN_PROGRESS)
- return;
-
- // Remove effects of Demonic Circle Summon
- player->RemoveAurasDueToSpell(SPELL_WARL_DEMONIC_CIRCLE);
-
- // Someone has get back into the pipes and the knockback has already been performed,
- // so we reset the knockback count for kicking the player again into the arena.
- if (battleground->GetData(BG_DS_DATA_PIPE_KNOCKBACK_COUNT) >= BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT)
- battleground->SetData(BG_DS_DATA_PIPE_KNOCKBACK_COUNT, 0);
- }
- }
-
- bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/) override
- {
- Trigger(player);
- return true;
- }
-
- bool OnExit(Player* player, AreaTriggerEntry const* /*trigger*/) override
- {
- Trigger(player);
- return true;
- }
-};
-
void AddSC_dalaran()
{
RegisterCreatureAI(npc_mageguard_dalaran);
RegisterCreatureAI(npc_minigob_manabonk);
- new at_ds_pipe_knockback();
}
diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp
index 828523e0bf3..f0c1e460815 100644
--- a/src/server/scripts/Spells/spell_item.cpp
+++ b/src/server/scripts/Spells/spell_item.cpp
@@ -3081,9 +3081,6 @@ class spell_item_rocket_boots : public SpellScript
void HandleDummy(SpellEffIndex /* effIndex */)
{
Player* caster = GetCaster()->ToPlayer();
- if (Battleground* bg = caster->GetBattleground())
- bg->EventPlayerDroppedFlag(caster);
-
caster->GetSpellHistory()->ResetCooldown(SPELL_ROCKET_BOOTS_PROC);
caster->CastSpell(caster, SPELL_ROCKET_BOOTS_PROC, true);
}