From 3e19b5e63791c76f110e0d6d2b9b21d3faa36be4 Mon Sep 17 00:00:00 2001 From: Dan <83884799+elthehablo@users.noreply.github.com> Date: Mon, 5 Jun 2023 04:42:40 +0200 Subject: [PATCH] fix(Scripts/Underbog): modernise boss scripts (#16149) --- src/server/game/Movement/MotionMaster.cpp | 26 +++++ src/server/game/Movement/MotionMaster.h | 1 + .../underbog/boss_ghazan.cpp | 83 ++++++---------- .../underbog/boss_hungarfen.cpp | 33 +++---- .../underbog/boss_swamplord_muselek.cpp | 11 ++- .../underbog/boss_the_black_stalker.cpp | 95 ++++++++----------- 6 files changed, 112 insertions(+), 137 deletions(-) diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 27daa3196..be0fb7951 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -344,6 +344,32 @@ void MotionMaster::MoveBackwards(Unit* target, float dist) init.Launch(); } +void MotionMaster::MoveForwards(Unit* target, float dist) +{ + //like movebackwards, but without the inversion + if (!target) + { + return; + } + + Position const& pos = target->GetPosition(); + float angle = target->GetAngle(_owner); + G3D::Vector3 point; + point.x = pos.m_positionX + dist * cosf(angle); + point.y = pos.m_positionY + dist * sinf(angle); + point.z = pos.m_positionZ; + + if (!_owner->GetMap()->CanReachPositionAndGetValidCoords(_owner, point.x, point.y, point.z, true, true)) + { + return; + } + + Movement::MoveSplineInit init(_owner); + init.MoveTo(point.x, point.y, point.z, false); + init.SetFacing(target); + init.Launch(); +} + void MotionMaster::MoveCircleTarget(Unit* target) { if (!target) diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index 4693025de..d9131295d 100644 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -205,6 +205,7 @@ public: void MoveChase(Unit* target, float dist) { MoveChase(target, ChaseRange(dist)); } void MoveCircleTarget(Unit* target); void MoveBackwards(Unit* target, float dist); + void MoveForwards(Unit* target, float dist); void MoveConfused(); void MoveFleeing(Unit* enemy, uint32 time = 0); void MovePoint(uint32 id, const Position& pos, bool generatePath = true, bool forceDestination = true) diff --git a/src/server/scripts/Outland/CoilfangReservoir/underbog/boss_ghazan.cpp b/src/server/scripts/Outland/CoilfangReservoir/underbog/boss_ghazan.cpp index 8054fa261..cba57f85e 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/underbog/boss_ghazan.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/underbog/boss_ghazan.cpp @@ -28,10 +28,6 @@ enum eBlackStalker SPELL_TAIL_SWEEP = 34267, SPELL_ENRAGE = 15716, - EVENT_ACID_BREATH = 1, - EVENT_ACID_SPIT = 2, - EVENT_TAIL_SWEEP = 3, - ACTION_MOVE_TO_PLATFORM = 1 }; @@ -39,6 +35,10 @@ struct boss_ghazan : public BossAI { boss_ghazan(Creature* creature) : BossAI(creature, DATA_GHAZAN) { + scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); } void InitializeAI() override @@ -50,31 +50,34 @@ struct boss_ghazan : public BossAI void Reset() override { - _enraged = false; + _Reset(); if (!_reachedPlatform) { _movedToPlatform = false; } - BossAI::Reset(); - } - - void JustEngagedWith(Unit* who) override - { - events.ScheduleEvent(EVENT_ACID_BREATH, 3s); - events.ScheduleEvent(EVENT_ACID_SPIT, 1s); - events.ScheduleEvent(EVENT_TAIL_SWEEP, DUNGEON_MODE(5900ms, 10s)); - - BossAI::JustEngagedWith(who); - } - - void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*type*/, SpellSchoolMask /*school*/) override - { - if (!_enraged && me->HealthBelowPctDamaged(20, damage)) - { - _enraged = true; + ScheduleHealthCheckEvent(20, [&] { DoCastSelf(SPELL_ENRAGE); - } + }); + } + + void JustEngagedWith(Unit* /*who*/) override + { + scheduler.Schedule(3s, [this](TaskContext context) + { + DoCastVictim(SPELL_ACID_BREATH); + context.Repeat(7s, 9s); + }).Schedule(1s, [this](TaskContext context) + { + DoCastRandomTarget(SPELL_ACID_SPIT); + context.Repeat(7s, 9s); + }).Schedule(DUNGEON_MODE(5900ms, 10s), [this](TaskContext context) + { + DoCastVictim(SPELL_TAIL_SWEEP); + context.Repeat(7s, 9s); + }); + + _JustEngagedWith(); } void DoAction(int32 type) override @@ -110,7 +113,7 @@ struct boss_ghazan : public BossAI me->GetMotionMaster()->MoveRandom(12.f); } - BossAI::JustReachedHome(); + _JustReachedHome(); } void UpdateAI(uint32 diff) override @@ -120,42 +123,12 @@ struct boss_ghazan : public BossAI return; } - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - { - return; - } - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_ACID_BREATH: - DoCastVictim(SPELL_ACID_BREATH); - events.Repeat(7s, 9s); - break; - case EVENT_ACID_SPIT: - if (Unit* target = SelectTarget(SelectTargetMethod::Random)) - { - DoCast(target, SPELL_ACID_SPIT); - } - events.Repeat(7s, 9s); - break; - case EVENT_TAIL_SWEEP: - DoCastVictim(SPELL_TAIL_SWEEP); - events.Repeat(7s, 9s); - break; - default: - break; - } - } + scheduler.Update(diff); DoMeleeAttackIfReady(); } private: - bool _enraged; bool _movedToPlatform; bool _reachedPlatform; }; diff --git a/src/server/scripts/Outland/CoilfangReservoir/underbog/boss_hungarfen.cpp b/src/server/scripts/Outland/CoilfangReservoir/underbog/boss_hungarfen.cpp index 980ef0969..38b76287b 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/underbog/boss_hungarfen.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/underbog/boss_hungarfen.cpp @@ -44,35 +44,29 @@ enum Misc struct boss_hungarfen : public BossAI { - boss_hungarfen(Creature* creature) : BossAI(creature, DATA_HUNGARFEN), _foul_spores(false) { } + boss_hungarfen(Creature* creature) : BossAI(creature, DATA_HUNGARFEN) { } - void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType, SpellSchoolMask) override + void Reset() override { - if (me->HealthBelowPctDamaged(20, damage) && !_foul_spores) - { - _foul_spores = true; + _Reset(); + _scheduler.CancelAll(); + DoCastAOE(SPELL_DESPAWN_MUSHROOMS, true); + + ScheduleHealthCheckEvent(20, [&] { me->AddUnitState(UNIT_STATE_ROOT); Talk(EMOTE_ROARS); DoCastSelf(SPELL_FOUL_SPORES); _scheduler.DelayAll(11s); _scheduler.Schedule(11s, [this](TaskContext /*context*/) - { - me->ClearUnitState(UNIT_STATE_ROOT); - }); - } + { + me->ClearUnitState(UNIT_STATE_ROOT); + }); + }); } - void Reset() override + void JustEngagedWith(Unit* /*who*/) override { - BossAI::Reset(); - _foul_spores = false; - _scheduler.CancelAll(); - DoCastAOE(SPELL_DESPAWN_MUSHROOMS, true); - } - - void JustEngagedWith(Unit* who) override - { - BossAI::JustEngagedWith(who); + _JustEngagedWith(); _scheduler.Schedule(IsHeroic() ? randtime(2400ms, 3600ms) : 10s, [this](TaskContext context) { @@ -107,7 +101,6 @@ struct boss_hungarfen : public BossAI private: TaskScheduler _scheduler; - bool _foul_spores; }; struct npc_underbog_mushroom : public ScriptedAI diff --git a/src/server/scripts/Outland/CoilfangReservoir/underbog/boss_swamplord_muselek.cpp b/src/server/scripts/Outland/CoilfangReservoir/underbog/boss_swamplord_muselek.cpp index 0d220613b..9b310f2e6 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/underbog/boss_swamplord_muselek.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/underbog/boss_swamplord_muselek.cpp @@ -17,6 +17,7 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "TaskScheduler.h" #include "the_underbog.h" enum Spells @@ -27,14 +28,14 @@ enum Spells SPELL_MULTISHOT = 34974, SPELL_THROW_FREEZING_TRAP = 31946, SPELL_AIMED_SHOT = 31623, - SPELL_HUNTERS_MARK = 31615 + SPELL_HUNTERS_MARK = 31615, }; enum Text { - SAY_AGGRO = 1, - SAY_KILL = 2, - SAY_JUST_DIED = 3 + SAY_AGGRO = 1, + SAY_KILL = 2, + SAY_JUST_DIED = 3 }; enum Misc @@ -133,7 +134,7 @@ struct boss_swamplord_muselek : public BossAI if (me->IsWithinMeleeRange(me->GetVictim())) { me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MoveBackwards(me->GetVictim(), 10.0f); + me->GetMotionMaster()->MoveForwards(me->GetVictim(), 10.0f); } me->m_Events.AddEventAtOffset([this]() diff --git a/src/server/scripts/Outland/CoilfangReservoir/underbog/boss_the_black_stalker.cpp b/src/server/scripts/Outland/CoilfangReservoir/underbog/boss_the_black_stalker.cpp index e3171541d..5a0297c34 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/underbog/boss_the_black_stalker.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/underbog/boss_the_black_stalker.cpp @@ -47,14 +47,6 @@ enum eBlackStalker SPELL_SUSPENSION_PRIMER = 31720, SPELL_SUSPENSION = 31719, - EVENT_LEVITATE = 1, - EVENT_SPELL_CHAIN = 2, - EVENT_SPELL_STATIC = 3, - EVENT_SPELL_SPORES = 4, - EVENT_CHECK = 5, - EVENT_LEVITATE_TARGET_1 = 6, - EVENT_LEVITATE_TARGET_2 = 7, - ENTRY_SPORE_STRIDER = 22299 }; @@ -62,18 +54,47 @@ struct boss_the_black_stalker : public BossAI { boss_the_black_stalker(Creature* creature) : BossAI(creature, DATA_BLACK_STALKER) { + scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); } - void JustEngagedWith(Unit* who) override + void JustEngagedWith(Unit* /*who*/) override { - events.ScheduleEvent(EVENT_LEVITATE, urand(8000, 12000)); - events.ScheduleEvent(EVENT_SPELL_CHAIN, 6000); - events.ScheduleEvent(EVENT_SPELL_STATIC, 10000); - events.ScheduleEvent(EVENT_CHECK, 5000); - if (IsHeroic()) - events.ScheduleEvent(EVENT_SPELL_SPORES, urand(10000, 15000)); + scheduler.Schedule(8s, 12s, [this](TaskContext context) + { + DoCastSelf(SPELL_LEVITATE); + context.Repeat(18s, 24s); + }).Schedule(6s, [this](TaskContext context) + { + DoCastRandomTarget(SPELL_CHAIN_LIGHTNING, false); + context.Repeat(9s); + }).Schedule(10s, [this](TaskContext context) + { + DoCastRandomTarget(SPELL_STATIC_CHARGE, false); + context.Repeat(10s); + }).Schedule(5s, [this](TaskContext /*context*/) + { + float x, y, z, o = 0.f; + me->GetHomePosition(x, y, z, o); + if (!me->IsWithinDist3d(x, y, z, 60.0f)) + { + EnterEvadeMode(); + return; + } + }); - BossAI::JustEngagedWith(who); + if (IsHeroic()) + { + scheduler.Schedule(10s, 15s, [this](TaskContext context) + { + DoCastSelf(SPELL_SUMMON_SPORE_STRIDER, false); + context.Repeat(10s, 15s); + }); + } + + _JustEngagedWith(); } void JustSummoned(Creature* summon) override @@ -89,8 +110,6 @@ struct boss_the_black_stalker : public BossAI void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override { summons.Despawn(summon); - for (uint8 i = 0; i < 3; ++i) - me->CastSpell(me, SPELL_SUMMON_SPORE_STRIDER, false); } void UpdateAI(uint32 diff) override @@ -98,45 +117,7 @@ struct boss_the_black_stalker : public BossAI if (!UpdateVictim()) return; - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_CHECK: - float x, y, z, o; - me->GetHomePosition(x, y, z, o); - if (!me->IsWithinDist3d(x, y, z, 60)) - { - EnterEvadeMode(); - return; - } - events.RepeatEvent(5000); - break; - case EVENT_SPELL_SPORES: - me->CastSpell(me, SPELL_SUMMON_SPORE_STRIDER, false); - events.RepeatEvent(urand(10000, 15000)); - break; - case EVENT_SPELL_CHAIN: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - me->CastSpell(target, SPELL_CHAIN_LIGHTNING, false); - events.RepeatEvent(9000); - break; - case EVENT_SPELL_STATIC: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30, true)) - me->CastSpell(target, SPELL_STATIC_CHARGE, false); - events.RepeatEvent(10000); - break; - case EVENT_LEVITATE: - DoCastSelf(SPELL_LEVITATE); - events.RepeatEvent(urand(18000, 24000)); - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + scheduler.Update(diff); DoMeleeAttackIfReady(); }