diff --git a/data/sql/updates/pending_db_world/shadowboltwhirl.sql b/data/sql/updates/pending_db_world/shadowboltwhirl.sql new file mode 100644 index 000000000..1b6f3d548 --- /dev/null +++ b/data/sql/updates/pending_db_world/shadowboltwhirl.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_script_names` WHERE `spell_id` = 24834; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(24834, 'spell_shadow_bolt_whirl'); diff --git a/src/server/scripts/World/boss_emerald_dragons.cpp b/src/server/scripts/World/boss_emerald_dragons.cpp index 84a9740f6..b667c468d 100644 --- a/src/server/scripts/World/boss_emerald_dragons.cpp +++ b/src/server/scripts/World/boss_emerald_dragons.cpp @@ -302,9 +302,6 @@ public: * --- * --- Dragonspecific scripts and handling: LETHON * --- - * - * @todo - * - Spell: Shadow bolt whirl casts needs custom handling (spellscript) */ enum LethonTexts @@ -318,6 +315,14 @@ enum LethonSpells SPELL_DRAW_SPIRIT = 24811, SPELL_SHADOW_BOLT_WHIRL = 24834, SPELL_DARK_OFFERING = 24804, + SPELL_SHADOW_BOLT_WHIRL1 = 24820, + SPELL_SHADOW_BOLT_WHIRL2 = 24821, + SPELL_SHADOW_BOLT_WHIRL3 = 24822, + SPELL_SHADOW_BOLT_WHIRL4 = 24823, + SPELL_SHADOW_BOLT_WHIRL5 = 24835, + SPELL_SHADOW_BOLT_WHIRL6 = 24836, + SPELL_SHADOW_BOLT_WHIRL7 = 24837, + SPELL_SHADOW_BOLT_WHIRL8 = 24838, }; enum LethonCreatures @@ -340,13 +345,14 @@ public: { _stage = 1; emerald_dragonAI::Reset(); - events.ScheduleEvent(EVENT_SHADOW_BOLT_WHIRL, 10000); + me->RemoveAurasDueToSpell(SPELL_SHADOW_BOLT_WHIRL); } void EnterCombat(Unit* who) override { Talk(SAY_LETHON_AGGRO); WorldBossAI::EnterCombat(who); + DoCastSelf(SPELL_SHADOW_BOLT_WHIRL, true); } void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override @@ -368,20 +374,6 @@ public: } } - void ExecuteEvent(uint32 eventId) override - { - switch (eventId) - { - case EVENT_SHADOW_BOLT_WHIRL: - me->CastSpell((Unit*)nullptr, SPELL_SHADOW_BOLT_WHIRL, false); - events.ScheduleEvent(EVENT_SHADOW_BOLT_WHIRL, urand(15000, 30000)); - break; - default: - emerald_dragonAI::ExecuteEvent(eventId); - break; - } - } - private: uint8 _stage; }; @@ -712,6 +704,41 @@ public: } }; +class spell_shadow_bolt_whirl : public AuraScript +{ + PrepareAuraScript(spell_shadow_bolt_whirl); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHADOW_BOLT_WHIRL1, SPELL_SHADOW_BOLT_WHIRL2, SPELL_SHADOW_BOLT_WHIRL3, SPELL_SHADOW_BOLT_WHIRL4, SPELL_SHADOW_BOLT_WHIRL5, SPELL_SHADOW_BOLT_WHIRL6, SPELL_SHADOW_BOLT_WHIRL7, SPELL_SHADOW_BOLT_WHIRL8 }); + } + + void HandlePeriodic(AuraEffect const* aurEff) + { + Unit* caster = GetCaster(); + Unit* target = GetTarget(); + + if (!caster || !target) + return; + std::array spellForTick = { SPELL_SHADOW_BOLT_WHIRL1, SPELL_SHADOW_BOLT_WHIRL2, SPELL_SHADOW_BOLT_WHIRL3, SPELL_SHADOW_BOLT_WHIRL4, SPELL_SHADOW_BOLT_WHIRL5, SPELL_SHADOW_BOLT_WHIRL6, SPELL_SHADOW_BOLT_WHIRL7, SPELL_SHADOW_BOLT_WHIRL8 }; + uint32 tick = (aurEff->GetTickNumber() + 7/*-1*/) % 8; + + // casted in left/right (but triggered spell have wide forward cone) + float forward = target->GetOrientation(); + if (tick <= 3) + target->SetOrientation(forward + 0.75f * M_PI - tick * M_PI / 8); // Left + else + target->SetOrientation(forward - 0.75f * M_PI + (8 - tick) * M_PI / 8); // Right + + target->CastSpell(target, spellForTick[tick], true); + target->SetOrientation(forward); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_shadow_bolt_whirl::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } +}; class spell_mark_of_nature : public SpellScriptLoader { public: @@ -765,4 +792,5 @@ void AddSC_emerald_dragons() // dragon spellscripts new spell_dream_fog_sleep(); new spell_mark_of_nature(); + RegisterSpellScript(spell_shadow_bolt_whirl); };