diff options
author | Keader <keader.android@gmail.com> | 2017-11-10 11:28:59 -0300 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2021-02-06 21:41:51 +0100 |
commit | 0a68d4679866f9146475fb071c61f1ae9afe1fb4 (patch) | |
tree | a4464bb33edf272c488edb4f684dfaf567172a7e /src | |
parent | f36d2424a67599a667268e1b0ca275529feec8ce (diff) |
Core/Scripts: Updated Black Temple to new Creature/Spell/Aura/GOB model
Fixed some codestyle issues.
Removed ENSUREAI
(cherry picked from commit 78f4f54f81e092c9c7b99af445fb6ec85e00e6b0)
Diffstat (limited to 'src')
9 files changed, 2744 insertions, 3418 deletions
diff --git a/src/server/scripts/Outland/BlackTemple/black_temple.cpp b/src/server/scripts/Outland/BlackTemple/black_temple.cpp index 647f678fbb8..14e83d45ffe 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 0cbf6010f8d..ed4b49da640 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 4acd27f7d32..4e9d325d9b0 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, 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, 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* /*spellInfo*/) 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* /*spellInfo*/) 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* /*spellInfo*/) 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, nullptr, true, nullptr, aurEff); - } + bool Validate(SpellInfo const* /*spellInfo*/) 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, 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 c38bf68ea04..ad2bcb2eaf2 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp @@ -109,299 +109,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* /*spellInfo*/) 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* /*spellInfo*/) 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* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_FATAL_ATTRACTION_DAMAGE }); - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(GetCaster(), SPELL_FATAL_ATTRACTION_DAMAGE, true); - } + bool Validate(SpellInfo const* /*spellInfo*/) 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->GetEffect(EFFECT_1)->TriggerSpell }); - } - - void OnTrigger(AuraEffect const* aurEff) - { - PreventDefaultAction(); + bool Validate(SpellInfo const* spellInfo) override + { + return ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_1)->TriggerSpell }); + } - uint32 triggerSpell = GetSpellInfo()->GetEffect(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()->GetEffect(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->GetEffect(EFFECT_0)->TriggerSpell }); - } + PrepareAuraScript(spell_mother_shahraz_generic_periodic); - void OnTrigger(AuraEffect const* aurEff) - { - PreventDefaultAction(); + bool Validate(SpellInfo const* spellInfo) override + { + return ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0)->TriggerSpell }); + } - uint32 triggerSpell = GetSpellInfo()->GetEffect(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()->GetEffect(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 34a8289629f..5dbb7775d32 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp @@ -138,737 +138,637 @@ 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->SetStandState(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->SetStandState(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); - - DoCastSelf(SPELL_ENSLAVED_SOUL_PASSIVE, true); - - _scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/) - { - me->SetReactState(REACT_AGGRESSIVE); - me->SetInCombatWithZone(); - }); - } + me->SetReactState(REACT_PASSIVE); + if (Creature* reliquary = _instance->GetCreature(DATA_RELIQUARY_OF_SOULS)) + reliquary->AI()->JustSummoned(me); - void DoAction(int32 actionId) override - { - if (actionId == ACTION_KILL_SELF) - me->KillSelf(); - } + DoCastSelf(SPELL_ENSLAVED_SOUL_PASSIVE, true); - void UpdateAI(uint32 diff) override + _scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/) { - if (!UpdateVictim()) - return; + me->SetReactState(REACT_AGGRESSIVE); + me->SetInCombatWithZone(); + }); + } - _scheduler.Update(diff); + void DoAction(int32 actionId) override + { + if (actionId == ACTION_KILL_SELF) + me->KillSelf(); + } - DoMeleeAttackIfReady(); - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - void JustDied(Unit* /*killer*/) override - { - DoCastSelf(SPELL_SOUL_RELEASE, true); - } + _scheduler.Update(diff); - 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); - - void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->SetStandState(UNIT_STAND_STATE_SUBMERGED); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->SetStandState(UNIT_STAND_STATE_STAND); - } + PrepareAuraScript(spell_reliquary_of_souls_submerge); + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->SetStandState(UNIT_STAND_STATE_SUBMERGED); + } - 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); - } - }; + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->SetStandState(UNIT_STAND_STATE_STAND); + } - 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") { } + PrepareAuraScript(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 }); - } - - 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 23ba4d03d97..c54050c5c3f 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->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->SetEmoteState(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->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->SetEmoteState(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->SetEmoteState(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->RemoveUnitFlag(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->SetEmoteState(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->RemoveUnitFlag(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->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + break; + } + case EVENT_START_CHANNELERS_AND_SPAWNERS: + { + for (ObjectGuid const summonGuid : summons) + if (Creature* channeler = ObjectAccessor::GetCreature(*me, summonGuid)) + channeler->RemoveUnitFlag(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->AddNpcFlag(UNIT_NPC_FLAG_GOSSIP); - } + if (_instance->GetBossState(DATA_SHADE_OF_AKAMA) != DONE) + me->AddNpcFlag(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->RemoveNpcFlag(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->RemoveNpcFlag(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->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) - DoCastSelf(SPELL_SHADE_SOUL_CHANNEL); - - else - me->DespawnOrUnsummon(Seconds(3)); - } - - channel.Repeat(Seconds(2)); - }); - me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - } + if (shade->HasUnitFlag(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->AddUnitFlag(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->HasUnitFlag(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->HasUnitFlag(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->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) + { + me->SetFacingToObject(shade); + DoCastSelf(SPELL_SHADE_SOUL_CHANNEL); + sorcer_channel.Repeat(Seconds(2)); + } + else { - if (shade->HasUnitFlag(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->SetStandState(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->SetStandState(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 789ba19fa5b..e6e7673163a 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() + { + uint64 health = 0; + Unit* target = nullptr; - Unit* CalculateHatefulStrikeTarget() + for (auto* ref : me->GetThreatManager().GetUnsortedThreatList()) { - uint64 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 3544532d8d9..aeb35728456 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp @@ -74,9 +74,9 @@ enum Spells 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,418 +108,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->AddUnitFlag(UnitFlags(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE)); - me->SetReactState(REACT_PASSIVE); - } + me->AddUnitFlag(UnitFlags(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->RemoveUnitFlag(UnitFlags(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->RemoveUnitFlag(UnitFlags(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") { } + npc_doom_blossom(Creature* creature) : NullCreatureAI(creature), _instance(me->GetInstanceScript()) { } - struct npc_doom_blossomAI : public NullCreatureAI + void Reset() override { - npc_doom_blossomAI(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) { - /* 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 - { - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_SHADOWBOLT); - _scheduler.Update(diff); - } - - 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) { - if (_instance->GetBossState(DATA_TERON_GOREFIEND) != IN_PROGRESS) + DoCastVictim(SPELL_ATROPHY); + atrophy.Repeat(Seconds(10), Seconds(12)); + }); + _scheduler.Schedule(Milliseconds(200), [this](TaskContext checkPlayer) + { + 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*/, bool entered) override - { - if (!entered) - return true; - - 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* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareAuraScript(spell_teron_gorefiend_shadow_of_death_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) 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(); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) - { - Unit* target = GetTarget(); - target->CastSpell(target, SPELL_SUMMON_SPIRIT, true); + 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 + }); + } - for (uint8 i = 0; i < 4; ++i) - target->CastSpell(target, SkeletronSpells[i], true); + void Absorb(AuraEffect* /*aurEff*/, DamageInfo& /*dmgInfo*/, uint32& /*absorbAmount*/) + { + PreventDefaultAction(); + } - target->CastSpell(target, SPELL_POSSESS_SPIRIT_IMMUNE, true); - target->CastSpell(target, SPELL_SPIRITUAL_VENGEANCE, 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); - 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); - } - }; + for (uint8 i = 0; i < 4; ++i) + target->CastSpell(target, SkeletronSpells[i], true); - 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* /*spellInfo*/) 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* /*spellInfo*/) 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*/, bool /*entered*/) 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 c3861becf6b..52bb63caf68 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp @@ -29,220 +29,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::fromEulerAnglesZYX(target->GetOrientation(), 0.0f, 0.0f), 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); } |