From daec8345e02ecf0d10479a44cc05a008c93de363 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sun, 26 Nov 2023 19:47:15 -0300 Subject: [PATCH] refactor(Scripts/BlackTemple): Modernize Najentus boss script (#17871) * refactor(Scripts/BlackTemple): Modernize Najentus boss script * fix build * Update ScriptedCreature.h --- .../game/AI/ScriptedAI/ScriptedCreature.cpp | 4 +- .../game/AI/ScriptedAI/ScriptedCreature.h | 8 +- .../BlackTemple/boss_warlord_najentus.cpp | 110 ++++++++---------- 3 files changed, 59 insertions(+), 63 deletions(-) diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index f68b45cdc..307393920 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -311,14 +311,14 @@ Creature* ScriptedAI::DoSpawnCreature(uint32 entry, float offsetX, float offsetY return me->SummonCreature(entry, me->GetPositionX() + offsetX, me->GetPositionY() + offsetY, me->GetPositionZ() + offsetZ, angle, TempSummonType(type), despawntime); } -void ScriptedAI::ScheduleTimedEvent(Milliseconds timer, std::function exec, Milliseconds repeatMin, Milliseconds repeatMax, uint32 uniqueId) +void ScriptedAI::ScheduleTimedEvent(Milliseconds timerMin, Milliseconds timerMax, std::function exec, Milliseconds repeatMin, Milliseconds repeatMax, uint32 uniqueId) { if (uniqueId && IsUniqueTimedEventDone(uniqueId)) { return; } - scheduler.Schedule(timer, [exec, repeatMin, repeatMax, uniqueId](TaskContext context) + scheduler.Schedule(timerMin == 0s ? timerMax : timerMin, timerMax, [exec, repeatMin, repeatMax, uniqueId](TaskContext context) { exec(); diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h index 29519906f..669367ca6 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h @@ -357,7 +357,13 @@ struct ScriptedAI : public CreatureAI void SetUniqueTimedEventDone(uint32 id) { _uniqueTimedEvents.insert(id); } void ResetUniqueTimedEvent(uint32 id) { _uniqueTimedEvents.erase(id); } void ClearUniqueTimedEventsDone() { _uniqueTimedEvents.clear(); } - void ScheduleTimedEvent(Milliseconds timer, std::function exec, Milliseconds repeatMin, Milliseconds repeatMax = 0s, uint32 uniqueId = 0); + + // Schedules a timed event using task scheduler. + void ScheduleTimedEvent(Milliseconds timerMin, Milliseconds timerMax, std::function exec, Milliseconds repeatMin, Milliseconds repeatMax = 0s, uint32 uniqueId = 0); + void ScheduleTimedEvent(Milliseconds timerMax, std::function exec, Milliseconds repeatMin, Milliseconds repeatMax = 0s, uint32 uniqueId = 0) { ScheduleTimedEvent(0s, timerMax, exec, repeatMin, repeatMax, uniqueId); }; + + // Schedules a timed event using task scheduler that never repeats. Requires an unique non-zero ID. + void ScheduleUniqueTimedEvent(Milliseconds timer, std::function exec, uint32 uniqueId) { ScheduleTimedEvent(0s, timer, exec, 0s, 0s, uniqueId); }; bool HealthBelowPct(uint32 pct) const { return me->HealthBelowPct(pct); } bool HealthAbovePct(uint32 pct) const { return me->HealthAbovePct(pct); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp b/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp index a618b7239..7c18911a3 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp @@ -43,23 +43,63 @@ enum Spells enum Events { EVENT_SPELL_BERSERK = 1, - EVENT_YELL = 2, - EVENT_SPELL_NEEDLE = 3, - EVENT_SPELL_SPINE = 4, - EVENT_SPELL_SHIELD = 5, - EVENT_KILL_SPEAK = 6 + EVENT_TALK_CHECK = 2 }; struct boss_najentus : public BossAI { - boss_najentus(Creature* creature) : BossAI(creature, DATA_HIGH_WARLORD_NAJENTUS) { } + boss_najentus(Creature* creature) : BossAI(creature, DATA_HIGH_WARLORD_NAJENTUS), _canTalk(true) { } + + void JustEngagedWith(Unit* who) override + { + _canTalk = true; + + BossAI::JustEngagedWith(who); + Talk(SAY_AGGRO); + + ScheduleUniqueTimedEvent(8min, [&] + { + Talk(SAY_ENRAGE); + DoCastSelf(SPELL_BERSERK, true); + }, EVENT_SPELL_BERSERK); + + ScheduleTimedEvent(25s, 100s, [&] + { + Talk(SAY_SPECIAL); + }, 25s, 100s); + + ScheduleTimedEvent(10s, [&] + { + me->CastCustomSpell(SPELL_NEEDLE_SPINE, SPELLVALUE_MAX_TARGETS, 3, me, false); + }, 15s, 15s); + + ScheduleTimedEvent(21s, [&] + { + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1)) + { + DoCast(target, SPELL_IMPALING_SPINE); + target->CastSpell(target, SPELL_SUMMON_IMPALING_SPINE, true); + Talk(SAY_NEEDLE); + } + }, 20s, 20s); + + ScheduleTimedEvent(1min, [&] + { + DoCastSelf(SPELL_TIDAL_SHIELD); + scheduler.DelayAll(10s); + }, 1min, 1min); + } void KilledUnit(Unit* victim) override { - if (victim->GetTypeId() == TYPEID_PLAYER && events.GetNextEventTime(EVENT_KILL_SPEAK) == 0) + if (victim->GetTypeId() == TYPEID_PLAYER && _canTalk) { Talk(SAY_SLAY); - events.ScheduleEvent(EVENT_KILL_SPEAK, 5000); + _canTalk = false; + ScheduleUniqueTimedEvent(5s, [&] + { + _canTalk = true; + }, EVENT_TALK_CHECK); } } @@ -69,58 +109,8 @@ struct boss_najentus : public BossAI Talk(SAY_DEATH); } - void JustEngagedWith(Unit* who) override - { - BossAI::JustEngagedWith(who); - Talk(SAY_AGGRO); - events.ScheduleEvent(EVENT_SPELL_BERSERK, 480000); - events.ScheduleEvent(EVENT_YELL, urand(25000, 100000)); - events.RescheduleEvent(EVENT_SPELL_NEEDLE, 10000); - events.RescheduleEvent(EVENT_SPELL_SPINE, 20001); - events.RescheduleEvent(EVENT_SPELL_SHIELD, 60000); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_SPELL_SHIELD: - me->CastSpell(me, SPELL_TIDAL_SHIELD, false); - events.DelayEvents(10000); - events.ScheduleEvent(EVENT_SPELL_SHIELD, 60000); - break; - case EVENT_SPELL_BERSERK: - Talk(SAY_ENRAGE); - me->CastSpell(me, SPELL_BERSERK, true); - break; - case EVENT_SPELL_NEEDLE: - me->CastCustomSpell(SPELL_NEEDLE_SPINE, SPELLVALUE_MAX_TARGETS, 3, me, false); - events.ScheduleEvent(EVENT_SPELL_NEEDLE, 15000); - break; - case EVENT_SPELL_SPINE: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1)) - { - me->CastSpell(target, SPELL_IMPALING_SPINE, false); - target->CastSpell(target, SPELL_SUMMON_IMPALING_SPINE, true); - Talk(SAY_NEEDLE); - } - events.ScheduleEvent(EVENT_SPELL_SPINE, 20000); - return; - case EVENT_YELL: - Talk(SAY_SPECIAL); - events.ScheduleEvent(EVENT_YELL, urand(25000, 100000)); - break; - } - - DoMeleeAttackIfReady(); - } +private: + bool _canTalk; }; class spell_najentus_needle_spine : public SpellScript