diff options
Diffstat (limited to 'src/server')
9 files changed, 2745 insertions, 3415 deletions
| diff --git a/src/server/scripts/Outland/BlackTemple/black_temple.cpp b/src/server/scripts/Outland/BlackTemple/black_temple.cpp index e43c26ec319..693d2be970d 100644 --- a/src/server/scripts/Outland/BlackTemple/black_temple.cpp +++ b/src/server/scripts/Outland/BlackTemple/black_temple.cpp @@ -57,274 +57,226 @@ enum Misc      GROUP_OUT_OF_COMBAT = 1  }; -// ######################################################## -// Wrathbone Flayer -// ######################################################## - -class npc_wrathbone_flayer : public CreatureScript +struct npc_wrathbone_flayer : public ScriptedAI  { -public: -    npc_wrathbone_flayer() : CreatureScript("npc_wrathbone_flayer") { } +    npc_wrathbone_flayer(Creature* creature) : ScriptedAI(creature) +    { +        Initialize(); +        _instance = creature->GetInstanceScript(); +    } -    struct npc_wrathbone_flayerAI : public ScriptedAI +    void Initialize()      { -        npc_wrathbone_flayerAI(Creature* creature) : ScriptedAI(creature) -        { -            Initialize(); -            _instance = creature->GetInstanceScript(); -        } +        _enteredCombat = false; +    } -        void Initialize() -        { -            _enteredCombat = false; -        } +    void Reset() override +    { +        _events.ScheduleEvent(EVENT_GET_CHANNELERS, 3000); +        Initialize(); +        _bloodmageList.clear(); +        _deathshaperList.clear(); +    } -        void Reset() override -        { -            _events.ScheduleEvent(EVENT_GET_CHANNELERS, 3000); -            Initialize(); -            _bloodmageList.clear(); -            _deathshaperList.clear(); -        } +    void JustDied(Unit* /*killer*/) override { } -        void JustDied(Unit* /*killer*/) override { } +    void EnterCombat(Unit* /*who*/) override +    { +        _events.ScheduleEvent(EVENT_CLEAVE, 5000); +        _events.ScheduleEvent(EVENT_IGNORED, 7000); +        _enteredCombat = true; +    } -        void EnterCombat(Unit* /*who*/) override +    void UpdateAI(uint32 diff) override +    { +        if (!_enteredCombat)          { -            _events.ScheduleEvent(EVENT_CLEAVE, 5000); -            _events.ScheduleEvent(EVENT_IGNORED, 7000); -            _enteredCombat = true; -        } +            _events.Update(diff); -        void UpdateAI(uint32 diff) override -        { -            if (!_enteredCombat) +            while (uint32 eventId = _events.ExecuteEvent())              { -                _events.Update(diff); - -                while (uint32 eventId = _events.ExecuteEvent()) +                switch (eventId)                  { -                    switch (eventId) +                    case EVENT_GET_CHANNELERS:                      { -                        case EVENT_GET_CHANNELERS: -                        { -                            std::list<Creature*> BloodMageList; -                            me->GetCreatureListWithEntryInGrid(BloodMageList, NPC_BLOOD_MAGE, 15.0f); - -                            if (!BloodMageList.empty()) -                                for (std::list<Creature*>::const_iterator itr = BloodMageList.begin(); itr != BloodMageList.end(); ++itr) -                                { -                                    _bloodmageList.push_back((*itr)->GetGUID()); -                                    if ((*itr)->isDead()) -                                        (*itr)->Respawn(); -                                } - -                            std::list<Creature*> DeathShaperList; -                            me->GetCreatureListWithEntryInGrid(DeathShaperList, NPC_DEATHSHAPER, 15.0f); - -                            if (!DeathShaperList.empty()) -                                for (std::list<Creature*>::const_iterator itr = DeathShaperList.begin(); itr != DeathShaperList.end(); ++itr) -                                { -                                    _deathshaperList.push_back((*itr)->GetGUID()); -                                    if ((*itr)->isDead()) -                                        (*itr)->Respawn(); -                                } - -                            _events.ScheduleEvent(EVENT_SET_CHANNELERS, 3000); - -                            break; -                        } -                        case EVENT_SET_CHANNELERS: -                        { -                            for (ObjectGuid guid : _bloodmageList) -                                if (Creature* bloodmage = ObjectAccessor::GetCreature(*me, guid)) -                                    bloodmage->CastSpell(nullptr, SPELL_SUMMON_CHANNEL); - -                            for (ObjectGuid guid : _deathshaperList) -                                if (Creature* deathshaper = ObjectAccessor::GetCreature(*me, guid)) -                                    deathshaper->CastSpell(nullptr, SPELL_SUMMON_CHANNEL); - -                            _events.ScheduleEvent(EVENT_SET_CHANNELERS, 12000); - -                            break; -                        } -                        default: -                            break; +                        std::list<Creature*> BloodMageList; +                        me->GetCreatureListWithEntryInGrid(BloodMageList, NPC_BLOOD_MAGE, 15.0f); + +                        if (!BloodMageList.empty()) +                            for (std::list<Creature*>::const_iterator itr = BloodMageList.begin(); itr != BloodMageList.end(); ++itr) +                            { +                                _bloodmageList.push_back((*itr)->GetGUID()); +                                if ((*itr)->isDead()) +                                    (*itr)->Respawn(); +                            } + +                        std::list<Creature*> DeathShaperList; +                        me->GetCreatureListWithEntryInGrid(DeathShaperList, NPC_DEATHSHAPER, 15.0f); + +                        if (!DeathShaperList.empty()) +                            for (std::list<Creature*>::const_iterator itr = DeathShaperList.begin(); itr != DeathShaperList.end(); ++itr) +                            { +                                _deathshaperList.push_back((*itr)->GetGUID()); +                                if ((*itr)->isDead()) +                                    (*itr)->Respawn(); +                            } + +                        _events.ScheduleEvent(EVENT_SET_CHANNELERS, 3000); + +                        break;                      } -                } -            } +                    case EVENT_SET_CHANNELERS: +                    { +                        for (ObjectGuid guid : _bloodmageList) +                            if (Creature* bloodmage = ObjectAccessor::GetCreature(*me, guid)) +                                bloodmage->CastSpell(nullptr, SPELL_SUMMON_CHANNEL); -            if (!UpdateVictim()) -                return; +                        for (ObjectGuid guid : _deathshaperList) +                            if (Creature* deathshaper = ObjectAccessor::GetCreature(*me, guid)) +                                deathshaper->CastSpell(nullptr, SPELL_SUMMON_CHANNEL); -            _events.Update(diff); +                        _events.ScheduleEvent(EVENT_SET_CHANNELERS, 12000); -            while (uint32 eventId = _events.ExecuteEvent()) -            { -                switch (eventId) -                { -                    case EVENT_CLEAVE: -                        DoCastVictim(SPELL_CLEAVE); -                        _events.ScheduleEvent(EVENT_CLEAVE, urand (1000, 2000)); -                        break; -                    case EVENT_IGNORED: -                        if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) -                            DoCast(target, SPELL_IGNORED); -                        _events.ScheduleEvent(EVENT_IGNORED, 10000);                          break; +                    }                      default:                          break;                  }              } -            DoMeleeAttackIfReady();          } -        private: -            InstanceScript* _instance; -            EventMap _events; -            GuidList _bloodmageList; -            GuidList _deathshaperList; -            bool _enteredCombat; -        }; +        if (!UpdateVictim()) +            return; -    CreatureAI* GetAI(Creature* creature) const override -    { -        return GetBlackTempleAI<npc_wrathbone_flayerAI>(creature); +        _events.Update(diff); + +        while (uint32 eventId = _events.ExecuteEvent()) +        { +            switch (eventId) +            { +                case EVENT_CLEAVE: +                    DoCastVictim(SPELL_CLEAVE); +                    _events.ScheduleEvent(EVENT_CLEAVE, urand(1000, 2000)); +                    break; +                case EVENT_IGNORED: +                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) +                        DoCast(target, SPELL_IGNORED); +                    _events.ScheduleEvent(EVENT_IGNORED, 10000); +                    break; +                default: +                    break; +            } +        } +        DoMeleeAttackIfReady();      } + +private: +    InstanceScript* _instance; +    EventMap _events; +    GuidList _bloodmageList; +    GuidList _deathshaperList; +    bool _enteredCombat;  }; -class npc_angered_soul_fragment : public CreatureScript +struct npc_angered_soul_fragment : public ScriptedAI  { -public: -    npc_angered_soul_fragment() : CreatureScript("npc_angered_soul_fragment") { } +    npc_angered_soul_fragment(Creature* creature) : ScriptedAI(creature) { } -    struct npc_angered_soul_fragmentAI : public ScriptedAI +    void Reset() override      { -        npc_angered_soul_fragmentAI(Creature* creature) : ScriptedAI(creature) { } +        _scheduler.CancelAll(); -        void Reset() override +        _scheduler.Schedule(Seconds(1), GROUP_OUT_OF_COMBAT, [this](TaskContext invi)          { -            _scheduler.CancelAll(); +            DoCastSelf(SPELL_GREATER_INVISIBILITY); -            _scheduler.Schedule(Seconds(1), GROUP_OUT_OF_COMBAT, [this](TaskContext invi) +            /* Workaround - On Retail creature appear and "vanish" again periodically, but i cant find packets +            with UPDATE_AURA on sniffs about it */ +            _scheduler.Schedule(Seconds(5), Seconds(10), GROUP_OUT_OF_COMBAT, [this](TaskContext /*context*/)              { -                DoCastSelf(SPELL_GREATER_INVISIBILITY); - -                /* Workaround - On Retail creature appear and "vanish" again periodically, but i cant find packets -                with UPDATE_AURA on sniffs about it */ -                _scheduler.Schedule(Seconds(5), Seconds(10), GROUP_OUT_OF_COMBAT, [this](TaskContext /*context*/) -                { -                    me->RemoveAurasDueToSpell(SPELL_GREATER_INVISIBILITY); -                }); - -                invi.Repeat(Seconds(15), Seconds(25)); +                me->RemoveAurasDueToSpell(SPELL_GREATER_INVISIBILITY);              }); -        } -        void EnterCombat(Unit* /*who*/) override -        { -            me->RemoveAurasDueToSpell(SPELL_GREATER_INVISIBILITY); +            invi.Repeat(Seconds(15), Seconds(25)); +        }); +    } -            _scheduler.CancelGroup(GROUP_OUT_OF_COMBAT); -            _scheduler.Schedule(Seconds(1), [this](TaskContext anger) -            { -                Unit* target = me->GetVictim(); -                if (target && me->IsWithinMeleeRange(target)) -                    DoCastSelf(SPELL_ANGER); -                else -                    anger.Repeat(Seconds(1)); -            }); -        } +    void EnterCombat(Unit* /*who*/) override +    { +        me->RemoveAurasDueToSpell(SPELL_GREATER_INVISIBILITY); -        void UpdateAI(uint32 diff) override +        _scheduler.CancelGroup(GROUP_OUT_OF_COMBAT); +        _scheduler.Schedule(Seconds(1), [this](TaskContext anger)          { -            _scheduler.Update(diff); - -            if (!UpdateVictim()) -                return; +            Unit* target = me->GetVictim(); +            if (target && me->IsWithinMeleeRange(target)) +                DoCastSelf(SPELL_ANGER); +            else +                anger.Repeat(Seconds(1)); +        }); +    } -            if (me->HasUnitState(UNIT_STATE_CASTING)) -                return; +    void UpdateAI(uint32 diff) override +    { +        _scheduler.Update(diff); -            DoMeleeAttackIfReady(); -        } +        if (!UpdateVictim()) +            return; -    private: -        TaskScheduler _scheduler; -    }; +        if (me->HasUnitState(UNIT_STATE_CASTING)) +            return; -    CreatureAI* GetAI(Creature* creature) const override -    { -        return GetBlackTempleAI<npc_angered_soul_fragmentAI>(creature); +        DoMeleeAttackIfReady();      } + +private: +    TaskScheduler _scheduler;  };  // 41986 - Anger -class spell_soul_fragment_anger : public SpellScriptLoader +class spell_soul_fragment_anger : public SpellScript  { -    public: -        spell_soul_fragment_anger() : SpellScriptLoader("spell_soul_fragment_anger") { } - -        class spell_soul_fragment_anger_SpellScript : public SpellScript -        { -            PrepareSpellScript(spell_soul_fragment_anger_SpellScript); +    PrepareSpellScript(spell_soul_fragment_anger); -            void HandleKill() -            { -                if (Creature* caster = GetCaster()->ToCreature()) -                    caster->DespawnOrUnsummon(Milliseconds(200)); -            } - -            void Register() override -            { -                AfterCast += SpellCastFn(spell_soul_fragment_anger_SpellScript::HandleKill); -            } -        }; +    void HandleKill() +    { +        if (Creature* caster = GetCaster()->ToCreature()) +            caster->DespawnOrUnsummon(Milliseconds(200)); +    } -        SpellScript* GetSpellScript() const override -        { -            return new spell_soul_fragment_anger_SpellScript(); -        } +    void Register() override +    { +        AfterCast += SpellCastFn(spell_soul_fragment_anger::HandleKill); +    }  };  // 39645 - Shadow Inferno -class spell_illidari_nightlord_shadow_inferno : public SpellScriptLoader +class spell_illidari_nightlord_shadow_inferno : public AuraScript  { -    public: -        spell_illidari_nightlord_shadow_inferno() : SpellScriptLoader("spell_illidari_nightlord_shadow_inferno") { } - -        class spell_illidari_nightlord_shadow_inferno_AuraScript : public AuraScript -        { -            PrepareAuraScript(spell_illidari_nightlord_shadow_inferno_AuraScript); +    PrepareAuraScript(spell_illidari_nightlord_shadow_inferno); -            bool Validate(SpellInfo const* /*spellInfo*/) override -            { -                return ValidateSpellInfo({ SPELL_SHADOW_INFERNO_DAMAGE }); -            } - -            void OnPeriodic(AuraEffect const* aurEffect) -            { -                PreventDefaultAction(); -                int32 bp = aurEffect->GetTickNumber() * aurEffect->GetAmount(); -                GetUnitOwner()->CastCustomSpell(SPELL_SHADOW_INFERNO_DAMAGE, SPELLVALUE_BASE_POINT0, bp, GetUnitOwner(), true); -            } +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo({ SPELL_SHADOW_INFERNO_DAMAGE }); +    } -            void Register() override -            { -                OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidari_nightlord_shadow_inferno_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); -            } -        }; +    void OnPeriodic(AuraEffect const* aurEffect) +    { +        PreventDefaultAction(); +        int32 bp = aurEffect->GetTickNumber() * aurEffect->GetAmount(); +        GetUnitOwner()->CastCustomSpell(SPELL_SHADOW_INFERNO_DAMAGE, SPELLVALUE_BASE_POINT0, bp, GetUnitOwner(), true); +    } -        AuraScript* GetAuraScript() const override -        { -            return new spell_illidari_nightlord_shadow_inferno_AuraScript(); -        } +    void Register() override +    { +        OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidari_nightlord_shadow_inferno::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); +    }  };  void AddSC_black_temple()  { -    new npc_wrathbone_flayer(); -    new npc_angered_soul_fragment(); -    new spell_soul_fragment_anger(); -    new spell_illidari_nightlord_shadow_inferno(); +    RegisterBlackTempleCreatureAI(npc_wrathbone_flayer); +    RegisterBlackTempleCreatureAI(npc_angered_soul_fragment); +    RegisterSpellScript(spell_soul_fragment_anger); +    RegisterAuraScript(spell_illidari_nightlord_shadow_inferno);  } diff --git a/src/server/scripts/Outland/BlackTemple/boss_gurtogg_bloodboil.cpp b/src/server/scripts/Outland/BlackTemple/boss_gurtogg_bloodboil.cpp index 037eaa82d99..7e743b1c62e 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_gurtogg_bloodboil.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_gurtogg_bloodboil.cpp @@ -89,322 +89,279 @@ enum Events      EVENT_CHARGE_PLAYER  }; -class boss_gurtogg_bloodboil : public CreatureScript + +struct boss_gurtogg_bloodboil : public BossAI  { -public: -    boss_gurtogg_bloodboil() : CreatureScript("boss_gurtogg_bloodboil") { } +    boss_gurtogg_bloodboil(Creature* creature) : BossAI(creature, DATA_GURTOGG_BLOODBOIL) +    { +        Initialize(); +    } -    struct boss_gurtogg_bloodboilAI : public BossAI +    void Reset() override      { -        boss_gurtogg_bloodboilAI(Creature* creature) : BossAI(creature, DATA_GURTOGG_BLOODBOIL) -        { -            Initialize(); -        } +        _Reset(); +        Initialize(); +        events.SetPhase(PHASE_1); +        me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); +        me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false); +    } -        void Reset() override -        { -            _Reset(); -            Initialize(); -            events.SetPhase(PHASE_1); -            me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); -            me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false); -        } +    void Initialize() +    { +        _oldThreat = 0.0f; +        _oldTargetGUID.Clear(); +        _targetGUID.Clear(); +    } -        void Initialize() -        { -            _oldThreat = 0.0f; -            _oldTargetGUID.Clear(); -            _targetGUID.Clear(); -        } +    bool CanAIAttack(Unit const* who) const override +    { +        return BossAI::CanAIAttack(who) && !who->HasAura(SPELL_BEWILDERING_STRIKE); +    } -        bool CanAIAttack(Unit const* who) const override -        { -            return BossAI::CanAIAttack(who) && !who->HasAura(SPELL_BEWILDERING_STRIKE); -        } +    void AttackStart(Unit* who) override +    { +        if (!CanAIAttack(who)) +            return; -        void AttackStart(Unit* who) override -        { -            if (!CanAIAttack(who)) -                return; +        BossAI::AttackStart(who); +    } -            BossAI::AttackStart(who); -        } +    void EnterCombat(Unit* /*who*/) override +    { +        Talk(SAY_AGGRO); +        _EnterCombat(); +        events.ScheduleEvent(EVENT_BERSERK, Minutes(10)); +        events.ScheduleEvent(EVENT_CHANGE_PHASE, Seconds(60)); +        ScheduleEvents(); +    } -        void EnterCombat(Unit* /*who*/) override -        { -            Talk(SAY_AGGRO); -            _EnterCombat(); -            events.ScheduleEvent(EVENT_BERSERK, Minutes(10)); -            events.ScheduleEvent(EVENT_CHANGE_PHASE, Seconds(60)); -            ScheduleEvents(); -        } +    void EnterEvadeMode(EvadeReason /*why*/) override +    { +        _DespawnAtEvade(); +    } -        void EnterEvadeMode(EvadeReason /*why*/) override +    void ScheduleEvents() +    { +        if (events.IsInPhase(PHASE_1))          { -            _DespawnAtEvade(); +            events.ScheduleEvent(EVENT_BLOODBOIL, Seconds(10), GROUP_PHASE_1, PHASE_1); +            events.ScheduleEvent(EVENT_ARCING_SMASH, Seconds(10), GROUP_PHASE_1, PHASE_1); +            events.ScheduleEvent(EVENT_FEL_ACID_BREATH, Seconds(25), GROUP_PHASE_1, PHASE_1); +            events.ScheduleEvent(EVENT_EJECT, Seconds(35), GROUP_PHASE_1, PHASE_1); +            events.ScheduleEvent(EVENT_BEWILDERING_STRIKE, Seconds(47), GROUP_PHASE_1, PHASE_1);          } - -        void ScheduleEvents() +        else if (events.IsInPhase(PHASE_2))          { -            if (events.IsInPhase(PHASE_1)) -            { -                events.ScheduleEvent(EVENT_BLOODBOIL, Seconds(10), GROUP_PHASE_1, PHASE_1); -                events.ScheduleEvent(EVENT_ARCING_SMASH, Seconds(10), GROUP_PHASE_1, PHASE_1); -                events.ScheduleEvent(EVENT_FEL_ACID_BREATH, Seconds(25), GROUP_PHASE_1, PHASE_1); -                events.ScheduleEvent(EVENT_EJECT, Seconds(35), GROUP_PHASE_1, PHASE_1); -                events.ScheduleEvent(EVENT_BEWILDERING_STRIKE, Seconds(47), GROUP_PHASE_1, PHASE_1); -            } -            else if (events.IsInPhase(PHASE_2)) -            { -                events.ScheduleEvent(EVENT_START_PHASE_2, Milliseconds(100), GROUP_PHASE_2, PHASE_2); -                events.ScheduleEvent(EVENT_EJECT_2, Seconds(14), GROUP_PHASE_2, PHASE_2); -                events.ScheduleEvent(EVENT_FEL_ACID_BREATH_2, Seconds(16), GROUP_PHASE_2, PHASE_2); -                events.ScheduleEvent(EVENT_ARCING_SMASH_2, Seconds(8), GROUP_PHASE_2, PHASE_2); -            } +            events.ScheduleEvent(EVENT_START_PHASE_2, Milliseconds(100), GROUP_PHASE_2, PHASE_2); +            events.ScheduleEvent(EVENT_EJECT_2, Seconds(14), GROUP_PHASE_2, PHASE_2); +            events.ScheduleEvent(EVENT_FEL_ACID_BREATH_2, Seconds(16), GROUP_PHASE_2, PHASE_2); +            events.ScheduleEvent(EVENT_ARCING_SMASH_2, Seconds(8), GROUP_PHASE_2, PHASE_2);          } +    } -        void KilledUnit(Unit* victim) override -        { -            if (victim->GetTypeId() == TYPEID_PLAYER) -                Talk(SAY_SLAY); -        } +    void KilledUnit(Unit* victim) override +    { +        if (victim->GetTypeId() == TYPEID_PLAYER) +            Talk(SAY_SLAY); +    } -        void JustDied(Unit* /*killer*/) override -        { -            _JustDied(); -            DoPlaySoundToSet(me, SOUND_ID_DEATH); -        } +    void JustDied(Unit* /*killer*/) override +    { +        _JustDied(); +        DoPlaySoundToSet(me, SOUND_ID_DEATH); +    } -        void UpdateAI(uint32 diff) override -        { -            if (!UpdateVictim()) -                return; +    void UpdateAI(uint32 diff) override +    { +        if (!UpdateVictim()) +            return; -            if (me->HasUnitState(UNIT_STATE_CASTING)) -                 return; +        if (me->HasUnitState(UNIT_STATE_CASTING)) +            return; -            events.Update(diff); +        events.Update(diff); -            while (uint32 eventId = events.ExecuteEvent()) +        while (uint32 eventId = events.ExecuteEvent()) +        { +            switch (eventId)              { -                switch (eventId) -                { -                    case EVENT_BLOODBOIL: -                        DoCast(SPELL_BLOODBOIL); -                        events.Repeat(Seconds(10)); -                        break; -                    case EVENT_ARCING_SMASH: -                        DoCastVictim(SPELL_ARCING_SMASH); -                        events.Repeat(Seconds(10)); -                        break; -                    case EVENT_FEL_ACID_BREATH: -                        if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, me->GetCombatReach())) -                            DoCast(target, SPELL_FEL_ACID_BREATH); -                        events.Repeat(Seconds(25), Seconds(30)); -                        break; -                    case EVENT_EJECT: -                        Talk(SAY_SPECIAL); -                        DoCastVictim(SPELL_EJECT); -                        break; -                    case EVENT_BEWILDERING_STRIKE: -                        DoCastVictim(SPELL_BEWILDERING_STRIKE); -                        break; -                    case EVENT_CHANGE_PHASE: -                        ChangePhase(); -                        break; -                    case EVENT_START_PHASE_2: -                        if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) -                        { -                            if (Unit* oldTarget = me->GetVictim()) -                            { -                                _oldTargetGUID = oldTarget->GetGUID(); -                                _oldThreat = GetThreat(oldTarget); -                            } -                            _targetGUID = target->GetGUID(); -                            DoCastSelf(SPELL_FEL_RAGE_SELF, true); -                            DoCast(target, SPELL_FEL_RAGE_TARGET, true); -                            DoCast(target, SPELL_FEL_RAGE_2, true); -                            DoCast(target, SPELL_FEL_RAGE_3, true); -                            DoCast(target, SPELL_FEL_GEYSER, true); -                            DoCast(target, SPELL_FEL_RAGE_TARGET_2, true); -                            target->CastSpell(target, SPELL_FEL_RAGE_P, true); -                            target->CastSpell(target, SPELL_TAUNT_GURTOGG, true); -                            DoCastAOE(SPELL_INSIGNIFIGANCE, true); - -                            events.ScheduleEvent(EVENT_CHARGE_PLAYER, Seconds(2), GROUP_PHASE_2, PHASE_2); - -                            me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); -                            me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); -                        } -                        else // If no other targets are found, reset phase 1 +                case EVENT_BLOODBOIL: +                    DoCast(SPELL_BLOODBOIL); +                    events.Repeat(Seconds(10)); +                    break; +                case EVENT_ARCING_SMASH: +                    DoCastVictim(SPELL_ARCING_SMASH); +                    events.Repeat(Seconds(10)); +                    break; +                case EVENT_FEL_ACID_BREATH: +                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, me->GetCombatReach())) +                        DoCast(target, SPELL_FEL_ACID_BREATH); +                    events.Repeat(Seconds(25), Seconds(30)); +                    break; +                case EVENT_EJECT: +                    Talk(SAY_SPECIAL); +                    DoCastVictim(SPELL_EJECT); +                    break; +                case EVENT_BEWILDERING_STRIKE: +                    DoCastVictim(SPELL_BEWILDERING_STRIKE); +                    break; +                case EVENT_CHANGE_PHASE: +                    ChangePhase(); +                    break; +                case EVENT_START_PHASE_2: +                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) +                    { +                        if (Unit* oldTarget = me->GetVictim())                          { -                            events.SetPhase(PHASE_1); -                            events.CancelEventGroup(GROUP_PHASE_2); -                            ScheduleEvents(); -                            events.RescheduleEvent(EVENT_CHANGE_PHASE, Seconds(60)); +                            _oldTargetGUID = oldTarget->GetGUID(); +                            _oldThreat = GetThreat(oldTarget);                          } -                        break; -                    case EVENT_CHARGE_PLAYER: -                        if (Unit* target = ObjectAccessor::GetUnit(*me, _targetGUID)) -                            DoCast(target, SPELL_CHARGE); -                        break; -                    case EVENT_EJECT_2: -                        DoCastVictim(SPELL_EJECT_2); -                        break; -                    case EVENT_FEL_ACID_BREATH_2: -                        DoCastVictim(SPELL_FEL_ACID_BREATH_2); -                        break; -                    case EVENT_ARCING_SMASH_2: -                        DoCastVictim(SPELL_ARCING_SMASH_2); -                        events.Repeat(Seconds(13)); -                        break; -                    case EVENT_BERSERK: -                        DoCast(SPELL_BERSERK); -                        roll_chance_i(50) ? Talk(SAY_ENRAGE) : DoPlaySoundToSet(me, SOUND_ID_ENRAGE); -                        break; -                    default: -                        break; -                } -                if (me->HasUnitState(UNIT_STATE_CASTING)) -                    return; -            } - -            DoMeleeAttackIfReady(); -        } - -        void ChangePhase() -        { -            if (events.IsInPhase(PHASE_1)) -            { -                events.SetPhase(PHASE_2); -                events.CancelEventGroup(GROUP_PHASE_1); -                events.ScheduleEvent(EVENT_CHANGE_PHASE, Seconds(30)); -                ScheduleEvents(); -            } -            else if (events.IsInPhase(PHASE_2)) -            { -                events.SetPhase(PHASE_1); -                events.CancelEventGroup(GROUP_PHASE_2); -                events.ScheduleEvent(EVENT_CHANGE_PHASE, Seconds(60)); -                me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); -                me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false); -                ScheduleEvents(); - -                // Attack the stored target -                if (Unit* oldTarget = ObjectAccessor::GetUnit(*me, _oldTargetGUID)) -                    if (Unit* currentTarget = ObjectAccessor::GetUnit(*me, _targetGUID)) +                        _targetGUID = target->GetGUID(); +                        DoCastSelf(SPELL_FEL_RAGE_SELF, true); +                        DoCast(target, SPELL_FEL_RAGE_TARGET, true); +                        DoCast(target, SPELL_FEL_RAGE_2, true); +                        DoCast(target, SPELL_FEL_RAGE_3, true); +                        DoCast(target, SPELL_FEL_GEYSER, true); +                        DoCast(target, SPELL_FEL_RAGE_TARGET_2, true); +                        target->CastSpell(target, SPELL_FEL_RAGE_P, true); +                        target->CastSpell(target, SPELL_TAUNT_GURTOGG, true); +                        DoCastAOE(SPELL_INSIGNIFIGANCE, true); + +                        events.ScheduleEvent(EVENT_CHARGE_PLAYER, Seconds(2), GROUP_PHASE_2, PHASE_2); + +                        me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); +                        me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); +                    } +                    else // If no other targets are found, reset phase 1                      { -                        ModifyThreatByPercent(currentTarget, -100); -                        AttackStart(oldTarget); -                        AddThreat(oldTarget, _oldThreat); -                        Initialize(); +                        events.SetPhase(PHASE_1); +                        events.CancelEventGroup(GROUP_PHASE_2); +                        ScheduleEvents(); +                        events.RescheduleEvent(EVENT_CHANGE_PHASE, Seconds(60));                      } +                    break; +                case EVENT_CHARGE_PLAYER: +                    if (Unit* target = ObjectAccessor::GetUnit(*me, _targetGUID)) +                        DoCast(target, SPELL_CHARGE); +                    break; +                case EVENT_EJECT_2: +                    DoCastVictim(SPELL_EJECT_2); +                    break; +                case EVENT_FEL_ACID_BREATH_2: +                    DoCastVictim(SPELL_FEL_ACID_BREATH_2); +                    break; +                case EVENT_ARCING_SMASH_2: +                    DoCastVictim(SPELL_ARCING_SMASH_2); +                    events.Repeat(Seconds(13)); +                    break; +                case EVENT_BERSERK: +                    DoCast(SPELL_BERSERK); +                    roll_chance_i(50) ? Talk(SAY_ENRAGE) : DoPlaySoundToSet(me, SOUND_ID_ENRAGE); +                    break; +                default: +                    break;              } +            if (me->HasUnitState(UNIT_STATE_CASTING)) +                return;          } -    private: -        ObjectGuid _targetGUID; -        ObjectGuid _oldTargetGUID; -        float _oldThreat; -    }; +        DoMeleeAttackIfReady(); +    } -    CreatureAI* GetAI(Creature* creature) const override +    void ChangePhase()      { -        return GetBlackTempleAI<boss_gurtogg_bloodboilAI>(creature); +        if (events.IsInPhase(PHASE_1)) +        { +            events.SetPhase(PHASE_2); +            events.CancelEventGroup(GROUP_PHASE_1); +            events.ScheduleEvent(EVENT_CHANGE_PHASE, Seconds(30)); +            ScheduleEvents(); +        } +        else if (events.IsInPhase(PHASE_2)) +        { +            events.SetPhase(PHASE_1); +            events.CancelEventGroup(GROUP_PHASE_2); +            events.ScheduleEvent(EVENT_CHANGE_PHASE, Seconds(60)); +            me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); +            me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false); +            ScheduleEvents(); + +            // Attack the stored target +            if (Unit* oldTarget = ObjectAccessor::GetUnit(*me, _oldTargetGUID)) +                if (Unit* currentTarget = ObjectAccessor::GetUnit(*me, _targetGUID)) +                { +                    ModifyThreatByPercent(currentTarget, -100); +                    AttackStart(oldTarget); +                    AddThreat(oldTarget, _oldThreat); +                    Initialize(); +                } +        }      } + +private: +    ObjectGuid _targetGUID; +    ObjectGuid _oldTargetGUID; +    float _oldThreat;  }; -class npc_fel_geyser : public CreatureScript +struct npc_fel_geyser : public PassiveAI  { -public: -    npc_fel_geyser() : CreatureScript("npc_fel_geyser") { } - -    struct npc_fel_geyserAI : public PassiveAI -    { -        npc_fel_geyserAI(Creature* creature) : PassiveAI(creature) { } - -        void Reset() override -        { -            DoCastSelf(SPELL_FEL_GEYSER_2, true); -            DoCastSelf(SPELL_BIRTH, true); -        } -    }; +    npc_fel_geyser(Creature* creature) : PassiveAI(creature) { } -    CreatureAI* GetAI(Creature* creature) const override +    void Reset() override      { -        return GetBlackTempleAI<npc_fel_geyserAI>(creature); +        DoCastSelf(SPELL_FEL_GEYSER_2, true); +        DoCastSelf(SPELL_BIRTH, true);      }  };  // 42005 - Bloodboil -class spell_gurtogg_bloodboil_bloodboil : public SpellScriptLoader +class spell_gurtogg_bloodboil_bloodboil : public SpellScript  { -    public: -        spell_gurtogg_bloodboil_bloodboil() : SpellScriptLoader("spell_gurtogg_bloodboil_bloodboil") { } - -        class spell_gurtogg_bloodboil_bloodboil_SpellScript : public SpellScript -        { -            PrepareSpellScript(spell_gurtogg_bloodboil_bloodboil_SpellScript); - -            void FilterTargets(std::list<WorldObject*>& targets) -            { -                if (targets.size() <= 5) -                    return; +    PrepareSpellScript(spell_gurtogg_bloodboil_bloodboil); -                // Sort the list of players -                targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster(), false)); -                // Resize so we only get top 5 -                targets.resize(5); -            } +    void FilterTargets(std::list<WorldObject*>& targets) +    { +        if (targets.size() <= 5) +            return; -            void Register() override -            { -                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gurtogg_bloodboil_bloodboil_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); -            } -        }; +        // Sort the list of players +        targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster(), false)); +        // Resize so we only get top 5 +        targets.resize(5); +    } -        SpellScript* GetSpellScript() const override -        { -            return new spell_gurtogg_bloodboil_bloodboil_SpellScript(); -        } +    void Register() override +    { +        OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gurtogg_bloodboil_bloodboil::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +    }  };  // 40618 - Insignificance -class spell_gurtogg_bloodboil_insignificance : public SpellScriptLoader +class spell_gurtogg_bloodboil_insignificance : public SpellScript  { -public: -    spell_gurtogg_bloodboil_insignificance() : SpellScriptLoader("spell_gurtogg_bloodboil_insignificance") { } +    PrepareSpellScript(spell_gurtogg_bloodboil_insignificance); -    class spell_gurtogg_bloodboil_insignificance_SpellScript : public SpellScript +    bool Validate(SpellInfo const* /*spell*/) override      { -        PrepareSpellScript(spell_gurtogg_bloodboil_insignificance_SpellScript); - -        bool Validate(SpellInfo const* /*spell*/) override -        { -            return ValidateSpellInfo({ SPELL_FEL_RAGE_TARGET }); -        } - -        void FilterTargets(std::list<WorldObject*>& targets) -        { -            targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_FEL_RAGE_TARGET)); -        } +        return ValidateSpellInfo({ SPELL_FEL_RAGE_TARGET }); +    } -        void Register() override -        { -            OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gurtogg_bloodboil_insignificance_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); -        } -    }; +    void FilterTargets(std::list<WorldObject*>& targets) +    { +        targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_FEL_RAGE_TARGET)); +    } -    SpellScript* GetSpellScript() const override +    void Register() override      { -        return new spell_gurtogg_bloodboil_insignificance_SpellScript(); +        OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gurtogg_bloodboil_insignificance::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);      }  };  void AddSC_boss_gurtogg_bloodboil()  { -    new boss_gurtogg_bloodboil(); -    new npc_fel_geyser(); -    new spell_gurtogg_bloodboil_bloodboil(); -    new spell_gurtogg_bloodboil_insignificance(); +    RegisterBlackTempleCreatureAI(boss_gurtogg_bloodboil); +    RegisterBlackTempleCreatureAI(npc_fel_geyser); +    RegisterSpellScript(spell_gurtogg_bloodboil_bloodboil); +    RegisterSpellScript(spell_gurtogg_bloodboil_insignificance);  } diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp index 245f7960628..72597d52d42 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp @@ -27,63 +27,63 @@  enum Says  { -    SAY_COUNCIL_AGRO        = 0, -    SAY_COUNCIL_ENRAGE      = 1, -    SAY_COUNCIL_SPECIAL     = 2, -    SAY_COUNCIL_SLAY        = 3, -    SAY_COUNCIL_COMNT       = 4, -    SAY_COUNCIL_DEATH       = 5 +    SAY_COUNCIL_AGRO     = 0, +    SAY_COUNCIL_ENRAGE   = 1, +    SAY_COUNCIL_SPECIAL  = 2, +    SAY_COUNCIL_SLAY     = 3, +    SAY_COUNCIL_COMNT    = 4, +    SAY_COUNCIL_DEATH    = 5  };  enum Spells  {      // Illidari Council (Trigger) -    SPELL_EMPYREAL_BALANCE              = 41499, -    SPELL_EMPYREAL_EQUIVALENCY          = 41333, +    SPELL_EMPYREAL_BALANCE         = 41499, +    SPELL_EMPYREAL_EQUIVALENCY     = 41333,      // Generic -    SPELL_SHARED_RULE                   = 41342, -    SPELL_BERSERK                       = 45078, -    SPELL_BALANCE_OF_POWER              = 41341, -    SPELL_QUIET_SUICIDE                 = 3617, // Serverside spell +    SPELL_SHARED_RULE              = 41342, +    SPELL_BERSERK                  = 45078, +    SPELL_BALANCE_OF_POWER         = 41341, +    SPELL_QUIET_SUICIDE            = 3617,      // High Nethermancer Zerevor's -    SPELL_FLAMESTRIKE                   = 41481, -    SPELL_BLIZZARD                      = 41482, -    SPELL_ARCANE_BOLT                   = 41483, -    SPELL_ARCANE_EXPLOSION              = 41524, -    SPELL_DAMPEN_MAGIC                  = 41478, +    SPELL_FLAMESTRIKE              = 41481, +    SPELL_BLIZZARD                 = 41482, +    SPELL_ARCANE_BOLT              = 41483, +    SPELL_ARCANE_EXPLOSION         = 41524, +    SPELL_DAMPEN_MAGIC             = 41478,      // Lady Malande's -    SPELL_EMPOWERED_SMITE               = 41471, -    SPELL_CIRCLE_OF_HEALING             = 41455, -    SPELL_REFLECTIVE_SHIELD             = 41475, -    SPELL_REFLECTIVE_SHIELD_DAMAGE      = 33619, -    SPELL_DIVINE_WRATH                  = 41472, +    SPELL_EMPOWERED_SMITE          = 41471, +    SPELL_CIRCLE_OF_HEALING        = 41455, +    SPELL_REFLECTIVE_SHIELD        = 41475, +    SPELL_REFLECTIVE_SHIELD_DAMAGE = 33619, +    SPELL_DIVINE_WRATH             = 41472,      // Gathios the Shatterer's -    SPELL_BLESS_PROTECTION              = 41450, -    SPELL_BLESS_SPELL_WARDING           = 41451, -    SPELL_CONSECRATION                  = 41541, -    SPELL_HAMMER_OF_JUSTICE             = 41468, -    SPELL_SEAL_OF_COMMAND               = 41469, -    SPELL_SEAL_OF_BLOOD                 = 41459, -    SPELL_CHROMATIC_AURA                = 41453, -    SPELL_DEVOTION_AURA                 = 41452, -    SPELL_JUDGEMENT_PRIMER              = 41473, -    SPELL_JUDGEMENT                     = 41467, -    SPELL_JUDGEMENT_OF_COMMAND          = 41470, -    SPELL_JUDGEMENT_OF_BLOOD            = 41461, +    SPELL_BLESS_PROTECTION         = 41450, +    SPELL_BLESS_SPELL_WARDING      = 41451, +    SPELL_CONSECRATION             = 41541, +    SPELL_HAMMER_OF_JUSTICE        = 41468, +    SPELL_SEAL_OF_COMMAND          = 41469, +    SPELL_SEAL_OF_BLOOD            = 41459, +    SPELL_CHROMATIC_AURA           = 41453, +    SPELL_DEVOTION_AURA            = 41452, +    SPELL_JUDGEMENT_PRIMER         = 41473, +    SPELL_JUDGEMENT                = 41467, +    SPELL_JUDGEMENT_OF_COMMAND     = 41470, +    SPELL_JUDGEMENT_OF_BLOOD       = 41461,      // Veras Darkshadow's -    SPELL_DEADLY_STRIKE                 = 41480, -    SPELL_DEADLY_POISON                 = 41485, -    SPELL_ENVENOM                       = 41487, -    SPELL_VANISH                        = 41476, +    SPELL_DEADLY_STRIKE             = 41480, +    SPELL_DEADLY_POISON             = 41485, +    SPELL_ENVENOM                   = 41487, +    SPELL_VANISH                    = 41476,      // Veras Vanish Effect -    SPELL_BIRTH                         = 40031, -    SPELL_ENVENOM_DUMMY                 = 41510 +    SPELL_BIRTH                     = 40031, +    SPELL_ENVENOM_DUMMY             = 41510  };  enum IllidariEvents @@ -131,123 +131,113 @@ static uint32 GetRandomBossExcept(uint32 exception)      return bossData[urand(0, 3)];  } -class boss_illidari_council : public CreatureScript +struct boss_illidari_council : public BossAI  { -public: -    boss_illidari_council() : CreatureScript("boss_illidari_council") { } +    boss_illidari_council(Creature* creature) : BossAI(creature, DATA_ILLIDARI_COUNCIL), _inCombat(false) { } -    struct boss_illidari_councilAI : public BossAI +    void Reset() override      { -        boss_illidari_councilAI(Creature* creature) : BossAI(creature, DATA_ILLIDARI_COUNCIL), _inCombat(false) { } - -        void Reset() override -        { -            _Reset(); -            _inCombat = false; -            me->SummonCreatureGroup(SUMMON_COUNCIL_GROUP); -            DoCastSelf(SPELL_EMPYREAL_BALANCE, true); -        } +        _Reset(); +        _inCombat = false; +        me->SummonCreatureGroup(SUMMON_COUNCIL_GROUP); +        DoCastSelf(SPELL_EMPYREAL_BALANCE, true); +    } -        void EnterCombat(Unit* /*who*/) override +    void EnterCombat(Unit* /*who*/) override +    { +        if (!_inCombat)          { -            if (!_inCombat) +            _inCombat = true; +            _EnterCombat(); +            for (uint32 bossData : CouncilData)              { -                _inCombat = true; -                _EnterCombat(); -                for (uint32 bossData : CouncilData) +                if (Creature* council = instance->GetCreature(bossData))                  { -                    if (Creature* council = instance->GetCreature(bossData)) -                    { -                        instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, council); -                        DoZoneInCombat(council); -                    } +                    instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, council); +                    DoZoneInCombat(council);                  } -                events.ScheduleEvent(EVENT_EMPYREAL_EQUIVALENCY, Seconds(2)); -                events.ScheduleEvent(EVENT_BERSERK, Minutes(15)); -                if (Creature* council = instance->GetCreature(CouncilData[urand(0, 3)])) -                    council->AI()->Talk(SAY_COUNCIL_AGRO);              } +            events.ScheduleEvent(EVENT_EMPYREAL_EQUIVALENCY, Seconds(2)); +            events.ScheduleEvent(EVENT_BERSERK, Minutes(15)); +            if (Creature* council = instance->GetCreature(CouncilData[urand(0, 3)])) +                council->AI()->Talk(SAY_COUNCIL_AGRO);          } +    } -        void EnterEvadeMode(EvadeReason /*why*/) override +    void EnterEvadeMode(EvadeReason /*why*/) override +    { +        if (!me->IsInEvadeMode())          { -            if (!me->IsInEvadeMode()) -            { -                _inCombat = false; -                for (uint32 bossData : CouncilData) -                    if (Creature* council = instance->GetCreature(bossData)) -                        instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, council); +            _inCombat = false; +            for (uint32 bossData : CouncilData) +                if (Creature* council = instance->GetCreature(bossData)) +                    instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, council); -                summons.DespawnAll(); -                _DespawnAtEvade(); -            } +            summons.DespawnAll(); +            _DespawnAtEvade();          } +    } -        void JustDied(Unit* /*killer*/) override -        { -            _inCombat = false; -            events.Reset(); -            instance->SetBossState(DATA_ILLIDARI_COUNCIL, DONE); +    void JustDied(Unit* /*killer*/) override +    { +        _inCombat = false; +        events.Reset(); +        instance->SetBossState(DATA_ILLIDARI_COUNCIL, DONE); -            for (uint32 bossData : CouncilData) +        for (uint32 bossData : CouncilData) +        { +            if (Creature* council = instance->GetCreature(bossData))              { -                if (Creature* council = instance->GetCreature(bossData)) -                { -                    // Allow loot -                    instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, council); -                    council->LowerPlayerDamageReq(council->GetMaxHealth()); -                    council->CastSpell(council, SPELL_QUIET_SUICIDE, true); -                } +                // Allow loot +                instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, council); +                council->LowerPlayerDamageReq(council->GetMaxHealth()); +                council->CastSpell(council, SPELL_QUIET_SUICIDE, true);              }          } +    } -        void UpdateAI(uint32 diff) override -        { -            if (!UpdateVictim()) -                return; +    void UpdateAI(uint32 diff) override +    { +        if (!UpdateVictim()) +            return; -            if (me->HasUnitState(UNIT_STATE_CASTING)) -                return; +        if (me->HasUnitState(UNIT_STATE_CASTING)) +            return; -            events.Update(diff); +        events.Update(diff); -            while (uint32 eventId = events.ExecuteEvent()) +        while (uint32 eventId = events.ExecuteEvent()) +        { +            switch (eventId)              { -                switch (eventId) -                { -                    case EVENT_EMPYREAL_EQUIVALENCY: -                        DoCastSelf(SPELL_EMPYREAL_EQUIVALENCY, true); -                        events.Repeat(Seconds(2)); -                        break; -                    case EVENT_BERSERK: -                        for (uint32 bossData : CouncilData) +                case EVENT_EMPYREAL_EQUIVALENCY: +                    DoCastSelf(SPELL_EMPYREAL_EQUIVALENCY, true); +                    events.Repeat(Seconds(2)); +                    break; +                case EVENT_BERSERK: +                    for (uint32 bossData : CouncilData) +                    { +                        if (Creature* council = instance->GetCreature(bossData))                          { -                            if (Creature* council = instance->GetCreature(bossData)) -                            { -                                council->CastSpell(council, SPELL_BERSERK, true); -                                council->AI()->Talk(SAY_COUNCIL_ENRAGE); -                            } +                            council->CastSpell(council, SPELL_BERSERK, true); +                            council->AI()->Talk(SAY_COUNCIL_ENRAGE);                          } -                        break; -                    default: -                        break; -                } - -                if (me->HasUnitState(UNIT_STATE_CASTING)) -                    return; +                    } +                    break; +                default: +                    break;              } -        } -        private: -            bool _inCombat; -    }; - -    CreatureAI* GetAI(Creature* creature) const override -    { -        return GetBlackTempleAI<boss_illidari_councilAI>(creature); +            if (me->HasUnitState(UNIT_STATE_CASTING)) +                return; +        }      } + +private: +    bool _inCombat;  }; +  struct IllidariCouncilBossAI : public BossAI  {      IllidariCouncilBossAI(Creature* creature, uint32 bossId) : BossAI(creature, bossId), _bossId(bossId) @@ -317,648 +307,492 @@ private:      Unit const* _me;  }; -class boss_gathios_the_shatterer : public CreatureScript +struct boss_gathios_the_shatterer : public IllidariCouncilBossAI  { -public: -    boss_gathios_the_shatterer() : CreatureScript("boss_gathios_the_shatterer") { } +    boss_gathios_the_shatterer(Creature* creature) : IllidariCouncilBossAI(creature, DATA_GATHIOS_THE_SHATTERER) { } -    struct boss_gathios_the_shattererAI : public IllidariCouncilBossAI +    void ScheduleEvents() override      { -        boss_gathios_the_shattererAI(Creature* creature) : IllidariCouncilBossAI(creature, DATA_GATHIOS_THE_SHATTERER) { } - -        void ScheduleEvents() override -        { -            DoCastSelf(SPELL_SEAL_OF_BLOOD); -            events.ScheduleEvent(EVENT_BLESS, Seconds(20)); -            events.ScheduleEvent(EVENT_CONSECRATION, Seconds(10)); -            events.ScheduleEvent(EVENT_HAMMER_OF_JUSTICE, Seconds(10)); -            events.ScheduleEvent(EVENT_JUDGEMENT, Seconds(15)); -            events.ScheduleEvent(EVENT_AURA, Seconds(6)); -        } +        DoCastSelf(SPELL_SEAL_OF_BLOOD); +        events.ScheduleEvent(EVENT_BLESS, Seconds(20)); +        events.ScheduleEvent(EVENT_CONSECRATION, Seconds(10)); +        events.ScheduleEvent(EVENT_HAMMER_OF_JUSTICE, Seconds(10)); +        events.ScheduleEvent(EVENT_JUDGEMENT, Seconds(15)); +        events.ScheduleEvent(EVENT_AURA, Seconds(6)); +    } -        void ExecuteEvent(uint32 eventId) override +    void ExecuteEvent(uint32 eventId) override +    { +        switch (eventId)          { -            switch (eventId) +            case EVENT_BLESS:              { -                case EVENT_BLESS: -                { -                    std::list<Unit*> TargetList; -                    Trinity::AnyFriendlyUnitInObjectRangeCheck checker(me, me, 100.0f); -                    Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(me, TargetList, checker); -                    Cell::VisitAllObjects(me, searcher, 100.0f); +                std::list<Unit*> TargetList; +                Trinity::AnyFriendlyUnitInObjectRangeCheck checker(me, me, 100.0f); +                Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(me, TargetList, checker); +                Cell::VisitAllObjects(me, searcher, 100.0f); -                    if (!TargetList.empty()) -                    { -                        Unit* target = Trinity::Containers::SelectRandomContainerElement(TargetList); -                        DoCast(target, RAND(SPELL_BLESS_PROTECTION, SPELL_BLESS_SPELL_WARDING)); -                    } -                    events.Repeat(Seconds(30), Seconds(45)); -                    break; +                if (!TargetList.empty()) +                { +                    Unit* target = Trinity::Containers::SelectRandomContainerElement(TargetList); +                    DoCast(target, RAND(SPELL_BLESS_PROTECTION, SPELL_BLESS_SPELL_WARDING));                  } -                case EVENT_AURA: -                    DoCastSelf(RAND(SPELL_CHROMATIC_AURA, SPELL_DEVOTION_AURA)); -                    events.Repeat(Seconds(30)); -                    break; -                case EVENT_HAMMER_OF_JUSTICE: -                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, HammerTargetSelector(me))) -                        DoCast(target, SPELL_HAMMER_OF_JUSTICE); -                    events.Repeat(Seconds(20)); -                    break; -                case EVENT_JUDGEMENT: -                    DoCastVictim(SPELL_JUDGEMENT); -                    events.Repeat(Seconds(15)); -                    break; -                case EVENT_CONSECRATION: -                    DoCastSelf(SPELL_CONSECRATION); -                    events.Repeat(Seconds(30), Seconds(35)); -                    break; -                default: -                    break; -            } +                events.Repeat(Seconds(30), Seconds(45)); +                break; +            } +            case EVENT_AURA: +                DoCastSelf(RAND(SPELL_CHROMATIC_AURA, SPELL_DEVOTION_AURA)); +                events.Repeat(Seconds(30)); +                break; +            case EVENT_HAMMER_OF_JUSTICE: +                if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, HammerTargetSelector(me))) +                    DoCast(target, SPELL_HAMMER_OF_JUSTICE); +                events.Repeat(Seconds(20)); +                break; +            case EVENT_JUDGEMENT: +                DoCastVictim(SPELL_JUDGEMENT); +                events.Repeat(Seconds(15)); +                break; +            case EVENT_CONSECRATION: +                DoCastSelf(SPELL_CONSECRATION); +                events.Repeat(Seconds(30), Seconds(35)); +                break; +            default: +                break;          } -    }; - -    CreatureAI* GetAI(Creature* creature) const override -    { -        return GetBlackTempleAI<boss_gathios_the_shattererAI>(creature);      }  }; -class boss_high_nethermancer_zerevor : public CreatureScript +struct boss_high_nethermancer_zerevor : public IllidariCouncilBossAI  { -public: -    boss_high_nethermancer_zerevor() : CreatureScript("boss_high_nethermancer_zerevor") { } +    boss_high_nethermancer_zerevor(Creature* creature) : IllidariCouncilBossAI(creature, DATA_HIGH_NETHERMANCER_ZEREVOR), _canUseArcaneExplosion(true) { } -    struct boss_high_nethermancer_zerevorAI : public IllidariCouncilBossAI +    void Reset() override      { -        boss_high_nethermancer_zerevorAI(Creature* creature) : IllidariCouncilBossAI(creature, DATA_HIGH_NETHERMANCER_ZEREVOR), _canUseArcaneExplosion(true) { } +        IllidariCouncilBossAI::Reset(); +        _canUseArcaneExplosion = true; +        DoCastSelf(SPELL_DAMPEN_MAGIC); +    } -        void Reset() override -        { -            IllidariCouncilBossAI::Reset(); -            _canUseArcaneExplosion = true; -            DoCastSelf(SPELL_DAMPEN_MAGIC); -        } +    void ScheduleEvents() override +    { +        events.ScheduleEvent(EVENT_FLAMESTRIKE, Seconds(8)); +        events.ScheduleEvent(EVENT_BLIZZARD, Seconds(25)); +        events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, Seconds(5)); +        DoCastSelf(SPELL_DAMPEN_MAGIC); +    } -        void ScheduleEvents() override -        { -            events.ScheduleEvent(EVENT_FLAMESTRIKE, Seconds(8)); -            events.ScheduleEvent(EVENT_BLIZZARD, Seconds(25)); -            events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, Seconds(5)); -            DoCastSelf(SPELL_DAMPEN_MAGIC); +    void DoAction(int32 actionId) override +    { +        if (actionId == ACTION_REFRESH_DAMPEN) +            events.ScheduleEvent(EVENT_DAMPEN_MAGIC, Seconds(50)); +    } +    void ExecuteEvent(uint32 eventId) override +    { +        switch (eventId) +        { +            case EVENT_FLAMESTRIKE: +                if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) +                    DoCast(target, SPELL_FLAMESTRIKE); +                Talk(SAY_COUNCIL_SPECIAL); +                events.Repeat(Seconds(40)); +                break; +            case EVENT_BLIZZARD: +                if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) +                    DoCast(target, SPELL_BLIZZARD); +                events.Repeat(Seconds(15), Seconds(40)); +                break; +            case EVENT_ARCANE_EXPLOSION_CHECK: +                _canUseArcaneExplosion = true; +                break; +            case EVENT_ARCANE_EXPLOSION: +                if (_canUseArcaneExplosion && SelectTarget(SELECT_TARGET_RANDOM, 0, 10.0f)) +                { +                    DoCastSelf(SPELL_ARCANE_EXPLOSION); +                    _canUseArcaneExplosion = false; +                    events.ScheduleEvent(EVENT_ARCANE_EXPLOSION_CHECK, Seconds(5)); +                } +                events.Repeat(Seconds(1)); +                break; +            case EVENT_DAMPEN_MAGIC: +                DoCastSelf(SPELL_DAMPEN_MAGIC); +                break; +            default: +                break;          } +    } -        void DoAction(int32 actionId) override -        { -            if (actionId == ACTION_REFRESH_DAMPEN) -                events.ScheduleEvent(EVENT_DAMPEN_MAGIC, Seconds(50)); -        } -        void ExecuteEvent(uint32 eventId) override -        { -            switch (eventId) -            { -                case EVENT_FLAMESTRIKE: -                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) -                        DoCast(target, SPELL_FLAMESTRIKE); -                    Talk(SAY_COUNCIL_SPECIAL); -                    events.Repeat(Seconds(40)); -                    break; -                case EVENT_BLIZZARD: -                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) -                        DoCast(target, SPELL_BLIZZARD); -                    events.Repeat(Seconds(15), Seconds(40)); -                    break; -                case EVENT_ARCANE_EXPLOSION_CHECK: -                    _canUseArcaneExplosion = true; -                    break; -                case EVENT_ARCANE_EXPLOSION: -                    if (_canUseArcaneExplosion && SelectTarget(SELECT_TARGET_RANDOM, 0, 10.0f)) -                    { -                        DoCastSelf(SPELL_ARCANE_EXPLOSION); -                        _canUseArcaneExplosion = false; -                        events.ScheduleEvent(EVENT_ARCANE_EXPLOSION_CHECK, Seconds(5)); -                    } -                    events.Repeat(Seconds(1)); -                    break; -                case EVENT_DAMPEN_MAGIC: -                    DoCastSelf(SPELL_DAMPEN_MAGIC); -                    break; -                default: -                    break; -            } -        } +    void UpdateAI(uint32 diff) override +    { +        if (!UpdateVictim()) +            return; -        void UpdateAI(uint32 diff) override -        { -            if (!UpdateVictim()) -                return; +        events.Update(diff); -            events.Update(diff); +        if (me->HasUnitState(UNIT_STATE_CASTING)) +            return; +        while (uint32 eventId = events.ExecuteEvent()) +        { +            ExecuteEvent(eventId);              if (me->HasUnitState(UNIT_STATE_CASTING))                  return; - -            while (uint32 eventId = events.ExecuteEvent()) -            { -                ExecuteEvent(eventId); -                if (me->HasUnitState(UNIT_STATE_CASTING)) -                    return; -            } - -            DoSpellAttackIfReady(SPELL_ARCANE_BOLT);          } -    private: -        bool _canUseArcaneExplosion; -    }; - -    CreatureAI* GetAI(Creature* creature) const override -    { -        return GetBlackTempleAI<boss_high_nethermancer_zerevorAI>(creature); +        DoSpellAttackIfReady(SPELL_ARCANE_BOLT);      } +private: +    bool _canUseArcaneExplosion;  }; -class boss_lady_malande : public CreatureScript +struct boss_lady_malande : public IllidariCouncilBossAI  { -public: -    boss_lady_malande() : CreatureScript("boss_lady_malande") { } +    boss_lady_malande(Creature* creature) : IllidariCouncilBossAI(creature, DATA_LADY_MALANDE) { } -    struct boss_lady_malandeAI : public IllidariCouncilBossAI +    void ScheduleEvents() override      { -        boss_lady_malandeAI(Creature* creature) : IllidariCouncilBossAI(creature, DATA_LADY_MALANDE) { } +        events.ScheduleEvent(EVENT_CIRCLE_OF_HEALING, Seconds(20)); +        events.ScheduleEvent(EVENT_REFLECTIVE_SHIELD, Seconds(25)); +        events.ScheduleEvent(EVENT_DIVINE_WRATH, Seconds(32)); +    } -        void ScheduleEvents() override -        { -            events.ScheduleEvent(EVENT_CIRCLE_OF_HEALING, Seconds(20)); -            events.ScheduleEvent(EVENT_REFLECTIVE_SHIELD, Seconds(25)); -            events.ScheduleEvent(EVENT_DIVINE_WRATH, Seconds(32)); -        } +    void HealReceived(Unit* /*who*/, uint32& addhealth) override +    { +        // Need be negative to heal trigger +        int32 bp = addhealth * (-1); +        me->CastCustomSpell(SPELL_SHARED_RULE, SPELLVALUE_BASE_POINT0, bp, (Unit*) nullptr, true); +    } -        void HealReceived(Unit* /*who*/, uint32& addhealth) override -        { -            // Need be negative to heal trigger -            int32 bp = addhealth * (-1); -            me->CastCustomSpell(SPELL_SHARED_RULE, SPELLVALUE_BASE_POINT0, bp, (Unit*) nullptr, true); +    void ExecuteEvent(uint32 eventId) override +    { +        switch (eventId) +        { +            case EVENT_CIRCLE_OF_HEALING: +                DoCastSelf(SPELL_CIRCLE_OF_HEALING); +                events.Repeat(Seconds(20), Seconds(35)); +                break; +            case EVENT_REFLECTIVE_SHIELD: +                DoCastSelf(SPELL_REFLECTIVE_SHIELD); +                Talk(SAY_COUNCIL_SPECIAL); +                events.Repeat(Seconds(40)); +                break; +            case EVENT_DIVINE_WRATH: +                DoCastVictim(SPELL_DIVINE_WRATH); +                events.Repeat(Seconds(20)); +                break; +            default: +                break;          } +    } -        void ExecuteEvent(uint32 eventId) override -        { -            switch (eventId) -            { -                case EVENT_CIRCLE_OF_HEALING: -                    DoCastSelf(SPELL_CIRCLE_OF_HEALING); -                    events.Repeat(Seconds(20), Seconds(35)); -                    break; -                case EVENT_REFLECTIVE_SHIELD: -                    DoCastSelf(SPELL_REFLECTIVE_SHIELD); -                    Talk(SAY_COUNCIL_SPECIAL); -                    events.Repeat(Seconds(40)); -                    break; -                case EVENT_DIVINE_WRATH: -                    DoCastVictim(SPELL_DIVINE_WRATH); -                    events.Repeat(Seconds(20)); -                    break; -                default: -                    break; -            } -        } +    void UpdateAI(uint32 diff) override +    { +        if (!UpdateVictim()) +            return; -        void UpdateAI(uint32 diff) override -        { -            if (!UpdateVictim()) -                return; +        events.Update(diff); -            events.Update(diff); +        if (me->HasUnitState(UNIT_STATE_CASTING)) +            return; +        while (uint32 eventId = events.ExecuteEvent()) +        { +            ExecuteEvent(eventId);              if (me->HasUnitState(UNIT_STATE_CASTING))                  return; - -            while (uint32 eventId = events.ExecuteEvent()) -            { -                ExecuteEvent(eventId); -                if (me->HasUnitState(UNIT_STATE_CASTING)) -                    return; -            } - -            DoSpellAttackIfReady(SPELL_EMPOWERED_SMITE);          } -    }; -    CreatureAI* GetAI(Creature* creature) const override -    { -        return GetBlackTempleAI<boss_lady_malandeAI>(creature); +        DoSpellAttackIfReady(SPELL_EMPOWERED_SMITE);      } -  }; -class boss_veras_darkshadow : public CreatureScript +struct boss_veras_darkshadow : public IllidariCouncilBossAI  { -public: -    boss_veras_darkshadow() : CreatureScript("boss_veras_darkshadow") { } - -    struct boss_veras_darkshadowAI : public IllidariCouncilBossAI +    boss_veras_darkshadow(Creature* creature) : IllidariCouncilBossAI(creature, DATA_VERAS_DARKSHADOW)      { -        boss_veras_darkshadowAI(Creature* creature) : IllidariCouncilBossAI(creature, DATA_VERAS_DARKSHADOW) -        { -            me->SetMaxHealth(1327900); -            me->SetFullHealth(); -        } - -        void ScheduleEvents() override -        { -            events.ScheduleEvent(EVENT_DEADLY_STRIKE, Seconds(18)); -            events.ScheduleEvent(EVENT_VANISH, Seconds(18)); -        } +        me->SetMaxHealth(1327900); +        me->SetFullHealth(); +    } -        void ExecuteEvent(uint32 eventId) override -        { -            switch (eventId) -            { -                case EVENT_DEADLY_STRIKE: -                    DoCastSelf(SPELL_DEADLY_STRIKE); -                    events.Repeat(Seconds(60)); -                    break; -                case EVENT_VANISH: -                    DoCastSelf(SPELL_VANISH); -                    Talk(SAY_COUNCIL_SPECIAL); -                    events.Repeat(Seconds(60)); -                    break; -                default: -                    break; -            } -        } -    }; +    void ScheduleEvents() override +    { +        events.ScheduleEvent(EVENT_DEADLY_STRIKE, Seconds(18)); +        events.ScheduleEvent(EVENT_VANISH, Seconds(18)); +    } -    CreatureAI* GetAI(Creature* creature) const override +    void ExecuteEvent(uint32 eventId) override      { -        return GetBlackTempleAI<boss_veras_darkshadowAI>(creature); +        switch (eventId) +        { +            case EVENT_DEADLY_STRIKE: +                DoCastSelf(SPELL_DEADLY_STRIKE); +                events.Repeat(Seconds(60)); +                break; +            case EVENT_VANISH: +                DoCastSelf(SPELL_VANISH); +                Talk(SAY_COUNCIL_SPECIAL); +                events.Repeat(Seconds(60)); +                break; +            default: +                break; +        }      }  }; -class npc_veras_vanish_effect : public CreatureScript +struct npc_veras_vanish_effect : public PassiveAI  { -public: -    npc_veras_vanish_effect() : CreatureScript("npc_veras_vanish_effect") { } - -    struct npc_veras_vanish_effectAI : public PassiveAI -    { -        npc_veras_vanish_effectAI(Creature* creature) : PassiveAI(creature) { } - -        void Reset() override -        { -            DoCastSelf(SPELL_BIRTH, true); -            DoCastSelf(SPELL_ENVENOM_DUMMY, true); -        } -    }; +    npc_veras_vanish_effect(Creature* creature) : PassiveAI(creature) { } -    CreatureAI* GetAI(Creature* creature) const override +    void Reset() override      { -        return GetBlackTempleAI<npc_veras_vanish_effectAI>(creature); +        DoCastSelf(SPELL_BIRTH, true); +        DoCastSelf(SPELL_ENVENOM_DUMMY, true);      }  };  // 41499 - Empyreal Balance -class spell_illidari_council_empyreal_balance : public SpellScriptLoader +class spell_illidari_council_empyreal_balance : public SpellScript  { -    public: -        spell_illidari_council_empyreal_balance() : SpellScriptLoader("spell_illidari_council_empyreal_balance") { } - -        class spell_illidari_council_empyreal_balance_SpellScript : public SpellScript -        { -            PrepareSpellScript(spell_illidari_council_empyreal_balance_SpellScript); - -            bool Validate(SpellInfo const* /*spell*/) override -            { -                return ValidateSpellInfo({ SPELL_BALANCE_OF_POWER }); -            } +    PrepareSpellScript(spell_illidari_council_empyreal_balance); -            void HandleDummy(SpellEffIndex /*effIndex*/) -            { -                Unit* target = GetHitUnit(); -                target->CastSpell(target, SPELL_BALANCE_OF_POWER, true); -            } +    bool Validate(SpellInfo const* /*spell*/) override +    { +        return ValidateSpellInfo({ SPELL_BALANCE_OF_POWER }); +    } -            void Register() override -            { -                OnEffectHitTarget += SpellEffectFn(spell_illidari_council_empyreal_balance_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); -            } -        }; +    void HandleDummy(SpellEffIndex /*effIndex*/) +    { +        Unit* target = GetHitUnit(); +        target->CastSpell(target, SPELL_BALANCE_OF_POWER, true); +    } -        SpellScript* GetSpellScript() const override -        { -            return new spell_illidari_council_empyreal_balance_SpellScript(); -        } +    void Register() override +    { +        OnEffectHitTarget += SpellEffectFn(spell_illidari_council_empyreal_balance::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); +    }  };  // 41333 - Empyreal Equivalency -class spell_illidari_council_empyreal_equivalency : public SpellScriptLoader +class spell_illidari_council_empyreal_equivalency : public SpellScript  { -    public: -        spell_illidari_council_empyreal_equivalency() : SpellScriptLoader("spell_illidari_council_empyreal_equivalency") { } +    PrepareSpellScript(spell_illidari_council_empyreal_equivalency); -        class spell_illidari_council_empyreal_equivalency_SpellScript : public SpellScript -        { -            PrepareSpellScript(spell_illidari_council_empyreal_equivalency_SpellScript); - -            void HandleScript(SpellEffIndex /*effIndex*/) -            { -                Unit* target = GetHitUnit(); -                int32 casterHpPct = (int32) GetCaster()->GetHealthPct(); -                uint32 newHp = target->CountPctFromMaxHealth(casterHpPct); -                if (newHp <= 0) -                    newHp = target->GetMaxHealth() - 1; -                target->SetHealth(newHp); -            } - -            void Register() override -            { -                OnEffectHitTarget += SpellEffectFn(spell_illidari_council_empyreal_equivalency_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); -            } -        }; +    void HandleScript(SpellEffIndex /*effIndex*/) +    { +        Unit* target = GetHitUnit(); +        int32 casterHpPct = (int32)GetCaster()->GetHealthPct(); +        uint32 newHp = target->CountPctFromMaxHealth(casterHpPct); +        if (newHp <= 0) +            newHp = target->GetMaxHealth() - 1; +        target->SetHealth(newHp); +    } -        SpellScript* GetSpellScript() const override -        { -            return new spell_illidari_council_empyreal_equivalency_SpellScript(); -        } +    void Register() override +    { +        OnEffectHitTarget += SpellEffectFn(spell_illidari_council_empyreal_equivalency::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); +    }  };  // 41341 - Balance of Power -class spell_illidari_council_balance_of_power : public SpellScriptLoader +class spell_illidari_council_balance_of_power : public AuraScript  { -    public: -        spell_illidari_council_balance_of_power() : SpellScriptLoader("spell_illidari_council_balance_of_power") { } +    PrepareAuraScript(spell_illidari_council_balance_of_power); -        class spell_illidari_council_balance_of_power_AuraScript : public AuraScript -        { -            PrepareAuraScript(spell_illidari_council_balance_of_power_AuraScript); - -            bool Validate(SpellInfo const* /*spell*/) override -            { -                return ValidateSpellInfo({ SPELL_SHARED_RULE }); -            } - -            void Absorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& /*absorbAmount*/) -            { -                PreventDefaultAction(); -                int32 bp = dmgInfo.GetDamage(); -                GetTarget()->CastCustomSpell(SPELL_SHARED_RULE, SPELLVALUE_BASE_POINT0, bp, (Unit*) nullptr, true, nullptr, aurEff); -            } +    bool Validate(SpellInfo const* /*spell*/) override +    { +        return ValidateSpellInfo({ SPELL_SHARED_RULE }); +    } -            void Register() override -            { -                OnEffectAbsorb += AuraEffectAbsorbFn(spell_illidari_council_balance_of_power_AuraScript::Absorb, EFFECT_0); -            } -        }; +    void Absorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& /*absorbAmount*/) +    { +        PreventDefaultAction(); +        int32 bp = dmgInfo.GetDamage(); +        GetTarget()->CastCustomSpell(SPELL_SHARED_RULE, SPELLVALUE_BASE_POINT0, bp, (Unit*) nullptr, true, nullptr, aurEff); +    } -        AuraScript* GetAuraScript() const override -        { -            return new spell_illidari_council_balance_of_power_AuraScript(); -        } +    void Register() override +    { +        OnEffectAbsorb += AuraEffectAbsorbFn(spell_illidari_council_balance_of_power::Absorb, EFFECT_0); +    }  };  // 41480 - Deadly Strike -class spell_illidari_council_deadly_strike : public SpellScriptLoader +class spell_illidari_council_deadly_strike : public AuraScript  { -    public: -        spell_illidari_council_deadly_strike() : SpellScriptLoader("spell_illidari_council_deadly_strike") { } - -        class spell_illidari_council_deadly_strike_AuraScript : public AuraScript -        { -            PrepareAuraScript(spell_illidari_council_deadly_strike_AuraScript); +    PrepareAuraScript(spell_illidari_council_deadly_strike); -            bool Validate(SpellInfo const* /*spellInfo*/) override -            { -                return ValidateSpellInfo({ SPELL_DEADLY_POISON }); -            } - -            void OnTrigger(AuraEffect const* aurEff) -            { -                PreventDefaultAction(); +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo({ SPELL_DEADLY_POISON }); +    } -                if (Unit* victim = GetTarget()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0)) -                    GetTarget()->CastSpell(victim, SPELL_DEADLY_POISON, true, nullptr, aurEff); -            } +    void OnTrigger(AuraEffect const* aurEff) +    { +        PreventDefaultAction(); -            void Register() override -            { -                OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidari_council_deadly_strike_AuraScript::OnTrigger, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); -            } -        }; +        if (Unit* victim = GetTarget()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0)) +            GetTarget()->CastSpell(victim, SPELL_DEADLY_POISON, true, nullptr, aurEff); +    } -        AuraScript* GetAuraScript() const override -        { -            return new spell_illidari_council_deadly_strike_AuraScript(); -        } +    void Register() override +    { +        OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidari_council_deadly_strike::OnTrigger, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); +    }  };  // 41485 - Deadly Poison -class spell_illidari_council_deadly_poison : public SpellScriptLoader +class spell_illidari_council_deadly_poison : public AuraScript  { -    public: -        spell_illidari_council_deadly_poison() : SpellScriptLoader("spell_illidari_council_deadly_poison") { } - -        class spell_illidari_council_deadly_poison_AuraScript : public AuraScript -        { -            PrepareAuraScript(spell_illidari_council_deadly_poison_AuraScript); +    PrepareAuraScript(spell_illidari_council_deadly_poison); -            bool Validate(SpellInfo const* /*spellInfo*/) override -            { -                return ValidateSpellInfo({ SPELL_ENVENOM }); -            } - -            void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) -            { -                if (Unit* caster = GetCaster()) -                    caster->CastSpell(GetTarget(), SPELL_ENVENOM, true); -            } +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo({ SPELL_ENVENOM }); +    } -            void Register() override -            { -                OnEffectRemove += AuraEffectRemoveFn(spell_illidari_council_deadly_poison_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); -            } -        }; +    void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +    { +        if (Unit* caster = GetCaster()) +            caster->CastSpell(GetTarget(), SPELL_ENVENOM, true); +    } -        AuraScript* GetAuraScript() const override -        { -            return new spell_illidari_council_deadly_poison_AuraScript(); -        } +    void Register() override +    { +        OnEffectRemove += AuraEffectRemoveFn(spell_illidari_council_deadly_poison::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); +    }  };  // 41475 - Reflective Shield -class spell_illidari_council_reflective_shield : public SpellScriptLoader +class spell_illidari_council_reflective_shield : public AuraScript  { -    public: -        spell_illidari_council_reflective_shield() : SpellScriptLoader("spell_illidari_council_reflective_shield") { } +    PrepareAuraScript(spell_illidari_council_reflective_shield); -        class spell_illidari_council_reflective_shield_AuraScript : public AuraScript -        { -            PrepareAuraScript(spell_illidari_council_reflective_shield_AuraScript); - -            bool Validate(SpellInfo const* /*spellInfo*/) override -            { -                return ValidateSpellInfo({ SPELL_REFLECTIVE_SHIELD_DAMAGE }); -            } - -            void OnAbsorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount) -            { -                Unit* target = GetTarget(); -                if (dmgInfo.GetAttacker() == target) -                    return; +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo({ SPELL_REFLECTIVE_SHIELD_DAMAGE }); +    } -                int32 bp = absorbAmount / 2; -                target->CastCustomSpell(dmgInfo.GetAttacker(), SPELL_REFLECTIVE_SHIELD_DAMAGE, &bp, nullptr, nullptr, true, nullptr, aurEff); -            } +    void OnAbsorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount) +    { +        Unit* target = GetTarget(); +        if (dmgInfo.GetAttacker() == target) +            return; -            void Register() override -            { -                 AfterEffectAbsorb += AuraEffectAbsorbFn(spell_illidari_council_reflective_shield_AuraScript::OnAbsorb, EFFECT_0); -            } -        }; +        int32 bp = absorbAmount / 2; +        target->CastCustomSpell(dmgInfo.GetAttacker(), SPELL_REFLECTIVE_SHIELD_DAMAGE, &bp, nullptr, nullptr, true, nullptr, aurEff); +    } -        AuraScript* GetAuraScript() const override -        { -            return new spell_illidari_council_reflective_shield_AuraScript(); -        } +    void Register() override +    { +        AfterEffectAbsorb += AuraEffectAbsorbFn(spell_illidari_council_reflective_shield::OnAbsorb, EFFECT_0); +    }  };  // 41467 - Judgement -class spell_illidari_council_judgement : public SpellScriptLoader +class spell_illidari_council_judgement : public SpellScript  { -    public: -        spell_illidari_council_judgement() : SpellScriptLoader("spell_illidari_council_judgement") { } +    PrepareSpellScript(spell_illidari_council_judgement); -        class spell_illidari_council_judgement_SpellScript : public SpellScript +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo(          { -            PrepareSpellScript(spell_illidari_council_judgement_SpellScript); - -            bool Validate(SpellInfo const* /*spellInfo*/) override -            { -                return ValidateSpellInfo( -                { -                    SPELL_JUDGEMENT_OF_BLOOD, -                    SPELL_JUDGEMENT_OF_COMMAND, -                    SPELL_JUDGEMENT_PRIMER -                }); -            } - -            void HandleScript(SpellEffIndex /*effIndex*/) -            { -                Unit* caster = GetCaster(); -                Unit* target = GetHitUnit(); -                uint32 judgementId = caster->HasAura(SPELL_SEAL_OF_BLOOD) ? SPELL_JUDGEMENT_OF_BLOOD : SPELL_JUDGEMENT_OF_COMMAND; -                caster->CastSpell(target, SPELL_JUDGEMENT_PRIMER, true); -                caster->CastSpell(target, judgementId, true); -            } +            SPELL_JUDGEMENT_OF_BLOOD, +            SPELL_JUDGEMENT_OF_COMMAND, +            SPELL_JUDGEMENT_PRIMER +        }); +    } -            void OnFinishCast() -            { -                if (Creature* caster = GetCaster()->ToCreature()) -                    caster->AI()->Talk(SAY_COUNCIL_SPECIAL); -            } +    void HandleScript(SpellEffIndex /*effIndex*/) +    { +        Unit* caster = GetCaster(); +        Unit* target = GetHitUnit(); +        uint32 judgementId = caster->HasAura(SPELL_SEAL_OF_BLOOD) ? SPELL_JUDGEMENT_OF_BLOOD : SPELL_JUDGEMENT_OF_COMMAND; +        caster->CastSpell(target, SPELL_JUDGEMENT_PRIMER, true); +        caster->CastSpell(target, judgementId, true); +    } -            void Register() override -            { -                OnEffectHitTarget += SpellEffectFn(spell_illidari_council_judgement_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); -                AfterCast += SpellCastFn(spell_illidari_council_judgement_SpellScript::OnFinishCast); -            } -        }; +    void OnFinishCast() +    { +        if (Creature* caster = GetCaster()->ToCreature()) +            caster->AI()->Talk(SAY_COUNCIL_SPECIAL); +    } -        SpellScript* GetSpellScript() const override -        { -            return new spell_illidari_council_judgement_SpellScript(); -        } +    void Register() override +    { +        OnEffectHitTarget += SpellEffectFn(spell_illidari_council_judgement::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); +        AfterCast += SpellCastFn(spell_illidari_council_judgement::OnFinishCast); +    }  };  /* 41469 - Seal of Command     41459 - Seal of Blood */ -class spell_illidari_council_seal : public SpellScriptLoader +class spell_illidari_council_seal : public AuraScript  { -    public: -        spell_illidari_council_seal() : SpellScriptLoader("spell_illidari_council_seal") { } +    PrepareAuraScript(spell_illidari_council_seal); -        class spell_illidari_council_seal_AuraScript : public AuraScript +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo(          { -            PrepareAuraScript(spell_illidari_council_seal_AuraScript); - -            bool Validate(SpellInfo const* /*spellInfo*/) override -            { -                return ValidateSpellInfo( -                { -                    SPELL_SEAL_OF_COMMAND, -                    SPELL_SEAL_OF_BLOOD -                }); -            } - -            void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) -            { -                Unit* target = GetTarget(); -                if (target->IsInWorld() && target->IsAlive()) -                { -                    uint32 spellId = aurEff->GetId() == SPELL_SEAL_OF_COMMAND ? SPELL_SEAL_OF_BLOOD : SPELL_SEAL_OF_COMMAND; -                    target->CastSpell(target, spellId, true); -                } -            } - -            void Register() override -            { -                OnEffectRemove += AuraEffectRemoveFn(spell_illidari_council_seal_AuraScript::OnRemove, EFFECT_2, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); -            } -        }; +            SPELL_SEAL_OF_COMMAND, +            SPELL_SEAL_OF_BLOOD +        }); +    } -        AuraScript* GetAuraScript() const override +    void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) +    { +        Unit* target = GetTarget(); +        if (target->IsInWorld() && target->IsAlive())          { -            return new spell_illidari_council_seal_AuraScript(); +            uint32 spellId = aurEff->GetId() == SPELL_SEAL_OF_COMMAND ? SPELL_SEAL_OF_BLOOD : SPELL_SEAL_OF_COMMAND; +            target->CastSpell(target, spellId, true);          } +    } + +    void Register() override +    { +        OnEffectRemove += AuraEffectRemoveFn(spell_illidari_council_seal::OnRemove, EFFECT_2, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); +    }  };  // 41478 - Dampen Magic -class spell_illidari_dampen_magic : public SpellScriptLoader +class spell_illidari_dampen_magic : public AuraScript  { -    public: -        spell_illidari_dampen_magic() : SpellScriptLoader("spell_illidari_dampen_magic") { } - -        class spell_illidari_dampen_magic_AuraScript : public AuraScript -        { -            PrepareAuraScript(spell_illidari_dampen_magic_AuraScript); - -            void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) -            { -                if (Creature* target = GetTarget()->ToCreature()) -                { -                    AuraRemoveMode mode = GetTargetApplication()->GetRemoveMode(); -                    if (mode == AURA_REMOVE_BY_ENEMY_SPELL || mode == AURA_REMOVE_BY_EXPIRE) -                        target->AI()->DoAction(ACTION_REFRESH_DAMPEN); -                } -            } - -            void Register() override -            { -                OnEffectRemove += AuraEffectRemoveFn(spell_illidari_dampen_magic_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL); -            } -        }; +    PrepareAuraScript(spell_illidari_dampen_magic); -        AuraScript* GetAuraScript() const override +    void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +    { +        if (Creature* target = GetTarget()->ToCreature())          { -            return new spell_illidari_dampen_magic_AuraScript(); +            AuraRemoveMode mode = GetTargetApplication()->GetRemoveMode(); +            if (mode == AURA_REMOVE_BY_ENEMY_SPELL || mode == AURA_REMOVE_BY_EXPIRE) +                target->AI()->DoAction(ACTION_REFRESH_DAMPEN);          } +    } + +    void Register() override +    { +        OnEffectRemove += AuraEffectRemoveFn(spell_illidari_dampen_magic::OnRemove, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL); +    }  };  void AddSC_boss_illidari_council()  { -    new boss_illidari_council(); -    new boss_gathios_the_shatterer(); -    new boss_lady_malande(); -    new boss_veras_darkshadow(); -    new boss_high_nethermancer_zerevor(); -    new npc_veras_vanish_effect(); -    new spell_illidari_council_empyreal_balance(); -    new spell_illidari_council_empyreal_equivalency(); -    new spell_illidari_council_balance_of_power(); -    new spell_illidari_council_deadly_strike(); -    new spell_illidari_council_deadly_poison(); -    new spell_illidari_council_reflective_shield(); -    new spell_illidari_council_judgement(); -    new spell_illidari_council_seal(); -    new spell_illidari_dampen_magic(); +    RegisterBlackTempleCreatureAI(boss_illidari_council); +    RegisterBlackTempleCreatureAI(boss_gathios_the_shatterer); +    RegisterBlackTempleCreatureAI(boss_lady_malande); +    RegisterBlackTempleCreatureAI(boss_veras_darkshadow); +    RegisterBlackTempleCreatureAI(boss_high_nethermancer_zerevor); +    RegisterBlackTempleCreatureAI(npc_veras_vanish_effect); +    RegisterSpellScript(spell_illidari_council_empyreal_balance); +    RegisterSpellScript(spell_illidari_council_empyreal_equivalency); +    RegisterAuraScript(spell_illidari_council_balance_of_power); +    RegisterAuraScript(spell_illidari_council_deadly_strike); +    RegisterAuraScript(spell_illidari_council_deadly_poison); +    RegisterAuraScript(spell_illidari_council_reflective_shield); +    RegisterSpellScript(spell_illidari_council_judgement); +    RegisterAuraScript(spell_illidari_council_seal); +    RegisterAuraScript(spell_illidari_dampen_magic);  } diff --git a/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp b/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp index 38fa695c5db..fdd79cf92ea 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp @@ -107,299 +107,233 @@ Position const TeleportPoint[7]=      { 965.997f, 278.398f, 195.777f }  }; -class boss_mother_shahraz : public CreatureScript +struct boss_mother_shahraz : public BossAI  { -public: -    boss_mother_shahraz() : CreatureScript("boss_mother_shahraz") { } +    boss_mother_shahraz(Creature* creature) : BossAI(creature, DATA_MOTHER_SHAHRAZ), _enraged(false) { } -    struct boss_shahrazAI : public BossAI +    void Reset() override      { -        boss_shahrazAI(Creature* creature) : BossAI(creature, DATA_MOTHER_SHAHRAZ), _enraged(false) { } +        _Reset(); +        _enraged = false; +    } -        void Reset() override -        { -            _Reset(); -            _enraged = false; -        } +    void EnterCombat(Unit* /*who*/) override +    { +        _EnterCombat(); +        Talk(SAY_AGGRO); +        events.ScheduleEvent(EVENT_SILENCING_SHRIEK, Seconds(22)); +        events.ScheduleEvent(EVENT_PRISMATIC_SHIELD, Seconds(15)); +        events.ScheduleEvent(EVENT_FATAL_ATTRACTION, Seconds(35)); +        events.ScheduleEvent(EVENT_RANDOM_BEAM, Seconds(6)); +        events.ScheduleEvent(EVENT_BERSERK, Minutes(10)); +        events.ScheduleEvent(EVENT_TAUNT, Seconds(35)); +    } -        void EnterCombat(Unit* /*who*/) override -        { -            _EnterCombat(); -            Talk(SAY_AGGRO); -            events.ScheduleEvent(EVENT_SILENCING_SHRIEK, Seconds(22)); -            events.ScheduleEvent(EVENT_PRISMATIC_SHIELD, Seconds(15)); -            events.ScheduleEvent(EVENT_FATAL_ATTRACTION, Seconds(35)); -            events.ScheduleEvent(EVENT_RANDOM_BEAM, Seconds(6)); -            events.ScheduleEvent(EVENT_BERSERK, Minutes(10)); -            events.ScheduleEvent(EVENT_TAUNT, Seconds(35)); -        } +    void KilledUnit(Unit* victim) override +    { +        if (victim->GetTypeId() == TYPEID_PLAYER) +            Talk(SAY_SLAY); +    } -        void KilledUnit(Unit* victim) override -        { -            if (victim->GetTypeId() == TYPEID_PLAYER) -                Talk(SAY_SLAY); -        } +    void JustDied(Unit* /*killer*/) override +    { +        _JustDied(); +        Talk(SAY_DEATH); +    } -        void JustDied(Unit* /*killer*/) override -        { -            _JustDied(); -            Talk(SAY_DEATH); -        } +    void EnterEvadeMode(EvadeReason /*why*/) override +    { +        _DespawnAtEvade(); +    } -        void EnterEvadeMode(EvadeReason /*why*/) override +    void DamageTaken(Unit* /*attacker*/, uint32 &damage) override +    { +        if (!_enraged && me->HealthBelowPctDamaged(10, damage))          { -            _DespawnAtEvade(); +            _enraged = true; +            DoCastSelf(SPELL_RANDOM_PERIODIC, true); +            Talk(EMOTE_ENRAGE, me); +            Talk(SAY_ENRAGE);          } +    } -        void DamageTaken(Unit* /*attacker*/, uint32 &damage) override +    void ExecuteEvent(uint32 eventId) override +    { +        switch (eventId)          { -            if (!_enraged && me->HealthBelowPctDamaged(10, damage)) -            { -                _enraged = true; -                DoCastSelf(SPELL_RANDOM_PERIODIC, true); -                Talk(EMOTE_ENRAGE, me); -                Talk(SAY_ENRAGE); -            } +            case EVENT_RANDOM_BEAM: +                DoCastSelf(BeamTriggers[urand(0, 3)]); +                events.Repeat(Seconds(30)); +                break; +            case EVENT_PRISMATIC_SHIELD: +                DoCastSelf(PrismaticAuras[urand(0, 5)]); +                events.Repeat(Seconds(15)); +                break; +            case EVENT_FATAL_ATTRACTION: +                Talk(SAY_SPELL); +                me->CastCustomSpell(SPELL_FATAL_ATTACTION_TELEPORT, SPELLVALUE_MAX_TARGETS, 3, me); +                events.Repeat(Seconds(30)); +                break; +            case EVENT_SILENCING_SHRIEK: +                DoCastVictim(SPELL_SILENCING_SHRIEK); +                events.Repeat(Seconds(18), Seconds(30)); +                break; +            case EVENT_TAUNT: +                Talk(SAY_TAUNT); +                events.Repeat(Seconds(30), Seconds(40)); +                break; +            case EVENT_BERSERK: +                Talk(EMOTE_BERSERK, me); +                DoCastSelf(SPELL_BERSERK); +                break; +            default: +                break;          } +    } -        void ExecuteEvent(uint32 eventId) override +private: +    bool _enraged; +}; + +// 40869 - Fatal Attraction +class spell_mother_shahraz_fatal_attraction : public SpellScript +{ +    PrepareSpellScript(spell_mother_shahraz_fatal_attraction); + +    bool Validate(SpellInfo const* /*spell*/) override +    { +        return ValidateSpellInfo(          { -            switch (eventId) -            { -                case EVENT_RANDOM_BEAM: -                    DoCastSelf(BeamTriggers[urand(0, 3)]); -                    events.Repeat(Seconds(30)); -                    break; -                case EVENT_PRISMATIC_SHIELD: -                    DoCastSelf(PrismaticAuras[urand(0, 5)]); -                    events.Repeat(Seconds(15)); -                    break; -                case EVENT_FATAL_ATTRACTION: -                    Talk(SAY_SPELL); -                    me->CastCustomSpell(SPELL_FATAL_ATTACTION_TELEPORT, SPELLVALUE_MAX_TARGETS, 3, me); -                    events.Repeat(Seconds(30)); -                    break; -                case EVENT_SILENCING_SHRIEK: -                    DoCastVictim(SPELL_SILENCING_SHRIEK); -                    events.Repeat(Seconds(18), Seconds(30)); -                    break; -                case EVENT_TAUNT: -                    Talk(SAY_TAUNT); -                    events.Repeat(Seconds(30), Seconds(40)); -                    break; -                case EVENT_BERSERK: -                    Talk(EMOTE_BERSERK, me); -                    DoCastSelf(SPELL_BERSERK); -                    break; -                default: -                    break; -            } -        } +            SPELL_SABER_LASH_IMMUNITY, +            SPELL_FATAL_ATTRACTION +        }); +    } -    private: -        bool _enraged; -    }; +    void FilterTargets(std::list<WorldObject*>& targets) +    { +        targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_SABER_LASH_IMMUNITY)); +    } -    CreatureAI* GetAI(Creature* creature) const override +    void SetDest(SpellDestination& dest)      { -        return GetBlackTempleAI<boss_shahrazAI>(creature); +        dest.Relocate(TeleportPoint[urand(0, 6)]);      } -}; -// 40869 - Fatal Attraction -class spell_mother_shahraz_fatal_attraction : public SpellScriptLoader -{ -    public: -        spell_mother_shahraz_fatal_attraction() : SpellScriptLoader("spell_mother_shahraz_fatal_attraction") { } +    void HandleTeleport(SpellEffIndex /*effIndex*/) +    { +        GetCaster()->CastSpell(GetHitUnit(), SPELL_FATAL_ATTRACTION, true); +    } -        class spell_mother_shahraz_fatal_attraction_SpellScript : public SpellScript -        { -            PrepareSpellScript(spell_mother_shahraz_fatal_attraction_SpellScript); - -            bool Validate(SpellInfo const* /*spell*/) override -            { -                return ValidateSpellInfo( -                { -                    SPELL_SABER_LASH_IMMUNITY, -                    SPELL_FATAL_ATTRACTION -                }); -            } - -            void FilterTargets(std::list<WorldObject*>& targets) -            { -                targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_SABER_LASH_IMMUNITY)); -            } - -            void SetDest(SpellDestination& dest) -            { -                dest.Relocate(TeleportPoint[urand(0, 6)]); -            } - -            void HandleTeleport(SpellEffIndex /*effIndex*/) -            { -                GetCaster()->CastSpell(GetHitUnit(), SPELL_FATAL_ATTRACTION, true); -            } - -            void Register() override -            { -                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mother_shahraz_fatal_attraction_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY); -                OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_mother_shahraz_fatal_attraction_SpellScript::SetDest, EFFECT_1, TARGET_DEST_CASTER_RANDOM); -                OnEffectHitTarget += SpellEffectFn(spell_mother_shahraz_fatal_attraction_SpellScript::HandleTeleport, EFFECT_1, SPELL_EFFECT_TELEPORT_UNITS); -            } -        }; - -        SpellScript* GetSpellScript() const override -        { -            return new spell_mother_shahraz_fatal_attraction_SpellScript(); -        } +    void Register() override +    { +        OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mother_shahraz_fatal_attraction::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY); +        OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_mother_shahraz_fatal_attraction::SetDest, EFFECT_1, TARGET_DEST_CASTER_RANDOM); +        OnEffectHitTarget += SpellEffectFn(spell_mother_shahraz_fatal_attraction::HandleTeleport, EFFECT_1, SPELL_EFFECT_TELEPORT_UNITS); +    }  };  // 40870 - Fatal Attraction Dummy Visual -class spell_mother_shahraz_fatal_attraction_link : public SpellScriptLoader +class spell_mother_shahraz_fatal_attraction_link : public SpellScript  { -    public: -        spell_mother_shahraz_fatal_attraction_link() : SpellScriptLoader("spell_mother_shahraz_fatal_attraction_link") { } - -        class spell_mother_shahraz_fatal_attraction_link_SpellScript : public SpellScript -        { -            PrepareSpellScript(spell_mother_shahraz_fatal_attraction_link_SpellScript); +    PrepareSpellScript(spell_mother_shahraz_fatal_attraction_link); -            bool Validate(SpellInfo const* /*spell*/) override -            { -                return ValidateSpellInfo({ SPELL_FATAL_ATTRACTION_DAMAGE }); -            } - -            void HandleDummy(SpellEffIndex /*effIndex*/) -            { -                GetCaster()->CastSpell(GetCaster(), SPELL_FATAL_ATTRACTION_DAMAGE, true); -            } +    bool Validate(SpellInfo const* /*spell*/) override +    { +        return ValidateSpellInfo({ SPELL_FATAL_ATTRACTION_DAMAGE }); +    } -            void Register() override -            { -                OnEffectHitTarget += SpellEffectFn(spell_mother_shahraz_fatal_attraction_link_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); -            } -        }; +    void HandleDummy(SpellEffIndex /*effIndex*/) +    { +        GetCaster()->CastSpell(GetCaster(), SPELL_FATAL_ATTRACTION_DAMAGE, true); +    } -        SpellScript* GetSpellScript() const override -        { -            return new spell_mother_shahraz_fatal_attraction_link_SpellScript(); -        } +    void Register() override +    { +        OnEffectHitTarget += SpellEffectFn(spell_mother_shahraz_fatal_attraction_link::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); +    }  };  // 40816 - Saber Lash -class spell_mother_shahraz_saber_lash : public SpellScriptLoader +class spell_mother_shahraz_saber_lash : public AuraScript  { -    public: -        spell_mother_shahraz_saber_lash() : SpellScriptLoader("spell_mother_shahraz_saber_lash") { } - -        class spell_mother_shahraz_saber_lash_AuraScript : public AuraScript -        { -            PrepareAuraScript(spell_mother_shahraz_saber_lash_AuraScript); +    PrepareAuraScript(spell_mother_shahraz_saber_lash); -            bool Validate(SpellInfo const* spellInfo) override -            { -                return ValidateSpellInfo({ spellInfo->Effects[EFFECT_1].TriggerSpell }); -            } - -            void OnTrigger(AuraEffect const* aurEff) -            { -                PreventDefaultAction(); +    bool Validate(SpellInfo const* spellInfo) override +    { +        return ValidateSpellInfo({ spellInfo->Effects[EFFECT_1].TriggerSpell }); +    } -                uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; -                if (Unit* target = GetUnitOwner()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0)) -                    GetUnitOwner()->CastSpell(target, triggerSpell, true); -            } +    void OnTrigger(AuraEffect const* aurEff) +    { +        PreventDefaultAction(); -            void Register() override -            { -                OnEffectPeriodic += AuraEffectPeriodicFn(spell_mother_shahraz_saber_lash_AuraScript::OnTrigger, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); -            } -        }; +        uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; +        if (Unit* target = GetUnitOwner()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0)) +            GetUnitOwner()->CastSpell(target, triggerSpell, true); +    } -        AuraScript* GetAuraScript() const override -        { -            return new spell_mother_shahraz_saber_lash_AuraScript(); -        } +    void Register() override +    { +        OnEffectPeriodic += AuraEffectPeriodicFn(spell_mother_shahraz_saber_lash::OnTrigger, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); +    }  };  /* 40863 - Sinister Periodic     40865 - Vile Periodic     40866 - Wicked Periodic     40862 - Sinful Periodic */ -class spell_mother_shahraz_generic_periodic : public SpellScriptLoader +class spell_mother_shahraz_generic_periodic : public AuraScript  { -    public: -        spell_mother_shahraz_generic_periodic() : SpellScriptLoader("spell_mother_shahraz_generic_periodic") { } - -        class spell_mother_shahraz_generic_periodic_AuraScript : public AuraScript -        { -            PrepareAuraScript(spell_mother_shahraz_generic_periodic_AuraScript); - -            bool Validate(SpellInfo const* spellInfo) override -            { -                return ValidateSpellInfo({ spellInfo->Effects[EFFECT_0].TriggerSpell }); -            } +    PrepareAuraScript(spell_mother_shahraz_generic_periodic); -            void OnTrigger(AuraEffect const* aurEff) -            { -                PreventDefaultAction(); +    bool Validate(SpellInfo const* spellInfo) override +    { +        return ValidateSpellInfo({ spellInfo->Effects[EFFECT_0].TriggerSpell }); +    } -                uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; -                if (Unit* target = GetUnitOwner()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0)) -                    GetUnitOwner()->CastSpell(target, triggerSpell, true); -            } +    void OnTrigger(AuraEffect const* aurEff) +    { +        PreventDefaultAction(); -            void Register() override -            { -                OnEffectPeriodic += AuraEffectPeriodicFn(spell_mother_shahraz_generic_periodic_AuraScript::OnTrigger, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); -            } -        }; +        uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; +        if (Unit* target = GetUnitOwner()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0)) +            GetUnitOwner()->CastSpell(target, triggerSpell, true); +    } -        AuraScript* GetAuraScript() const override -        { -            return new spell_mother_shahraz_generic_periodic_AuraScript(); -        } +    void Register() override +    { +        OnEffectPeriodic += AuraEffectPeriodicFn(spell_mother_shahraz_generic_periodic::OnTrigger, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); +    }  };  // 40867 - Random Periodic -class spell_mother_shahraz_random_periodic : public SpellScriptLoader +class spell_mother_shahraz_random_periodic : public AuraScript  { -    public: -        spell_mother_shahraz_random_periodic() : SpellScriptLoader("spell_mother_shahraz_random_periodic") { } +    PrepareAuraScript(spell_mother_shahraz_random_periodic); -        class spell_mother_shahraz_random_periodic_AuraScript : public AuraScript -        { -            PrepareAuraScript(spell_mother_shahraz_random_periodic_AuraScript); - -            bool Validate(SpellInfo const* /*spellInfo*/) override -            { -                return ValidateSpellInfo(RandomBeam); -            } - -            void OnPeriodic(AuraEffect const* /*aurEffect*/) -            { -                PreventDefaultAction(); -                GetUnitOwner()->CastSpell(GetUnitOwner(), RandomBeam[urand(0, 3)], true); -            } - -            void Register() override -            { -                OnEffectPeriodic += AuraEffectPeriodicFn(spell_mother_shahraz_random_periodic_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); -            } -        }; - -        AuraScript* GetAuraScript() const override -        { -            return new spell_mother_shahraz_random_periodic_AuraScript(); -        } +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo(RandomBeam); +    } + +    void OnPeriodic(AuraEffect const* /*aurEffect*/) +    { +        PreventDefaultAction(); +        GetUnitOwner()->CastSpell(GetUnitOwner(), RandomBeam[urand(0, 3)], true); +    } + +    void Register() override +    { +        OnEffectPeriodic += AuraEffectPeriodicFn(spell_mother_shahraz_random_periodic::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); +    }  };  void AddSC_boss_mother_shahraz()  { -    new boss_mother_shahraz(); -    new spell_mother_shahraz_fatal_attraction(); -    new spell_mother_shahraz_fatal_attraction_link(); -    new spell_mother_shahraz_saber_lash(); -    new spell_mother_shahraz_generic_periodic(); -    new spell_mother_shahraz_random_periodic(); +    RegisterBlackTempleCreatureAI(boss_mother_shahraz); +    RegisterSpellScript(spell_mother_shahraz_fatal_attraction); +    RegisterSpellScript(spell_mother_shahraz_fatal_attraction_link); +    RegisterAuraScript(spell_mother_shahraz_saber_lash); +    RegisterAuraScript(spell_mother_shahraz_generic_periodic); +    RegisterAuraScript(spell_mother_shahraz_random_periodic);  } diff --git a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp index ae3d961ca68..c069482f139 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp @@ -136,737 +136,638 @@ class EnslavedSoulEvent : public BasicEvent          Creature* _owner;  }; -class boss_reliquary_of_souls : public CreatureScript +struct boss_reliquary_of_souls : public BossAI  { -public: -    boss_reliquary_of_souls() : CreatureScript("boss_reliquary_of_souls") { } +    boss_reliquary_of_souls(Creature* creature) : BossAI(creature, DATA_RELIQUARY_OF_SOULS), _inCombat(false) +    { +        creature->m_SightDistance = 70.0f; +    } -    struct boss_reliquary_of_soulsAI : public BossAI +    void Reset() override      { -        boss_reliquary_of_soulsAI(Creature* creature) : BossAI(creature, DATA_RELIQUARY_OF_SOULS), _inCombat(false) -        { -            creature->m_SightDistance = 70.0f; -        } +        _Reset(); +        me->SetReactState(REACT_PASSIVE); +        _inCombat = false; +        events.SetPhase(PHASE_ESSENCE_OF_SUFFERING); +    } -        void Reset() override +    void MoveInLineOfSight(Unit* who) override +    { +        if (!_inCombat && who->GetTypeId() == TYPEID_PLAYER && !who->ToPlayer()->IsGameMaster() && CanAIAttack(who))          { -            _Reset(); -            me->SetReactState(REACT_PASSIVE); -            _inCombat = false; -            events.SetPhase(PHASE_ESSENCE_OF_SUFFERING); +            _inCombat = true; +            DoZoneInCombat(); +            me->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_STAND); +            events.ScheduleEvent(EVENT_SUBMERGE, Seconds(10));          } +    } -        void MoveInLineOfSight(Unit* who) override -        { -            if (!_inCombat && who->GetTypeId() == TYPEID_PLAYER && !who->ToPlayer()->IsGameMaster() && CanAIAttack(who)) -            { -                _inCombat = true; -                DoZoneInCombat(); -                me->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_STAND); -                events.ScheduleEvent(EVENT_SUBMERGE, Seconds(10)); -            } -        } +    uint32 GetSummonSpell() +    { +        if (events.IsInPhase(PHASE_ESSENCE_OF_SUFFERING)) +            return SPELL_SUMMON_ESSENCE_OF_SUFFERING; +        else if (events.IsInPhase(PHASE_ESSENCE_OF_DESIRE)) +            return SPELL_SUMMON_ESSENCE_OF_DESIRE; +        else if (events.IsInPhase(PHASE_ESSENCE_OF_ANGER)) +            return SPELL_SUMMON_ESSENCE_OF_ANGER; +        else //Should never happen +            return 0; +    } -        uint32 GetSummonSpell() -        { -            if (events.IsInPhase(PHASE_ESSENCE_OF_SUFFERING)) -                return SPELL_SUMMON_ESSENCE_OF_SUFFERING; -            else if (events.IsInPhase(PHASE_ESSENCE_OF_DESIRE)) -                return SPELL_SUMMON_ESSENCE_OF_DESIRE; -            else if (events.IsInPhase(PHASE_ESSENCE_OF_ANGER)) -                return SPELL_SUMMON_ESSENCE_OF_ANGER; -            else //Should never happen -                return 0; +    void DoAction(int32 actionId) override +    { +        switch (actionId) +        { +            case ACTION_ESSENCE_OF_SUFFERING_DEAD: +                me->RemoveAurasDueToSpell(SPELL_SUBMERGE_VISUAL); +                events.SetPhase(PHASE_ESSENCE_OF_DESIRE); +                HandleSpirits(); +                events.ScheduleEvent(EVENT_SUBMERGE, Seconds(40)); +                break; +            case ACTION_ESSENCE_OF_DESIRE_DEAD: +                me->RemoveAurasDueToSpell(SPELL_SUBMERGE_VISUAL); +                events.SetPhase(PHASE_ESSENCE_OF_ANGER); +                HandleSpirits(); +                events.ScheduleEvent(EVENT_SUBMERGE, Seconds(40)); +                break; +            case ACTION_KILL_SELF: +                me->KillSelf(); +                break;          } +    } -        void DoAction(int32 actionId) override -        { -            switch (actionId) -            { -                case ACTION_ESSENCE_OF_SUFFERING_DEAD: -                    me->RemoveAurasDueToSpell(SPELL_SUBMERGE_VISUAL); -                    events.SetPhase(PHASE_ESSENCE_OF_DESIRE); -                    HandleSpirits(); -                    events.ScheduleEvent(EVENT_SUBMERGE, Seconds(40)); -                    break; -                case ACTION_ESSENCE_OF_DESIRE_DEAD: -                    me->RemoveAurasDueToSpell(SPELL_SUBMERGE_VISUAL); -                    events.SetPhase(PHASE_ESSENCE_OF_ANGER); -                    HandleSpirits(); -                    events.ScheduleEvent(EVENT_SUBMERGE, Seconds(40)); -                    break; -                case ACTION_KILL_SELF: -                    me->KillSelf(); -                    break; -            } +    void HandleSpirits() +    { +        std::vector<Creature*> _worldTriggerList; +        me->GetCreatureListWithEntryInGrid(_worldTriggerList, NPC_RELIQUARY_WORLD_TRIGGER, 70.0f); + +        if (_worldTriggerList.empty()) +            return; + +        //Get random creatures +        Trinity::Containers::RandomShuffle(_worldTriggerList); +        _worldTriggerList.resize(21); + +        for (uint8 i = 0; i < 21; i++) +        { +            Creature* wTrigger = _worldTriggerList[i]; +            if (i < 3) +                wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(4000)); +            else if (i < 6) +                wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(8000)); +            else if (i < 9) +                wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(12000)); +            else if (i < 12) +                wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(16000)); +            else if (i < 15) +                wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(20000)); +            else if (i < 18) +                wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(24000)); +            else +                wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(28000));          } +    } -        void HandleSpirits() -        { -            std::vector<Creature*> _worldTriggerList; -            me->GetCreatureListWithEntryInGrid(_worldTriggerList, NPC_RELIQUARY_WORLD_TRIGGER, 70.0f); - -            if (_worldTriggerList.empty()) -                return; +    void KillAssyncEvents() +    { +        std::vector<Creature*> _worldTriggerList; +        me->GetCreatureListWithEntryInGrid(_worldTriggerList, NPC_RELIQUARY_WORLD_TRIGGER, 70.0f); -            //Get random creatures -            Trinity::Containers::RandomShuffle(_worldTriggerList); -            _worldTriggerList.resize(21); +        if (_worldTriggerList.empty()) +            return; -            for (uint8 i = 0; i < 21; i++) -            { -                Creature* wTrigger = _worldTriggerList[i]; -                if (i < 3) -                    wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(4000)); -                else if (i < 6) -                    wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(8000)); -                else if (i < 9) -                    wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(12000)); -                else if (i < 12) -                    wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(16000)); -                else if (i < 15) -                    wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(20000)); -                else if (i < 18) -                    wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(24000)); -                else -                    wTrigger->m_Events.AddEvent(new EnslavedSoulEvent(wTrigger), wTrigger->m_Events.CalculateTime(28000)); -            } -        } +        for (Creature* trigger : _worldTriggerList) +            trigger->m_Events.KillAllEvents(true); +    } -        void KillAssyncEvents() -        { -            std::vector<Creature*> _worldTriggerList; -            me->GetCreatureListWithEntryInGrid(_worldTriggerList, NPC_RELIQUARY_WORLD_TRIGGER, 70.0f); +    void EnterEvadeMode(EvadeReason /*why*/) override +    { +        events.Reset(); +        summons.DespawnAll(); +        KillAssyncEvents(); +        _DespawnAtEvade(); +    } -            if (_worldTriggerList.empty()) -                return; +    void JustDied(Unit* /*killer*/) override +    { +        events.Reset(); +        instance->SetBossState(DATA_RELIQUARY_OF_SOULS, DONE); +    } -            for (Creature* trigger : _worldTriggerList) -                trigger->m_Events.KillAllEvents(true); -        } +    void UpdateAI(uint32 diff) override +    { +        if (!UpdateVictim()) +            return; -        void EnterEvadeMode(EvadeReason /*why*/) override -        { -            events.Reset(); -            summons.DespawnAll(); -            KillAssyncEvents(); -            _DespawnAtEvade(); -        } +        if (me->HasUnitState(UNIT_STATE_CASTING)) +            return; -        void JustDied(Unit* /*killer*/) override -        { -            events.Reset(); -            instance->SetBossState(DATA_RELIQUARY_OF_SOULS, DONE); -        } +        events.Update(diff); -        void UpdateAI(uint32 diff) override +        while (uint32 eventId = events.ExecuteEvent())          { -            if (!UpdateVictim()) -                return; - -            if (me->HasUnitState(UNIT_STATE_CASTING)) -                return; - -            events.Update(diff); - -            while (uint32 eventId = events.ExecuteEvent()) +            switch (eventId)              { -                switch (eventId) +                case EVENT_SUBMERGE: +                    DoCastSelf(SPELL_SUBMERGE_VISUAL, true); +                    events.ScheduleEvent(EVENT_SUMMON_ESSENCE, Seconds(3)); +                    break; +                case EVENT_SUMMON_ESSENCE:                  { -                    case EVENT_SUBMERGE: -                        DoCastSelf(SPELL_SUBMERGE_VISUAL, true); -                        events.ScheduleEvent(EVENT_SUMMON_ESSENCE, Seconds(3)); -                        break; -                    case EVENT_SUMMON_ESSENCE: -                    { -                        EntryCheckPredicate pred(NPC_ENSLAVED_SOUL); -                        summons.DoAction(ACTION_KILL_SELF, pred); -                        DoCastSelf(GetSummonSpell()); -                        break; -                    } -                    default: -                        break; +                    EntryCheckPredicate pred(NPC_ENSLAVED_SOUL); +                    summons.DoAction(ACTION_KILL_SELF, pred); +                    DoCastSelf(GetSummonSpell()); +                    break;                  } - -                if (me->HasUnitState(UNIT_STATE_CASTING)) -                    return; +                default: +                    break;              } -        } - -    private: -        bool _inCombat; -    }; -    CreatureAI* GetAI(Creature* creature) const override -    { -        return GetBlackTempleAI<boss_reliquary_of_soulsAI>(creature); +            if (me->HasUnitState(UNIT_STATE_CASTING)) +                return; +        }      } + +private: +    bool _inCombat;  }; -class boss_essence_of_suffering : public CreatureScript +struct boss_essence_of_suffering : public BossAI  { -public: -    boss_essence_of_suffering() : CreatureScript("boss_essence_of_suffering") { } +    boss_essence_of_suffering(Creature* creature) : BossAI(creature, DATA_ESSENCE_OF_SUFFERING), _dead(false) +    { +        SetBoundary(instance->GetBossBoundary(DATA_RELIQUARY_OF_SOULS)); +    } -    struct boss_essence_of_sufferingAI : public BossAI +    void Reset() override      { -        boss_essence_of_sufferingAI(Creature* creature) : BossAI(creature, DATA_ESSENCE_OF_SUFFERING), _dead(false) -        { -            SetBoundary(instance->GetBossBoundary(DATA_RELIQUARY_OF_SOULS)); -        } +        DoCastAOE(SPELL_AURA_OF_SUFFERING, true); +        events.Reset(); +        _dead = false; +    } -        void Reset() override -        { -            DoCastAOE(SPELL_AURA_OF_SUFFERING, true); -            events.Reset(); -            _dead = false; -        } +    void MovementInform(uint32 motionType, uint32 pointId) override +    { +        if (motionType != POINT_MOTION_TYPE) +            return; -        void MovementInform(uint32 motionType, uint32 pointId) override +        if (pointId == RELIQUARY_DESPAWN_WAYPOINT)          { -            if (motionType != POINT_MOTION_TYPE) -                return; - -            if (pointId == RELIQUARY_DESPAWN_WAYPOINT) -            { -                if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) -                    reliquary->AI()->DoAction(ACTION_ESSENCE_OF_SUFFERING_DEAD); +            if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) +                reliquary->AI()->DoAction(ACTION_ESSENCE_OF_SUFFERING_DEAD); -                DoCastSelf(SPELL_SUBMERGE_VISUAL, true); -                me->DespawnOrUnsummon(Seconds(2)); -            } +            DoCastSelf(SPELL_SUBMERGE_VISUAL, true); +            me->DespawnOrUnsummon(Seconds(2));          } +    } -        void DamageTaken(Unit* /*done_by*/, uint32 &damage) override +    void DamageTaken(Unit* /*done_by*/, uint32 &damage) override +    { +        if (damage >= me->GetHealth())          { -            if (damage >= me->GetHealth()) +            damage = 0; +            if (!_dead)              { -                damage = 0; -                if (!_dead) -                { -                    _dead = true; -                    Talk(SUFF_SAY_RECAP); -                    me->AttackStop(); -                    me->SetReactState(REACT_PASSIVE); -                    events.Reset(); -                    me->InterruptNonMeleeSpells(false); -                    me->GetMotionMaster()->MovePoint(RELIQUARY_DESPAWN_WAYPOINT, DespawnPoint); -                } +                _dead = true; +                Talk(SUFF_SAY_RECAP); +                me->AttackStop(); +                me->SetReactState(REACT_PASSIVE); +                events.Reset(); +                me->InterruptNonMeleeSpells(false); +                me->GetMotionMaster()->MovePoint(RELIQUARY_DESPAWN_WAYPOINT, DespawnPoint);              }          } +    } -        void EnterCombat(Unit* /*who*/) override -        { -            me->SetCombatPulseDelay(5); -            me->setActive(true); -            DoZoneInCombat(); +    void EnterCombat(Unit* /*who*/) override +    { +        me->SetCombatPulseDelay(5); +        me->setActive(true); +        DoZoneInCombat(); -            events.ScheduleEvent(EVENT_SOUL_DRAIN, Seconds(20)); -            events.ScheduleEvent(EVENT_FRENZY, Seconds(45)); -            Talk(SUFF_SAY_AGRO); -        } +        events.ScheduleEvent(EVENT_SOUL_DRAIN, Seconds(20)); +        events.ScheduleEvent(EVENT_FRENZY, Seconds(45)); +        Talk(SUFF_SAY_AGRO); +    } -        void KilledUnit(Unit* victim) override -        { -            if (victim->GetTypeId() == TYPEID_PLAYER) -                Talk(SUFF_SAY_SLAY); -        } +    void KilledUnit(Unit* victim) override +    { +        if (victim->GetTypeId() == TYPEID_PLAYER) +            Talk(SUFF_SAY_SLAY); +    } -        void EnterEvadeMode(EvadeReason /*why*/) override -        { -            if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) -                reliquary->AI()->EnterEvadeMode(EVADE_REASON_OTHER); -        } +    void EnterEvadeMode(EvadeReason /*why*/) override +    { +        if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) +            reliquary->AI()->EnterEvadeMode(EVADE_REASON_OTHER); +    } -        void UpdateAI(uint32 diff) override -        { -            if (!UpdateVictim()) -                return; +    void UpdateAI(uint32 diff) override +    { +        if (!UpdateVictim()) +            return; -            if (me->HasUnitState(UNIT_STATE_CASTING)) -                return; +        if (me->HasUnitState(UNIT_STATE_CASTING)) +            return; -            events.Update(diff); +        events.Update(diff); -            while (uint32 eventId = events.ExecuteEvent()) +        while (uint32 eventId = events.ExecuteEvent()) +        { +            switch (eventId)              { -                switch (eventId) -                { -                    case EVENT_SOUL_DRAIN: -                        me->CastCustomSpell(SPELL_SOUL_DRAIN, SPELLVALUE_MAX_TARGETS, 5, me); -                        events.Repeat(Seconds(30), Seconds(35)); -                        break; -                    case EVENT_FRENZY: -                        Talk(SUFF_SAY_ENRAGE); -                        DoCastSelf(SPELL_FRENZY); -                        events.Repeat(Seconds(45), Seconds(50)); -                        break; -                    default: -                        break; -                } - -                if (me->HasUnitState(UNIT_STATE_CASTING)) -                    return; +                case EVENT_SOUL_DRAIN: +                    me->CastCustomSpell(SPELL_SOUL_DRAIN, SPELLVALUE_MAX_TARGETS, 5, me); +                    events.Repeat(Seconds(30), Seconds(35)); +                    break; +                case EVENT_FRENZY: +                    Talk(SUFF_SAY_ENRAGE); +                    DoCastSelf(SPELL_FRENZY); +                    events.Repeat(Seconds(45), Seconds(50)); +                    break; +                default: +                    break;              } -            DoMeleeAttackIfReady(); +            if (me->HasUnitState(UNIT_STATE_CASTING)) +                return;          } -    private: -        bool _dead; -    }; -    CreatureAI* GetAI(Creature* creature) const override -    { -        return GetBlackTempleAI<boss_essence_of_sufferingAI>(creature); +        DoMeleeAttackIfReady();      } +private: +    bool _dead;  }; -class boss_essence_of_desire : public CreatureScript +struct boss_essence_of_desire : public BossAI  { -public: -    boss_essence_of_desire() : CreatureScript("boss_essence_of_desire") { } - -    struct boss_essence_of_desireAI : public BossAI +    boss_essence_of_desire(Creature* creature) : BossAI(creature, DATA_ESSENCE_OF_DESIRE), _dead(false)      { -        boss_essence_of_desireAI(Creature* creature) : BossAI(creature, DATA_ESSENCE_OF_DESIRE), _dead(false) -        { -            SetBoundary(instance->GetBossBoundary(DATA_RELIQUARY_OF_SOULS)); -        } +        SetBoundary(instance->GetBossBoundary(DATA_RELIQUARY_OF_SOULS)); +    } -        void Reset() override -        { -            DoCastSelf(SPELL_AURA_OF_DESIRE, true); -            events.Reset(); -            _dead = false; -        } +    void Reset() override +    { +        DoCastSelf(SPELL_AURA_OF_DESIRE, true); +        events.Reset(); +        _dead = false; +    } -        void EnterCombat(Unit* /*who*/) override -        { -            events.ScheduleEvent(EVENT_SPIRIT_SHOCK, Seconds(11)); -            events.ScheduleEvent(EVENT_RUNE_SHIELD, Seconds(16)); -            events.ScheduleEvent(EVENT_DEADEN, Seconds(31)); +    void EnterCombat(Unit* /*who*/) override +    { +        events.ScheduleEvent(EVENT_SPIRIT_SHOCK, Seconds(11)); +        events.ScheduleEvent(EVENT_RUNE_SHIELD, Seconds(16)); +        events.ScheduleEvent(EVENT_DEADEN, Seconds(31)); + +        me->SetCombatPulseDelay(5); +        me->setActive(true); +        DoZoneInCombat(); +        Talk(DESI_SAY_FREED); +    } -            me->SetCombatPulseDelay(5); -            me->setActive(true); -            DoZoneInCombat(); -            Talk(DESI_SAY_FREED); -        } +    void MovementInform(uint32 motionType, uint32 pointId) override +    { +        if (motionType != POINT_MOTION_TYPE) +            return; -        void MovementInform(uint32 motionType, uint32 pointId) override +        if (pointId == RELIQUARY_DESPAWN_WAYPOINT)          { -            if (motionType != POINT_MOTION_TYPE) -                return; - -            if (pointId == RELIQUARY_DESPAWN_WAYPOINT) -            { -                if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) -                    reliquary->AI()->DoAction(ACTION_ESSENCE_OF_DESIRE_DEAD); +            if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) +                reliquary->AI()->DoAction(ACTION_ESSENCE_OF_DESIRE_DEAD); -                DoCastSelf(SPELL_SUBMERGE_VISUAL, true); -                me->DespawnOrUnsummon(Seconds(2)); -            } +            DoCastSelf(SPELL_SUBMERGE_VISUAL, true); +            me->DespawnOrUnsummon(Seconds(2));          } +    } -        void DamageTaken(Unit* /*done_by*/, uint32 &damage) override +    void DamageTaken(Unit* /*done_by*/, uint32 &damage) override +    { +        if (damage >= me->GetHealth())          { -            if (damage >= me->GetHealth()) +            damage = 0; +            if (!_dead)              { -                damage = 0; -                if (!_dead) -                { -                    _dead = true; -                    Talk(DESI_SAY_RECAP); -                    me->AttackStop(); -                    me->SetReactState(REACT_PASSIVE); -                    events.Reset(); -                    me->InterruptNonMeleeSpells(false); -                    me->GetMotionMaster()->MovePoint(RELIQUARY_DESPAWN_WAYPOINT, DespawnPoint); -                } +                _dead = true; +                Talk(DESI_SAY_RECAP); +                me->AttackStop(); +                me->SetReactState(REACT_PASSIVE); +                events.Reset(); +                me->InterruptNonMeleeSpells(false); +                me->GetMotionMaster()->MovePoint(RELIQUARY_DESPAWN_WAYPOINT, DespawnPoint);              }          } +    } -        void KilledUnit(Unit* victim) override -        { -            if (victim->GetTypeId() == TYPEID_PLAYER) -                Talk(DESI_SAY_SLAY); -        } +    void KilledUnit(Unit* victim) override +    { +        if (victim->GetTypeId() == TYPEID_PLAYER) +            Talk(DESI_SAY_SLAY); +    } -        void EnterEvadeMode(EvadeReason /*why*/) override -        { -            if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) -                reliquary->AI()->EnterEvadeMode(EVADE_REASON_OTHER); -        } +    void EnterEvadeMode(EvadeReason /*why*/) override +    { +        if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) +            reliquary->AI()->EnterEvadeMode(EVADE_REASON_OTHER); +    } -        void UpdateAI(uint32 diff) override -        { -            if (!UpdateVictim()) -                return; +    void UpdateAI(uint32 diff) override +    { +        if (!UpdateVictim()) +            return; -            if (me->HasUnitState(UNIT_STATE_CASTING)) -                return; +        if (me->HasUnitState(UNIT_STATE_CASTING)) +            return; -            events.Update(diff); +        events.Update(diff); -            while (uint32 eventId = events.ExecuteEvent()) +        while (uint32 eventId = events.ExecuteEvent()) +        { +            switch (eventId)              { -                switch (eventId) -                { -                    case EVENT_SPIRIT_SHOCK: -                        DoCastVictim(SPELL_SPIRIT_SHOCK); -                        events.Repeat(Seconds(10), Seconds(15)); -                        break; -                    case EVENT_RUNE_SHIELD: -                        DoCastSelf(SPELL_RUNE_SHIELD); -                        events.Repeat(Seconds(16)); -                        break; -                    case EVENT_DEADEN: -                        Talk(DESI_SAY_SPEC); -                        DoCastVictim(SPELL_DEADEN); -                        events.Repeat(Seconds(31)); -                        break; -                    default: -                        break; -                } - -                if (me->HasUnitState(UNIT_STATE_CASTING)) -                    return; +                case EVENT_SPIRIT_SHOCK: +                    DoCastVictim(SPELL_SPIRIT_SHOCK); +                    events.Repeat(Seconds(10), Seconds(15)); +                    break; +                case EVENT_RUNE_SHIELD: +                    DoCastSelf(SPELL_RUNE_SHIELD); +                    events.Repeat(Seconds(16)); +                    break; +                case EVENT_DEADEN: +                    Talk(DESI_SAY_SPEC); +                    DoCastVictim(SPELL_DEADEN); +                    events.Repeat(Seconds(31)); +                    break; +                default: +                    break;              } -            DoMeleeAttackIfReady(); +            if (me->HasUnitState(UNIT_STATE_CASTING)) +                return;          } -    private: -        bool _dead; -    }; -    CreatureAI* GetAI(Creature* creature) const override -    { -        return GetBlackTempleAI<boss_essence_of_desireAI>(creature); +        DoMeleeAttackIfReady();      } +private: +    bool _dead;  }; -class boss_essence_of_anger : public CreatureScript +struct boss_essence_of_anger : public BossAI  { -public: -    boss_essence_of_anger() : CreatureScript("boss_essence_of_anger") { } - -    struct boss_essence_of_angerAI : public BossAI +    boss_essence_of_anger(Creature* creature) :BossAI(creature, DATA_ESSENCE_OF_ANGER)      { -        boss_essence_of_angerAI(Creature* creature) :BossAI(creature, DATA_ESSENCE_OF_ANGER) -        { -            SetBoundary(instance->GetBossBoundary(DATA_RELIQUARY_OF_SOULS)); -        } +        SetBoundary(instance->GetBossBoundary(DATA_RELIQUARY_OF_SOULS)); +    } -        void Reset() override -        { -            events.Reset(); -            _targetGUID.Clear(); -            DoCastSelf(SPELL_AURA_OF_ANGER); -        } +    void Reset() override +    { +        events.Reset(); +        _targetGUID.Clear(); +        DoCastSelf(SPELL_AURA_OF_ANGER); +    } -        void EnterCombat(Unit* /*who*/) override -        { -            Talk(ANGER_SAY_FREED); +    void EnterCombat(Unit* /*who*/) override +    { +        Talk(ANGER_SAY_FREED); -            events.ScheduleEvent(EVENT_START_CHECK_TANKER, Seconds(5)); -            events.ScheduleEvent(EVENT_SOUL_SCREAM, Seconds(11)); -            events.ScheduleEvent(EVENT_SPITE, Seconds(20)); -            events.ScheduleEvent(EVENT_FREED_2, Seconds(1), Minutes(3)); +        events.ScheduleEvent(EVENT_START_CHECK_TANKER, Seconds(5)); +        events.ScheduleEvent(EVENT_SOUL_SCREAM, Seconds(11)); +        events.ScheduleEvent(EVENT_SPITE, Seconds(20)); +        events.ScheduleEvent(EVENT_FREED_2, Seconds(1), Minutes(3)); -            me->SetCombatPulseDelay(5); -            me->setActive(true); -            DoZoneInCombat(); -        } +        me->SetCombatPulseDelay(5); +        me->setActive(true); +        DoZoneInCombat(); +    } -        void JustDied(Unit* /*killer*/) override -        { -            DoPlaySoundToSet(me, ANGER_SOUND_ID_DEATH); -            if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) -                reliquary->AI()->DoAction(ACTION_KILL_SELF); -        } +    void JustDied(Unit* /*killer*/) override +    { +        DoPlaySoundToSet(me, ANGER_SOUND_ID_DEATH); +        if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) +            reliquary->AI()->DoAction(ACTION_KILL_SELF); +    } -        void UpdateAI(uint32 diff) override -        { -            if (!UpdateVictim()) -                return; +    void UpdateAI(uint32 diff) override +    { +        if (!UpdateVictim()) +            return; -            if (me->HasUnitState(UNIT_STATE_CASTING)) -                return; +        if (me->HasUnitState(UNIT_STATE_CASTING)) +            return; -            events.Update(diff); +        events.Update(diff); -            while (uint32 eventId = events.ExecuteEvent()) +        while (uint32 eventId = events.ExecuteEvent()) +        { +            switch (eventId)              { -                switch (eventId) +                case EVENT_CHECK_TANKER:                  { -                    case EVENT_CHECK_TANKER: +                    Unit* target = me->GetVictim(); +                    if (!_targetGUID || !target) +                        return; + +                    if (target->GetGUID() != _targetGUID)                      { -                        Unit* target = me->GetVictim(); -                        if (!_targetGUID || !target) -                            return; - -                        if (target->GetGUID() != _targetGUID) -                        { -                            Talk(ANGER_SAY_SEETHE); -                            Talk(ANGER_EMOTE_SEETHE, me); -                            _targetGUID = target->GetGUID(); -                            DoCastSelf(SPELL_SEETHE, true); -                        } -                        break; +                        Talk(ANGER_SAY_SEETHE); +                        Talk(ANGER_EMOTE_SEETHE, me); +                        _targetGUID = target->GetGUID(); +                        DoCastSelf(SPELL_SEETHE, true);                      } -                    case EVENT_SOUL_SCREAM: -                        DoCastSelf(SPELL_SOUL_SCREAM); -                        events.Repeat(Seconds(11)); -                        break; -                    case EVENT_SPITE: -                        Talk(ANGER_SAY_SPITE); -                        me->CastCustomSpell(SPELL_SPITE, SPELLVALUE_MAX_TARGETS, 3, me); -                        events.Repeat(Seconds(20)); -                        break; -                    case EVENT_START_CHECK_TANKER: -                        if (Unit* target = me->GetVictim()) -                        { -                            _targetGUID = target->GetGUID(); -                            events.ScheduleEvent(EVENT_CHECK_TANKER, Seconds(1)); -                        } -                        else -                            events.Repeat(Seconds(1)); -                        break; -                    case EVENT_FREED_2: -                        Talk(ANGER_SAY_FREED_2); -                        break; -                    default: -                        break; +                    break;                  } - -                if (me->HasUnitState(UNIT_STATE_CASTING)) -                    return; +                case EVENT_SOUL_SCREAM: +                    DoCastSelf(SPELL_SOUL_SCREAM); +                    events.Repeat(Seconds(11)); +                    break; +                case EVENT_SPITE: +                    Talk(ANGER_SAY_SPITE); +                    me->CastCustomSpell(SPELL_SPITE, SPELLVALUE_MAX_TARGETS, 3, me); +                    events.Repeat(Seconds(20)); +                    break; +                case EVENT_START_CHECK_TANKER: +                    if (Unit* target = me->GetVictim()) +                    { +                        _targetGUID = target->GetGUID(); +                        events.ScheduleEvent(EVENT_CHECK_TANKER, Seconds(1)); +                    } +                    else +                        events.Repeat(Seconds(1)); +                    break; +                case EVENT_FREED_2: +                    Talk(ANGER_SAY_FREED_2); +                    break; +                default: +                    break;              } -            DoMeleeAttackIfReady(); -        } - -        void EnterEvadeMode(EvadeReason /*why*/) override -        { -            if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) -                reliquary->AI()->EnterEvadeMode(EVADE_REASON_OTHER); +            if (me->HasUnitState(UNIT_STATE_CASTING)) +                return;          } -    private: -        ObjectGuid _targetGUID; -    }; +        DoMeleeAttackIfReady(); +    } -    CreatureAI* GetAI(Creature* creature) const override +    void EnterEvadeMode(EvadeReason /*why*/) override      { -        return GetBlackTempleAI<boss_essence_of_angerAI>(creature); +        if (Creature* reliquary = instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) +            reliquary->AI()->EnterEvadeMode(EVADE_REASON_OTHER);      } + +private: +    ObjectGuid _targetGUID;  }; -class npc_enslaved_soul : public CreatureScript +struct npc_enslaved_soul : public ScriptedAI  { -public: -    npc_enslaved_soul() : CreatureScript("npc_enslaved_soul") { } +    npc_enslaved_soul(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } -    struct npc_enslaved_soulAI : public ScriptedAI +    void Reset() override      { -        npc_enslaved_soulAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } - -        void Reset() override -        { -            me->SetReactState(REACT_PASSIVE); -            if (Creature* reliquary = _instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) -                reliquary->AI()->JustSummoned(me); +        me->SetReactState(REACT_PASSIVE); +        if (Creature* reliquary = _instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) +            reliquary->AI()->JustSummoned(me); -            DoCastSelf(SPELL_ENSLAVED_SOUL_PASSIVE, true); +        DoCastSelf(SPELL_ENSLAVED_SOUL_PASSIVE, true); -            _scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/) -            { -                me->SetReactState(REACT_AGGRESSIVE); -                me->SetInCombatWithZone(); -            }); -        } - -        void DoAction(int32 actionId) override +        _scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/)          { -            if (actionId == ACTION_KILL_SELF) -                me->KillSelf(); -        } +            me->SetReactState(REACT_AGGRESSIVE); +            me->SetInCombatWithZone(); +        }); +    } -        void UpdateAI(uint32 diff) override -        { -            if (!UpdateVictim()) -                return; +    void DoAction(int32 actionId) override +    { +        if (actionId == ACTION_KILL_SELF) +            me->KillSelf(); +    } -            _scheduler.Update(diff); +    void UpdateAI(uint32 diff) override +    { +        if (!UpdateVictim()) +            return; -            DoMeleeAttackIfReady(); -        } +        _scheduler.Update(diff); -        void JustDied(Unit* /*killer*/) override -        { -            DoCastSelf(SPELL_SOUL_RELEASE, true); -        } - -    private: -        InstanceScript* _instance; -        TaskScheduler _scheduler; -    }; +        DoMeleeAttackIfReady(); +    } -    CreatureAI* GetAI(Creature* creature) const override +    void JustDied(Unit* /*killer*/) override      { -        return GetBlackTempleAI<npc_enslaved_soulAI>(creature); +        DoCastSelf(SPELL_SOUL_RELEASE, true);      } + +private: +    InstanceScript* _instance; +    TaskScheduler _scheduler;  };  // 41350 - Aura of Desire -class spell_reliquary_of_souls_aura_of_desire : public SpellScriptLoader +class spell_reliquary_of_souls_aura_of_desire : public AuraScript  { -    public: -        spell_reliquary_of_souls_aura_of_desire() : SpellScriptLoader("spell_reliquary_of_souls_aura_of_desire") { } - -        class spell_reliquary_of_souls_aura_of_desire_AuraScript : public AuraScript -        { -            PrepareAuraScript(spell_reliquary_of_souls_aura_of_desire_AuraScript); - -            bool Validate(SpellInfo const* /*spellInfo*/) override -            { -                return ValidateSpellInfo({ SPELL_AURA_OF_DESIRE_DAMAGE }); -            } +    PrepareAuraScript(spell_reliquary_of_souls_aura_of_desire); -            void OnProcSpell(AuraEffect const* aurEff, ProcEventInfo& eventInfo) -            { -                PreventDefaultAction(); -                DamageInfo* damageInfo = eventInfo.GetDamageInfo(); -                if (!damageInfo || !damageInfo->GetDamage()) -                    return; - -                Unit* caster = eventInfo.GetActor(); -                int32 bp = damageInfo->GetDamage() / 2; -                caster->CastCustomSpell(SPELL_AURA_OF_DESIRE_DAMAGE, SPELLVALUE_BASE_POINT0, bp, caster, true, nullptr, aurEff); -            } +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo({ SPELL_AURA_OF_DESIRE_DAMAGE }); +    } -            void UpdateAmount(AuraEffect* /*aurEff*/) -            { -                if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_1)) -                    effect->ChangeAmount(effect->GetAmount() - 5); -            } +    void OnProcSpell(AuraEffect const* aurEff, ProcEventInfo& eventInfo) +    { +        PreventDefaultAction(); +        DamageInfo* damageInfo = eventInfo.GetDamageInfo(); +        if (!damageInfo || !damageInfo->GetDamage()) +            return; + +        Unit* caster = eventInfo.GetActor(); +        int32 bp = damageInfo->GetDamage() / 2; +        caster->CastCustomSpell(SPELL_AURA_OF_DESIRE_DAMAGE, SPELLVALUE_BASE_POINT0, bp, caster, true, nullptr, aurEff); +    } -            void Register() override -            { -                OnEffectProc += AuraEffectProcFn(spell_reliquary_of_souls_aura_of_desire_AuraScript::OnProcSpell, EFFECT_0, SPELL_AURA_MOD_HEALING_PCT); -                OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_reliquary_of_souls_aura_of_desire_AuraScript::UpdateAmount, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL); -            } -        }; +    void UpdateAmount(AuraEffect* /*aurEff*/) +    { +        if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_1)) +            effect->ChangeAmount(effect->GetAmount() - 5); +    } -        AuraScript* GetAuraScript() const override -        { -            return new spell_reliquary_of_souls_aura_of_desire_AuraScript(); -        } +    void Register() override +    { +        OnEffectProc += AuraEffectProcFn(spell_reliquary_of_souls_aura_of_desire::OnProcSpell, EFFECT_0, SPELL_AURA_MOD_HEALING_PCT); +        OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_reliquary_of_souls_aura_of_desire::UpdateAmount, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL); +    }  };  // 28819 - Submerge Visual -class spell_reliquary_of_souls_submerge : public SpellScriptLoader +class spell_reliquary_of_souls_submerge : public AuraScript  { -    public: -        spell_reliquary_of_souls_submerge() : SpellScriptLoader("spell_reliquary_of_souls_submerge") { } - -        class spell_reliquary_of_souls_submerge_AuraScript : public AuraScript -        { -            PrepareAuraScript(spell_reliquary_of_souls_submerge_AuraScript); +    PrepareAuraScript(spell_reliquary_of_souls_submerge); -            void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) -            { -                GetTarget()->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_SUBMERGED); -            } +    void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +    { +        GetTarget()->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_SUBMERGED); +    } -            void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) -            { -                GetTarget()->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_STAND); -            } +    void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +    { +        GetTarget()->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_STAND); +    } -            void Register() override -            { -                AfterEffectApply += AuraEffectApplyFn(spell_reliquary_of_souls_submerge_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); -                AfterEffectRemove += AuraEffectRemoveFn(spell_reliquary_of_souls_submerge_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); -            } -        }; - -        AuraScript* GetAuraScript() const override -        { -            return new spell_reliquary_of_souls_submerge_AuraScript(); -        } +    void Register() override +    { +        AfterEffectApply += AuraEffectApplyFn(spell_reliquary_of_souls_submerge::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); +        AfterEffectRemove += AuraEffectRemoveFn(spell_reliquary_of_souls_submerge::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); +    }  };  // 41376 - Spite -class spell_reliquary_of_souls_spite : public SpellScriptLoader +class spell_reliquary_of_souls_spite : public AuraScript  { -    public: -        spell_reliquary_of_souls_spite() : SpellScriptLoader("spell_reliquary_of_souls_spite") { } - -        class spell_reliquary_of_souls_spite_AuraScript : public AuraScript -        { -            PrepareAuraScript(spell_reliquary_of_souls_spite_AuraScript); - -            bool Validate(SpellInfo const* /*spellInfo*/) override -            { -                return ValidateSpellInfo({ SPELL_SPITE_DAMAGE }); -            } +    PrepareAuraScript(spell_reliquary_of_souls_spite); -            void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) -            { -                if (Unit* caster = GetCaster()) -                    caster->CastSpell(GetTarget(), SPELL_SPITE_DAMAGE, true); -            } +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo({ SPELL_SPITE_DAMAGE }); +    } -            void Register() override -            { -                AfterEffectRemove += AuraEffectRemoveFn(spell_reliquary_of_souls_spite_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DAMAGE_IMMUNITY, AURA_EFFECT_HANDLE_REAL); -            } -        }; +    void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +    { +        if (Unit* caster = GetCaster()) +            caster->CastSpell(GetTarget(), SPELL_SPITE_DAMAGE, true); +    } -        AuraScript* GetAuraScript() const -        { -            return new spell_reliquary_of_souls_spite_AuraScript(); -        } +    void Register() override +    { +        AfterEffectRemove += AuraEffectRemoveFn(spell_reliquary_of_souls_spite::OnRemove, EFFECT_0, SPELL_AURA_DAMAGE_IMMUNITY, AURA_EFFECT_HANDLE_REAL); +    }  };  // 41305 - Frenzy -class spell_reliquary_of_souls_frenzy : public SpellScriptLoader +class spell_reliquary_of_souls_frenzy : public SpellScript  { -    public: -        spell_reliquary_of_souls_frenzy() : SpellScriptLoader("spell_reliquary_of_souls_frenzy") { } - -        class spell_reliquary_of_souls_frenzy_SpellScript : public SpellScript -        { -            PrepareSpellScript(spell_reliquary_of_souls_frenzy_SpellScript); - -            void HandleAfterCast() -            { -                if (Creature* caster = GetCaster()->ToCreature()) -                    caster->AI()->Talk(SUFF_EMOTE_ENRAGE, caster); -            } +    PrepareSpellScript(spell_reliquary_of_souls_frenzy); -            void Register() override -            { -                AfterCast += SpellCastFn(spell_reliquary_of_souls_frenzy_SpellScript::HandleAfterCast); -            } -        }; +    void HandleAfterCast() +    { +        if (Creature* caster = GetCaster()->ToCreature()) +            caster->AI()->Talk(SUFF_EMOTE_ENRAGE, caster); +    } -        SpellScript* GetSpellScript() const override -        { -            return new spell_reliquary_of_souls_frenzy_SpellScript(); -        } +    void Register() override +    { +        AfterCast += SpellCastFn(spell_reliquary_of_souls_frenzy::HandleAfterCast); +    }  };  void AddSC_boss_reliquary_of_souls()  { -    new boss_reliquary_of_souls(); -    new boss_essence_of_suffering(); -    new boss_essence_of_desire(); -    new boss_essence_of_anger(); -    new npc_enslaved_soul(); -    new spell_reliquary_of_souls_aura_of_desire(); -    new spell_reliquary_of_souls_submerge(); -    new spell_reliquary_of_souls_spite(); -    new spell_reliquary_of_souls_frenzy(); +    RegisterBlackTempleCreatureAI(boss_reliquary_of_souls); +    RegisterBlackTempleCreatureAI(boss_essence_of_suffering); +    RegisterBlackTempleCreatureAI(boss_essence_of_desire); +    RegisterBlackTempleCreatureAI(boss_essence_of_anger); +    RegisterBlackTempleCreatureAI(npc_enslaved_soul); +    RegisterAuraScript(spell_reliquary_of_souls_aura_of_desire); +    RegisterAuraScript(spell_reliquary_of_souls_submerge); +    RegisterAuraScript(spell_reliquary_of_souls_spite); +    RegisterSpellScript(spell_reliquary_of_souls_frenzy);  } diff --git a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp index 41090701682..17fd7d91c21 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp @@ -32,14 +32,14 @@  enum Says  {      // Akama -    SAY_BROKEN_FREE_0                = 0, -    SAY_BROKEN_FREE_1                = 1, -    SAY_BROKEN_FREE_2                = 2, -    SAY_LOW_HEALTH                   = 3, -    SAY_DEAD                         = 4, +    SAY_BROKEN_FREE_0  = 0, +    SAY_BROKEN_FREE_1  = 1, +    SAY_BROKEN_FREE_2  = 2, +    SAY_LOW_HEALTH     = 3, +    SAY_DEAD           = 4,      // Ashtongue Broken -    SAY_BROKEN_SPECIAL               = 0, -    SAY_BROKEN_HAIL                  = 1 +    SAY_BROKEN_SPECIAL = 0, +    SAY_BROKEN_HAIL    = 1  };  enum Spells @@ -81,20 +81,20 @@ enum Spells  enum Creatures  { -    NPC_ASHTONGUE_CHANNELER          = 23421, -    NPC_ASHTONGUE_BROKEN             = 23319, -    NPC_CREATURE_SPAWNER_AKAMA       = 23210 +    NPC_ASHTONGUE_CHANNELER    = 23421, +    NPC_ASHTONGUE_BROKEN       = 23319, +    NPC_CREATURE_SPAWNER_AKAMA = 23210  };  enum Actions  { -    ACTION_START_SPAWNING            = 0, -    ACTION_STOP_SPAWNING             = 1, -    ACTION_DESPAWN_ALL_SPAWNS        = 2, -    ACTION_SHADE_OF_AKAMA_DEAD       = 3, -    ACTION_BROKEN_SPECIAL            = 4, -    ACTION_BROKEN_EMOTE              = 5, -    ACTION_BROKEN_HAIL               = 6 +    ACTION_START_SPAWNING      = 0, +    ACTION_STOP_SPAWNING       = 1, +    ACTION_DESPAWN_ALL_SPAWNS  = 2, +    ACTION_SHADE_OF_AKAMA_DEAD = 3, +    ACTION_BROKEN_SPECIAL      = 4, +    ACTION_BROKEN_EMOTE        = 5, +    ACTION_BROKEN_HAIL         = 6  };  enum Events @@ -139,10 +139,9 @@ enum Events  enum Misc  { -    AKAMA_CHANNEL_WAYPOINT  = 0, -    AKAMA_INTRO_WAYPOINT    = 1, - -    SUMMON_GROUP_RESET      = 1 +    AKAMA_CHANNEL_WAYPOINT = 0, +    AKAMA_INTRO_WAYPOINT   = 1, +    SUMMON_GROUP_RESET     = 1  };  Position const AkamaWP[2] = @@ -199,1073 +198,941 @@ static float const MIDDLE_OF_ROOM    = 400.0f;  static float const FACE_THE_DOOR     = 0.08726646f;  static float const FACE_THE_PLATFORM = 3.118662f; -class boss_shade_of_akama : public CreatureScript + +struct boss_shade_of_akama : public BossAI  { -public: -    boss_shade_of_akama() : CreatureScript("boss_shade_of_akama") { } +    boss_shade_of_akama(Creature* creature) : BossAI(creature, DATA_SHADE_OF_AKAMA) +    { +        Initialize(); +    } -    struct boss_shade_of_akamaAI : public BossAI +    void Initialize()      { -        boss_shade_of_akamaAI(Creature* creature) : BossAI(creature, DATA_SHADE_OF_AKAMA) -        { -            Initialize(); -        } +        _spawners.clear(); +        _isInPhaseOne = true; +    } -        void Initialize() -        { -            _spawners.clear(); -            _isInPhaseOne = true; -        } +    void Reset() override +    { +        _Reset(); +        Initialize(); +        me->SetImmuneToPC(true); +        me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); +        me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STUN); +        me->SetWalk(true); +        events.ScheduleEvent(EVENT_INITIALIZE_SPAWNERS, Seconds(1)); +        me->SummonCreatureGroup(SUMMON_GROUP_RESET); +    } + +    void EnterEvadeMode(EvadeReason /*why*/) override +    { +        events.Reset(); +        summons.DespawnAll(); + +        for (ObjectGuid const spawnerGuid : _spawners) +            if (Creature* spawner = ObjectAccessor::GetCreature(*me, spawnerGuid)) +                spawner->AI()->DoAction(ACTION_DESPAWN_ALL_SPAWNS); -        void Reset() override +        _DespawnAtEvade(); +    } + +    void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override +    { +        if (spell->Id == SPELL_AKAMA_SOUL_CHANNEL)          { -            _Reset(); -            Initialize(); -            me->SetImmuneToPC(true); -            me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); -            me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STUN); -            me->SetWalk(true); -            events.ScheduleEvent(EVENT_INITIALIZE_SPAWNERS, Seconds(1)); -            me->SummonCreatureGroup(SUMMON_GROUP_RESET); +            events.ScheduleEvent(EVENT_START_CHANNELERS_AND_SPAWNERS, Seconds(1)); +            me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); +            events.ScheduleEvent(EVENT_EVADE_CHECK, Seconds(10)); +            if (Creature* akama = instance->GetCreature(DATA_AKAMA_SHADE)) +                AttackStart(akama);          } -        void EnterEvadeMode(EvadeReason /*why*/) override +        if (spell->Id == SPELL_AKAMA_SOUL_RETRIEVE) +            DoCastSelf(SPELL_AKAMA_SOUL_EXPEL_CHANNEL); +    } + +    void MovementInform(uint32 motionType, uint32 /*pointId*/) override +    { +        if (_isInPhaseOne && motionType == CHASE_MOTION_TYPE)          { -            events.Reset(); -            summons.DespawnAll(); +            _isInPhaseOne = false; +            me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); +            me->SetImmuneToPC(false); +            me->SetWalk(false); +            events.ScheduleEvent(EVENT_ADD_THREAT, Milliseconds(100));              for (ObjectGuid const spawnerGuid : _spawners)                  if (Creature* spawner = ObjectAccessor::GetCreature(*me, spawnerGuid)) -                    spawner->AI()->DoAction(ACTION_DESPAWN_ALL_SPAWNS); - -            _DespawnAtEvade(); +                    spawner->AI()->DoAction(ACTION_STOP_SPAWNING);          } +    } -        void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override -        { -            if (spell->Id == SPELL_AKAMA_SOUL_CHANNEL) -            { -                events.ScheduleEvent(EVENT_START_CHANNELERS_AND_SPAWNERS, Seconds(1)); -                me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); -                events.ScheduleEvent(EVENT_EVADE_CHECK, Seconds(10)); -                if (Creature* akama = instance->GetCreature(DATA_AKAMA_SHADE)) -                    AttackStart(akama); -            } - -            if (spell->Id == SPELL_AKAMA_SOUL_RETRIEVE) -                DoCastSelf(SPELL_AKAMA_SOUL_EXPEL_CHANNEL); -        } +    void JustDied(Unit* /*killer*/) override +    { +        DoCastSelf(SPELL_SHADE_OF_AKAMA_TRIGGER); -        void MovementInform(uint32 motionType, uint32 /*pointId*/) override -        { -            if (_isInPhaseOne && motionType == CHASE_MOTION_TYPE) -            { -                _isInPhaseOne = false; -                me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); -                me->SetImmuneToPC(false); -                me->SetWalk(false); -                events.ScheduleEvent(EVENT_ADD_THREAT, Milliseconds(100)); - -                for (ObjectGuid const spawnerGuid : _spawners) -                    if (Creature* spawner = ObjectAccessor::GetCreature(*me, spawnerGuid)) -                        spawner->AI()->DoAction(ACTION_STOP_SPAWNING); -            } -        } +        if (Creature* akama = instance->GetCreature(DATA_AKAMA_SHADE)) +            akama->AI()->DoAction(ACTION_SHADE_OF_AKAMA_DEAD); -        void JustDied(Unit* /*killer*/) override -        { -            DoCastSelf(SPELL_SHADE_OF_AKAMA_TRIGGER); +        for (ObjectGuid const spawnerGuid : _spawners) +            if (Creature* spawner = ObjectAccessor::GetCreature(*me, spawnerGuid)) +                spawner->AI()->DoAction(ACTION_DESPAWN_ALL_SPAWNS); -            if (Creature* akama = instance->GetCreature(DATA_AKAMA_SHADE)) -                akama->AI()->DoAction(ACTION_SHADE_OF_AKAMA_DEAD); +        events.Reset(); +        summons.DespawnEntry(NPC_ASHTONGUE_CHANNELER); +        instance->SetBossState(DATA_SHADE_OF_AKAMA, DONE); +    } -            for (ObjectGuid const spawnerGuid : _spawners) -                if (Creature* spawner = ObjectAccessor::GetCreature(*me, spawnerGuid)) -                    spawner->AI()->DoAction(ACTION_DESPAWN_ALL_SPAWNS); +    void EnterEvadeModeIfNeeded() +    { +        Map::PlayerList const& players = me->GetMap()->GetPlayers(); +        for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) +            if (Player* player = i->GetSource()) +                if (player->IsAlive() && !player->IsGameMaster() && CheckBoundary(player)) +                    return; -            events.Reset(); -            summons.DespawnEntry(NPC_ASHTONGUE_CHANNELER); -            instance->SetBossState(DATA_SHADE_OF_AKAMA, DONE); -        } +        EnterEvadeMode(EVADE_REASON_NO_HOSTILES); +    } -        void EnterEvadeModeIfNeeded() -        { -            Map::PlayerList const& players = me->GetMap()->GetPlayers(); -            for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) -                if (Player* player = i->GetSource()) -                    if (player->IsAlive() && !player->IsGameMaster() && CheckBoundary(player)) -                        return; +    void UpdateAI(uint32 diff) override +    { +        events.Update(diff); -            EnterEvadeMode(EVADE_REASON_NO_HOSTILES); -        } +        if (!UpdateVictim()) +            return; -        void UpdateAI(uint32 diff) override +        while (uint32 eventId = events.ExecuteEvent())          { -            events.Update(diff); - -            if (!UpdateVictim()) -                return; - -            while (uint32 eventId = events.ExecuteEvent()) +            switch (eventId)              { -                switch (eventId) +                case EVENT_INITIALIZE_SPAWNERS:                  { -                    case EVENT_INITIALIZE_SPAWNERS: -                    { -                        std::list<Creature*> SpawnerList; -                        me->GetCreatureListWithEntryInGrid(SpawnerList, NPC_CREATURE_SPAWNER_AKAMA); -                        for (Creature* spawner : SpawnerList) -                            _spawners.push_back(spawner->GetGUID()); +                    std::list<Creature*> SpawnerList; +                    me->GetCreatureListWithEntryInGrid(SpawnerList, NPC_CREATURE_SPAWNER_AKAMA); +                    for (Creature* spawner : SpawnerList) +                        _spawners.push_back(spawner->GetGUID()); -                        break; -                    } -                    case EVENT_START_CHANNELERS_AND_SPAWNERS: -                    { -                        for (ObjectGuid const summonGuid : summons) -                            if (Creature* channeler = ObjectAccessor::GetCreature(*me, summonGuid)) -                                channeler->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); +                    break; +                } +                case EVENT_START_CHANNELERS_AND_SPAWNERS: +                { +                    for (ObjectGuid const summonGuid : summons) +                        if (Creature* channeler = ObjectAccessor::GetCreature(*me, summonGuid)) +                            channeler->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); -                        for (ObjectGuid const spawnerGuid : _spawners) -                            if (Creature* spawner = ObjectAccessor::GetCreature(*me, spawnerGuid)) -                                spawner->AI()->DoAction(ACTION_START_SPAWNING); +                    for (ObjectGuid const spawnerGuid : _spawners) +                        if (Creature* spawner = ObjectAccessor::GetCreature(*me, spawnerGuid)) +                            spawner->AI()->DoAction(ACTION_START_SPAWNING); -                        break; -                    } -                    case EVENT_ADD_THREAT: -                        DoCast(SPELL_THREAT); -                        events.Repeat(Seconds(3) + Milliseconds(500)); -                        break; -                    case EVENT_EVADE_CHECK: -                        EnterEvadeModeIfNeeded(); -                        events.Repeat(Seconds(10)); -                        break; -                    default: -                        break; +                    break;                  } +                case EVENT_ADD_THREAT: +                    DoCast(SPELL_THREAT); +                    events.Repeat(Seconds(3) + Milliseconds(500)); +                    break; +                case EVENT_EVADE_CHECK: +                    EnterEvadeModeIfNeeded(); +                    events.Repeat(Seconds(10)); +                    break; +                default: +                    break;              } - -            DoMeleeAttackIfReady();          } -    private: -        GuidVector _spawners; -        bool _isInPhaseOne; -    }; - -    CreatureAI* GetAI(Creature* creature) const override -    { -        return GetBlackTempleAI<boss_shade_of_akamaAI>(creature); +        DoMeleeAttackIfReady();      } + +private: +    GuidVector _spawners; +    bool _isInPhaseOne;  }; -class npc_akama_shade : public CreatureScript +struct npc_akama_shade : public ScriptedAI  { -public: -    npc_akama_shade() : CreatureScript("npc_akama_shade") { } - -    struct npc_akamaAI : public ScriptedAI +    npc_akama_shade(Creature* creature) : ScriptedAI(creature), _summons(me)      { -        npc_akamaAI(Creature* creature) : ScriptedAI(creature), _summons(me) -        { -            Initialize(); -            _instance = creature->GetInstanceScript(); -        } +        Initialize(); +        _instance = creature->GetInstanceScript(); +    } -        void Initialize() -        { -            _isInCombat = false; -            _hasYelledOnce = false; -            _chosen.Clear(); -            _summons.DespawnAll(); -            _events.Reset(); -        } +    void Initialize() +    { +        _isInCombat = false; +        _hasYelledOnce = false; +        _chosen.Clear(); +        _summons.DespawnAll(); +        _events.Reset(); +    } -        void Reset() override -        { -            Initialize(); -            me->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); -            DoCastSelf(SPELL_STEALTH); +    void Reset() override +    { +        Initialize(); +        me->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); +        DoCastSelf(SPELL_STEALTH); -            if (_instance->GetBossState(DATA_SHADE_OF_AKAMA) != DONE) -                me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); -        } +        if (_instance->GetBossState(DATA_SHADE_OF_AKAMA) != DONE) +            me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); +    } -        void JustSummoned(Creature* summon) override -        { -            _summons.Summon(summon); -        } +    void JustSummoned(Creature* summon) override +    { +        _summons.Summon(summon); +    } -        void EnterEvadeMode(EvadeReason /*why*/) override { } +    void EnterEvadeMode(EvadeReason /*why*/) override { } -        void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override +    void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override +    { +        if (spell->Id == SPELL_THREAT && !_isInCombat)          { -            if (spell->Id == SPELL_THREAT && !_isInCombat) +            _isInCombat = true; +            me->SetWalk(false); +            me->RemoveAurasDueToSpell(SPELL_AKAMA_SOUL_CHANNEL); +            if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA))              { -                _isInCombat = true; -                me->SetWalk(false); -                me->RemoveAurasDueToSpell(SPELL_AKAMA_SOUL_CHANNEL); -                if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA)) -                { -                    shade->RemoveAurasDueToSpell(SPELL_AKAMA_SOUL_CHANNEL); -                    AttackStart(shade); -                    _events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, Seconds(2)); -                    _events.ScheduleEvent(EVENT_DESTRUCTIVE_POISON, Seconds(5)); -                } +                shade->RemoveAurasDueToSpell(SPELL_AKAMA_SOUL_CHANNEL); +                AttackStart(shade); +                _events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, Seconds(2)); +                _events.ScheduleEvent(EVENT_DESTRUCTIVE_POISON, Seconds(5));              }          } +    } -        void DamageTaken(Unit* /*who*/, uint32& /*damage*/) override +    void DamageTaken(Unit* /*who*/, uint32& /*damage*/) override +    { +        if (me->HealthBelowPct(20) && !_hasYelledOnce)          { -            if (me->HealthBelowPct(20) && !_hasYelledOnce) -            { -                _hasYelledOnce = true; -                Talk(SAY_LOW_HEALTH); -            } +            _hasYelledOnce = true; +            Talk(SAY_LOW_HEALTH);          } +    } -        void DoAction(int32 actionId) override +    void DoAction(int32 actionId) override +    { +        if (actionId == ACTION_SHADE_OF_AKAMA_DEAD)          { -            if (actionId == ACTION_SHADE_OF_AKAMA_DEAD) -            { -                _isInCombat = false; -                me->CombatStop(true); -                me->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); -                me->SetWalk(true); -                _events.Reset(); -                me->GetMotionMaster()->MovePoint(AKAMA_INTRO_WAYPOINT, AkamaWP[1]); -            } +            _isInCombat = false; +            me->CombatStop(true); +            me->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); +            me->SetWalk(true); +            _events.Reset(); +            me->GetMotionMaster()->MovePoint(AKAMA_INTRO_WAYPOINT, AkamaWP[1]);          } +    } -        void MovementInform(uint32 motionType, uint32 pointId) override -        { -            if (motionType != POINT_MOTION_TYPE) -                return; +    void MovementInform(uint32 motionType, uint32 pointId) override +    { +        if (motionType != POINT_MOTION_TYPE) +            return; -            if (pointId == AKAMA_CHANNEL_WAYPOINT) -                _events.ScheduleEvent(EVENT_SHADE_CHANNEL, Seconds(1)); +        if (pointId == AKAMA_CHANNEL_WAYPOINT) +            _events.ScheduleEvent(EVENT_SHADE_CHANNEL, Seconds(1)); -            else if (pointId == AKAMA_INTRO_WAYPOINT) -            { -                me->SetWalk(false); -                _events.ScheduleEvent(EVENT_START_SOUL_RETRIEVE, Seconds(1)); -            } +        else if (pointId == AKAMA_INTRO_WAYPOINT) +        { +            me->SetWalk(false); +            _events.ScheduleEvent(EVENT_START_SOUL_RETRIEVE, Seconds(1));          } +    } -        void SummonBrokens() +    void SummonBrokens() +    { +        for (uint8 i = 0; i < 18; i++)          { -            for (uint8 i = 0; i < 18; i++) +            if (TempSummon* summoned = me->SummonCreature(NPC_ASHTONGUE_BROKEN, BrokenPos[i]))              { -                if (TempSummon* summoned = me->SummonCreature(NPC_ASHTONGUE_BROKEN, BrokenPos[i])) -                { -                    summoned->SetWalk(true); -                    summoned->GetMotionMaster()->MovePoint(0, BrokenWP[i]); -                    if (i == 9) //On Sniffs, npc that Yell "Special" is the tenth to be created -                        _chosen = summoned->GetGUID(); -                } +                summoned->SetWalk(true); +                summoned->GetMotionMaster()->MovePoint(0, BrokenWP[i]); +                if (i == 9) //On Sniffs, npc that Yell "Special" is the tenth to be created +                    _chosen = summoned->GetGUID();              }          } +    } -        void UpdateAI(uint32 diff) override -        { -            _events.Update(diff); - -            while (uint32 eventId = _events.ExecuteEvent()) -            { -                switch (eventId) -                { -                    case EVENT_SHADE_START: -                        _instance->SetBossState(DATA_SHADE_OF_AKAMA, IN_PROGRESS); -                        me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); -                        me->RemoveAurasDueToSpell(SPELL_STEALTH); -                        me->SetWalk(true); -                        me->GetMotionMaster()->MovePoint(AKAMA_CHANNEL_WAYPOINT, AkamaWP[0], false); -                        break; -                    case EVENT_SHADE_CHANNEL: -                        me->SetFacingTo(FACE_THE_PLATFORM); -                        DoCastSelf(SPELL_AKAMA_SOUL_CHANNEL); -                        me->SetFaction(FACTION_MONSTER_SPAR_BUDDY); -                        _events.ScheduleEvent(EVENT_FIXATE, Seconds(5)); -                        break; -                    case EVENT_FIXATE: -                        DoCast(SPELL_FIXATE); -                        break; -                    case EVENT_CHAIN_LIGHTNING: -                        DoCastVictim(SPELL_CHAIN_LIGHTNING); -                        _events.Repeat(Seconds(8), Seconds(15)); -                        break; -                    case EVENT_DESTRUCTIVE_POISON: -                        DoCastSelf(SPELL_DESTRUCTIVE_POISON); -                        _events.Repeat(Seconds(3), Seconds(7)); -                        break; -                    case EVENT_START_SOUL_RETRIEVE: -                        me->SetFacingTo(FACE_THE_DOOR); -                        DoCast(SPELL_AKAMA_SOUL_RETRIEVE); -                        _events.ScheduleEvent(EVENT_START_BROKEN_FREE, Seconds(15)); -                        break; -                    case EVENT_START_BROKEN_FREE: -                        me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); -                        Talk(SAY_BROKEN_FREE_0); -                        SummonBrokens(); -                        _events.ScheduleEvent(EVENT_BROKEN_FREE_1, Seconds(10)); -                        break; -                    case EVENT_BROKEN_FREE_1: -                        Talk(SAY_BROKEN_FREE_1); -                        _events.ScheduleEvent(EVENT_BROKEN_FREE_2, Seconds(12)); -                        break; -                    case EVENT_BROKEN_FREE_2: -                        Talk(SAY_BROKEN_FREE_2); -                        _events.ScheduleEvent(EVENT_BROKEN_FREE_3, Seconds(15)); -                        break; -                    case EVENT_BROKEN_FREE_3: -                        if (Creature* special = ObjectAccessor::GetCreature(*me, _chosen)) -                            special->AI()->Talk(SAY_BROKEN_SPECIAL); - -                        _summons.DoAction(ACTION_BROKEN_EMOTE, _pred); -                        _events.ScheduleEvent(EVENT_BROKEN_FREE_4, Seconds(5)); -                        break; -                    case EVENT_BROKEN_FREE_4: -                        _summons.DoAction(ACTION_BROKEN_HAIL, _pred); -                        break; -                    default: -                        break; -                } -            } +    void UpdateAI(uint32 diff) override +    { +        _events.Update(diff); -            if (me->GetFaction() == FACTION_MONSTER_SPAR_BUDDY) +        while (uint32 eventId = _events.ExecuteEvent()) +        { +            switch (eventId)              { -                if (!UpdateVictim()) -                    return; +                case EVENT_SHADE_START: +                    _instance->SetBossState(DATA_SHADE_OF_AKAMA, IN_PROGRESS); +                    me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); +                    me->RemoveAurasDueToSpell(SPELL_STEALTH); +                    me->SetWalk(true); +                    me->GetMotionMaster()->MovePoint(AKAMA_CHANNEL_WAYPOINT, AkamaWP[0], false); +                    break; +                case EVENT_SHADE_CHANNEL: +                    me->SetFacingTo(FACE_THE_PLATFORM); +                    DoCastSelf(SPELL_AKAMA_SOUL_CHANNEL); +                    me->SetFaction(FACTION_MONSTER_SPAR_BUDDY); +                    _events.ScheduleEvent(EVENT_FIXATE, Seconds(5)); +                    break; +                case EVENT_FIXATE: +                    DoCast(SPELL_FIXATE); +                    break; +                case EVENT_CHAIN_LIGHTNING: +                    DoCastVictim(SPELL_CHAIN_LIGHTNING); +                    _events.Repeat(Seconds(8), Seconds(15)); +                    break; +                case EVENT_DESTRUCTIVE_POISON: +                    DoCastSelf(SPELL_DESTRUCTIVE_POISON); +                    _events.Repeat(Seconds(3), Seconds(7)); +                    break; +                case EVENT_START_SOUL_RETRIEVE: +                    me->SetFacingTo(FACE_THE_DOOR); +                    DoCast(SPELL_AKAMA_SOUL_RETRIEVE); +                    _events.ScheduleEvent(EVENT_START_BROKEN_FREE, Seconds(15)); +                    break; +                case EVENT_START_BROKEN_FREE: +                    me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); +                    Talk(SAY_BROKEN_FREE_0); +                    SummonBrokens(); +                    _events.ScheduleEvent(EVENT_BROKEN_FREE_1, Seconds(10)); +                    break; +                case EVENT_BROKEN_FREE_1: +                    Talk(SAY_BROKEN_FREE_1); +                    _events.ScheduleEvent(EVENT_BROKEN_FREE_2, Seconds(12)); +                    break; +                case EVENT_BROKEN_FREE_2: +                    Talk(SAY_BROKEN_FREE_2); +                    _events.ScheduleEvent(EVENT_BROKEN_FREE_3, Seconds(15)); +                    break; +                case EVENT_BROKEN_FREE_3: +                    if (Creature* special = ObjectAccessor::GetCreature(*me, _chosen)) +                        special->AI()->Talk(SAY_BROKEN_SPECIAL); -                DoMeleeAttackIfReady(); +                    _summons.DoAction(ACTION_BROKEN_EMOTE, _pred); +                    _events.ScheduleEvent(EVENT_BROKEN_FREE_4, Seconds(5)); +                    break; +                case EVENT_BROKEN_FREE_4: +                    _summons.DoAction(ACTION_BROKEN_HAIL, _pred); +                    break; +                default: +                    break;              }          } -        void JustDied(Unit* /*killer*/) override +        if (me->GetFaction() == FACTION_MONSTER_SPAR_BUDDY)          { -            _summons.DespawnAll(); -            Talk(SAY_DEAD); -            if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA)) -                if (shade->IsAlive()) -                    shade->AI()->EnterEvadeMode(EVADE_REASON_OTHER); -        } +            if (!UpdateVictim()) +                return; -        bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override -        { -            if (gossipListId == 0) -            { -                CloseGossipMenuFor(player); -                _events.ScheduleEvent(EVENT_SHADE_START, Milliseconds(500)); -            } -            return false; +            DoMeleeAttackIfReady();          } +    } -    private: -        InstanceScript* _instance; -        EventMap _events; -        SummonList _summons; -        DummyEntryCheckPredicate _pred; -        ObjectGuid _chosen; //Creature that should yell the speech special. -        bool _isInCombat; -        bool _hasYelledOnce; -    }; +    void JustDied(Unit* /*killer*/) override +    { +        _summons.DespawnAll(); +        Talk(SAY_DEAD); +        if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA)) +            if (shade->IsAlive()) +                shade->AI()->EnterEvadeMode(EVADE_REASON_OTHER); +    } -    CreatureAI* GetAI(Creature* creature) const override +    bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override      { -        return GetBlackTempleAI<npc_akamaAI>(creature); +        if (gossipListId == 0) +        { +            CloseGossipMenuFor(player); +            _events.ScheduleEvent(EVENT_SHADE_START, Milliseconds(500)); +        } +        return false;      } + +private: +    InstanceScript* _instance; +    EventMap _events; +    SummonList _summons; +    DummyEntryCheckPredicate _pred; +    ObjectGuid _chosen; //Creature that should yell the speech special. +    bool _isInCombat; +    bool _hasYelledOnce;  }; -class npc_ashtongue_channeler : public CreatureScript +struct npc_ashtongue_channeler : public PassiveAI  { -public: -    npc_ashtongue_channeler() : CreatureScript("npc_ashtongue_channeler") { } - -    struct npc_ashtongue_channelerAI : public PassiveAI +    npc_ashtongue_channeler(Creature* creature) : PassiveAI(creature)      { -        npc_ashtongue_channelerAI(Creature* creature) : PassiveAI(creature) -        { -            _instance = creature->GetInstanceScript(); -        } +        _instance = creature->GetInstanceScript(); +    } -        void Reset() override +    void Reset() override +    { +        _scheduler.Schedule(Seconds(2), [this](TaskContext channel)          { -            _scheduler.Schedule(Seconds(2), [this](TaskContext channel) +            if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA))              { -                if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA)) -                { -                    if (shade->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) -                        DoCastSelf(SPELL_SHADE_SOUL_CHANNEL); - -                    else -                        me->DespawnOrUnsummon(Seconds(3)); -                } - -                channel.Repeat(Seconds(2)); -            }); -            me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); -        } +                if (shade->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) +                    DoCastSelf(SPELL_SHADE_SOUL_CHANNEL); -        void UpdateAI(uint32 diff) override -        { -            _scheduler.Update(diff); -        } +                else +                    me->DespawnOrUnsummon(Seconds(3)); +            } -    private: -        InstanceScript* _instance; -        TaskScheduler _scheduler; -    }; +            channel.Repeat(Seconds(2)); +        }); +        me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); +    } -    CreatureAI* GetAI(Creature* creature) const override +    void UpdateAI(uint32 diff) override      { -        return GetBlackTempleAI<npc_ashtongue_channelerAI>(creature); +        _scheduler.Update(diff);      } + +private: +    InstanceScript* _instance; +    TaskScheduler _scheduler;  }; -class npc_creature_generator_akama : public CreatureScript +struct npc_creature_generator_akama : public ScriptedAI  { -public: -    npc_creature_generator_akama() : CreatureScript("npc_creature_generator_akama") { } +    npc_creature_generator_akama(Creature* creature) : ScriptedAI(creature), _summons(me) +    { +        Initialize(); +    } -    struct npc_creature_generator_akamaAI : public ScriptedAI +    void Initialize()      { -        npc_creature_generator_akamaAI(Creature* creature) : ScriptedAI(creature), _summons(me) -        { -            Initialize(); -        } +        _leftSide = false; +        _events.Reset(); +        _summons.DespawnAll(); +    } -        void Initialize() -        { -            _leftSide = false; -            _events.Reset(); -            _summons.DespawnAll(); -        } +    void Reset() override +    { +        Initialize(); -        void Reset() override -        { -            Initialize(); +        if (me->GetPositionY() < MIDDLE_OF_ROOM) +            _leftSide = true; +    } -            if (me->GetPositionY() < MIDDLE_OF_ROOM) -                _leftSide   = true; -        } +    void JustSummoned(Creature* summon) override +    { +        _summons.Summon(summon); +    } -        void JustSummoned(Creature* summon) override +    void DoAction(int32 actionId) override +    { +        switch (actionId)          { -            _summons.Summon(summon); +            case ACTION_START_SPAWNING: +                if (_leftSide) +                { +                    _events.ScheduleEvent(EVENT_SPAWN_WAVE_B, Milliseconds(100)); +                    _events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_SORCERER, Seconds(2), Seconds(5)); +                } +                else +                { +                    _events.ScheduleEvent(EVENT_SPAWN_WAVE_B, Seconds(10)); +                    _events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_DEFENDER, Seconds(2), Seconds(5)); +                } +                break; +            case ACTION_STOP_SPAWNING: +                _events.Reset(); +                break; +            case ACTION_DESPAWN_ALL_SPAWNS: +                _events.Reset(); +                _summons.DespawnAll(); +                break; +            default: +                break;          } +    } + +    void UpdateAI(uint32 diff) override +    { +        _events.Update(diff); -        void DoAction(int32 actionId) override +        while (uint32 eventId = _events.ExecuteEvent())          { -            switch (actionId) +            switch (eventId)              { -                case ACTION_START_SPAWNING: -                    if (_leftSide) -                    { -                        _events.ScheduleEvent(EVENT_SPAWN_WAVE_B, Milliseconds(100)); -                        _events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_SORCERER, Seconds(2), Seconds(5)); -                    } -                    else -                    { -                        _events.ScheduleEvent(EVENT_SPAWN_WAVE_B, Seconds(10)); -                        _events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_DEFENDER, Seconds(2), Seconds(5)); -                    } +                case EVENT_SPAWN_WAVE_B: +                    DoCastSelf(SPELL_ASHTONGUE_WAVE_B); +                    _events.Repeat(Seconds(50), Seconds(60));                      break; -                case ACTION_STOP_SPAWNING: -                    _events.Reset(); +                case EVENT_SUMMON_ASHTONGUE_SORCERER: // left +                    DoCastSelf(SPELL_SUMMON_ASHTONGUE_SORCERER); +                    _events.Repeat(Seconds(30), Seconds(35));                      break; -                case ACTION_DESPAWN_ALL_SPAWNS: -                    _events.Reset(); -                    _summons.DespawnAll(); +                case EVENT_SUMMON_ASHTONGUE_DEFENDER: // right +                    DoCastSelf(SPELL_SUMMON_ASHTONGUE_DEFENDER); +                    _events.Repeat(Seconds(30), Seconds(40));                      break;                  default:                      break;              }          } +    } -        void UpdateAI(uint32 diff) override -        { -            _events.Update(diff); - -            while (uint32 eventId = _events.ExecuteEvent()) -            { -                switch (eventId) -                { -                    case EVENT_SPAWN_WAVE_B: -                        DoCastSelf(SPELL_ASHTONGUE_WAVE_B); -                        _events.Repeat(Seconds(50), Seconds(60)); -                        break; -                    case EVENT_SUMMON_ASHTONGUE_SORCERER: // left -                        DoCastSelf(SPELL_SUMMON_ASHTONGUE_SORCERER); -                        _events.Repeat(Seconds(30), Seconds(35)); -                        break; -                    case EVENT_SUMMON_ASHTONGUE_DEFENDER: // right -                        DoCastSelf(SPELL_SUMMON_ASHTONGUE_DEFENDER); -                        _events.Repeat(Seconds(30), Seconds(40)); -                        break; -                    default: -                        break; -                } -            } -        } - -    private: -        EventMap _events; -        SummonList _summons; -        bool _leftSide; -    }; +private: +    EventMap _events; +    SummonList _summons; +    bool _leftSide; +}; -    CreatureAI* GetAI(Creature* creature) const override +struct npc_ashtongue_sorcerer : public ScriptedAI +{ +    npc_ashtongue_sorcerer(Creature* creature) : ScriptedAI(creature)      { -        return GetBlackTempleAI<npc_creature_generator_akamaAI>(creature); +        Initialize(); +        _instance = creature->GetInstanceScript();      } -}; -class npc_ashtongue_sorcerer : public CreatureScript -{ -public: -    npc_ashtongue_sorcerer() : CreatureScript("npc_ashtongue_sorcerer") { } +    void Initialize() +    { +        _switchToCombat = false; +        _inBanish = false; +    } -    struct npc_ashtongue_sorcererAI : public ScriptedAI +    void Reset() override      { -        npc_ashtongue_sorcererAI(Creature* creature) : ScriptedAI(creature) +        if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA))          { -            Initialize(); -            _instance = creature->GetInstanceScript(); -        } +            if (shade->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) +                me->GetMotionMaster()->MovePoint(0, shade->GetPosition()); -        void Initialize() -        { -            _switchToCombat = false; -            _inBanish = false; +            else if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) +                AttackStart(akama);          } +        Initialize(); +    } -        void Reset() override -        { -            if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA)) -            { -                if (shade->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) -                    me->GetMotionMaster()->MovePoint(0, shade->GetPosition()); +    void JustDied(Unit* /*killer*/) override +    { +        me->DespawnOrUnsummon(Seconds(5)); +    } -                else if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) -                    AttackStart(akama); -            } -            Initialize(); -        } +    void EnterEvadeMode(EvadeReason /*why*/) override { } +    void EnterCombat(Unit* /*who*/) override { } -        void JustDied(Unit* /*killer*/) override -        { -            me->DespawnOrUnsummon(Seconds(5)); -        } +    void AttackStart(Unit* who) override +    { +        if (!_switchToCombat) +            return; -        void EnterEvadeMode(EvadeReason /*why*/) override { } -        void EnterCombat(Unit* /*who*/) override { } +        ScriptedAI::AttackStart(who); +    } -        void AttackStart(Unit* who) override +    void MoveInLineOfSight(Unit* who) override +    { +        if (!_inBanish && who->GetGUID() == _instance->GetGuidData(DATA_SHADE_OF_AKAMA) && me->IsWithinDist(who, 20.0f, false))          { -            if (!_switchToCombat) -                return; +            _inBanish = true; +            me->StopMoving(); +            me->GetMotionMaster()->Clear(false); +            me->GetMotionMaster()->MovePoint(1, me->GetPositionX() + frand(-8.0f, 8.0f), me->GetPositionY() + frand(-8.0f, 8.0f), me->GetPositionZ()); -            ScriptedAI::AttackStart(who); -        } - -        void MoveInLineOfSight(Unit* who) override -        { -            if (!_inBanish && who->GetGUID() == _instance->GetGuidData(DATA_SHADE_OF_AKAMA) && me->IsWithinDist(who, 20.0f, false)) +            _scheduler.Schedule(Seconds(1) + Milliseconds(500), [this](TaskContext sorcer_channel)              { -                _inBanish = true; -                me->StopMoving(); -                me->GetMotionMaster()->Clear(false); -                me->GetMotionMaster()->MovePoint(1, me->GetPositionX() + frand(-8.0f, 8.0f), me->GetPositionY() + frand(-8.0f, 8.0f), me->GetPositionZ()); - -                _scheduler.Schedule(Seconds(1) + Milliseconds(500), [this](TaskContext sorcer_channel) +                if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA))                  { -                    if (Creature* shade = _instance->GetCreature(DATA_SHADE_OF_AKAMA)) +                    if (shade->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) +                    { +                        me->SetFacingToObject(shade); +                        DoCastSelf(SPELL_SHADE_SOUL_CHANNEL); +                        sorcer_channel.Repeat(Seconds(2)); +                    } +                    else                      { -                        if (shade->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) -                        { -                            me->SetFacingToObject(shade); -                            DoCastSelf(SPELL_SHADE_SOUL_CHANNEL); -                            sorcer_channel.Repeat(Seconds(2)); -                        } -                        else -                        { -                            me->InterruptSpell(CURRENT_CHANNELED_SPELL); -                            _switchToCombat = true; -                            if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) -                                AttackStart(akama); -                        } +                        me->InterruptSpell(CURRENT_CHANNELED_SPELL); +                        _switchToCombat = true; +                        if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) +                            AttackStart(akama);                      } -                }); -            } +                } +            });          } +    } -        void UpdateAI(uint32 diff) override -        { -            _scheduler.Update(diff); +    void UpdateAI(uint32 diff) override +    { +        _scheduler.Update(diff); -            if (me->HasUnitState(UNIT_STATE_CASTING)) -                return; +        if (me->HasUnitState(UNIT_STATE_CASTING)) +            return; -            if (!UpdateVictim()) -                return; +        if (!UpdateVictim()) +            return; -            DoMeleeAttackIfReady(); -        } +        DoMeleeAttackIfReady(); +    } -    private: -        InstanceScript* _instance; -        TaskScheduler _scheduler; -        bool _switchToCombat; -        bool _inBanish; -    }; +private: +    InstanceScript* _instance; +    TaskScheduler _scheduler; +    bool _switchToCombat; +    bool _inBanish; +}; -    CreatureAI* GetAI(Creature* creature) const override +struct npc_ashtongue_defender : public ScriptedAI +{ +    npc_ashtongue_defender(Creature* creature) : ScriptedAI(creature)      { -        return GetBlackTempleAI<npc_ashtongue_sorcererAI>(creature); +        _instance = creature->GetInstanceScript();      } -}; -class npc_ashtongue_defender : public CreatureScript -{ -public: -    npc_ashtongue_defender() : CreatureScript("npc_ashtongue_defender") { } +    void Reset() override +    { +        if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) +            AttackStart(akama); +    } -    struct npc_ashtongue_defenderAI : public ScriptedAI +    void JustDied(Unit* /*killer*/) override      { -        npc_ashtongue_defenderAI(Creature* creature) : ScriptedAI(creature) -        { -            _instance = creature->GetInstanceScript(); -        } +        me->DespawnOrUnsummon(Seconds(5)); +    } -        void Reset() override -        { -            if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) -                AttackStart(akama); -        } +    void EnterCombat(Unit* /*who*/) override +    { +        _events.ScheduleEvent(EVENT_HEROIC_STRIKE, Seconds(5)); +        _events.ScheduleEvent(EVENT_SHIELD_BASH, Seconds(10), Seconds(16)); +        _events.ScheduleEvent(EVENT_DEBILITATING_STRIKE, Seconds(10), Seconds(16)); +        _events.ScheduleEvent(EVENT_WINDFURY, Seconds(8), Seconds(12)); +    } -        void JustDied(Unit* /*killer*/) override -        { -            me->DespawnOrUnsummon(Seconds(5)); -        } -        void EnterCombat(Unit* /*who*/) override -        { -            _events.ScheduleEvent(EVENT_HEROIC_STRIKE, Seconds(5)); -            _events.ScheduleEvent(EVENT_SHIELD_BASH, Seconds(10), Seconds(16)); -            _events.ScheduleEvent(EVENT_DEBILITATING_STRIKE, Seconds(10), Seconds(16)); -            _events.ScheduleEvent(EVENT_WINDFURY, Seconds(8), Seconds(12)); -        } +    void UpdateAI(uint32 diff) override +    { +        if (!UpdateVictim()) +            return; +        _events.Update(diff); -        void UpdateAI(uint32 diff) override +        while (uint32 eventId = _events.ExecuteEvent())          { -            if (!UpdateVictim()) -                return; - -            _events.Update(diff); - -            while (uint32 eventId = _events.ExecuteEvent()) +            switch (eventId)              { -                switch (eventId) -                { -                    case EVENT_DEBILITATING_STRIKE: -                        DoCastVictim(SPELL_DEBILITATING_STRIKE); -                        _events.Repeat(Seconds(20), Seconds(25)); -                        break; -                    case EVENT_HEROIC_STRIKE: -                        DoCastSelf(SPELL_HEROIC_STRIKE); -                        _events.Repeat(Seconds(5), Seconds(15)); -                        break; -                    case EVENT_SHIELD_BASH: -                        DoCastVictim(SPELL_SHIELD_BASH); -                        _events.Repeat(Seconds(10), Seconds(20)); -                        break; -                    case EVENT_WINDFURY: -                        DoCastVictim(SPELL_WINDFURY); -                        _events.Repeat(Seconds(6), Seconds(8)); -                        break; -                    default: -                        break; -                } +                case EVENT_DEBILITATING_STRIKE: +                    DoCastVictim(SPELL_DEBILITATING_STRIKE); +                    _events.Repeat(Seconds(20), Seconds(25)); +                    break; +                case EVENT_HEROIC_STRIKE: +                    DoCastSelf(SPELL_HEROIC_STRIKE); +                    _events.Repeat(Seconds(5), Seconds(15)); +                    break; +                case EVENT_SHIELD_BASH: +                    DoCastVictim(SPELL_SHIELD_BASH); +                    _events.Repeat(Seconds(10), Seconds(20)); +                    break; +                case EVENT_WINDFURY: +                    DoCastVictim(SPELL_WINDFURY); +                    _events.Repeat(Seconds(6), Seconds(8)); +                    break; +                default: +                    break;              } - -            DoMeleeAttackIfReady();          } -    private: -        InstanceScript* _instance; -        EventMap _events; -    }; - -    CreatureAI* GetAI(Creature* creature) const override -    { -        return GetBlackTempleAI<npc_ashtongue_defenderAI>(creature); +        DoMeleeAttackIfReady();      } + +private: +    InstanceScript* _instance; +    EventMap _events;  }; -class npc_ashtongue_rogue : public CreatureScript +struct npc_ashtongue_rogue : public ScriptedAI  { -public: -    npc_ashtongue_rogue() : CreatureScript("npc_ashtongue_rogue") { } - -    struct npc_ashtongue_rogueAI : public ScriptedAI +    npc_ashtongue_rogue(Creature* creature) : ScriptedAI(creature)      { -        npc_ashtongue_rogueAI(Creature* creature) : ScriptedAI(creature) -        { -            _instance = creature->GetInstanceScript(); -        } +        _instance = creature->GetInstanceScript(); +    } -        void Reset() override -        { -            if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) -                AttackStart(akama); -        } +    void Reset() override +    { +        if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) +            AttackStart(akama); +    } -        void JustDied(Unit* /*killer*/) override -        { -            me->DespawnOrUnsummon(Seconds(5)); -        } +    void JustDied(Unit* /*killer*/) override +    { +        me->DespawnOrUnsummon(Seconds(5)); +    } -        void EnterCombat(Unit* /*who*/) override -        { -            _events.ScheduleEvent(EVENT_DEBILITATING_POISON, Milliseconds(500), Seconds(2)); -            _events.ScheduleEvent(EVENT_EVISCERATE, Seconds(2), Seconds(5)); -        } +    void EnterCombat(Unit* /*who*/) override +    { +        _events.ScheduleEvent(EVENT_DEBILITATING_POISON, Milliseconds(500), Seconds(2)); +        _events.ScheduleEvent(EVENT_EVISCERATE, Seconds(2), Seconds(5)); +    } -        void EnterEvadeMode(EvadeReason /*why*/) override { } +    void EnterEvadeMode(EvadeReason /*why*/) override { } -        void UpdateAI(uint32 diff) override -        { -            if (!UpdateVictim()) -                return; +    void UpdateAI(uint32 diff) override +    { +        if (!UpdateVictim()) +            return; -            _events.Update(diff); +        _events.Update(diff); -            while (uint32 eventId = _events.ExecuteEvent()) +        while (uint32 eventId = _events.ExecuteEvent()) +        { +            switch (eventId)              { -                switch (eventId) -                { -                    case EVENT_DEBILITATING_POISON: -                        DoCastVictim(SPELL_DEBILITATING_POISON); -                        _events.Repeat(Seconds(15), Seconds(20)); -                        break; -                    case EVENT_EVISCERATE: -                        DoCastVictim(SPELL_EVISCERATE); -                        _events.Repeat(Seconds(12), Seconds(20)); -                        break; -                    default: -                        break; -                } +                case EVENT_DEBILITATING_POISON: +                    DoCastVictim(SPELL_DEBILITATING_POISON); +                    _events.Repeat(Seconds(15), Seconds(20)); +                    break; +                case EVENT_EVISCERATE: +                    DoCastVictim(SPELL_EVISCERATE); +                    _events.Repeat(Seconds(12), Seconds(20)); +                    break; +                default: +                    break;              } - -            DoMeleeAttackIfReady();          } -    private: -        InstanceScript* _instance; -        EventMap _events; -    }; - -    CreatureAI* GetAI(Creature* creature) const override -    { -        return GetBlackTempleAI<npc_ashtongue_rogueAI>(creature); +        DoMeleeAttackIfReady();      } + +private: +    InstanceScript* _instance; +    EventMap _events;  }; -class npc_ashtongue_elementalist : public CreatureScript +struct npc_ashtongue_elementalist : public ScriptedAI  { -public: -    npc_ashtongue_elementalist() : CreatureScript("npc_ashtongue_elementalist") { } - -    struct npc_ashtongue_elementalistAI : public ScriptedAI +    npc_ashtongue_elementalist(Creature* creature) : ScriptedAI(creature)      { -        npc_ashtongue_elementalistAI(Creature* creature) : ScriptedAI(creature) -        { -            _instance = creature->GetInstanceScript(); -        } +        _instance = creature->GetInstanceScript(); +    } -        void Reset() override -        { -            if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) -                AttackStart(akama); -        } +    void Reset() override +    { +        if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) +            AttackStart(akama); +    } -        void JustDied(Unit* /*killer*/) override -        { -            me->DespawnOrUnsummon(Seconds(5)); -        } +    void JustDied(Unit* /*killer*/) override +    { +        me->DespawnOrUnsummon(Seconds(5)); +    } -        void EnterCombat(Unit* /*who*/) override -        { -            _events.ScheduleEvent(EVENT_RAIN_OF_FIRE, Seconds(18)); -            _events.ScheduleEvent(EVENT_LIGHTNING_BOLT, Seconds(6)); -        } +    void EnterCombat(Unit* /*who*/) override +    { +        _events.ScheduleEvent(EVENT_RAIN_OF_FIRE, Seconds(18)); +        _events.ScheduleEvent(EVENT_LIGHTNING_BOLT, Seconds(6)); +    } -        void EnterEvadeMode(EvadeReason /*why*/) override { } +    void EnterEvadeMode(EvadeReason /*why*/) override { } -        void UpdateAI(uint32 diff) override -        { -            if (!UpdateVictim()) -                return; +    void UpdateAI(uint32 diff) override +    { +        if (!UpdateVictim()) +            return; -            _events.Update(diff); +        _events.Update(diff); -            while (uint32 eventId = _events.ExecuteEvent()) +        while (uint32 eventId = _events.ExecuteEvent()) +        { +            switch (eventId)              { -                switch (eventId) -                { -                    case EVENT_RAIN_OF_FIRE: -                        DoCastVictim(SPELL_RAIN_OF_FIRE); -                        _events.Repeat(Seconds(15), Seconds(20)); -                        break; -                    case EVENT_LIGHTNING_BOLT: -                        DoCastVictim(SPELL_LIGHTNING_BOLT); -                        _events.Repeat(Seconds(8), Seconds(15)); -                        break; -                    default: -                        break; -                } +                case EVENT_RAIN_OF_FIRE: +                    DoCastVictim(SPELL_RAIN_OF_FIRE); +                    _events.Repeat(Seconds(15), Seconds(20)); +                    break; +                case EVENT_LIGHTNING_BOLT: +                    DoCastVictim(SPELL_LIGHTNING_BOLT); +                    _events.Repeat(Seconds(8), Seconds(15)); +                    break; +                default: +                    break;              } - -            DoMeleeAttackIfReady();          } -    private: -        InstanceScript* _instance; -        EventMap _events; -    }; - -    CreatureAI* GetAI(Creature* creature) const override -    { -        return GetBlackTempleAI<npc_ashtongue_elementalistAI>(creature); +        DoMeleeAttackIfReady();      } + +private: +    InstanceScript* _instance; +    EventMap _events;  }; -class npc_ashtongue_spiritbinder : public CreatureScript +struct npc_ashtongue_spiritbinder : public ScriptedAI  { -public: -    npc_ashtongue_spiritbinder() : CreatureScript("npc_ashtongue_spiritbinder") { } - -    struct npc_ashtongue_spiritbinderAI : public ScriptedAI +    npc_ashtongue_spiritbinder(Creature* creature) : ScriptedAI(creature)      { -        npc_ashtongue_spiritbinderAI(Creature* creature) : ScriptedAI(creature) -        { -            Initialize(); -            _instance = creature->GetInstanceScript(); -        } - -        void Initialize() -        { -            _spiritMend = false; -            _chainHeal = false; -        } - -        void Reset() override -        { -            Initialize(); - -            if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) -                AttackStart(akama); -        } - -        void JustDied(Unit* /*killer*/) override -        { -            me->DespawnOrUnsummon(Seconds(5)); -        } - -        void EnterCombat(Unit* /*who*/) override -        { -            _events.ScheduleEvent(EVENT_SPIRIT_HEAL, Seconds(5), Seconds(6)); -        } +        Initialize(); +        _instance = creature->GetInstanceScript(); +    } -        void DamageTaken(Unit* /*who*/, uint32& /*damage*/) override -        { -            if (!_spiritMend) -                if (HealthBelowPct(30)) -                { -                    DoCastSelf(SPELL_SPIRIT_MEND); -                    _spiritMend = true; -                    _events.ScheduleEvent(EVENT_SPIRIT_MEND_RESET, Seconds(10),Seconds(15)); -                } +    void Initialize() +    { +        _spiritMend = false; +        _chainHeal = false; +    } -            if (!_chainHeal) -                if (HealthBelowPct(50)) -                { -                    DoCastSelf(SPELL_CHAIN_HEAL); -                    _chainHeal = true; -                    _events.ScheduleEvent(EVENT_CHAIN_HEAL_RESET, Seconds(10), Seconds(15)); -                } +    void Reset() override +    { +        Initialize(); -        } +        if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) +            AttackStart(akama); +    } -        void EnterEvadeMode(EvadeReason /*why*/) override { } +    void JustDied(Unit* /*killer*/) override +    { +        me->DespawnOrUnsummon(Seconds(5)); +    } -        void UpdateAI(uint32 diff) override -        { -            _events.Update(diff); +    void EnterCombat(Unit* /*who*/) override +    { +        _events.ScheduleEvent(EVENT_SPIRIT_HEAL, Seconds(5), Seconds(6)); +    } -            while (uint32 eventId = _events.ExecuteEvent()) +    void DamageTaken(Unit* /*who*/, uint32& /*damage*/) override +    { +        if (!_spiritMend) +            if (HealthBelowPct(30))              { -                switch (eventId) -                { -                    case EVENT_SPIRIT_HEAL: -                        DoCastSelf(SPELL_SPIRITBINDER_SPIRIT_HEAL); -                        _events.Repeat(Seconds(13), Seconds(16)); -                        break; -                    case EVENT_SPIRIT_MEND_RESET: -                        _spiritMend = false; -                        break; -                    case EVENT_CHAIN_HEAL_RESET: -                        _chainHeal = false; -                        break; -                    default: -                        break; -                } +                DoCastSelf(SPELL_SPIRIT_MEND); +                _spiritMend = true; +                _events.ScheduleEvent(EVENT_SPIRIT_MEND_RESET, Seconds(10), Seconds(15));              } -            if (!UpdateVictim()) -                return; - -            DoMeleeAttackIfReady(); -        } - -    private: -        InstanceScript* _instance; -        EventMap _events; -        bool _spiritMend; -        bool _chainHeal; -    }; +        if (!_chainHeal) +            if (HealthBelowPct(50)) +            { +                DoCastSelf(SPELL_CHAIN_HEAL); +                _chainHeal = true; +                _events.ScheduleEvent(EVENT_CHAIN_HEAL_RESET, Seconds(10), Seconds(15)); +            } -    CreatureAI* GetAI(Creature* creature) const override -    { -        return GetBlackTempleAI<npc_ashtongue_spiritbinderAI>(creature);      } -}; -class npc_ashtongue_broken : public CreatureScript -{ -public: -    npc_ashtongue_broken() : CreatureScript("npc_ashtongue_broken") { } +    void EnterEvadeMode(EvadeReason /*why*/) override { } -    struct npc_ashtongue_brokenAI : public ScriptedAI +    void UpdateAI(uint32 diff) override      { -        npc_ashtongue_brokenAI(Creature* creature) : ScriptedAI(creature) -        { -            _instance = me->GetInstanceScript(); -        } - -        void MovementInform(uint32 motionType, uint32 /*pointId*/) override -        { -            if (motionType != POINT_MOTION_TYPE) -                return; - -            if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) -                me->SetFacingToObject(akama); -        } +        _events.Update(diff); -        void DoAction(int32 actionId) override +        while (uint32 eventId = _events.ExecuteEvent())          { -            switch (actionId) +            switch (eventId)              { -                case ACTION_BROKEN_SPECIAL: -                    Talk(SAY_BROKEN_SPECIAL); +                case EVENT_SPIRIT_HEAL: +                    DoCastSelf(SPELL_SPIRITBINDER_SPIRIT_HEAL); +                    _events.Repeat(Seconds(13), Seconds(16));                      break; -                case ACTION_BROKEN_HAIL: -                    me->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); -                    Talk(SAY_BROKEN_HAIL); +                case EVENT_SPIRIT_MEND_RESET: +                    _spiritMend = false;                      break; -                case ACTION_BROKEN_EMOTE: -                    me->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_KNEEL); +                case EVENT_CHAIN_HEAL_RESET: +                    _chainHeal = false;                      break;                  default:                      break;              }          } -    private: -        InstanceScript* _instance; -    }; - +        if (!UpdateVictim()) +            return; -    CreatureAI* GetAI(Creature* creature) const override -    { -        return GetBlackTempleAI<npc_ashtongue_brokenAI>(creature); +        DoMeleeAttackIfReady();      } + +private: +    InstanceScript* _instance; +    EventMap _events; +    bool _spiritMend; +    bool _chainHeal;  }; -// 40401 - Shade Soul Channel (serverside spell) -class spell_shade_soul_channel_serverside : public SpellScriptLoader +struct npc_ashtongue_broken : public ScriptedAI  { -public: -    spell_shade_soul_channel_serverside() : SpellScriptLoader("spell_shade_soul_channel_serverside") { } +    npc_ashtongue_broken(Creature* creature) : ScriptedAI(creature) +    { +        _instance = me->GetInstanceScript(); +    } -    class spell_shade_soul_channel_serverside_AuraScript : public AuraScript +    void MovementInform(uint32 motionType, uint32 /*pointId*/) override      { -        PrepareAuraScript(spell_shade_soul_channel_serverside_AuraScript); +        if (motionType != POINT_MOTION_TYPE) +            return; -        bool Validate(SpellInfo const* /*spell*/) override -        { -            return ValidateSpellInfo({ SPELL_SHADE_SOUL_CHANNEL_2 }); -        } +        if (Creature* akama = _instance->GetCreature(DATA_AKAMA_SHADE)) +            me->SetFacingToObject(akama); +    } -        void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +    void DoAction(int32 actionId) override +    { +        switch (actionId)          { -            GetTarget()->RemoveAuraFromStack(SPELL_SHADE_SOUL_CHANNEL_2); +            case ACTION_BROKEN_SPECIAL: +                Talk(SAY_BROKEN_SPECIAL); +                break; +            case ACTION_BROKEN_HAIL: +                me->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); +                Talk(SAY_BROKEN_HAIL); +                break; +            case ACTION_BROKEN_EMOTE: +                me->SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, UNIT_STAND_STATE_KNEEL); +                break; +            default: +                break;          } +    } -        void Register() override -        { -            AfterEffectRemove += AuraEffectRemoveFn(spell_shade_soul_channel_serverside_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); -        } -    }; +private: +    InstanceScript* _instance; +}; + +// 40401 - Shade Soul Channel (serverside spell) +class spell_shade_soul_channel_serverside : public AuraScript +{ +    PrepareAuraScript(spell_shade_soul_channel_serverside); -    AuraScript* GetAuraScript() const override +    bool Validate(SpellInfo const* /*spell*/) override      { -        return new spell_shade_soul_channel_serverside_AuraScript(); +        return ValidateSpellInfo({ SPELL_SHADE_SOUL_CHANNEL_2 }); +    } + +    void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +    { +        GetTarget()->RemoveAuraFromStack(SPELL_SHADE_SOUL_CHANNEL_2); +    } + +    void Register() override +    { +        AfterEffectRemove += AuraEffectRemoveFn(spell_shade_soul_channel_serverside::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);      }  };  // 40520 - Shade Soul Channel -class spell_shade_soul_channel : public SpellScriptLoader +class spell_shade_soul_channel : public AuraScript  { -public: -    spell_shade_soul_channel() : SpellScriptLoader("spell_shade_soul_channel") { } +    PrepareAuraScript(spell_shade_soul_channel); -    class spell_shade_soul_channel_AuraScript : public AuraScript +    void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)      { -        PrepareAuraScript(spell_shade_soul_channel_AuraScript); - -        void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) -        { -            int32 const maxSlowEff = -99; -            if (aurEff->GetAmount() < maxSlowEff) -                if (AuraEffect* slowEff = GetEffect(EFFECT_0)) -                    slowEff->ChangeAmount(maxSlowEff); -        } - -        void Register() override -        { -            AfterEffectApply += AuraEffectApplyFn(spell_shade_soul_channel_AuraScript::OnApply, EFFECT_0, SPELL_AURA_MOD_DECREASE_SPEED, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); -        } -    }; +        int32 const maxSlowEff = -99; +        if (aurEff->GetAmount() < maxSlowEff) +            if (AuraEffect* slowEff = GetEffect(EFFECT_0)) +                slowEff->ChangeAmount(maxSlowEff); +    } -    AuraScript* GetAuraScript() const override +    void Register() override      { -        return new spell_shade_soul_channel_AuraScript(); +        AfterEffectApply += AuraEffectApplyFn(spell_shade_soul_channel::OnApply, EFFECT_0, SPELL_AURA_MOD_DECREASE_SPEED, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);      }  };  void AddSC_boss_shade_of_akama()  { -    new boss_shade_of_akama(); -    new npc_akama_shade(); -    new npc_ashtongue_channeler(); -    new npc_creature_generator_akama(); -    new npc_ashtongue_sorcerer(); -    new npc_ashtongue_defender(); -    new npc_ashtongue_rogue(); -    new npc_ashtongue_elementalist(); -    new npc_ashtongue_spiritbinder(); -    new npc_ashtongue_broken(); -    new spell_shade_soul_channel_serverside(); -    new spell_shade_soul_channel(); +    RegisterBlackTempleCreatureAI(boss_shade_of_akama); +    RegisterBlackTempleCreatureAI(npc_akama_shade); +    RegisterBlackTempleCreatureAI(npc_ashtongue_channeler); +    RegisterBlackTempleCreatureAI(npc_creature_generator_akama); +    RegisterBlackTempleCreatureAI(npc_ashtongue_sorcerer); +    RegisterBlackTempleCreatureAI(npc_ashtongue_defender); +    RegisterBlackTempleCreatureAI(npc_ashtongue_rogue); +    RegisterBlackTempleCreatureAI(npc_ashtongue_elementalist); +    RegisterBlackTempleCreatureAI(npc_ashtongue_spiritbinder); +    RegisterBlackTempleCreatureAI(npc_ashtongue_broken); +    RegisterAuraScript(spell_shade_soul_channel_serverside); +    RegisterAuraScript(spell_shade_soul_channel);  } diff --git a/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp b/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp index c84a3504f61..ca7bc790aa1 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp @@ -63,200 +63,165 @@ enum Actions  {      ACTION_DISABLE_VULCANO = 1  }; - -class boss_supremus : public CreatureScript +struct boss_supremus : public BossAI  { -public: -    boss_supremus() : CreatureScript("boss_supremus") { } +    boss_supremus(Creature* creature) : BossAI(creature, DATA_SUPREMUS) { } -    struct boss_supremusAI : public BossAI +    void Reset() override      { -        boss_supremusAI(Creature* creature) : BossAI(creature, DATA_SUPREMUS) { } +        _Reset(); +        events.SetPhase(PHASE_INITIAL); +        me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); +        me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false); +    } -        void Reset() override +    void EnterEvadeMode(EvadeReason /*why*/) override +    { +        summons.DespawnAll(); +        _DespawnAtEvade(); +    } + +    void EnterCombat(Unit* /*who*/) override +    { +        _EnterCombat(); +        ChangePhase(); +        events.ScheduleEvent(EVENT_BERSERK, Minutes(15)); +        events.ScheduleEvent(EVENT_FLAME, Seconds(20)); +    } + +    void ChangePhase() +    { +        if (events.IsInPhase(PHASE_INITIAL) || events.IsInPhase(PHASE_CHASE))          { -            _Reset(); -            events.SetPhase(PHASE_INITIAL); +            events.SetPhase(PHASE_STRIKE); +            DummyEntryCheckPredicate pred; +            summons.DoAction(ACTION_DISABLE_VULCANO, pred); +            events.ScheduleEvent(EVENT_HATEFUL_STRIKE, Seconds(2), 0, PHASE_STRIKE); +            me->RemoveAurasDueToSpell(SPELL_SNARE_SELF);              me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);              me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false);          } - -        void EnterEvadeMode(EvadeReason /*why*/) override -        { -            summons.DespawnAll(); -            _DespawnAtEvade(); -        } - -        void EnterCombat(Unit* /*who*/) override +        else          { -            _EnterCombat(); -            ChangePhase(); -            events.ScheduleEvent(EVENT_BERSERK, Minutes(15)); -            events.ScheduleEvent(EVENT_FLAME, Seconds(20)); +            events.SetPhase(PHASE_CHASE); +            events.ScheduleEvent(EVENT_VOLCANO, Seconds(5), 0, PHASE_CHASE); +            events.ScheduleEvent(EVENT_SWITCH_TARGET, Seconds(10), 0, PHASE_CHASE); +            me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); +            me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); +            DoCast(SPELL_SNARE_SELF);          } +        ResetThreatList(); +        DoZoneInCombat(); +        events.ScheduleEvent(EVENT_SWITCH_PHASE, Seconds(60)); +    } -        void ChangePhase() -        { -            if (events.IsInPhase(PHASE_INITIAL) || events.IsInPhase(PHASE_CHASE)) -            { -                events.SetPhase(PHASE_STRIKE); -                DummyEntryCheckPredicate pred; -                summons.DoAction(ACTION_DISABLE_VULCANO, pred); -                events.ScheduleEvent(EVENT_HATEFUL_STRIKE, Seconds(2), 0, PHASE_STRIKE); -                me->RemoveAurasDueToSpell(SPELL_SNARE_SELF); -                me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); -                me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false); -            } -            else -            { -                events.SetPhase(PHASE_CHASE); -                events.ScheduleEvent(EVENT_VOLCANO, Seconds(5), 0, PHASE_CHASE); -                events.ScheduleEvent(EVENT_SWITCH_TARGET, Seconds(10), 0, PHASE_CHASE); -                me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); -                me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); -                DoCast(SPELL_SNARE_SELF); -            } -            ResetThreatList(); -            DoZoneInCombat(); -            events.ScheduleEvent(EVENT_SWITCH_PHASE, Seconds(60)); -        } +    Unit* CalculateHatefulStrikeTarget() +    { +        uint32 health = 0; +        Unit* target = nullptr; -        Unit* CalculateHatefulStrikeTarget() +        for (auto* ref : me->GetThreatManager().GetUnsortedThreatList())          { -            uint32 health = 0; -            Unit* target = nullptr; - -            for (auto* ref : me->GetThreatManager().GetUnsortedThreatList()) +            Unit* unit = ref->GetVictim(); +            if (me->IsWithinMeleeRange(unit))              { -                Unit* unit = ref->GetVictim(); -                if (me->IsWithinMeleeRange(unit)) +                if (unit->GetHealth() > health)                  { -                    if (unit->GetHealth() > health) -                    { -                        health = unit->GetHealth(); -                        target = unit; -                    } +                    health = unit->GetHealth(); +                    target = unit;                  }              } - -            return target;          } -        void ExecuteEvent(uint32 eventId) override -        { -            switch (eventId) -            { -                case EVENT_BERSERK: -                    DoCastSelf(SPELL_BERSERK, true); -                    break; -                case EVENT_FLAME: -                    DoCast(SPELL_MOLTEN_PUNCH); -                    events.Repeat(Seconds(15), Seconds(20)); -                    break; -                case EVENT_HATEFUL_STRIKE: -                    if (Unit* target = CalculateHatefulStrikeTarget()) -                        DoCast(target, SPELL_HATEFUL_STRIKE); -                    events.Repeat(Seconds(5)); -                    break; -                case EVENT_SWITCH_TARGET: -                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true)) -                    { -                        ResetThreatList(); -                        AddThreat(target, 1000000.0f); -                        DoCast(target, SPELL_CHARGE); -                        Talk(EMOTE_NEW_TARGET); -                    } -                    events.Repeat(Seconds(10)); -                    break; -                case EVENT_VOLCANO: -                    DoCastAOE(SPELL_VOLCANIC_SUMMON, true); -                    Talk(EMOTE_GROUND_CRACK); -                    events.Repeat(Seconds(10)); -                    break; -                case EVENT_SWITCH_PHASE: -                    ChangePhase(); -                    break; -                default: -                    break; -            } -        } - -    }; +        return target; +    } -    CreatureAI* GetAI(Creature* creature) const override +    void ExecuteEvent(uint32 eventId) override      { -        return GetBlackTempleAI<boss_supremusAI>(creature); +        switch (eventId) +        { +            case EVENT_BERSERK: +                DoCastSelf(SPELL_BERSERK, true); +                break; +            case EVENT_FLAME: +                DoCast(SPELL_MOLTEN_PUNCH); +                events.Repeat(Seconds(15), Seconds(20)); +                break; +            case EVENT_HATEFUL_STRIKE: +                if (Unit* target = CalculateHatefulStrikeTarget()) +                    DoCast(target, SPELL_HATEFUL_STRIKE); +                events.Repeat(Seconds(5)); +                break; +            case EVENT_SWITCH_TARGET: +                if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true)) +                { +                    ResetThreatList(); +                    AddThreat(target, 1000000.0f); +                    DoCast(target, SPELL_CHARGE); +                    Talk(EMOTE_NEW_TARGET); +                } +                events.Repeat(Seconds(10)); +                break; +            case EVENT_VOLCANO: +                DoCastAOE(SPELL_VOLCANIC_SUMMON, true); +                Talk(EMOTE_GROUND_CRACK); +                events.Repeat(Seconds(10)); +                break; +            case EVENT_SWITCH_PHASE: +                ChangePhase(); +                break; +            default: +                break; +        }      }  }; -class npc_molten_flame : public CreatureScript +struct npc_molten_flame : public NullCreatureAI  { -public: -    npc_molten_flame() : CreatureScript("npc_molten_flame") { } +    npc_molten_flame(Creature* creature) : NullCreatureAI(creature) { } -    struct npc_molten_flameAI : public NullCreatureAI +    void InitializeAI() override      { -        npc_molten_flameAI(Creature* creature) : NullCreatureAI(creature) { } - -        void InitializeAI() override -        { -            float x, y, z; -            me->GetNearPoint(me, x, y, z, 1, 100.0f, frand(0.f, 2.f * float(M_PI))); -            me->GetMotionMaster()->MovePoint(0, x, y, z); -            DoCastSelf(SPELL_MOLTEN_FLAME, true); -        } -    }; - -    CreatureAI* GetAI(Creature* creature) const override -    { -        return GetBlackTempleAI<npc_molten_flameAI>(creature); +        float x, y, z; +        me->GetNearPoint(me, x, y, z, 1, 100.0f, frand(0.f, 2.f * float(M_PI))); +        me->GetMotionMaster()->MovePoint(0, x, y, z); +        DoCastSelf(SPELL_MOLTEN_FLAME, true);      }  }; -class npc_volcano : public CreatureScript +struct npc_volcano : public NullCreatureAI  { -public: -    npc_volcano() : CreatureScript("npc_volcano") { } +    npc_volcano(Creature* creature) : NullCreatureAI(creature) { } -    struct npc_volcanoAI : public NullCreatureAI +    void Reset() override      { -        npc_volcanoAI(Creature* creature) : NullCreatureAI(creature) { } - -        void Reset() override +        _scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/)          { -            _scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/) -            { -                DoCastSelf(SPELL_VOLCANIC_ERUPTION); -            }); -        } - -        void DoAction(int32 action) override -        { -            if (action == ACTION_DISABLE_VULCANO) -            { -                me->RemoveAurasDueToSpell(SPELL_VOLCANIC_ERUPTION); -                me->RemoveAurasDueToSpell(SPELL_VOLCANIC_GEYSER); -            } -        } +            DoCastSelf(SPELL_VOLCANIC_ERUPTION); +        }); +    } -        void UpdateAI(uint32 diff) override +    void DoAction(int32 action) override +    { +        if (action == ACTION_DISABLE_VULCANO)          { -            _scheduler.Update(diff); +            me->RemoveAurasDueToSpell(SPELL_VOLCANIC_ERUPTION); +            me->RemoveAurasDueToSpell(SPELL_VOLCANIC_GEYSER);          } +    } -    private: -        TaskScheduler _scheduler; -    }; - -    CreatureAI* GetAI(Creature* creature) const override +    void UpdateAI(uint32 diff) override      { -        return GetBlackTempleAI<npc_volcanoAI>(creature); +        _scheduler.Update(diff);      } + +private: +    TaskScheduler _scheduler;  };  void AddSC_boss_supremus()  { -    new boss_supremus(); -    new npc_molten_flame(); -    new npc_volcano(); +    RegisterBlackTempleCreatureAI(boss_supremus); +    RegisterBlackTempleCreatureAI(npc_molten_flame); +    RegisterBlackTempleCreatureAI(npc_volcano);  } diff --git a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp index 727f14ed239..496212ed692 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp @@ -69,14 +69,13 @@ enum Spells      SPELL_SPIRIT_VOLLEY              = 40314,      SPELL_SPIRIT_SHIELD              = 40322,      SPELL_SPIRIT_LANCE               = 40157 -  };  enum Npcs  { -    NPC_DOOM_BLOSSOM                 = 23123, -    NPC_SHADOWY_CONSTRUCT            = 23111, -    NPC_VENGEFUL_SPIRIT              = 23109 //Npc controlled by player +    NPC_DOOM_BLOSSOM      = 23123, +    NPC_SHADOWY_CONSTRUCT = 23111, +    NPC_VENGEFUL_SPIRIT   = 23109 //Npc controlled by player  };  enum Events @@ -108,414 +107,348 @@ uint32 const SkeletronSpells[4] =      SPELL_SUMMON_SKELETRON_4  }; -class boss_teron_gorefiend : public CreatureScript +struct boss_teron_gorefiend : public BossAI  { -public: -    boss_teron_gorefiend() : CreatureScript("boss_teron_gorefiend") { } +    boss_teron_gorefiend(Creature* creature) : BossAI(creature, DATA_TERON_GOREFIEND) { } -    struct boss_teron_gorefiendAI : public BossAI +    void Reset() override      { -        boss_teron_gorefiendAI(Creature* creature) : BossAI(creature, DATA_TERON_GOREFIEND) { } - -        void Reset() override +        _Reset(); +        if (instance->GetData(DATA_TERON_GOREFIEND_INTRO))          { -            _Reset(); -            if (instance->GetData(DATA_TERON_GOREFIEND_INTRO)) -            { -                me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); -                me->SetReactState(REACT_PASSIVE); -            } +            me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); +            me->SetReactState(REACT_PASSIVE);          } +    } -        void EnterCombat(Unit* /*who*/) override -        { -            _EnterCombat(); -            Talk(SAY_AGGRO); -            events.SetPhase(PHASE_COMBAT); -            events.ScheduleEvent(EVENT_ENRAGE, Minutes(10)); -            events.ScheduleEvent(EVENT_INCINERATE, Seconds(12)); -            events.ScheduleEvent(EVENT_SUMMON_DOOM_BLOSSOM, Seconds(8)); -            events.ScheduleEvent(EVENT_SHADOW_DEATH, Seconds(8)); -            events.ScheduleEvent(EVENT_CRUSHING_SHADOWS, Seconds(18)); -        } +    void EnterCombat(Unit* /*who*/) override +    { +        _EnterCombat(); +        Talk(SAY_AGGRO); +        events.SetPhase(PHASE_COMBAT); +        events.ScheduleEvent(EVENT_ENRAGE, Minutes(10)); +        events.ScheduleEvent(EVENT_INCINERATE, Seconds(12)); +        events.ScheduleEvent(EVENT_SUMMON_DOOM_BLOSSOM, Seconds(8)); +        events.ScheduleEvent(EVENT_SHADOW_DEATH, Seconds(8)); +        events.ScheduleEvent(EVENT_CRUSHING_SHADOWS, Seconds(18)); +    } -        void EnterEvadeMode(EvadeReason /*why*/) override -        { -            DoCast(SPELL_SHADOW_OF_DEATH_REMOVE); -            summons.DespawnAll(); -            _DespawnAtEvade(); -        } +    void EnterEvadeMode(EvadeReason /*why*/) override +    { +        DoCast(SPELL_SHADOW_OF_DEATH_REMOVE); +        summons.DespawnAll(); +        _DespawnAtEvade(); +    } -        void DoAction(int32 action) override +    void DoAction(int32 action) override +    { +        if (action == ACTION_START_INTRO && me->IsAlive())          { -            if (action == ACTION_START_INTRO && me->IsAlive()) -            { -                instance->SetData(DATA_TERON_GOREFIEND_INTRO, 0); -                Talk(SAY_INTRO); -                events.SetPhase(PHASE_INTRO); -                events.ScheduleEvent(EVENT_FINISH_INTRO, Seconds(20)); -            } +            instance->SetData(DATA_TERON_GOREFIEND_INTRO, 0); +            Talk(SAY_INTRO); +            events.SetPhase(PHASE_INTRO); +            events.ScheduleEvent(EVENT_FINISH_INTRO, Seconds(20));          } +    } -        void KilledUnit(Unit* victim) override -        { -            if (victim->GetTypeId() == TYPEID_PLAYER) -                Talk(SAY_SLAY); -        } +    void KilledUnit(Unit* victim) override +    { +        if (victim->GetTypeId() == TYPEID_PLAYER) +            Talk(SAY_SLAY); +    } -        void JustDied(Unit* /*killer*/) override -        { -            Talk(SAY_DEATH); -            DoCast(SPELL_SHADOW_OF_DEATH_REMOVE); -            _JustDied(); -        } +    void JustDied(Unit* /*killer*/) override +    { +        Talk(SAY_DEATH); +        DoCast(SPELL_SHADOW_OF_DEATH_REMOVE); +        _JustDied(); +    } -        void UpdateAI(uint32 diff) override -        { -            if (!events.IsInPhase(PHASE_INTRO) && !UpdateVictim()) -                return; +    void UpdateAI(uint32 diff) override +    { +        if (!events.IsInPhase(PHASE_INTRO) && !UpdateVictim()) +            return; -            if (me->HasUnitState(UNIT_STATE_CASTING)) -                return; +        if (me->HasUnitState(UNIT_STATE_CASTING)) +            return; -            events.Update(diff); +        events.Update(diff); -            while (uint32 eventId = events.ExecuteEvent()) +        while (uint32 eventId = events.ExecuteEvent()) +        { +            switch (eventId)              { -                switch (eventId) -                { -                    case EVENT_ENRAGE: -                        DoCast(SPELL_BERSERK); -                        break; -                    case EVENT_INCINERATE: -                        if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) -                            DoCast(target, SPELL_INCINERATE); -                        Talk(SAY_INCINERATE); -                        events.Repeat(Seconds(12), Seconds(20)); -                        break; -                    case EVENT_SUMMON_DOOM_BLOSSOM: -                        DoCastSelf(SPELL_SUMMON_DOOM_BLOSSOM, true); -                        Talk(SAY_BLOSSOM); -                        events.Repeat(Seconds(30), Seconds(40)); -                        break; -                    case EVENT_SHADOW_DEATH: -                        if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true, true, -SPELL_SPIRITUAL_VENGEANCE)) -                            DoCast(target, SPELL_SHADOW_OF_DEATH); -                        events.Repeat(Seconds(30), Seconds(35)); -                        break; -                    case EVENT_CRUSHING_SHADOWS: -                        me->CastCustomSpell(SPELL_CRUSHING_SHADOWS, SPELLVALUE_MAX_TARGETS, 5, me); -                        Talk(SAY_CRUSHING); -                        events.Repeat(Seconds(18), Seconds(30)); -                        break; -                    case EVENT_FINISH_INTRO: -                        me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); -                        me->SetReactState(REACT_AGGRESSIVE); -                        break; -                    default: -                        break; -                } - -                if (me->HasUnitState(UNIT_STATE_CASTING)) -                    return; +                case EVENT_ENRAGE: +                    DoCast(SPELL_BERSERK); +                    break; +                case EVENT_INCINERATE: +                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) +                        DoCast(target, SPELL_INCINERATE); +                    Talk(SAY_INCINERATE); +                    events.Repeat(Seconds(12), Seconds(20)); +                    break; +                case EVENT_SUMMON_DOOM_BLOSSOM: +                    DoCastSelf(SPELL_SUMMON_DOOM_BLOSSOM, true); +                    Talk(SAY_BLOSSOM); +                    events.Repeat(Seconds(30), Seconds(40)); +                    break; +                case EVENT_SHADOW_DEATH: +                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true, true, -SPELL_SPIRITUAL_VENGEANCE)) +                        DoCast(target, SPELL_SHADOW_OF_DEATH); +                    events.Repeat(Seconds(30), Seconds(35)); +                    break; +                case EVENT_CRUSHING_SHADOWS: +                    me->CastCustomSpell(SPELL_CRUSHING_SHADOWS, SPELLVALUE_MAX_TARGETS, 5, me); +                    Talk(SAY_CRUSHING); +                    events.Repeat(Seconds(18), Seconds(30)); +                    break; +                case EVENT_FINISH_INTRO: +                    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); +                    me->SetReactState(REACT_AGGRESSIVE); +                    break; +                default: +                    break;              } -            DoMeleeAttackIfReady(); +            if (me->HasUnitState(UNIT_STATE_CASTING)) +                return;          } -    }; -    CreatureAI* GetAI(Creature* creature) const override -    { -        return GetBlackTempleAI<boss_teron_gorefiendAI>(creature); +        DoMeleeAttackIfReady();      }  }; -class npc_doom_blossom : public CreatureScript +struct npc_doom_blossom : public NullCreatureAI  { -public: -    npc_doom_blossom() : CreatureScript("npc_doom_blossom") { } -    struct npc_doom_blossomAI : public NullCreatureAI -    { -        npc_doom_blossomAI(Creature* creature) : NullCreatureAI(creature), _instance(me->GetInstanceScript()) { } +    npc_doom_blossom(Creature* creature) : NullCreatureAI(creature), _instance(me->GetInstanceScript()) { } -        void Reset() override -        { -            /* Workaround - Until SMSG_SET_PLAY_HOVER_ANIM be implemented */ -            Position pos; -            pos.Relocate(me); -            pos.m_positionZ += 8.0f; -            me->GetMotionMaster()->MoveTakeoff(0, pos); - -            DoCast(SPELL_SUMMON_BLOSSOM_MOVE_TARGET); -            _scheduler.CancelAll(); -            me->SetInCombatWithZone(); -            _scheduler.Schedule(Seconds(12), [this](TaskContext shadowBolt) -            { -                if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) -                    DoCast(target, SPELL_SHADOWBOLT); - -                shadowBolt.Repeat(Seconds(2)); -            }); -        } - -        void UpdateAI(uint32 diff) override +    void Reset() override +    { +        /* Workaround - Until SMSG_SET_PLAY_HOVER_ANIM be implemented */ +        Position pos; +        pos.Relocate(me); +        pos.m_positionZ += 8.0f; +        me->GetMotionMaster()->MoveTakeoff(0, pos); + +        DoCast(SPELL_SUMMON_BLOSSOM_MOVE_TARGET); +        _scheduler.CancelAll(); +        me->SetInCombatWithZone(); +        _scheduler.Schedule(Seconds(12), [this](TaskContext shadowBolt)          { -            if (me->HasUnitState(UNIT_STATE_CASTING)) -                return; - -            _scheduler.Update(diff); -        } +            if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) +                DoCast(target, SPELL_SHADOWBOLT); -    private: -        TaskScheduler _scheduler; -        InstanceScript* _instance; -    }; +            shadowBolt.Repeat(Seconds(2)); +        }); +    } -    CreatureAI* GetAI(Creature* creature) const override +    void UpdateAI(uint32 diff) override      { -        return  GetBlackTempleAI<npc_doom_blossomAI>(creature); +        if (me->HasUnitState(UNIT_STATE_CASTING)) +            return; + +        _scheduler.Update(diff);      } + +private: +    TaskScheduler _scheduler; +    InstanceScript* _instance;  }; -class npc_shadowy_construct : public CreatureScript +struct npc_shadowy_construct : public ScriptedAI  { -public: -    npc_shadowy_construct() : CreatureScript("npc_shadowy_construct") { } +    npc_shadowy_construct(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) +    { +        //This creature must be immune everything, except spells of Vengeful Spirit. +        creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true); +        creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_MAGIC, true); +    } -    struct npc_shadowy_constructAI : public ScriptedAI +    void Reset() override      { -        npc_shadowy_constructAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) +        if (_instance->GetBossState(DATA_TERON_GOREFIEND) != IN_PROGRESS)          { -            //This creature must be immune everything, except spells of Vengeful Spirit. -            creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true); -            creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_MAGIC, true); +            me->DespawnOrUnsummon(); +            return;          } -        void Reset() override +        targetGUID.Clear(); +        _scheduler.CancelAll(); +        _scheduler.Schedule(Seconds(12), [this](TaskContext atrophy) +        { +            DoCastVictim(SPELL_ATROPHY); +            atrophy.Repeat(Seconds(10), Seconds(12)); +        }); +        _scheduler.Schedule(Milliseconds(200), [this](TaskContext checkPlayer)          { -            if (_instance->GetBossState(DATA_TERON_GOREFIEND) != IN_PROGRESS) +            if (Unit* target = ObjectAccessor::GetUnit(*me, targetGUID))              { -                me->DespawnOrUnsummon(); -                return; +                if (!target->IsAlive() || !me->CanCreatureAttack(target)) +                    SelectNewTarget();              } +            else +                SelectNewTarget(); -            targetGUID.Clear(); -            _scheduler.CancelAll(); -            _scheduler.Schedule(Seconds(12), [this](TaskContext atrophy) -            { -                DoCastVictim(SPELL_ATROPHY); -                atrophy.Repeat(Seconds(10), Seconds(12)); -            }); -            _scheduler.Schedule(Milliseconds(200), [this](TaskContext checkPlayer) -            { -                if (Unit* target = ObjectAccessor::GetUnit(*me, targetGUID)) -                { -                    if (!target->IsAlive() || !me->CanCreatureAttack(target)) -                        SelectNewTarget(); -                } -                else -                    SelectNewTarget(); +            checkPlayer.Repeat(Seconds(1)); +        }); -                checkPlayer.Repeat(Seconds(1)); -            }); +        if (Creature* teron = _instance->GetCreature(DATA_TERON_GOREFIEND)) +            teron->AI()->JustSummoned(me); -            if (Creature* teron = _instance->GetCreature(DATA_TERON_GOREFIEND)) -                teron->AI()->JustSummoned(me); +        SelectNewTarget(); +    } -            SelectNewTarget(); -        } +    void UpdateAI(uint32 diff) override +    { +        if (me->HasUnitState(UNIT_STATE_CASTING)) +            return; -        void UpdateAI(uint32 diff) override +        _scheduler.Update(diff, [this]          { -            if (me->HasUnitState(UNIT_STATE_CASTING)) -                return; - -            _scheduler.Update(diff, [this] -            { -                DoMeleeAttackIfReady(); -            }); -        } +            DoMeleeAttackIfReady(); +        }); +    } -        void SelectNewTarget() +    void SelectNewTarget() +    { +        if (Creature* teron = _instance->GetCreature(DATA_TERON_GOREFIEND))          { -            if (Creature* teron = _instance->GetCreature(DATA_TERON_GOREFIEND)) +            Unit* target = teron->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true, true, -SPELL_SPIRITUAL_VENGEANCE); +            // He should target Vengeful Spirits only if has no other player available +            if (!target) +                target = teron->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0); + +            if (target)              { -                Unit* target = teron->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true, true, -SPELL_SPIRITUAL_VENGEANCE); -                // He should target Vengeful Spirits only if has no other player available -                if (!target) -                    target = teron->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0); - -                if (target) -                { -                    ResetThreatList(); -                    AttackStart(target); -                    AddThreat(target, 1000000.0f); -                    targetGUID = target->GetGUID(); -                } +                ResetThreatList(); +                AttackStart(target); +                AddThreat(target, 1000000.0f); +                targetGUID = target->GetGUID();              }          } - -    private: -        TaskScheduler _scheduler; -        InstanceScript* _instance; -        ObjectGuid targetGUID; -    }; - -    CreatureAI* GetAI(Creature* creature) const override -    { -        return  GetBlackTempleAI<npc_shadowy_constructAI>(creature);      } -}; - -class at_teron_gorefiend_entrance : public OnlyOnceAreaTriggerScript -{ -public: -    at_teron_gorefiend_entrance() : OnlyOnceAreaTriggerScript("at_teron_gorefiend_entrance") { } -    bool _OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override -    { -        if (InstanceScript* instance = player->GetInstanceScript()) -            if (Creature* teron = instance->GetCreature(DATA_TERON_GOREFIEND)) -                teron->AI()->DoAction(ACTION_START_INTRO); - -        return true; -    } +private: +    TaskScheduler _scheduler; +    InstanceScript* _instance; +    ObjectGuid targetGUID;  };  // 40251 - Shadow of Death -class spell_teron_gorefiend_shadow_of_death : public SpellScriptLoader +class spell_teron_gorefiend_shadow_of_death : public AuraScript  { -    public: -        spell_teron_gorefiend_shadow_of_death() : SpellScriptLoader("spell_teron_gorefiend_shadow_of_death") { } +    PrepareAuraScript(spell_teron_gorefiend_shadow_of_death); -        class spell_teron_gorefiend_shadow_of_death_AuraScript : public AuraScript +    bool Validate(SpellInfo const* /*spell*/) override +    { +        return ValidateSpellInfo(          { -            PrepareAuraScript(spell_teron_gorefiend_shadow_of_death_AuraScript); - -            bool Validate(SpellInfo const* /*spell*/) override -            { -                return ValidateSpellInfo( -                { -                    SPELL_SUMMON_SPIRIT, -                    SPELL_POSSESS_SPIRIT_IMMUNE, -                    SPELL_SPIRITUAL_VENGEANCE, -                    SPELL_SUMMON_SKELETRON_1, -                    SPELL_SUMMON_SKELETRON_2, -                    SPELL_SUMMON_SKELETRON_3, -                    SPELL_SUMMON_SKELETRON_4 -                }); -            } - -            void Absorb(AuraEffect* /*aurEff*/, DamageInfo& /*dmgInfo*/, uint32& /*absorbAmount*/) -            { -                PreventDefaultAction(); -            } +            SPELL_SUMMON_SPIRIT, +            SPELL_POSSESS_SPIRIT_IMMUNE, +            SPELL_SPIRITUAL_VENGEANCE, +            SPELL_SUMMON_SKELETRON_1, +            SPELL_SUMMON_SKELETRON_2, +            SPELL_SUMMON_SKELETRON_3, +            SPELL_SUMMON_SKELETRON_4 +        }); +    } -            void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) -            { -                if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) -                { -                    Unit* target = GetTarget(); -                    target->CastSpell(target, SPELL_SUMMON_SPIRIT, true); +    void Absorb(AuraEffect* /*aurEff*/, DamageInfo& /*dmgInfo*/, uint32& /*absorbAmount*/) +    { +        PreventDefaultAction(); +    } -                    for (uint8 i = 0; i < 4; ++i) -                        target->CastSpell(target, SkeletronSpells[i], true); +    void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +    { +        if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) +        { +            Unit* target = GetTarget(); +            target->CastSpell(target, SPELL_SUMMON_SPIRIT, true); -                    target->CastSpell(target, SPELL_POSSESS_SPIRIT_IMMUNE, true); -                    target->CastSpell(target, SPELL_SPIRITUAL_VENGEANCE, true); -                } -            } +            for (uint8 i = 0; i < 4; ++i) +                target->CastSpell(target, SkeletronSpells[i], true); -            void Register() override -            { -                OnEffectAbsorb += AuraEffectAbsorbFn(spell_teron_gorefiend_shadow_of_death_AuraScript::Absorb, EFFECT_0); -                AfterEffectRemove += AuraEffectRemoveFn(spell_teron_gorefiend_shadow_of_death_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_OVERRIDE_CLASS_SCRIPTS, AURA_EFFECT_HANDLE_REAL); -            } -        }; - -        AuraScript* GetAuraScript() const override -        { -            return new spell_teron_gorefiend_shadow_of_death_AuraScript(); +            target->CastSpell(target, SPELL_POSSESS_SPIRIT_IMMUNE, true); +            target->CastSpell(target, SPELL_SPIRITUAL_VENGEANCE, true);          } +    } + +    void Register() override +    { +        OnEffectAbsorb += AuraEffectAbsorbFn(spell_teron_gorefiend_shadow_of_death::Absorb, EFFECT_0); +        AfterEffectRemove += AuraEffectRemoveFn(spell_teron_gorefiend_shadow_of_death::OnRemove, EFFECT_1, SPELL_AURA_OVERRIDE_CLASS_SCRIPTS, AURA_EFFECT_HANDLE_REAL); +    }  };  // 40268 - Spiritual Vengeance -class spell_teron_gorefiend_spiritual_vengeance : public SpellScriptLoader +class spell_teron_gorefiend_spiritual_vengeance : public AuraScript  { -    public: -        spell_teron_gorefiend_spiritual_vengeance() : SpellScriptLoader("spell_teron_gorefiend_spiritual_vengeance") { } - -        class spell_teron_gorefiend_spiritual_vengeance_AuraScript : public AuraScript -        { -            PrepareAuraScript(spell_teron_gorefiend_spiritual_vengeance_AuraScript); +    PrepareAuraScript(spell_teron_gorefiend_spiritual_vengeance); -            void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) -            { -                GetTarget()->KillSelf(); -            } - -            void Register() override -            { -                AfterEffectRemove += AuraEffectRemoveFn(spell_teron_gorefiend_spiritual_vengeance_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_POSSESS, AURA_EFFECT_HANDLE_REAL); -                AfterEffectRemove += AuraEffectRemoveFn(spell_teron_gorefiend_spiritual_vengeance_AuraScript::OnRemove, EFFECT_2, SPELL_AURA_MOD_PACIFY_SILENCE, AURA_EFFECT_HANDLE_REAL); -            } -        }; +    void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) +    { +        GetTarget()->KillSelf(); +    } -        AuraScript* GetAuraScript() const override -        { -            return new spell_teron_gorefiend_spiritual_vengeance_AuraScript(); -        } +    void Register() override +    { +        AfterEffectRemove += AuraEffectRemoveFn(spell_teron_gorefiend_spiritual_vengeance::OnRemove, EFFECT_0, SPELL_AURA_MOD_POSSESS, AURA_EFFECT_HANDLE_REAL); +        AfterEffectRemove += AuraEffectRemoveFn(spell_teron_gorefiend_spiritual_vengeance::OnRemove, EFFECT_2, SPELL_AURA_MOD_PACIFY_SILENCE, AURA_EFFECT_HANDLE_REAL); +    }  };  // 41999 - Shadow of Death Remove -class spell_teron_gorefiend_shadow_of_death_remove : public SpellScriptLoader +class spell_teron_gorefiend_shadow_of_death_remove : public SpellScript  { -    public: -        spell_teron_gorefiend_shadow_of_death_remove() : SpellScriptLoader("spell_teron_gorefiend_shadow_of_death_remove") { } +    PrepareSpellScript(spell_teron_gorefiend_shadow_of_death_remove); -        class spell_teron_gorefiend_shadow_of_death_remove_SpellScript : public SpellScript +    bool Validate(SpellInfo const* /*spell*/) override +    { +        return ValidateSpellInfo(          { -            PrepareSpellScript(spell_teron_gorefiend_shadow_of_death_remove_SpellScript); +            SPELL_SHADOW_OF_DEATH, +            SPELL_POSSESS_SPIRIT_IMMUNE, +            SPELL_SPIRITUAL_VENGEANCE +        }); +    } -            bool Validate(SpellInfo const* /*spell*/) override -            { -                return ValidateSpellInfo( -                { -                    SPELL_SHADOW_OF_DEATH, -                    SPELL_POSSESS_SPIRIT_IMMUNE, -                    SPELL_SPIRITUAL_VENGEANCE -                }); -            } +    void RemoveAuras() +    { +        Unit* target = GetHitUnit(); -            void RemoveAuras() -            { -                Unit* target = GetHitUnit(); +        target->RemoveAurasDueToSpell(SPELL_POSSESS_SPIRIT_IMMUNE); +        target->RemoveAurasDueToSpell(SPELL_SPIRITUAL_VENGEANCE); +        target->RemoveAurasDueToSpell(SPELL_SHADOW_OF_DEATH); +    } -                target->RemoveAurasDueToSpell(SPELL_POSSESS_SPIRIT_IMMUNE); -                target->RemoveAurasDueToSpell(SPELL_SPIRITUAL_VENGEANCE); -                target->RemoveAurasDueToSpell(SPELL_SHADOW_OF_DEATH); -            } +    void Register() override +    { +        OnHit += SpellHitFn(spell_teron_gorefiend_shadow_of_death_remove::RemoveAuras); +    } +}; -            void Register() override -            { -                OnHit += SpellHitFn(spell_teron_gorefiend_shadow_of_death_remove_SpellScript::RemoveAuras); -            } +class at_teron_gorefiend_entrance : public OnlyOnceAreaTriggerScript +{ +public: +    at_teron_gorefiend_entrance() : OnlyOnceAreaTriggerScript("at_teron_gorefiend_entrance") { } -        }; +    bool _OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override +    { +        if (InstanceScript* instance = player->GetInstanceScript()) +            if (Creature* teron = instance->GetCreature(DATA_TERON_GOREFIEND)) +                teron->AI()->DoAction(ACTION_START_INTRO); -        SpellScript* GetSpellScript() const override -        { -            return new spell_teron_gorefiend_shadow_of_death_remove_SpellScript(); -        } +        return true; +    }  };  void AddSC_boss_teron_gorefiend()  { -    new boss_teron_gorefiend(); -    new npc_doom_blossom(); -    new npc_shadowy_construct(); +    RegisterBlackTempleCreatureAI(boss_teron_gorefiend); +    RegisterBlackTempleCreatureAI(npc_doom_blossom); +    RegisterBlackTempleCreatureAI(npc_shadowy_construct); +    RegisterAuraScript(spell_teron_gorefiend_shadow_of_death); +    RegisterAuraScript(spell_teron_gorefiend_spiritual_vengeance); +    RegisterSpellScript(spell_teron_gorefiend_shadow_of_death_remove);      new at_teron_gorefiend_entrance(); -    new spell_teron_gorefiend_shadow_of_death(); -    new spell_teron_gorefiend_spiritual_vengeance(); -    new spell_teron_gorefiend_shadow_of_death_remove();  } diff --git a/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp b/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp index b49ad6e3f20..4a35acc20db 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp @@ -28,220 +28,207 @@  enum Texts  { -    SAY_AGGRO                       = 0, -    SAY_NEEDLE                      = 1, -    SAY_SLAY                        = 2, -    SAY_SPECIAL                     = 3, -    SAY_ENRAGE                      = 4, -    SAY_DEATH                       = 5 +    SAY_AGGRO   = 0, +    SAY_NEEDLE  = 1, +    SAY_SLAY    = 2, +    SAY_SPECIAL = 3, +    SAY_ENRAGE  = 4, +    SAY_DEATH   = 5  };  enum Spells  { -    SPELL_NEEDLE_SPINE_TARGETING    = 39992, -    SPELL_NEEDLE_SPINE              = 39835, -    SPELL_TIDAL_BURST               = 39878, -    SPELL_TIDAL_SHIELD              = 39872, -    SPELL_IMPALING_SPINE            = 39837, -    SPELL_CREATE_NAJENTUS_SPINE     = 39956, -    SPELL_HURL_SPINE                = 39948, -    SPELL_BERSERK                   = 26662 - +    SPELL_NEEDLE_SPINE_TARGETING = 39992, +    SPELL_NEEDLE_SPINE           = 39835, +    SPELL_TIDAL_BURST            = 39878, +    SPELL_TIDAL_SHIELD           = 39872, +    SPELL_IMPALING_SPINE         = 39837, +    SPELL_CREATE_NAJENTUS_SPINE  = 39956, +    SPELL_HURL_SPINE             = 39948, +    SPELL_BERSERK                = 26662  };  enum Events  { -    EVENT_BERSERK                   = 1, -    EVENT_YELL                      = 2, -    EVENT_NEEDLE                    = 3, -    EVENT_SPINE                     = 4, -    EVENT_SHIELD                    = 5 +    EVENT_BERSERK = 1, +    EVENT_YELL    = 2, +    EVENT_NEEDLE  = 3, +    EVENT_SPINE   = 4, +    EVENT_SHIELD  = 5  }; -class boss_najentus : public CreatureScript +enum Misc  { -public: -    boss_najentus() : CreatureScript("boss_najentus") { } - -    struct boss_najentusAI : public BossAI -    { -        boss_najentusAI(Creature* creature) : BossAI(creature, DATA_HIGH_WARLORD_NAJENTUS) { } - -        void Reset() override -        { -            _Reset(); -            SpineTargetGUID.Clear(); -        } - -        void EnterEvadeMode(EvadeReason /*why*/) override -        { -            _DespawnAtEvade(); -        } +    DATA_REMOVE_IMPALING_SPINE   = 1, +    ACTION_RESET_IMPALING_TARGET = 2 +}; -        void KilledUnit(Unit* victim) override -        { -            if (victim->GetTypeId() == TYPEID_PLAYER) -                Talk(SAY_SLAY); -        } +struct boss_najentus : public BossAI +{ +    boss_najentus(Creature* creature) : BossAI(creature, DATA_HIGH_WARLORD_NAJENTUS) { } -        void JustDied(Unit* /*killer*/) override -        { -            _JustDied(); -            Talk(SAY_DEATH); -        } +    void Reset() override +    { +        _Reset(); +        _spineTargetGUID.Clear(); +    } -        void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override -        { -            if (spell->Id == SPELL_HURL_SPINE && me->HasAura(SPELL_TIDAL_SHIELD)) -            { -                me->RemoveAurasDueToSpell(SPELL_TIDAL_SHIELD); -                DoCastSelf(SPELL_TIDAL_BURST, true); -                events.RescheduleEvent(EVENT_SPINE, Seconds(2)); -            } -        } +    void EnterEvadeMode(EvadeReason /*why*/) override +    { +        _EnterEvadeMode(); +        _DespawnAtEvade(); +    } -        void EnterCombat(Unit* /*who*/) override -        { -            _EnterCombat(); -            Talk(SAY_AGGRO); -            events.ScheduleEvent(EVENT_NEEDLE, Seconds(2)); -            events.ScheduleEvent(EVENT_SHIELD, Seconds(60)); -            events.ScheduleEvent(EVENT_SPINE, Seconds(30)); -            events.ScheduleEvent(EVENT_BERSERK, Seconds(480)); -            events.ScheduleEvent(EVENT_YELL, Seconds(45), Seconds(100)); -        } +    void KilledUnit(Unit* victim) override +    { +        if (victim->GetTypeId() == TYPEID_PLAYER) +            Talk(SAY_SLAY); +    } -        bool RemoveImpalingSpine() -        { -            if (!SpineTargetGUID) -                return false; - -            Unit* target = ObjectAccessor::GetUnit(*me, SpineTargetGUID); -            if (target && target->HasAura(SPELL_IMPALING_SPINE)) -                target->RemoveAurasDueToSpell(SPELL_IMPALING_SPINE); -            SpineTargetGUID.Clear(); -            return true; -        } +    void JustDied(Unit* /*killer*/) override +    { +        _JustDied(); +        Talk(SAY_DEATH); +    } -        void ExecuteEvent(uint32 eventId) override +    void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override +    { +        if (spell->Id == SPELL_HURL_SPINE && me->HasAura(SPELL_TIDAL_SHIELD))          { -            switch (eventId) -            { -                case EVENT_SHIELD: -                    DoCastSelf(SPELL_TIDAL_SHIELD, true); -                    events.RescheduleEvent(EVENT_SPINE, Seconds(50)); -                    events.Repeat(Seconds(55), Seconds(60)); -                    break; -                case EVENT_BERSERK: -                    Talk(SAY_ENRAGE); -                    DoCastSelf(SPELL_BERSERK, true); -                    break; -                case EVENT_SPINE: -                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 200.0f, true)) -                    { -                        DoCast(target, SPELL_IMPALING_SPINE, true); -                        SpineTargetGUID = target->GetGUID(); -                        //must let target summon, otherwise you cannot click the spine -                        target->SummonGameObject(GO_NAJENTUS_SPINE, *target, QuaternionData(), 30); -                        Talk(SAY_NEEDLE); -                    } -                    events.Repeat(Seconds(20), Seconds(25)); -                    break; -                case EVENT_NEEDLE: -                    DoCastSelf(SPELL_NEEDLE_SPINE_TARGETING, true); -                    events.Repeat(Seconds(2)); -                    break; -                case EVENT_YELL: -                    Talk(SAY_SPECIAL); -                    events.Repeat(Seconds(25), Seconds(100)); -                    break; -                default: -                    break; -            } +            me->RemoveAurasDueToSpell(SPELL_TIDAL_SHIELD); +            DoCastSelf(SPELL_TIDAL_BURST, true); +            events.RescheduleEvent(EVENT_SPINE, Seconds(2));          } +    } -    private: -        ObjectGuid SpineTargetGUID; -    }; +    void EnterCombat(Unit* /*who*/) override +    { +        _EnterCombat(); +        Talk(SAY_AGGRO); +        events.ScheduleEvent(EVENT_NEEDLE, Seconds(2)); +        events.ScheduleEvent(EVENT_SHIELD, Seconds(60)); +        events.ScheduleEvent(EVENT_SPINE, Seconds(30)); +        events.ScheduleEvent(EVENT_BERSERK, Seconds(480)); +        events.ScheduleEvent(EVENT_YELL, Seconds(45), Seconds(100)); +    } -    CreatureAI* GetAI(Creature* creature) const override +    uint32 GetData(uint32 data) const override      { -        return GetBlackTempleAI<boss_najentusAI>(creature); +        if (data == DATA_REMOVE_IMPALING_SPINE) +            return RemoveImpalingSpine() ? 1 : 0; +        return 0;      } -}; -class go_najentus_spine : public GameObjectScript -{ -public: -    go_najentus_spine() : GameObjectScript("go_najentus_spine") { } +    void DoAction(int32 actionId) override +    { +        if (actionId == ACTION_RESET_IMPALING_TARGET) +            _spineTargetGUID.Clear(); +    } -    struct go_najentus_spineAI : public GameObjectAI +    bool RemoveImpalingSpine() const      { -        go_najentus_spineAI(GameObject* go) : GameObjectAI(go), instance(go->GetInstanceScript()) { } +        if (!_spineTargetGUID) +            return false; -        InstanceScript* instance; +        Unit* target = ObjectAccessor::GetUnit(*me, _spineTargetGUID); +        if (target && target->HasAura(SPELL_IMPALING_SPINE)) +            target->RemoveAurasDueToSpell(SPELL_IMPALING_SPINE); +        return true; +    } -        bool GossipHello(Player* player) override +    void ExecuteEvent(uint32 eventId) override +    { +        switch (eventId)          { -            if (Creature* najentus = instance->GetCreature(DATA_HIGH_WARLORD_NAJENTUS)) -            { -                if (ENSURE_AI(boss_najentus::boss_najentusAI, najentus->AI())->RemoveImpalingSpine()) +            case EVENT_SHIELD: +                DoCastSelf(SPELL_TIDAL_SHIELD, true); +                events.RescheduleEvent(EVENT_SPINE, Seconds(50)); +                events.Repeat(Seconds(55), Seconds(60)); +                break; +            case EVENT_BERSERK: +                Talk(SAY_ENRAGE); +                DoCastSelf(SPELL_BERSERK, true); +                break; +            case EVENT_SPINE: +                if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 200.0f, true))                  { -                    me->CastSpell(player, SPELL_CREATE_NAJENTUS_SPINE, true); -                    me->Delete(); +                    DoCast(target, SPELL_IMPALING_SPINE, true); +                    _spineTargetGUID = target->GetGUID(); +                    //must let target summon, otherwise you cannot click the spine +                    target->SummonGameObject(GO_NAJENTUS_SPINE, *target, QuaternionData(), 30); +                    Talk(SAY_NEEDLE);                  } -            } -            return true; +                events.Repeat(Seconds(20), Seconds(25)); +                break; +            case EVENT_NEEDLE: +                DoCastSelf(SPELL_NEEDLE_SPINE_TARGETING, true); +                events.Repeat(Seconds(2)); +                break; +            case EVENT_YELL: +                Talk(SAY_SPECIAL); +                events.Repeat(Seconds(25), Seconds(100)); +                break; +            default: +                break;          } -    }; - -    GameObjectAI* GetAI(GameObject* go) const override -    { -        return GetBlackTempleAI<go_najentus_spineAI>(go);      } + +private: +    ObjectGuid _spineTargetGUID;  }; -// 39992 - Needle Spine Targeting -class spell_najentus_needle_spine : public SpellScriptLoader +struct go_najentus_spine : public GameObjectAI  { -    public: -        spell_najentus_needle_spine() : SpellScriptLoader("spell_najentus_needle_spine") { } +    go_najentus_spine(GameObject* go) : GameObjectAI(go), _instance(go->GetInstanceScript()) { } -        class spell_najentus_needle_spine_SpellScript : public SpellScript -        { -            PrepareSpellScript(spell_najentus_needle_spine_SpellScript); +    bool GossipHello(Player* player) override +    { +        if (!_instance) +            return false; -            bool Validate(SpellInfo const* /*spellInfo*/) override +        if (Creature* najentus = _instance->GetCreature(DATA_HIGH_WARLORD_NAJENTUS)) +            if (najentus->AI()->GetData(DATA_REMOVE_IMPALING_SPINE))              { -                return ValidateSpellInfo({ SPELL_NEEDLE_SPINE }); +                najentus->AI()->DoAction(ACTION_RESET_IMPALING_TARGET); +                me->CastSpell(player, SPELL_CREATE_NAJENTUS_SPINE, true); +                me->Delete();              } +        return true; +    } +private: +    InstanceScript* _instance; +}; -            void FilterTargets(std::list<WorldObject*>& targets) -            { -                targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_IMPALING_SPINE)); -            } +// 39992 - Needle Spine Targeting +class spell_najentus_needle_spine : public SpellScript +{ +    PrepareSpellScript(spell_najentus_needle_spine); -            void HandleScript(SpellEffIndex /*effIndex*/) -            { -                GetCaster()->CastSpell(GetHitUnit(), SPELL_NEEDLE_SPINE, true); -            } +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo({ SPELL_NEEDLE_SPINE }); +    } -            void Register() override -            { -                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_najentus_needle_spine_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); -                OnEffectHitTarget += SpellEffectFn(spell_najentus_needle_spine_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); -            } -        }; +    void FilterTargets(std::list<WorldObject*>& targets) +    { +        targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_IMPALING_SPINE)); +    } -        SpellScript* GetSpellScript() const override -        { -            return new spell_najentus_needle_spine_SpellScript(); -        } +    void HandleScript(SpellEffIndex /*effIndex*/) +    { +        GetCaster()->CastSpell(GetHitUnit(), SPELL_NEEDLE_SPINE, true); +    } + +    void Register() override +    { +        OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_najentus_needle_spine::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +        OnEffectHitTarget += SpellEffectFn(spell_najentus_needle_spine::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); +    }  };  void AddSC_boss_najentus()  { -    new boss_najentus(); -    new go_najentus_spine(); -    new spell_najentus_needle_spine(); +    RegisterBlackTempleCreatureAI(boss_najentus); +    RegisterGameObjectAI(go_najentus_spine); +    RegisterSpellScript(spell_najentus_needle_spine);  } | 
