diff options
author | Jeremy <Golrag@users.noreply.github.com> | 2025-09-28 11:55:26 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-09-28 11:55:26 +0200 |
commit | 974816b041d2fe102aaa798677813e166d989fcd (patch) | |
tree | 0cf1d37a70c0997e55553bc70dd8ea2e125e1298 /src/server | |
parent | c5d4dec24e020c24a3646e99af15e2d4259c585f (diff) |
Diffstat (limited to 'src/server')
-rw-r--r-- | src/server/scripts/Battlegrounds/DalaranSewers/arena_dalaran_sewers.cpp | 315 |
1 files changed, 178 insertions, 137 deletions
diff --git a/src/server/scripts/Battlegrounds/DalaranSewers/arena_dalaran_sewers.cpp b/src/server/scripts/Battlegrounds/DalaranSewers/arena_dalaran_sewers.cpp index bbdf5d4ab3b..24b16f3b904 100644 --- a/src/server/scripts/Battlegrounds/DalaranSewers/arena_dalaran_sewers.cpp +++ b/src/server/scripts/Battlegrounds/DalaranSewers/arena_dalaran_sewers.cpp @@ -25,64 +25,74 @@ #include "ObjectAccessor.h" #include "Player.h" #include "ScriptMgr.h" +#include "SpellAuraEffects.h" +#include "SpellInfo.h" +#include "SpellMgr.h" +#include "SpellScript.h" #include "TaskScheduler.h" -struct arena_dalaran_sewers : ArenaScript +namespace DalaranSewers { - enum GameObjects + namespace Creatures { - 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 + static constexpr uint32 WaterSpout = 28567; + } + + namespace Events + { + static constexpr uint32 WaterfallWarning = 1; + static constexpr uint32 WaterfallOn = 2; + static constexpr uint32 WaterfallOff = 3; + static constexpr uint32 WaterfallKnockBack = 4; + } + + namespace GameObjects { - 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, + static constexpr uint32 Door01 = 192642; + static constexpr uint32 Door02 = 192643; - BG_DS_EVENT_PIPE_KNOCKBACK = 5 - }; + static constexpr uint32 WaterCollision = 194395; + static constexpr uint32 Waterfall = 191877; + } - enum Creatures + namespace MapIds { - BG_DS_NPC_TYPE_WATER_SPOUT = 28567 - }; + static constexpr uint32 DalaranSewers = 617; + } - enum Spells + namespace 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 + static constexpr uint32 PipeFlushKnockbackSearchTrigger = 96539; + static constexpr uint32 DalaranSewersPetTeleport = 254013; + static constexpr uint32 WaterSpout = 58873; // Knock back + static constexpr uint32 Flush = 57405; + + static constexpr uint32 WarlockDemonicCircle = 48018; + } - SPELL_WARL_DEMONIC_CIRCLE = 48018 // Demonic Circle Summon - }; + namespace StringIds + { + static constexpr std::string_view WaterSpoutPipe = "arena_dalaran_sewers_water_spout_pipe"; + static constexpr std::string_view WaterSpoutCenter = "arena_dalaran_sewers_water_spout_center"; + } - enum Data + namespace Timers { - // 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) { } + static constexpr Seconds Waterfall = 30s; + static constexpr Seconds WaterfallWarningDuration = 5s; + static constexpr Seconds WaterfallDuration = 30s; + static constexpr Milliseconds WaterfallKnockBack = 1500ms; + } +} + +struct arena_dalaran_sewers : ArenaScript +{ + explicit arena_dalaran_sewers(BattlegroundMap* map) : ArenaScript(map) { } void OnUpdate(uint32 diff) override { + ArenaScript::OnUpdate(diff); + if (battleground->GetStatus() != STATUS_IN_PROGRESS) return; @@ -93,75 +103,44 @@ struct arena_dalaran_sewers : ArenaScript { switch (eventId) { - case BG_DS_EVENT_WATERFALL_WARNING: + case DalaranSewers::Events::WaterfallWarning: // Add the water - if (GameObject* go = battlegroundMap->GetGameObject(_water2GUID)) - go->ResetDoorOrButton(); - _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_ON, BG_DS_WATERFALL_WARNING_DURATION); + if (GameObject* go = battlegroundMap->GetGameObject(_waterfallGUID)) + go->UseDoorOrButton(); + _events.ScheduleEvent(DalaranSewers::Events::WaterfallOn, DalaranSewers::Timers::WaterfallWarningDuration); break; - case BG_DS_EVENT_WATERFALL_ON: + case DalaranSewers::Events::WaterfallOn: // 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)) + if (GameObject* go = battlegroundMap->GetGameObject(_waterCollisionGUID)) 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); + _events.ScheduleEvent(DalaranSewers::Events::WaterfallOff, DalaranSewers::Timers::WaterfallDuration); + _events.ScheduleEvent(DalaranSewers::Events::WaterfallKnockBack, DalaranSewers::Timers::WaterfallKnockBack); 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); + case DalaranSewers::Events::WaterfallOff: + // Remove collision and water + if (GameObject* go = battlegroundMap->GetGameObject(_waterCollisionGUID)) + go->ResetDoorOrButton(); + if (GameObject* go = battlegroundMap->GetGameObject(_waterfallGUID)) + go->ResetDoorOrButton(); + _events.CancelEvent(DalaranSewers::Events::WaterfallKnockBack); + _events.ScheduleEvent(DalaranSewers::Events::WaterfallWarning, DalaranSewers::Timers::Waterfall); 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); + case DalaranSewers::Events::WaterfallKnockBack: + // Repeat knock back while the waterfall still active + if (Creature* waterSpout = battlegroundMap->GetCreature(_waterSpoutCenterGUID)) + waterSpout->CastSpell(waterSpout, DalaranSewers::Spells::WaterSpout, true); + _events.ScheduleEvent(eventId, DalaranSewers::Timers::WaterfallKnockBack); 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 { + ArenaScript::OnStart(); + for (ObjectGuid const& guid : _doorGUIDs) { if (GameObject* door = battlegroundMap->GetGameObject(guid)) @@ -171,57 +150,79 @@ struct arena_dalaran_sewers : ArenaScript } } - _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; + _events.ScheduleEvent(DalaranSewers::Events::WaterfallWarning, DalaranSewers::Timers::Waterfall); // Remove collision and water - if (GameObject* go = battlegroundMap->GetGameObject(_water1GUID)) - go->UseDoorOrButton(); - if (GameObject* go = battlegroundMap->GetGameObject(_water2GUID)) - go->UseDoorOrButton(); + if (GameObject* go = battlegroundMap->GetGameObject(_waterCollisionGUID)) + go->ResetDoorOrButton(); + if (GameObject* go = battlegroundMap->GetGameObject(_waterfallGUID)) + go->ResetDoorOrButton(); for (const auto& [playerGuid, _] : battleground->GetPlayers()) if (Player* player = ObjectAccessor::FindPlayer(playerGuid)) - player->RemoveAurasDueToSpell(SPELL_WARL_DEMONIC_CIRCLE); - } + player->RemoveAurasDueToSpell(DalaranSewers::Spells::WarlockDemonicCircle); - 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()); + _scheduler.Schedule(6s, [&](TaskContext) + { + for (ObjectGuid const& guid : _waterSpoutEntranceGUIDs) + { + if (Creature* creature = battlegroundMap->GetCreature(guid)) + { + creature->CastSpell(nullptr, DalaranSewers::Spells::Flush, CastSpellExtraArgsInit{ + .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR + }); + creature->CastSpell(creature, DalaranSewers::Spells::PipeFlushKnockbackSearchTrigger, CastSpellExtraArgsInit{ + .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR + }); + } + } + }); } - void SetData(uint32 dataId, uint32 value) override + void OnCreatureCreate(Creature* creature) override { - ArenaScript::SetData(dataId, value); - if (dataId == BG_DS_DATA_PIPE_KNOCKBACK_COUNT) - _pipeKnockBackCount = value; + switch (creature->GetEntry()) + { + case DalaranSewers::Creatures::WaterSpout: + if (creature->HasStringId(DalaranSewers::StringIds::WaterSpoutPipe)) + _waterSpoutEntranceGUIDs.push_back(creature->GetGUID()); + else if (creature->HasStringId(DalaranSewers::StringIds::WaterSpoutCenter)) + _waterSpoutCenterGUID = creature->GetGUID(); + break; + default: + break; + } } - uint32 GetData(uint32 dataId) const override + void OnGameObjectCreate(GameObject* gameobject) override { - if (dataId == BG_DS_DATA_PIPE_KNOCKBACK_COUNT) - return _pipeKnockBackCount; - - return ArenaScript::GetData(dataId); + switch (gameobject->GetEntry()) + { + case DalaranSewers::GameObjects::Door01: + case DalaranSewers::GameObjects::Door02: + _doorGUIDs.push_back(gameobject->GetGUID()); + break; + case DalaranSewers::GameObjects::WaterCollision: + _waterCollisionGUID = gameobject->GetGUID(); + break; + case DalaranSewers::GameObjects::Waterfall: + _waterfallGUID = gameobject->GetGUID(); + break; + default: + break; + } } private: GuidVector _doorGUIDs; - ObjectGuid _water1GUID; - ObjectGuid _water2GUID; - ObjectGuid _waterfallCreatureGUID; - GuidVector _pipeCreatureGUIDs; - TaskScheduler _scheduler; + ObjectGuid _waterCollisionGUID; + ObjectGuid _waterfallGUID; EventMap _events; - uint32 _pipeKnockBackTimer; - uint8 _pipeKnockBackCount; + GuidVector _waterSpoutEntranceGUIDs; + ObjectGuid _waterSpoutCenterGUID; + + TaskScheduler _scheduler; }; class at_ds_pipe_knockback : public AreaTriggerScript @@ -229,7 +230,7 @@ class at_ds_pipe_knockback : public AreaTriggerScript public: at_ds_pipe_knockback() : AreaTriggerScript("at_ds_pipe_knockback") { } - void Trigger(Player* player) const + static void Trigger(Player* player) { if (Battleground const* battleground = player->GetBattleground()) { @@ -237,12 +238,8 @@ public: 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); + player->RemoveAurasDueToSpell(DalaranSewers::Spells::WarlockDemonicCircle); + player->CastSpell(nullptr, DalaranSewers::Spells::DalaranSewersPetTeleport); } } @@ -259,8 +256,52 @@ public: } }; +// 96538 - Pipe Flush Knockback Search Effect +class spell_arena_dalaran_sewers_pipe_flush_knockback_search_trigger : public SpellScript +{ + bool Validate(SpellInfo const* spellInfo) override + { + return ValidateSpellInfo({ + static_cast<uint32>(spellInfo->GetEffect(EFFECT_0).CalcValue()) + }); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) const + { + GetCaster()->CastSpell(nullptr, GetSpellInfo()->GetEffect(EFFECT_0).CalcValue(), CastSpellExtraArgsInit + { + .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR + }); + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_arena_dalaran_sewers_pipe_flush_knockback_search_trigger::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +// 61698 - Flush - Knockback effect (SERVERSIDE) +class spell_arena_dalaran_sewers_flush_knock_back_effect : public SpellScript +{ + void HandleDummy(SpellEffIndex /*effIndex*/) const + { + static constexpr float SpeedXY = 30.0f; + static constexpr float SpeedZ = 19.0f; + + Unit* caster = GetCaster(); + Unit const* target = GetHitUnit(); + caster->KnockbackFrom(target->GetPosition(), SpeedXY, SpeedZ); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_arena_dalaran_sewers_flush_knock_back_effect::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + void AddSC_arena_dalaran_sewers() { - RegisterBattlegroundMapScript(arena_dalaran_sewers, 617); + RegisterBattlegroundMapScript(arena_dalaran_sewers, DalaranSewers::MapIds::DalaranSewers); new at_ds_pipe_knockback(); + RegisterSpellScript(spell_arena_dalaran_sewers_flush_knock_back_effect); } |