aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorJeremy <Golrag@users.noreply.github.com>2025-02-01 01:58:23 +0100
committerGitHub <noreply@github.com>2025-02-01 01:58:23 +0100
commit5b83fec88e30a93fbc3179009cefda9a7b34ee01 (patch)
treebcbb72406f470044c99006a8de8c6ccb4ac08cd2 /src/server
parentdbd761d20a1b2343ffd8bb778185a649e551b48a (diff)
Scripts/Battlegrounds: Implement Deephaul Ravine (#30393)
Diffstat (limited to 'src/server')
-rw-r--r--src/server/game/Maps/Map.cpp2
-rw-r--r--src/server/game/Maps/MapManager.cpp3
-rw-r--r--src/server/game/Miscellaneous/Language.h6
-rw-r--r--src/server/scripts/Battlegrounds/DeephaulRavine/battleground_deephaul_ravine.cpp1109
-rw-r--r--src/server/scripts/Battlegrounds/battlegrounds_script_loader.cpp3
5 files changed, 1120 insertions, 3 deletions
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 49f41bf7856..4f7bf3a1338 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -3416,8 +3416,6 @@ void BattlegroundMap::InitScriptData()
else
_battlegroundScript = std::make_unique<BattlegroundScript>(this);
}
-
- _battlegroundScript->OnInit();
}
TransferAbortParams BattlegroundMap::CannotEnter(Player* player)
diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp
index f3fefda4c94..4332c5a52e2 100644
--- a/src/server/game/Maps/MapManager.cpp
+++ b/src/server/game/Maps/MapManager.cpp
@@ -18,6 +18,7 @@
#include "MapManager.h"
#include "BattlefieldMgr.h"
#include "Battleground.h"
+#include "BattlegroundScript.h"
#include "CharacterCache.h"
#include "Containers.h"
#include "DatabaseEnv.h"
@@ -33,6 +34,7 @@
#include "ScriptMgr.h"
#include "World.h"
#include "WorldStateMgr.h"
+
#include <boost/dynamic_bitset.hpp>
#include <numeric>
@@ -131,6 +133,7 @@ BattlegroundMap* MapManager::CreateBattleground(uint32 mapId, uint32 instanceId,
bg->SetBgMap(map);
map->InitScriptData();
map->InitSpawnGroupState();
+ map->GetBattlegroundScript()->OnInit();
if (sWorld->getBoolConfig(CONFIG_BATTLEGROUNDMAP_LOAD_GRIDS))
map->LoadAllCells();
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index bc6c15d525b..389b5930b99 100644
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -1211,7 +1211,11 @@ enum TrinityStrings
LANG_OPVP_ZM_GOSSIP_ALLIANCE = 10054,
LANG_OPVP_ZM_GOSSIP_HORDE = 10055,
- // 10056-10066 - free
+ // Deephaul Ravine
+ LANG_BG_DR_CRYSTAL_TAKEN = 10056,
+ LANG_BG_DR_CRYSTAL_TAKEN_TUTORIAL = 10057,
+
+ // 10058-10066 - free
// Use for custom patches 11000-11999
LANG_AUTO_BROADCAST = 11000,
diff --git a/src/server/scripts/Battlegrounds/DeephaulRavine/battleground_deephaul_ravine.cpp b/src/server/scripts/Battlegrounds/DeephaulRavine/battleground_deephaul_ravine.cpp
new file mode 100644
index 00000000000..663a6170963
--- /dev/null
+++ b/src/server/scripts/Battlegrounds/DeephaulRavine/battleground_deephaul_ravine.cpp
@@ -0,0 +1,1109 @@
+/*
+ * 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 "AreaTriggerAI.h"
+#include "Battleground.h"
+#include "BattlegroundScript.h"
+#include "GameObject.h"
+#include "Language.h"
+#include "Map.h"
+#include "MotionMaster.h"
+#include "ObjectAccessor.h"
+#include "Player.h"
+#include "ScriptedCreature.h"
+#include "ScriptMgr.h"
+#include "SpellScript.h"
+#include "TaskScheduler.h"
+#include "TemporarySummon.h"
+#include "Vehicle.h"
+
+namespace DeephaulRavine
+{
+ namespace Actions
+ {
+ static constexpr uint32 CaptureMineCart = 1;
+ static constexpr uint32 ConsumeBuff = 2;
+ static constexpr uint32 AllianceCartAppearedInitial = 3;
+ static constexpr uint32 HordeCartAppearedInitial = 4;
+ static constexpr uint32 CommanderStartIntro = 5;
+ }
+
+ namespace AreaTriggers
+ {
+ static constexpr uint32 CapturePointAlliance = 30;
+ static constexpr uint32 CapturePointHorde = 31;
+
+ static constexpr uint32 RuneOfFrequency = 33926;
+ static constexpr uint32 BerserkerBuff = 21077;
+ static constexpr uint32 HealingBuff = 21076;
+ }
+
+ namespace BroadcastTexts
+ {
+ static constexpr uint32 CrystalCapturedAlliance = 18375;
+ static constexpr uint32 CrystalCapturedHorde = 18384;
+
+ static constexpr uint32 AllianceControlMineCart = 60441; // copied from Silvershard Mines
+ static constexpr uint32 HordeControlMineCart = 60442; // copied from Silvershard Mines
+
+ static constexpr uint32 AllianceCaptureMineCart = 59689; // copied from Silvershard Mines
+ static constexpr uint32 HordeCaptureMineCart = 59690; // copied from Silvershard Mines
+
+ static constexpr uint32 FlagDropped = 18361;
+ }
+
+ namespace Creatures
+ {
+ static constexpr uint32 MineCartEast = 214690;
+ static constexpr uint32 MineCartWest = 217346;
+ static constexpr uint32 GenericBunny = 214731;
+
+ static constexpr uint32 ForemanUzjax = 224086;
+ static constexpr uint32 Ruffious = 224087;
+
+ static constexpr uint32 EarthenMineCartHorde = 211155;
+ static constexpr uint32 EarthenMineCartAlliance = 211271;
+ }
+
+ namespace CreatureTexts
+ {
+ static constexpr uint8 Intro1 = 0;
+ static constexpr uint8 Intro2 = 1;
+ static constexpr uint8 CrystalSpawn = 2;
+ static constexpr uint8 CartSpawn = 3;
+ static constexpr uint8 Lost = 4;
+ static constexpr uint8 Win = 5;
+ }
+
+ namespace Events
+ {
+ static constexpr uint32 ProgressEventHordeWest = 88514;
+ static constexpr uint32 ProgressEventAllianceWest = 88515;
+ static constexpr uint32 ProgressEventHordeEast = 88510;
+ static constexpr uint32 ProgressEventAllianceEast = 88511;
+
+ static constexpr uint32 BattlegroundStarted = 35912;
+ }
+
+ namespace GameObjects
+ {
+ static constexpr uint32 DeephaulCrystal = 422413; // Flag
+
+ static constexpr uint32 EarthenworksStartingGateX = 437274;
+ static constexpr uint32 WaterworksStartingGateX = 446147;
+ }
+
+ namespace PathIds
+ {
+ static constexpr int32 EastCart = 214690 * 100;
+ static constexpr int32 WestCart = 217346 * 100;
+
+ namespace Ruffious
+ {
+ static constexpr uint32 Path1 = 224087 * 100;
+ static constexpr uint32 Path2 = 224087 * 100 + 1;
+ static constexpr uint32 Path3 = 224087 * 100 + 2;
+ static constexpr uint32 Path4 = 224087 * 100 + 3;
+ }
+
+ namespace ForemanUzjax
+ {
+ static constexpr uint32 Path1 = 224086 * 100;
+ static constexpr uint32 Path2 = 224086 * 100 + 1;
+ static constexpr uint32 Path3 = 224086 * 100 + 2;
+ static constexpr uint32 Path4 = 224086 * 100 + 3;
+ }
+ }
+
+ namespace Positions
+ {
+ static constexpr Position WestMineCartSpawn = { 4250.3647f, -2751.066f, 239.46973f, static_cast<float>(M_PI) };
+ static constexpr Position EastMineCartSpawn = { 3875.0f, -3150.0f, 240.2913f, 0.0f };
+
+ static constexpr std::array<Position, 5> EarthenMineCartsHorde =
+ {{
+ { 4179.265625f, -2788.0712890625f, 240.7358856201171875f, 4.05515289306640625f },
+ { 4163.166015625f, -2809.192626953125f, 240.86444091796875f, 4.05515289306640625f },
+ { 4171.251953125f, -2798.54345703125f, 240.8136138916015625f, 4.05515289306640625f },
+ { 4175.2255859375f, -2793.239501953125f, 240.7935028076171875f, 4.091466903686523437f },
+ { 4167.109375f, -2803.795166015625f, 240.978973388671875f, 4.05515289306640625f }
+ }};
+
+ static constexpr std::array<Position, 5> EarthenMineCartsAlliance =
+ {{
+ { 3949.052978515625f, -3106.71875f, 240.960845947265625f, 4.05515289306640625f },
+ { 3961.213623046875f, -3090.671875f, 241.0115814208984375f, 4.05515289306640625f },
+ { 3957.064208984375f, -3095.954833984375f, 240.8014068603515625f, 4.05515289306640625f },
+ { 3965.46875f, -3084.96533203125f, 240.85400390625f, 4.068012237548828125f },
+ { 3953.146728515625f, -3101.30029296875f, 240.928680419921875f, 4.05515289306640625f },
+ }};
+ }
+
+ namespace PvpStats
+ {
+ static constexpr int32 FlagCaptures = 1020;
+ static constexpr int32 CartsControlled = 1021;
+ }
+
+ namespace Sounds
+ {
+ static constexpr uint32 PvpFlagTakenAlliance = 8174;
+ static constexpr uint32 PvpFlagTakenHorde = 8212;
+ static constexpr uint32 PvpFlagCapturedAlliance = 8173;
+ static constexpr uint32 PvpFlagCapturedHorde = 8213;
+ }
+
+ namespace Spells
+ {
+ static constexpr uint32 DeephaulCrystal = 434339;
+
+ static constexpr uint32 ControlVisualHorde = 430220;
+ static constexpr uint32 ControlVisualNeutral = 430178;
+ static constexpr uint32 ControlVisualAlliance = 430221;
+
+ static constexpr uint32 CartControlCapturePointUnitEast = 430211;
+ static constexpr uint32 CartControlCapturePointUnitWest = 430216;
+
+ static constexpr uint32 CartCap = 430207;
+
+ static constexpr uint32 DefendingCartAura = 128646;
+
+ static constexpr uint32 Restoration = 296575;
+ static constexpr uint32 Berserking = 296576;
+ static constexpr uint32 RuneOfFrequency = 422968;
+
+ static constexpr uint32 CartExhaustion = 456466;
+
+ static constexpr uint32 RecentlyDroppedFlag = 50327;
+ }
+
+ namespace WorldStates
+ {
+ static constexpr int32 FlagEnabled = 25412; // when this is 3, the flag is spawned
+
+ static constexpr int32 HordeTeamScore = 24959;
+ static constexpr int32 AllianceTeamScore = 24958;
+
+ static constexpr int32 MaxTeamScore = 24960;
+
+ static constexpr int32 BattleBegun = 7852;
+
+ static constexpr int32 AllianceControlsEastMineCart = 25415;
+ static constexpr int32 HordeControlsEastMineCart = 25414;
+
+ static constexpr int32 AllianceControlsWestMineCart = 25421;
+ static constexpr int32 HordeControlsWestMineCart = 25420;
+
+ static constexpr std::array<int32, 2> AllianceControlWorldStates = { AllianceControlsEastMineCart, AllianceControlsWestMineCart };
+ static constexpr std::array<int32, 2> HordeControlWorldStates = { HordeControlsEastMineCart, HordeControlsWestMineCart };
+
+ /*
+ * 1; on reset; dropped
+ * 2; when taken
+ */
+ static constexpr int32 HordeFlagState = 1546;
+ /*
+ * 1; on reset; dropped
+ * 2; when taken
+ */
+ static constexpr int32 AllianceFlagState = 1545;
+
+ // WSE: 12385, "(WorldState(6954) + WorldState(6955)) == 1")
+ // values might be swapped, they are not send to client
+ // See SilvershardMines
+ static constexpr int32 AllianceCapturedCart = 6954;
+ static constexpr int32 HordeCapturedCart = 6955;
+
+ namespace Values
+ {
+ static constexpr int32 FlagClaimed = 2; // On Player
+ static constexpr int32 FlagUnclaimed = 1; // Not on player (in base, dropped, respawning)
+ }
+ }
+}
+
+struct battleground_deephaul_ravine : BattlegroundScript
+{
+ explicit battleground_deephaul_ravine(BattlegroundMap* map) : BattlegroundScript(map), _cartsReached(0), _cartGUIDs({ }), _capturePointAreaTriggers({ }), _leaderGUIDs({ }) { }
+
+ void OnInit() override
+ {
+ BattlegroundScript::OnInit();
+
+ for (Position const& pos : DeephaulRavine::Positions::EarthenMineCartsHorde)
+ battlegroundMap->SummonCreature(DeephaulRavine::Creatures::EarthenMineCartHorde, pos);
+
+ for (Position const& pos : DeephaulRavine::Positions::EarthenMineCartsAlliance)
+ battlegroundMap->SummonCreature(DeephaulRavine::Creatures::EarthenMineCartAlliance, pos);
+ }
+
+ void OnStart() override
+ {
+ BattlegroundScript::OnStart();
+ _scheduler.Schedule(15s, [&](TaskContext)
+ {
+ UpdateWorldState(DeephaulRavine::WorldStates::FlagEnabled, 3);
+ });
+
+ UpdateWorldState(DeephaulRavine::WorldStates::BattleBegun, 1);
+
+ _scheduler.Schedule(2s, [&](TaskContext context)
+ {
+ uint32 const underAllianceControl = std::ranges::count_if(DeephaulRavine::WorldStates::AllianceControlWorldStates, [&](int32 worldState)
+ {
+ return battlegroundMap->GetWorldStateValue(worldState) == 1;
+ });
+
+ uint32 const underHordeControl = std::ranges::count_if(DeephaulRavine::WorldStates::HordeControlWorldStates, [&](int32 worldState)
+ {
+ return battlegroundMap->GetWorldStateValue(worldState) == 1;
+ });
+
+ int32 const maxTeamScore = battlegroundMap->GetWorldStateValue(DeephaulRavine::WorldStates::MaxTeamScore);
+
+ uint32 const hordeScoreToAdd = std::min<uint32>(maxTeamScore - battleground->GetTeamScore(TEAM_HORDE), underHordeControl * 3);
+ uint32 const allianceScoreToAdd = std::min<uint32>(maxTeamScore - battleground->GetTeamScore(TEAM_ALLIANCE), underAllianceControl * 3);
+
+ battleground->AddPoint(HORDE, hordeScoreToAdd);
+ battleground->AddPoint(ALLIANCE, allianceScoreToAdd);
+
+ SendTeamScores();
+
+ if (!CheckWinner())
+ context.Repeat();
+ });
+
+ _scheduler.Schedule(5s, [&](TaskContext context)
+ {
+ RespawnEarthenMineCarts();
+ context.Repeat();
+ });
+
+ for (ObjectGuid const& guid : _doorGUIDs)
+ {
+ if (GameObject* gameobject = battlegroundMap->GetGameObject(guid))
+ {
+ gameobject->UseDoorOrButton();
+ gameobject->DespawnOrUnsummon(3s);
+ }
+ }
+
+ TriggerGameEvent(DeephaulRavine::Events::BattlegroundStarted);
+ }
+
+ void OnPrepareStage3() override
+ {
+ BattlegroundScript::OnPrepareStage3();
+
+ _scheduler.Schedule(2s, [&](TaskContext)
+ {
+ SpawnMineCarts();
+ });
+
+ _scheduler.Schedule(15s, [&](TaskContext)
+ {
+ DoForLeaders([&](Creature const* creature)
+ {
+ creature->AI()->DoAction(DeephaulRavine::Actions::CommanderStartIntro);
+ });
+ });
+ }
+
+ void OnUpdate(uint32 diff) override
+ {
+ BattlegroundScript::OnUpdate(diff);
+ _scheduler.Update(diff);
+ }
+
+ void OnGameObjectCreate(GameObject* gameobject) override
+ {
+ BattlegroundScript::OnGameObjectCreate(gameobject);
+
+ switch (gameobject->GetEntry())
+ {
+ case DeephaulRavine::GameObjects::DeephaulCrystal:
+ _flagGUID = gameobject->GetGUID();
+ break;
+ case DeephaulRavine::GameObjects::WaterworksStartingGateX:
+ case DeephaulRavine::GameObjects::EarthenworksStartingGateX:
+ _doorGUIDs.emplace_back(gameobject->GetGUID());
+ break;
+ default:
+ break;
+ }
+ }
+
+ bool CanCaptureFlag(AreaTrigger* areaTrigger, Player* player) override
+ {
+ Team const team = battleground->GetPlayerTeam(player->GetGUID());
+ TeamId const teamId = Battleground::GetTeamIndexByTeamId(team);
+
+ if (areaTrigger->GetGUID() != _capturePointAreaTriggers[teamId])
+ return false;
+
+ if (GameObject const* flag = battlegroundMap->GetGameObject(_flagGUID))
+ return player->GetGUID() == flag->GetFlagCarrierGUID();
+
+ return false;
+ }
+
+ void OnCaptureFlag(AreaTrigger* areaTrigger, Player* player) override
+ {
+ BattlegroundScript::OnCaptureFlag(areaTrigger, player);
+
+ if (GameObject const* gameObject = battlegroundMap->GetGameObject(_flagGUID))
+ gameObject->HandleCustomTypeCommand(GameObjectType::SetNewFlagState(FlagState::Respawning, player));
+
+ player->RemoveAurasDueToSpell(DeephaulRavine::Spells::DeephaulCrystal);
+ battleground->UpdatePvpStat(player, DeephaulRavine::PvpStats::FlagCaptures, 1);
+
+ battleground->AddPoint(player->GetBGTeam(), 100);
+ if (player->GetBGTeam() == ALLIANCE)
+ {
+ battleground->SendBroadcastText(DeephaulRavine::BroadcastTexts::CrystalCapturedAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ battleground->PlaySoundToAll(DeephaulRavine::Sounds::PvpFlagCapturedAlliance);
+ }
+ else if (player->GetBGTeam() == HORDE)
+ {
+ battleground->SendBroadcastText(DeephaulRavine::BroadcastTexts::CrystalCapturedHorde, CHAT_MSG_BG_SYSTEM_HORDE, player);
+ battleground->PlaySoundToAll(DeephaulRavine::Sounds::PvpFlagCapturedHorde);
+ }
+ }
+
+ void OnFlagStateChange(GameObject* flagInBase, FlagState oldValue, FlagState newValue, Player* player) override
+ {
+ BattlegroundScript::OnFlagStateChange(flagInBase, oldValue, newValue, player);
+
+ switch (newValue)
+ {
+ case FlagState::Taken:
+ battleground->SendMessageToAll(LANG_BG_DR_CRYSTAL_TAKEN, player->GetBGTeam() == HORDE ? CHAT_MSG_BG_SYSTEM_HORDE : CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ battleground->SendMessageToAll(LANG_BG_DR_CRYSTAL_TAKEN_TUTORIAL, CHAT_MSG_RAID_BOSS_EMOTE, player); // player should also be the sender
+ battleground->PlaySoundToAll(player->GetBGTeam() == HORDE ? DeephaulRavine::Sounds::PvpFlagTakenHorde : DeephaulRavine::Sounds::PvpFlagTakenAlliance);
+ UpdateWorldState(DeephaulRavine::WorldStates::HordeFlagState, player->GetBGTeam() == HORDE ? DeephaulRavine::WorldStates::Values::FlagClaimed : DeephaulRavine::WorldStates::Values::FlagUnclaimed);
+ UpdateWorldState(DeephaulRavine::WorldStates::AllianceFlagState, player->GetBGTeam() == ALLIANCE ? DeephaulRavine::WorldStates::Values::FlagClaimed : DeephaulRavine::WorldStates::Values::FlagUnclaimed);
+ break;
+ case FlagState::Dropped:
+ if (player->GetBGTeam() == ALLIANCE)
+ battleground->SendBroadcastText(DeephaulRavine::BroadcastTexts::FlagDropped, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ else
+ battleground->SendBroadcastText(DeephaulRavine::BroadcastTexts::FlagDropped, CHAT_MSG_BG_SYSTEM_HORDE, player);
+ player->CastSpell(player, DeephaulRavine::Spells::RecentlyDroppedFlag, true);
+ UpdateWorldState(DeephaulRavine::WorldStates::HordeFlagState, DeephaulRavine::WorldStates::Values::FlagUnclaimed);
+ UpdateWorldState(DeephaulRavine::WorldStates::AllianceFlagState, DeephaulRavine::WorldStates::Values::FlagUnclaimed);
+ break;
+ case FlagState::Respawning:
+ UpdateWorldState(DeephaulRavine::WorldStates::HordeFlagState, DeephaulRavine::WorldStates::Values::FlagUnclaimed);
+ UpdateWorldState(DeephaulRavine::WorldStates::AllianceFlagState, DeephaulRavine::WorldStates::Values::FlagUnclaimed);
+
+ _scheduler.Schedule(Milliseconds(flagInBase->GetGOInfo()->newflag.RespawnTime) - 5s, [&](TaskContext)
+ {
+ DoForLeaders([&](Creature const* creature)
+ {
+ creature->AI()->Talk(DeephaulRavine::CreatureTexts::CrystalSpawn);
+ });
+ });
+ break;
+ case FlagState::InBase:
+ UpdateWorldState(DeephaulRavine::WorldStates::HordeFlagState, DeephaulRavine::WorldStates::Values::FlagUnclaimed);
+ UpdateWorldState(DeephaulRavine::WorldStates::AllianceFlagState, DeephaulRavine::WorldStates::Values::FlagUnclaimed);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void DoAction(uint32 actionId, WorldObject* source, WorldObject* target) override
+ {
+ BattlegroundScript::DoAction(actionId, source, target);
+
+ switch (actionId)
+ {
+ case DeephaulRavine::Actions::CaptureMineCart:
+ HandleMineCartCaptured();
+ break;
+ case DeephaulRavine::Actions::ConsumeBuff:
+ HandleConsumeBuff(Object::ToAreaTrigger(source), Object::ToPlayer(target));
+ break;
+ case DeephaulRavine::Actions::HordeCartAppearedInitial:
+ battleground->SendBroadcastText(DeephaulRavine::BroadcastTexts::HordeControlMineCart, CHAT_MSG_BG_SYSTEM_HORDE, source);
+ break;
+ case DeephaulRavine::Actions::AllianceCartAppearedInitial:
+ battleground->SendBroadcastText(DeephaulRavine::BroadcastTexts::AllianceControlMineCart, CHAT_MSG_BG_SYSTEM_ALLIANCE, source);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void HandleConsumeBuff(AreaTrigger* trigger, Player* player)
+ {
+ if (!trigger || !player)
+ return;
+
+ switch (trigger->GetCreateProperties()->Template->Id.Id)
+ {
+ case DeephaulRavine::AreaTriggers::BerserkerBuff:
+ player->CastSpell(player, DeephaulRavine::Spells::Berserking, true);
+ break;
+ case DeephaulRavine::AreaTriggers::RuneOfFrequency:
+ player->CastSpell(player, DeephaulRavine::Spells::RuneOfFrequency, true);
+ break;
+ case DeephaulRavine::AreaTriggers::HealingBuff:
+ player->CastSpell(player, DeephaulRavine::Spells::Restoration, true);
+ break;
+ default:
+ break;
+ }
+
+ AreaTriggerCreatePropertiesId const createPropertiesId = trigger->GetCreateProperties()->Id;
+ Position pos = trigger->GetPosition();
+
+ _scheduler.Schedule(90s, [&, createPropertiesId, pos](TaskContext)
+ {
+ if (Creature* genericBunny = battlegroundMap->GetCreature(_genericBunnyGUID))
+ AreaTrigger::CreateAreaTrigger(createPropertiesId, pos, -1, genericBunny, nullptr);
+ });
+
+ trigger->Remove();
+ }
+
+ void OnCreatureCreate(Creature* creature) override
+ {
+ BattlegroundScript::OnCreatureCreate(creature);
+
+ switch (creature->GetEntry())
+ {
+ case DeephaulRavine::Creatures::GenericBunny:
+ _genericBunnyGUID = creature->GetGUID();
+ break;
+ case DeephaulRavine::Creatures::ForemanUzjax:
+ _leaderGUIDs[TEAM_HORDE] = creature->GetGUID();
+ break;
+ case DeephaulRavine::Creatures::Ruffious:
+ _leaderGUIDs[TEAM_ALLIANCE] = creature->GetGUID();
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnCreatureRemove(Creature* creature) override
+ {
+ switch (creature->GetEntry())
+ {
+ case DeephaulRavine::Creatures::EarthenMineCartAlliance:
+ _allianceDespawnedMineCarts.push(creature->GetPosition());
+ break;
+ case DeephaulRavine::Creatures::EarthenMineCartHorde:
+ _hordeDespawnedMineCarts.push(creature->GetPosition());
+ break;
+ default:
+ break;
+ }
+ }
+
+ void ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* invoker) override
+ {
+ BattlegroundScript::ProcessEvent(obj, eventId, invoker);
+
+ switch (eventId)
+ {
+ case DeephaulRavine::Events::ProgressEventAllianceEast:
+ case DeephaulRavine::Events::ProgressEventAllianceWest:
+ HandleProgressEvent(Object::ToGameObject(invoker), ALLIANCE, DeephaulRavine::Spells::ControlVisualAlliance, DeephaulRavine::BroadcastTexts::AllianceControlMineCart, CHAT_MSG_BG_SYSTEM_ALLIANCE);
+ break;
+ case DeephaulRavine::Events::ProgressEventHordeEast:
+ case DeephaulRavine::Events::ProgressEventHordeWest:
+ HandleProgressEvent(Object::ToGameObject(invoker), HORDE, DeephaulRavine::Spells::ControlVisualHorde, DeephaulRavine::BroadcastTexts::HordeControlMineCart, CHAT_MSG_BG_SYSTEM_HORDE);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnAreaTriggerCreate(AreaTrigger* areaTrigger) override
+ {
+ BattlegroundScript::OnAreaTriggerCreate(areaTrigger);
+ if (!areaTrigger->IsStaticSpawn())
+ return;
+
+ switch (areaTrigger->GetEntry())
+ {
+ case DeephaulRavine::AreaTriggers::CapturePointAlliance:
+ _capturePointAreaTriggers[TEAM_ALLIANCE] = areaTrigger->GetGUID();
+ break;
+ case DeephaulRavine::AreaTriggers::CapturePointHorde:
+ _capturePointAreaTriggers[TEAM_HORDE] = areaTrigger->GetGUID();
+ break;
+ default:
+ break;
+ }
+ }
+
+ void HandleProgressEvent(GameObject const* controlZone, Team team, uint32 controlVisualSpell, uint32 textId, ChatMsg msgType) const
+ {
+ if (!controlZone)
+ return;
+
+ Creature* mineCart = Object::ToCreature(controlZone->GetOwner());
+ if (!mineCart)
+ return;
+
+ mineCart->RemoveAurasDueToSpell(DeephaulRavine::Spells::ControlVisualNeutral);
+ mineCart->RemoveAurasDueToSpell(DeephaulRavine::Spells::ControlVisualAlliance);
+ mineCart->RemoveAurasDueToSpell(DeephaulRavine::Spells::ControlVisualHorde);
+ mineCart->CastSpell(mineCart, controlVisualSpell, true);
+ UpdateCartWorldStates(controlZone);
+ battleground->SendBroadcastText(textId, msgType, controlZone);
+
+ for (ObjectGuid const& guid : *controlZone->GetInsidePlayers())
+ if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (player->GetBGTeam() == team)
+ battleground->UpdatePvpStat(player, DeephaulRavine::PvpStats::CartsControlled, 1);
+ }
+
+ void HandleMineCartCaptured()
+ {
+ _cartsReached++;
+ if (_cartsReached != 2)
+ return;
+
+ for (ObjectGuid const& cartGUID : _cartGUIDs)
+ {
+ if (Creature* creature = battlegroundMap->GetCreature(cartGUID))
+ {
+ GameObject* controlZone = nullptr;
+ if (creature->HasAura(DeephaulRavine::Spells::CartControlCapturePointUnitEast))
+ controlZone = creature->GetGameObject(DeephaulRavine::Spells::CartControlCapturePointUnitEast);
+ else if (creature->HasAura(DeephaulRavine::Spells::CartControlCapturePointUnitWest))
+ controlZone = creature->GetGameObject(DeephaulRavine::Spells::CartControlCapturePointUnitWest);
+
+ if (controlZone)
+ {
+ uint32 const scoreToAdd = std::min<uint32>(1500 - battleground->GetTeamScore(controlZone->GetControllingTeam()), 100);
+ if (controlZone->GetControllingTeam() == TEAM_HORDE)
+ {
+ if (battlegroundMap->GetWorldStateValue(DeephaulRavine::WorldStates::HordeCapturedCart) != 1)
+ UpdateWorldState(DeephaulRavine::WorldStates::HordeCapturedCart, 1, true);
+
+ battleground->SendBroadcastText(DeephaulRavine::BroadcastTexts::HordeCaptureMineCart, CHAT_MSG_BG_SYSTEM_HORDE, creature);
+ if (battleground->GetStatus() != STATUS_WAIT_LEAVE)
+ battleground->AddPoint(HORDE, scoreToAdd);
+ }
+ else if (controlZone->GetControllingTeam() == TEAM_ALLIANCE)
+ {
+ if (battlegroundMap->GetWorldStateValue(DeephaulRavine::WorldStates::AllianceCapturedCart) != 1)
+ UpdateWorldState(DeephaulRavine::WorldStates::AllianceCapturedCart, 1, true);
+
+ battleground->SendBroadcastText(DeephaulRavine::BroadcastTexts::AllianceCaptureMineCart, CHAT_MSG_BG_SYSTEM_ALLIANCE, creature);
+ if (battleground->GetStatus() != STATUS_WAIT_LEAVE)
+ battleground->AddPoint(ALLIANCE, scoreToAdd);
+ }
+ }
+
+ creature->DespawnOrUnsummon();
+ }
+ }
+
+ UpdateWorldState(DeephaulRavine::WorldStates::AllianceControlsWestMineCart, 0);
+ UpdateWorldState(DeephaulRavine::WorldStates::AllianceControlsEastMineCart, 0);
+ UpdateWorldState(DeephaulRavine::WorldStates::HordeControlsWestMineCart, 0);
+ UpdateWorldState(DeephaulRavine::WorldStates::HordeControlsEastMineCart, 0);
+
+ CheckWinner();
+
+ _scheduler.Schedule(2s, [&](TaskContext)
+ {
+ SpawnMineCarts();
+ });
+ }
+
+ void SpawnMineCarts()
+ {
+ _cartsReached = 0;
+
+ // both mine carts spawn with Neutral aura; while they are controlled by their faction, this gets overriden a few moments later
+ if (TempSummon* creature = battlegroundMap->SummonCreature(DeephaulRavine::Creatures::MineCartEast, DeephaulRavine::Positions::EastMineCartSpawn))
+ {
+ _cartGUIDs[0] = creature->GetGUID();
+
+ creature->CastSpell(creature, DeephaulRavine::Spells::CartControlCapturePointUnitEast, true);
+ creature->CastSpell(creature, DeephaulRavine::Spells::ControlVisualNeutral, true);
+ creature->CastSpell(creature, DeephaulRavine::Spells::DefendingCartAura, true);
+ creature->GetMotionMaster()->MovePath(DeephaulRavine::PathIds::EastCart, false);
+
+ UpdateWorldState(DeephaulRavine::WorldStates::AllianceControlsWestMineCart, 0);
+ UpdateWorldState(DeephaulRavine::WorldStates::AllianceControlsEastMineCart, 1);
+ }
+
+ if (TempSummon* creature = battlegroundMap->SummonCreature(DeephaulRavine::Creatures::MineCartWest, DeephaulRavine::Positions::WestMineCartSpawn))
+ {
+ _cartGUIDs[1] = creature->GetGUID();
+
+ creature->CastSpell(creature, DeephaulRavine::Spells::CartControlCapturePointUnitWest, true);
+ creature->CastSpell(creature, DeephaulRavine::Spells::ControlVisualNeutral, true);
+ creature->CastSpell(creature, DeephaulRavine::Spells::DefendingCartAura, true);
+ creature->GetMotionMaster()->MovePath(DeephaulRavine::PathIds::WestCart, false);
+
+ UpdateWorldState(DeephaulRavine::WorldStates::HordeControlsWestMineCart, 1);
+ UpdateWorldState(DeephaulRavine::WorldStates::HordeControlsEastMineCart, 0);
+ }
+
+ DoForLeaders([&](Creature const* creature)
+ {
+ creature->AI()->Talk(DeephaulRavine::CreatureTexts::CartSpawn);
+ });
+ }
+
+ void SendTeamScores() const
+ {
+ UpdateWorldState(DeephaulRavine::WorldStates::HordeTeamScore, battleground->GetTeamScore(TEAM_HORDE));
+ UpdateWorldState(DeephaulRavine::WorldStates::AllianceTeamScore, battleground->GetTeamScore(TEAM_ALLIANCE));
+ }
+
+ void UpdateCartWorldStates(GameObject const* controlZone) const
+ {
+ if (!controlZone)
+ return;
+
+ Creature const* creature = Object::ToCreature(controlZone->GetOwner());
+ if (!creature)
+ return;
+
+ TeamId const controllingTeam = controlZone->GetControllingTeam();
+
+ switch (creature->GetEntry())
+ {
+ case DeephaulRavine::Creatures::MineCartEast:
+ UpdateWorldState(DeephaulRavine::WorldStates::AllianceControlsEastMineCart, controllingTeam == TEAM_ALLIANCE);
+ UpdateWorldState(DeephaulRavine::WorldStates::HordeControlsEastMineCart, controllingTeam == TEAM_HORDE);
+ break;
+ case DeephaulRavine::Creatures::MineCartWest:
+ UpdateWorldState(DeephaulRavine::WorldStates::AllianceControlsWestMineCart, controllingTeam == TEAM_ALLIANCE);
+ UpdateWorldState(DeephaulRavine::WorldStates::HordeControlsWestMineCart, controllingTeam == TEAM_HORDE);
+ break;
+ default:
+ break;
+ }
+ }
+
+ bool CheckWinner() const
+ {
+ uint32 const hordeScore = battleground->GetTeamScore(TEAM_HORDE);
+ uint32 const allianceScore = battleground->GetTeamScore(TEAM_ALLIANCE);
+ uint32 const maxScore = static_cast<uint32>(battlegroundMap->GetWorldStateValue(DeephaulRavine::WorldStates::MaxTeamScore));
+
+ if (hordeScore >= maxScore || allianceScore >= maxScore)
+ {
+ SendTeamScores();
+
+ if (hordeScore >= maxScore && allianceScore >= maxScore)
+ {
+ battleground->EndBattleground(TEAM_OTHER);
+ return true;
+ }
+
+ if (hordeScore >= maxScore)
+ {
+ battleground->EndBattleground(HORDE);
+ if (Creature const* uzjax = battlegroundMap->GetCreature(_leaderGUIDs[TEAM_HORDE]))
+ uzjax->AI()->Talk(DeephaulRavine::CreatureTexts::Win);
+ if (Creature const* ruffious = battlegroundMap->GetCreature(_leaderGUIDs[TEAM_ALLIANCE]))
+ ruffious->AI()->Talk(DeephaulRavine::CreatureTexts::Lost);
+ return true;
+ }
+
+ if (allianceScore >= maxScore)
+ {
+ battleground->EndBattleground(ALLIANCE);
+ if (Creature const* uzjax = battlegroundMap->GetCreature(_leaderGUIDs[TEAM_HORDE]))
+ uzjax->AI()->Talk(DeephaulRavine::CreatureTexts::Lost);
+ if (Creature const* ruffious = battlegroundMap->GetCreature(_leaderGUIDs[TEAM_ALLIANCE]))
+ ruffious->AI()->Talk(DeephaulRavine::CreatureTexts::Win);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ void DoForLeaders(std::function<void(Creature*)> const& fn) const
+ {
+ for (ObjectGuid const& guid : _leaderGUIDs)
+ if (Creature* creature = battlegroundMap->GetCreature(guid))
+ fn(creature);
+ }
+
+ void RespawnEarthenMineCarts()
+ {
+ size_t allianceDespawnedMineCartCount = _allianceDespawnedMineCarts.size();
+ size_t hordeDespawnedMineCartCount = _hordeDespawnedMineCarts.size();
+
+ while (allianceDespawnedMineCartCount > 0 && !_hordeDespawnedMineCarts.empty())
+ {
+ --allianceDespawnedMineCartCount;
+ Position pos = _hordeDespawnedMineCarts.front();
+ _hordeDespawnedMineCarts.pop();
+ battlegroundMap->SummonCreature(DeephaulRavine::Creatures::EarthenMineCartHorde, pos);
+ }
+
+ while (hordeDespawnedMineCartCount > 0 && !_allianceDespawnedMineCarts.empty())
+ {
+ --hordeDespawnedMineCartCount;
+ Position pos = _allianceDespawnedMineCarts.front();
+ _allianceDespawnedMineCarts.pop();
+ battlegroundMap->SummonCreature(DeephaulRavine::Creatures::EarthenMineCartAlliance, pos);
+ }
+ }
+
+private:
+ TaskScheduler _scheduler;
+ ObjectGuid _flagGUID;
+ uint8 _cartsReached;
+ std::array<ObjectGuid, 2> _cartGUIDs;
+ std::array<ObjectGuid, 2> _controlZoneGUIDs;
+ std::array<ObjectGuid, 2> _capturePointAreaTriggers;
+ ObjectGuid _genericBunnyGUID;
+ std::array<ObjectGuid, 2> _leaderGUIDs; // Foreman Uzjax & Ruffious
+
+ std::queue<Position> _hordeDespawnedMineCarts;
+ std::queue<Position> _allianceDespawnedMineCarts;
+
+ GuidVector _doorGUIDs;
+};
+
+// 214690 - Mine Cart
+// 217346 - Mine Cart
+class npc_bg_deephaul_cavern_mine_cart : public ScriptedAI
+{
+public:
+ explicit npc_bg_deephaul_cavern_mine_cart(Creature* creature) : ScriptedAI(creature) { }
+
+ void JustAppeared() override
+ {
+ DoCastSelf(DeephaulRavine::Spells::ControlVisualNeutral, true);
+ DoCastSelf(DeephaulRavine::Spells::DefendingCartAura, true);
+
+ switch (me->GetEntry())
+ {
+ case DeephaulRavine::Creatures::MineCartEast:
+ me->RemoveAurasDueToSpell(DeephaulRavine::Spells::ControlVisualNeutral);
+ DoCastSelf(DeephaulRavine::Spells::ControlVisualAlliance, true);
+ if (ZoneScript* zonescript = me->GetZoneScript())
+ zonescript->DoAction(DeephaulRavine::Actions::AllianceCartAppearedInitial, me, me);
+ break;
+ case DeephaulRavine::Creatures::MineCartWest:
+ me->RemoveAurasDueToSpell(DeephaulRavine::Spells::ControlVisualNeutral);
+ DoCastSelf(DeephaulRavine::Spells::ControlVisualHorde, true);
+ if (ZoneScript* zonescript = me->GetZoneScript())
+ zonescript->DoAction(DeephaulRavine::Actions::HordeCartAppearedInitial, me, me);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void WaypointPathEnded(uint32 nodeId, uint32 pathId) override
+ {
+ ScriptedAI::WaypointPathEnded(nodeId, pathId);
+
+ switch (pathId)
+ {
+ case DeephaulRavine::PathIds::WestCart:
+ case DeephaulRavine::PathIds::EastCart:
+ OnCapture();
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnCapture()
+ {
+ DoCastSelf(DeephaulRavine::Spells::CartCap, true);
+ }
+};
+
+// 430207 - Cart Cap
+class spell_bg_deephaul_ravine_cart_cap final : public SpellScript
+{
+ void HandleScript(SpellEffIndex /*effIndex*/) const
+ {
+ Creature* hitCreature = GetHitCreature();
+ if (!hitCreature)
+ return;
+
+ if (ZoneScript* zoneScript = hitCreature->GetZoneScript())
+ zoneScript->DoAction(DeephaulRavine::Actions::CaptureMineCart, hitCreature, hitCreature);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_bg_deephaul_ravine_cart_cap::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+};
+
+// 211271 - Earthen Mine Cart
+// 211155 - Earthen Mine Cart
+class npc_bg_deephaul_ravine_earthen_mine_cart final : public ScriptedAI
+{
+public:
+ explicit npc_bg_deephaul_ravine_earthen_mine_cart(Creature* creature) : ScriptedAI(creature) { }
+
+ void OnSpellClick(Unit* clicker, bool spellClickHandled) override
+ {
+ ScriptedAI::OnSpellClick(clicker, spellClickHandled);
+
+ if (!spellClickHandled)
+ return;
+
+ me->DespawnOrUnsummon();
+ }
+};
+
+// 211153 - Earthen Mine Cart
+class npc_bg_deephaul_ravine_earthen_mine_cart_horde final : public ScriptedAI
+{
+public:
+ explicit npc_bg_deephaul_ravine_earthen_mine_cart_horde(Creature* creature) : ScriptedAI(creature)
+ {
+ }
+
+ static constexpr int32 Path1 = 211153 * 100;
+ static constexpr int32 Path2 = 211153 * 100 + 1;
+ static constexpr int32 Path3 = 211153 * 100 + 2;
+
+ void JustAppeared() override
+ {
+ me->ToTempSummon()->GetSummoner()->ToPlayer()->EnterVehicle(me);
+ _scheduler.Schedule(1500ms, [&](TaskContext)
+ {
+ // teleport packet sends same x & y for some reason
+ // teleport and movement start at same time
+ me->NearTeleportTo({ 4160.4297f, -2812.3852f, 240.29422f });
+ me->GetMotionMaster()->MovePath(Path1, false);
+ });
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _scheduler.Update(diff);
+ }
+
+ void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override
+ {
+ switch (pathId)
+ {
+ case Path1:
+ _scheduler.Schedule(500ms, [&](TaskContext)
+ {
+ if (Vehicle* vehicle = me->GetVehicleKit())
+ vehicle->RemoveAllPassengers();
+ me->GetMotionMaster()->MovePath(Path2, false);
+ });
+ break;
+ case Path2:
+ _scheduler.Schedule(1s, [&](TaskContext)
+ {
+ me->GetMotionMaster()->MovePath(Path3, false);
+ });
+ break;
+ case Path3:
+ me->DespawnOrUnsummon();
+ break;
+ default:
+ break;
+ }
+ }
+
+private:
+ TaskScheduler _scheduler;
+};
+
+// 211270 - Earthen Mine Cart
+class npc_bg_deephaul_ravine_earthen_mine_cart_alliance final : public ScriptedAI
+{
+public:
+ explicit npc_bg_deephaul_ravine_earthen_mine_cart_alliance(Creature* creature) : ScriptedAI(creature)
+ {
+ }
+
+ static constexpr int32 Path1 = 211270 * 100;
+ static constexpr int32 Path2 = 211270 * 100 + 1;
+
+ void JustAppeared() override
+ {
+ me->ToTempSummon()->GetSummoner()->ToPlayer()->EnterVehicle(me);
+ _scheduler.Schedule(1500ms, [&](TaskContext)
+ {
+ // teleport packet sends same x & y for some reason
+ // teleport and movement start at same time
+ me->NearTeleportTo({ 3968.5852f, -3080.5815f, 240.14261f, 0.0f });
+ me->GetMotionMaster()->MovePath(Path1, false);
+ });
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _scheduler.Update(diff);
+ }
+
+ void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override
+ {
+ switch (pathId)
+ {
+ case Path1:
+ _scheduler.Schedule(500ms, [&](TaskContext)
+ {
+ if (Vehicle* vehicle = me->GetVehicleKit())
+ {
+ for (auto const& [_, seat] : vehicle->Seats)
+ {
+ if (Unit* passenger = ObjectAccessor::GetUnit(*me, seat.Passenger.Guid))
+ {
+ passenger->CastSpell(passenger, DeephaulRavine::Spells::CartExhaustion, true);
+ passenger->_ExitVehicle();
+ }
+ }
+ }
+ me->GetMotionMaster()->MovePath(Path2, false);
+ });
+ break;
+ case Path2:
+ _scheduler.Schedule(1s, [&](TaskContext)
+ {
+ me->DespawnOrUnsummon();
+ });
+ break;
+ default:
+ break;
+ }
+ }
+
+private:
+ TaskScheduler _scheduler;
+};
+
+// 21076 - PvP Rune Rejuv Visual (New)
+// 21077 - PvP Rune Berserking Visual (New)
+// 33926 - PvP Rune Cooldown Visual (New)
+struct at_bg_deephaul_ravine_buff final : AreaTriggerAI
+{
+ explicit at_bg_deephaul_ravine_buff(AreaTrigger* areaTrigger) : AreaTriggerAI(areaTrigger) { }
+
+ void OnUnitEnter(Unit* unit) override
+ {
+ if (Player* player = unit->ToPlayer())
+ if (ZoneScript* zonescript = at->GetZoneScript())
+ zonescript->DoAction(DeephaulRavine::Actions::ConsumeBuff, at, player);
+ }
+};
+
+// 224087 - Ruffious
+// 224086 - Foreman Uzjax
+template<uint32 Path1, uint32 Path2, uint32 Path3, uint32 Path4>
+class npc_bg_deephaul_ravine_commander : public ScriptedAI
+{
+public:
+ explicit npc_bg_deephaul_ravine_commander(Creature* creature) : ScriptedAI(creature) { }
+
+ void JustAppeared() override
+ {
+ ScriptedAI::JustAppeared();
+ me->SetHover(true);
+ me->SetDisableGravity(true);
+ }
+
+ void DoAction(int32 actionId) override
+ {
+ if (actionId == DeephaulRavine::Actions::CommanderStartIntro)
+ {
+ Talk(DeephaulRavine::CreatureTexts::Intro1);
+ me->GetMotionMaster()->MovePath(Path1, false);
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ ScriptedAI::UpdateAI(diff);
+ _scheduler.Update(diff);
+ }
+
+ void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override
+ {
+ switch (pathId)
+ {
+ case Path1:
+ _scheduler.Schedule(10s, [this](TaskContext)
+ {
+ me->GetMotionMaster()->MovePath(Path2, false);
+ Talk(DeephaulRavine::CreatureTexts::Intro2);
+ });
+ break;
+ case Path2:
+ _scheduler.Schedule(3s, [this](TaskContext)
+ {
+ me->GetMotionMaster()->MovePath(Path3, false);
+ });
+ break;
+ case Path3:
+ _scheduler.Schedule(5s, [this](TaskContext)
+ {
+ me->GetMotionMaster()->MovePath(Path4, false);
+ });
+ break;
+ default:
+ break;
+ }
+ }
+
+private:
+ TaskScheduler _scheduler;
+};
+
+// 424383 - Earthen Mine Cart Ride
+// 424166 - Earthen Mine Cart Ride
+class spell_bg_deephaul_ravine_earthen_mine_cart_ride : public AuraScript
+{
+ void OnApply(AuraEffect const* /*auraEffect*/, AuraEffectHandleModes /*mode*/) const
+ {
+ // instantly remove this aura
+ GetTarget()->RemoveAura(GetAura());
+ }
+
+ void Register() override
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_bg_deephaul_ravine_earthen_mine_cart_ride::OnApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+};
+
+void AddSC_battleground_deephaul_ravine()
+{
+ RegisterBattlegroundMapScript(battleground_deephaul_ravine, 2656);
+ RegisterCreatureAI(npc_bg_deephaul_cavern_mine_cart);
+ RegisterSpellScript(spell_bg_deephaul_ravine_cart_cap);
+ RegisterCreatureAI(npc_bg_deephaul_ravine_earthen_mine_cart);
+ RegisterCreatureAI(npc_bg_deephaul_ravine_earthen_mine_cart_horde);
+ RegisterCreatureAI(npc_bg_deephaul_ravine_earthen_mine_cart_alliance);
+ RegisterAreaTriggerAI(at_bg_deephaul_ravine_buff);
+ RegisterSpellScript(spell_bg_deephaul_ravine_earthen_mine_cart_ride);
+
+ new GenericCreatureScript<npc_bg_deephaul_ravine_commander<DeephaulRavine::PathIds::ForemanUzjax::Path1, DeephaulRavine::PathIds::ForemanUzjax::Path2, DeephaulRavine::PathIds::ForemanUzjax::Path3, DeephaulRavine::PathIds::ForemanUzjax::Path4>>("npc_bg_deephaul_ravine_foreman_uzjax");
+ new GenericCreatureScript<npc_bg_deephaul_ravine_commander<DeephaulRavine::PathIds::Ruffious::Path1, DeephaulRavine::PathIds::Ruffious::Path2, DeephaulRavine::PathIds::Ruffious::Path3, DeephaulRavine::PathIds::Ruffious::Path4>>("npc_bg_deephaul_ravine_ruffious");
+}
diff --git a/src/server/scripts/Battlegrounds/battlegrounds_script_loader.cpp b/src/server/scripts/Battlegrounds/battlegrounds_script_loader.cpp
index eef52c7b6e6..d4afd1388a8 100644
--- a/src/server/scripts/Battlegrounds/battlegrounds_script_loader.cpp
+++ b/src/server/scripts/Battlegrounds/battlegrounds_script_loader.cpp
@@ -58,6 +58,8 @@ void AddSC_battleground_seething_shore();
void AddSC_battleground_silvershard_mines();
void AddSC_battleground_temple_of_kotmogu();
+void AddSC_battleground_deephaul_ravine();
+
// The name of this function should match:
// void Add${NameOfDirectory}Scripts()
void AddBattlegroundsScripts()
@@ -102,4 +104,5 @@ void AddBattlegroundsScripts()
AddSC_battleground_silvershard_mines();
AddSC_battleground_temple_of_kotmogu();
+ AddSC_battleground_deephaul_ravine();
}