From bf925eda3c94b5dfd099a740fee33e9c04071867 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sun, 10 Nov 2024 15:44:35 -0300 Subject: [PATCH] refactor(Scripts/SWP): Update creature scripts to new register method (#20503) --- .../SunwellPlateau/boss_brutallus.cpp | 544 ++++--- .../SunwellPlateau/boss_eredar_twins.cpp | 464 +++--- .../SunwellPlateau/boss_felmyst.cpp | 625 ++++---- .../SunwellPlateau/boss_kalecgos.cpp | 865 ++++++----- .../SunwellPlateau/boss_kiljaeden.cpp | 1329 ++++++++--------- .../SunwellPlateau/boss_muru.cpp | 429 +++--- .../SunwellPlateau/sunwell_plateau.h | 2 + 7 files changed, 2042 insertions(+), 2216 deletions(-) diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp index 1fdb6a115..e8e46a03f 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp @@ -63,106 +63,95 @@ enum Misc ACTION_SPAWN_FELMYST = 2 }; -class boss_brutallus : public CreatureScript +struct boss_brutallus : public BossAI { -public: - boss_brutallus() : CreatureScript("boss_brutallus") { } + boss_brutallus(Creature* creature) : BossAI(creature, DATA_BRUTALLUS) { } - struct boss_brutallusAI : public BossAI + void Reset() override { - boss_brutallusAI(Creature* creature) : BossAI(creature, DATA_BRUTALLUS) { } + BossAI::Reset(); + me->CastSpell(me, SPELL_DUAL_WIELD, true); + } - void Reset() override + void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (me->GetReactState() == REACT_PASSIVE && (!who || who->GetEntry() != NPC_MADRIGOSA)) { - BossAI::Reset(); - me->CastSpell(me, SPELL_DUAL_WIELD, true); + if (who) + Unit::Kill(me, who); + damage = 0; } + } - void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override + void JustEngagedWith(Unit* who) override + { + if (who->GetEntry() == NPC_MADRIGOSA) + return; + + Talk(YELL_AGGRO); + BossAI::JustEngagedWith(who); + + events.ScheduleEvent(EVENT_SPELL_SLASH, 11000); + events.ScheduleEvent(EVENT_SPELL_STOMP, 30000); + events.ScheduleEvent(EVENT_SPELL_BURN, 45000); + events.ScheduleEvent(EVENT_SPELL_BERSERK, 360000); + } + + void KilledUnit(Unit* victim) override + { + if (victim->IsPlayer() && roll_chance_i(50)) + Talk(YELL_KILL); + } + + void JustDied(Unit* killer) override + { + BossAI::JustDied(killer); + Talk(YELL_DEATH); + + me->CastSpell(me, SPELL_SUMMON_BRUTALLUS_DEATH_CLOUD, true); + if (Creature* madrigosa = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_MADRIGOSA))) + madrigosa->AI()->DoAction(ACTION_SPAWN_FELMYST); + } + + void AttackStart(Unit* who) override + { + if (who->GetEntry() == NPC_MADRIGOSA) + return; + BossAI::AttackStart(who); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { - if (me->GetReactState() == REACT_PASSIVE && (!who || who->GetEntry() != NPC_MADRIGOSA)) - { - if (who) - Unit::Kill(me, who); - damage = 0; - } - } - - void JustEngagedWith(Unit* who) override - { - if (who->GetEntry() == NPC_MADRIGOSA) - return; - - Talk(YELL_AGGRO); - BossAI::JustEngagedWith(who); - - events.ScheduleEvent(EVENT_SPELL_SLASH, 11000); + case EVENT_SPELL_SLASH: + me->CastSpell(me->GetVictim(), SPELL_METEOR_SLASH, false); + events.ScheduleEvent(EVENT_SPELL_SLASH, 10000); + break; + case EVENT_SPELL_STOMP: + me->CastSpell(me->GetVictim(), SPELL_STOMP, false); + Talk(YELL_LOVE); events.ScheduleEvent(EVENT_SPELL_STOMP, 30000); - events.ScheduleEvent(EVENT_SPELL_BURN, 45000); - events.ScheduleEvent(EVENT_SPELL_BERSERK, 360000); + break; + case EVENT_SPELL_BURN: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true, true, -SPELL_BURN_DAMAGE)) + me->CastSpell(target, SPELL_BURN, false); + events.ScheduleEvent(EVENT_SPELL_BURN, 60000); + break; + case EVENT_SPELL_BERSERK: + me->CastSpell(me, SPELL_BERSERK, true); + Talk(YELL_BERSERK); + break; } - void KilledUnit(Unit* victim) override - { - if (victim->IsPlayer() && roll_chance_i(50)) - Talk(YELL_KILL); - } - - void JustDied(Unit* killer) override - { - BossAI::JustDied(killer); - Talk(YELL_DEATH); - - me->CastSpell(me, SPELL_SUMMON_BRUTALLUS_DEATH_CLOUD, true); - if (Creature* madrigosa = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_MADRIGOSA))) - madrigosa->AI()->DoAction(ACTION_SPAWN_FELMYST); - } - - void AttackStart(Unit* who) override - { - if (who->GetEntry() == NPC_MADRIGOSA) - return; - BossAI::AttackStart(who); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_SPELL_SLASH: - me->CastSpell(me->GetVictim(), SPELL_METEOR_SLASH, false); - events.ScheduleEvent(EVENT_SPELL_SLASH, 10000); - break; - case EVENT_SPELL_STOMP: - me->CastSpell(me->GetVictim(), SPELL_STOMP, false); - Talk(YELL_LOVE); - events.ScheduleEvent(EVENT_SPELL_STOMP, 30000); - break; - case EVENT_SPELL_BURN: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true, true, -SPELL_BURN_DAMAGE)) - me->CastSpell(target, SPELL_BURN, false); - events.ScheduleEvent(EVENT_SPELL_BURN, 60000); - break; - case EVENT_SPELL_BERSERK: - me->CastSpell(me, SPELL_BERSERK, true); - Talk(YELL_BERSERK); - break; - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetSunwellPlateauAI(creature); + DoMeleeAttackIfReady(); } }; @@ -210,203 +199,192 @@ enum eMadrigosa SPELL_BRUTALLUS_BREAK_ICE = 46637, }; -class npc_madrigosa : public CreatureScript +struct npc_madrigosa : public NullCreatureAI { -public: - npc_madrigosa() : CreatureScript("npc_madrigosa") { } - - struct npc_madrigosaAI : public NullCreatureAI + npc_madrigosa(Creature* creature) : NullCreatureAI(creature) { - npc_madrigosaAI(Creature* creature) : NullCreatureAI(creature) - { - instance = creature->GetInstanceScript(); - bool appear = instance->GetBossState(DATA_BRUTALLUS) != DONE && instance->GetBossState(DATA_MADRIGOSA) == DONE; - creature->SetVisible(appear); - creature->SetStandState(UNIT_STAND_STATE_DEAD); - creature->SetDynamicFlag(UNIT_DYNFLAG_DEAD); - } + instance = creature->GetInstanceScript(); + bool appear = instance->GetBossState(DATA_BRUTALLUS) != DONE && instance->GetBossState(DATA_MADRIGOSA) == DONE; + creature->SetVisible(appear); + creature->SetStandState(UNIT_STAND_STATE_DEAD); + creature->SetDynamicFlag(UNIT_DYNFLAG_DEAD); + } - EventMap events; - InstanceScript* instance; + EventMap events; + InstanceScript* instance; - void DoAction(int32 param) override - { - if (param == ACTION_START_EVENT) - { - me->SetDisableGravity(true); - me->SetStandState(UNIT_STAND_STATE_STAND); - me->RemoveDynamicFlag(UNIT_DYNFLAG_DEAD); - me->NearTeleportTo(1570.97f, 725.51f, 79.77f, 3.82f); - events.ScheduleEvent(EVENT_MAD_1, 2000); - } - else if (param == ACTION_SPAWN_FELMYST) - events.ScheduleEvent(EVENT_SPAWN_FELMYST, 60000); - } - - void UpdateAI(uint32 diff) override - { - events.Update(diff); - switch (events.ExecuteEvent()) - { - case EVENT_MAD_1: - me->SetVisible(true); - if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) - { - me->SetTarget(brutallus->GetGUID()); - brutallus->SetReactState(REACT_PASSIVE); - brutallus->setActive(true); - } - me->GetMotionMaster()->MovePoint(1, 1477.94f, 643.22f, 21.21f); - me->AddUnitState(UNIT_STATE_NO_ENVIRONMENT_UPD); - events.ScheduleEvent(EVENT_MAD_2, 6000); - break; - case EVENT_MAD_2: - Talk(SAY_MAD_1); - me->CastSpell(me, SPELL_MADRIGOSA_FREEZE, false); - events.ScheduleEvent(EVENT_MAD_2_1, 1000); - break; - case EVENT_MAD_2_1: - me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); - me->SetDisableGravity(false); - me->CastSpell(me, SPELL_MADRIGOSA_FROST_BREATH, false); - events.ScheduleEvent(EVENT_MAD_3, 7000); - break; - case EVENT_MAD_3: - Talk(SAY_MAD_2); - events.ScheduleEvent(EVENT_MAD_4, 7000); - break; - case EVENT_MAD_4: - if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) - brutallus->AI()->Talk(YELL_INTRO); - events.ScheduleEvent(EVENT_MAD_5, 5000); - break; - case EVENT_MAD_5: - if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) - { - brutallus->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_ATTACK1H); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_ATTACK1H); - } - events.ScheduleEvent(EVENT_MAD_6, 10000); - break; - case EVENT_MAD_6: - if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) - { - brutallus->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - } - me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); - me->SetDisableGravity(true); - events.ScheduleEvent(EVENT_MAD_7, 4000); - break; - case EVENT_MAD_7: - Talk(SAY_MAD_3); - me->CastSpell(me, SPELL_MADRIGOSA_FROST_BLAST, false); - events.ScheduleEvent(EVENT_MAD_8, 3000); - events.ScheduleEvent(EVENT_MAD_8, 5000); - events.ScheduleEvent(EVENT_MAD_8, 6500); - events.ScheduleEvent(EVENT_MAD_8, 7500); - events.ScheduleEvent(EVENT_MAD_8, 8500); - events.ScheduleEvent(EVENT_MAD_8, 9500); - events.ScheduleEvent(EVENT_MAD_9, 11000); - events.ScheduleEvent(EVENT_MAD_8, 12000); - events.ScheduleEvent(EVENT_MAD_8, 14000); - break; - case EVENT_MAD_8: - if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) - me->CastSpell(brutallus, SPELL_MADRIGOSA_FROSTBOLT, false); - break; - case EVENT_MAD_9: - if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) - { - brutallus->CastSpell(brutallus, SPELL_BRUTALLUS_FLAME_RING, true); - brutallus->RemoveAllAuras(); - brutallus->CastSpell(brutallus, SPELL_BRUTALLUS_FEL_FIREBALL, false); - brutallus->AI()->Talk(YELL_INTRO_BREAK_ICE); - } - events.ScheduleEvent(EVENT_MAD_11, 6000); - break; - //case EVENT_MAD_10: - case EVENT_MAD_11: - me->SetDisableGravity(false); - me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); - events.ScheduleEvent(EVENT_MAD_13, 2500); - break; - case EVENT_MAD_13: - Talk(SAY_MAD_4); - me->RemoveAllAuras(); - me->CastSpell(me, SPELL_MADRIGOSA_ENCAPSULATE, false); - events.ScheduleEvent(EVENT_MAD_14, 2000); - break; - case EVENT_MAD_14: - if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) - { - brutallus->SetDisableGravity(true); - brutallus->GetMotionMaster()->MovePoint(0, brutallus->GetPositionX(), brutallus->GetPositionY() - 30.0f, brutallus->GetPositionZ() + 15.0f, false, true); - } - events.ScheduleEvent(EVENT_MAD_15, 10000); - break; - case EVENT_MAD_15: - if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) - { - brutallus->RemoveAllAuras(); - brutallus->SetDisableGravity(false); - brutallus->GetMotionMaster()->MoveFall(); - brutallus->AI()->Talk(YELL_INTRO_CHARGE); - } - events.ScheduleEvent(EVENT_MAD_16, 1400); - break; - case EVENT_MAD_16: - if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) - brutallus->CastSpell(me, SPELL_BRUTALLUS_CHARGE, true); - events.ScheduleEvent(EVENT_MAD_17, 1200); - break; - case EVENT_MAD_17: - if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) - brutallus->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK1H); - events.ScheduleEvent(EVENT_MAD_18, 500); - break; - case EVENT_MAD_18: - Talk(SAY_MAD_5); - me->SetDynamicFlag(UNIT_DYNFLAG_DEAD); - me->SetStandState(UNIT_STAND_STATE_DEAD); - events.ScheduleEvent(EVENT_MAD_19, 6000); - break; - case EVENT_MAD_19: - if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) - brutallus->AI()->Talk(YELL_INTRO_KILL_MADRIGOSA); - events.ScheduleEvent(EVENT_MAD_20, 7000); - break; - case EVENT_MAD_20: - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->SetFaction(FACTION_FRIENDLY); - if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) - { - brutallus->AI()->Talk(YELL_INTRO_TAUNT); - brutallus->CastSpell(brutallus, SPELL_BRUTALLUS_BREAK_ICE, false); - } - events.ScheduleEvent(EVENT_MAD_21, 4000); - break; - case EVENT_MAD_21: - if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) - { - brutallus->SetReactState(REACT_AGGRESSIVE); - brutallus->SetHealth(brutallus->GetMaxHealth()); - brutallus->AI()->EnterEvadeMode(); - brutallus->setActive(false); - } - break; - case EVENT_SPAWN_FELMYST: - me->DespawnOrUnsummon(1); - if (Creature* felmyst = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_FELMYST))) - felmyst->AI()->DoAction(ACTION_START_EVENT); - break; - } - } - }; - - CreatureAI* GetAI(Creature* creature) const override + void DoAction(int32 param) override { - return GetSunwellPlateauAI(creature); + if (param == ACTION_START_EVENT) + { + me->SetDisableGravity(true); + me->SetStandState(UNIT_STAND_STATE_STAND); + me->RemoveDynamicFlag(UNIT_DYNFLAG_DEAD); + me->NearTeleportTo(1570.97f, 725.51f, 79.77f, 3.82f); + events.ScheduleEvent(EVENT_MAD_1, 2000); + } + else if (param == ACTION_SPAWN_FELMYST) + events.ScheduleEvent(EVENT_SPAWN_FELMYST, 60000); + } + + void UpdateAI(uint32 diff) override + { + events.Update(diff); + switch (events.ExecuteEvent()) + { + case EVENT_MAD_1: + me->SetVisible(true); + if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) + { + me->SetTarget(brutallus->GetGUID()); + brutallus->SetReactState(REACT_PASSIVE); + brutallus->setActive(true); + } + me->GetMotionMaster()->MovePoint(1, 1477.94f, 643.22f, 21.21f); + me->AddUnitState(UNIT_STATE_NO_ENVIRONMENT_UPD); + events.ScheduleEvent(EVENT_MAD_2, 6000); + break; + case EVENT_MAD_2: + Talk(SAY_MAD_1); + me->CastSpell(me, SPELL_MADRIGOSA_FREEZE, false); + events.ScheduleEvent(EVENT_MAD_2_1, 1000); + break; + case EVENT_MAD_2_1: + me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); + me->SetDisableGravity(false); + me->CastSpell(me, SPELL_MADRIGOSA_FROST_BREATH, false); + events.ScheduleEvent(EVENT_MAD_3, 7000); + break; + case EVENT_MAD_3: + Talk(SAY_MAD_2); + events.ScheduleEvent(EVENT_MAD_4, 7000); + break; + case EVENT_MAD_4: + if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) + brutallus->AI()->Talk(YELL_INTRO); + events.ScheduleEvent(EVENT_MAD_5, 5000); + break; + case EVENT_MAD_5: + if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) + { + brutallus->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_ATTACK1H); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_ATTACK1H); + } + events.ScheduleEvent(EVENT_MAD_6, 10000); + break; + case EVENT_MAD_6: + if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) + { + brutallus->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + } + me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + me->SetDisableGravity(true); + events.ScheduleEvent(EVENT_MAD_7, 4000); + break; + case EVENT_MAD_7: + Talk(SAY_MAD_3); + me->CastSpell(me, SPELL_MADRIGOSA_FROST_BLAST, false); + events.ScheduleEvent(EVENT_MAD_8, 3000); + events.ScheduleEvent(EVENT_MAD_8, 5000); + events.ScheduleEvent(EVENT_MAD_8, 6500); + events.ScheduleEvent(EVENT_MAD_8, 7500); + events.ScheduleEvent(EVENT_MAD_8, 8500); + events.ScheduleEvent(EVENT_MAD_8, 9500); + events.ScheduleEvent(EVENT_MAD_9, 11000); + events.ScheduleEvent(EVENT_MAD_8, 12000); + events.ScheduleEvent(EVENT_MAD_8, 14000); + break; + case EVENT_MAD_8: + if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) + me->CastSpell(brutallus, SPELL_MADRIGOSA_FROSTBOLT, false); + break; + case EVENT_MAD_9: + if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) + { + brutallus->CastSpell(brutallus, SPELL_BRUTALLUS_FLAME_RING, true); + brutallus->RemoveAllAuras(); + brutallus->CastSpell(brutallus, SPELL_BRUTALLUS_FEL_FIREBALL, false); + brutallus->AI()->Talk(YELL_INTRO_BREAK_ICE); + } + events.ScheduleEvent(EVENT_MAD_11, 6000); + break; + //case EVENT_MAD_10: + case EVENT_MAD_11: + me->SetDisableGravity(false); + me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); + events.ScheduleEvent(EVENT_MAD_13, 2500); + break; + case EVENT_MAD_13: + Talk(SAY_MAD_4); + me->RemoveAllAuras(); + me->CastSpell(me, SPELL_MADRIGOSA_ENCAPSULATE, false); + events.ScheduleEvent(EVENT_MAD_14, 2000); + break; + case EVENT_MAD_14: + if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) + { + brutallus->SetDisableGravity(true); + brutallus->GetMotionMaster()->MovePoint(0, brutallus->GetPositionX(), brutallus->GetPositionY() - 30.0f, brutallus->GetPositionZ() + 15.0f, false, true); + } + events.ScheduleEvent(EVENT_MAD_15, 10000); + break; + case EVENT_MAD_15: + if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) + { + brutallus->RemoveAllAuras(); + brutallus->SetDisableGravity(false); + brutallus->GetMotionMaster()->MoveFall(); + brutallus->AI()->Talk(YELL_INTRO_CHARGE); + } + events.ScheduleEvent(EVENT_MAD_16, 1400); + break; + case EVENT_MAD_16: + if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) + brutallus->CastSpell(me, SPELL_BRUTALLUS_CHARGE, true); + events.ScheduleEvent(EVENT_MAD_17, 1200); + break; + case EVENT_MAD_17: + if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) + brutallus->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK1H); + events.ScheduleEvent(EVENT_MAD_18, 500); + break; + case EVENT_MAD_18: + Talk(SAY_MAD_5); + me->SetDynamicFlag(UNIT_DYNFLAG_DEAD); + me->SetStandState(UNIT_STAND_STATE_DEAD); + events.ScheduleEvent(EVENT_MAD_19, 6000); + break; + case EVENT_MAD_19: + if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) + brutallus->AI()->Talk(YELL_INTRO_KILL_MADRIGOSA); + events.ScheduleEvent(EVENT_MAD_20, 7000); + break; + case EVENT_MAD_20: + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + me->SetFaction(FACTION_FRIENDLY); + if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) + { + brutallus->AI()->Talk(YELL_INTRO_TAUNT); + brutallus->CastSpell(brutallus, SPELL_BRUTALLUS_BREAK_ICE, false); + } + events.ScheduleEvent(EVENT_MAD_21, 4000); + break; + case EVENT_MAD_21: + if (Creature* brutallus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRUTALLUS))) + { + brutallus->SetReactState(REACT_AGGRESSIVE); + brutallus->SetHealth(brutallus->GetMaxHealth()); + brutallus->AI()->EnterEvadeMode(); + brutallus->setActive(false); + } + break; + case EVENT_SPAWN_FELMYST: + me->DespawnOrUnsummon(1); + if (Creature* felmyst = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_FELMYST))) + felmyst->AI()->DoAction(ACTION_START_EVENT); + break; + } } }; @@ -519,8 +497,8 @@ public: void AddSC_boss_brutallus() { - new boss_brutallus(); - new npc_madrigosa(); + RegisterSunwellPlateauCreatureAI(boss_brutallus); + RegisterSunwellPlateauCreatureAI(npc_madrigosa); RegisterSpellScript(spell_madrigosa_activate_barrier); RegisterSpellScript(spell_madrigosa_deactivate_barrier); RegisterSpellScript(spell_brutallus_burn); diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp index 88375cdde..b3751e427 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp @@ -82,290 +82,268 @@ enum Misc EVENT_SPELL_FLAME_SEAR = 9 }; -class boss_sacrolash : public CreatureScript +struct boss_sacrolash : public BossAI { -public: - boss_sacrolash() : CreatureScript("boss_sacrolash") { } + boss_sacrolash(Creature* creature) : BossAI(creature, DATA_EREDAR_TWINS) {} - struct boss_sacrolashAI : public BossAI + bool sisterDied; + void Reset() override { - boss_sacrolashAI(Creature* creature) : BossAI(creature, DATA_EREDAR_TWINS) {} + me->CastSpell(me, SPELL_SHADOWFORM, true); + sisterDied = false; + BossAI::Reset(); + me->SetLootMode(0); + } - bool sisterDied; - void Reset() override + void DoAction(int32 param) override + { + if (param == ACTION_SISTER_DIED) { - me->CastSpell(me, SPELL_SHADOWFORM, true); - sisterDied = false; - BossAI::Reset(); - me->SetLootMode(0); + me->ResetLootMode(); + sisterDied = true; + Talk(YELL_SISTER_ALYTHESS_DEAD); + me->CastSpell(me, SPELL_EMPOWER, true); + + uint32 timer = events.GetNextEventTime(EVENT_SPELL_SHADOW_NOVA); + events.CancelEvent(EVENT_SPELL_SHADOW_NOVA); + events.ScheduleEvent(EVENT_SPELL_CONFLAGRATION, timer - events.GetTimer()); } + } - void DoAction(int32 param) override + void EnterEvadeMode(EvadeReason why) override + { + BossAI::EnterEvadeMode(why); + if (Creature* alythess = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_GRAND_WARLOCK_ALYTHESS))) { - if (param == ACTION_SISTER_DIED) - { - me->ResetLootMode(); - sisterDied = true; - Talk(YELL_SISTER_ALYTHESS_DEAD); - me->CastSpell(me, SPELL_EMPOWER, true); - - uint32 timer = events.GetNextEventTime(EVENT_SPELL_SHADOW_NOVA); - events.CancelEvent(EVENT_SPELL_SHADOW_NOVA); - events.ScheduleEvent(EVENT_SPELL_CONFLAGRATION, timer - events.GetTimer()); - } + if (!alythess->IsAlive()) + alythess->Respawn(true); + else if (!alythess->IsInEvadeMode()) + alythess->AI()->EnterEvadeMode(why); } + } - void EnterEvadeMode(EvadeReason why) override + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + if (Creature* alythess = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_GRAND_WARLOCK_ALYTHESS))) + if (alythess->IsAlive() && !alythess->IsInCombat()) + alythess->AI()->AttackStart(who); + + events.ScheduleEvent(EVENT_SPELL_SHADOW_BLADES, 10000); + events.ScheduleEvent(EVENT_SPELL_SHADOW_NOVA, 36000); + events.ScheduleEvent(EVENT_SPELL_CONFOUNDING_BLOW, 25000); + events.ScheduleEvent(EVENT_SHADOW_IMAGE, 20000); + events.ScheduleEvent(EVENT_SPELL_ENRAGE, 360000); + } + + void KilledUnit(Unit* victim) override + { + if (victim->IsPlayer() && urand(0, 1)) + Talk(YELL_SAC_KILL); + } + + void JustDied(Unit* /*killer*/) override + { + events.Reset(); + summons.DespawnAll(); + + if (sisterDied) { - BossAI::EnterEvadeMode(why); - if (Creature* alythess = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_GRAND_WARLOCK_ALYTHESS))) - { - if (!alythess->IsAlive()) - alythess->Respawn(true); - else if (!alythess->IsInEvadeMode()) - alythess->AI()->EnterEvadeMode(why); - } + Talk(YELL_SAC_DEAD); + instance->SetBossState(DATA_EREDAR_TWINS, DONE); } + else if (Creature* alythess = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_GRAND_WARLOCK_ALYTHESS))) + alythess->AI()->DoAction(ACTION_SISTER_DIED); + } - void JustEngagedWith(Unit* who) override + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true)) { - BossAI::JustEngagedWith(who); - if (Creature* alythess = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_GRAND_WARLOCK_ALYTHESS))) - if (alythess->IsAlive() && !alythess->IsInCombat()) - alythess->AI()->AttackStart(who); + summon->AI()->AttackStart(target); + summon->AddThreat(target, 10000000); + } + } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_SPELL_ENRAGE: + Talk(YELL_ENRAGE); + me->CastSpell(me, SPELL_ENRAGE, true); + break; + case EVENT_SPELL_CONFOUNDING_BLOW: + me->CastSpell(me->GetVictim(), SPELL_CONFOUNDING_BLOW, false); + events.ScheduleEvent(EVENT_SPELL_CONFOUNDING_BLOW, urand(20000, 25000)); + break; + case EVENT_SPELL_SHADOW_BLADES: + me->CastSpell(me, SPELL_SHADOW_BLADES, false); events.ScheduleEvent(EVENT_SPELL_SHADOW_BLADES, 10000); - events.ScheduleEvent(EVENT_SPELL_SHADOW_NOVA, 36000); - events.ScheduleEvent(EVENT_SPELL_CONFOUNDING_BLOW, 25000); - events.ScheduleEvent(EVENT_SHADOW_IMAGE, 20000); - events.ScheduleEvent(EVENT_SPELL_ENRAGE, 360000); - } - - void KilledUnit(Unit* victim) override + break; + case EVENT_SPELL_SHADOW_NOVA: { - if (victim->IsPlayer() && urand(0, 1)) - Talk(YELL_SAC_KILL); + Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 1, 100.0f); + if (!target) + target = me->GetVictim(); + Talk(EMOTE_SHADOW_NOVA, target); + Talk(YELL_SHADOW_NOVA); + me->CastSpell(target, SPELL_SHADOW_NOVA, false); + events.ScheduleEvent(EVENT_SPELL_SHADOW_NOVA, urand(30000, 35000)); + break; } - - void JustDied(Unit* /*killer*/) override + case EVENT_SHADOW_IMAGE: + me->SummonCreature(NPC_SHADOW_IMAGE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 12000); + events.ScheduleEvent(EVENT_SHADOW_IMAGE, 6000); + break; + case EVENT_SPELL_CONFLAGRATION: { - events.Reset(); - summons.DespawnAll(); - - if (sisterDied) - { - Talk(YELL_SAC_DEAD); - instance->SetBossState(DATA_EREDAR_TWINS, DONE); - } - else if (Creature* alythess = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_GRAND_WARLOCK_ALYTHESS))) - alythess->AI()->DoAction(ACTION_SISTER_DIED); + Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 1, 100.0f); + if (!target) + target = me->GetVictim(); + me->CastSpell(target, SPELL_CONFLAGRATION, false); + events.ScheduleEvent(EVENT_SPELL_CONFLAGRATION, urand(30000, 35000)); + break; + } } - void JustSummoned(Creature* summon) override - { - summons.Summon(summon); - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true)) - { - summon->AI()->AttackStart(target); - summon->AddThreat(target, 10000000); - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_SPELL_ENRAGE: - Talk(YELL_ENRAGE); - me->CastSpell(me, SPELL_ENRAGE, true); - break; - case EVENT_SPELL_CONFOUNDING_BLOW: - me->CastSpell(me->GetVictim(), SPELL_CONFOUNDING_BLOW, false); - events.ScheduleEvent(EVENT_SPELL_CONFOUNDING_BLOW, urand(20000, 25000)); - break; - case EVENT_SPELL_SHADOW_BLADES: - me->CastSpell(me, SPELL_SHADOW_BLADES, false); - events.ScheduleEvent(EVENT_SPELL_SHADOW_BLADES, 10000); - break; - case EVENT_SPELL_SHADOW_NOVA: - { - Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 1, 100.0f); - if (!target) - target = me->GetVictim(); - Talk(EMOTE_SHADOW_NOVA, target); - Talk(YELL_SHADOW_NOVA); - me->CastSpell(target, SPELL_SHADOW_NOVA, false); - events.ScheduleEvent(EVENT_SPELL_SHADOW_NOVA, urand(30000, 35000)); - break; - } - case EVENT_SHADOW_IMAGE: - me->SummonCreature(NPC_SHADOW_IMAGE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 12000); - events.ScheduleEvent(EVENT_SHADOW_IMAGE, 6000); - break; - case EVENT_SPELL_CONFLAGRATION: - { - Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 1, 100.0f); - if (!target) - target = me->GetVictim(); - me->CastSpell(target, SPELL_CONFLAGRATION, false); - events.ScheduleEvent(EVENT_SPELL_CONFLAGRATION, urand(30000, 35000)); - break; - } - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetSunwellPlateauAI(creature); - }; + DoMeleeAttackIfReady(); + } }; -class boss_alythess : public CreatureScript +struct boss_alythess : public BossAI { -public: - boss_alythess() : CreatureScript("boss_alythess") { } + boss_alythess(Creature* creature) : BossAI(creature, DATA_EREDAR_TWINS) { } - struct boss_alythessAI : public BossAI + bool sisterDied; + void Reset() override { - boss_alythessAI(Creature* creature) : BossAI(creature, DATA_EREDAR_TWINS) { } + me->CastSpell(me, SPELL_FIREFORM, true); + sisterDied = false; + BossAI::Reset(); + me->SetLootMode(0); + } - bool sisterDied; - void Reset() override + void DoAction(int32 param) override + { + if (param == ACTION_SISTER_DIED) { - me->CastSpell(me, SPELL_FIREFORM, true); - sisterDied = false; - BossAI::Reset(); - me->SetLootMode(0); + me->ResetLootMode(); + sisterDied = true; + Talk(YELL_SISTER_SACROLASH_DEAD); + me->CastSpell(me, SPELL_EMPOWER, true); + + uint32 timer = events.GetNextEventTime(EVENT_SPELL_CONFLAGRATION); + events.CancelEvent(EVENT_SPELL_CONFLAGRATION); + events.ScheduleEvent(EVENT_SPELL_SHADOW_NOVA, timer - events.GetTimer()); } + } - void DoAction(int32 param) override + void EnterEvadeMode(EvadeReason why) override + { + BossAI::EnterEvadeMode(why); + if (Creature* scorlash = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_LADY_SACROLASH))) { - if (param == ACTION_SISTER_DIED) - { - me->ResetLootMode(); - sisterDied = true; - Talk(YELL_SISTER_SACROLASH_DEAD); - me->CastSpell(me, SPELL_EMPOWER, true); - - uint32 timer = events.GetNextEventTime(EVENT_SPELL_CONFLAGRATION); - events.CancelEvent(EVENT_SPELL_CONFLAGRATION); - events.ScheduleEvent(EVENT_SPELL_SHADOW_NOVA, timer - events.GetTimer()); - } + if (!scorlash->IsAlive()) + scorlash->Respawn(true); + else if (!scorlash->IsInEvadeMode()) + scorlash->AI()->EnterEvadeMode(why); } + } - void EnterEvadeMode(EvadeReason why) override + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + if (Creature* scorlash = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_LADY_SACROLASH))) + if (scorlash->IsAlive() && !scorlash->IsInCombat()) + scorlash->AI()->AttackStart(who); + + events.ScheduleEvent(EVENT_SPELL_BLAZE, 100); + events.ScheduleEvent(EVENT_SPELL_PYROGENICS, 15000); + events.ScheduleEvent(EVENT_SPELL_FLAME_SEAR, 20000); + events.ScheduleEvent(EVENT_SPELL_CONFLAGRATION, 30000); + events.ScheduleEvent(EVENT_SPELL_ENRAGE, 360000); + } + + void KilledUnit(Unit* victim) override + { + if (victim->IsPlayer() && urand(0, 1)) + Talk(YELL_SAC_KILL); + } + + void JustDied(Unit* /*killer*/) override + { + events.Reset(); + summons.DespawnAll(); + + if (sisterDied) { - BossAI::EnterEvadeMode(why); - if (Creature* scorlash = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_LADY_SACROLASH))) - { - if (!scorlash->IsAlive()) - scorlash->Respawn(true); - else if (!scorlash->IsInEvadeMode()) - scorlash->AI()->EnterEvadeMode(why); - } + Talk(YELL_SAC_DEAD); + instance->SetBossState(DATA_EREDAR_TWINS, DONE); } + else if (Creature* scorlash = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_LADY_SACROLASH))) + scorlash->AI()->DoAction(ACTION_SISTER_DIED); + } - void JustEngagedWith(Unit* who) override + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { - BossAI::JustEngagedWith(who); - if (Creature* scorlash = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_LADY_SACROLASH))) - if (scorlash->IsAlive() && !scorlash->IsInCombat()) - scorlash->AI()->AttackStart(who); - - events.ScheduleEvent(EVENT_SPELL_BLAZE, 100); + case EVENT_SPELL_ENRAGE: + Talk(YELL_BERSERK); + me->CastSpell(me, SPELL_ENRAGE, true); + break; + case EVENT_SPELL_PYROGENICS: + me->CastSpell(me, SPELL_PYROGENICS, false); events.ScheduleEvent(EVENT_SPELL_PYROGENICS, 15000); - events.ScheduleEvent(EVENT_SPELL_FLAME_SEAR, 20000); - events.ScheduleEvent(EVENT_SPELL_CONFLAGRATION, 30000); - events.ScheduleEvent(EVENT_SPELL_ENRAGE, 360000); - } - - void KilledUnit(Unit* victim) override + break; + case EVENT_SPELL_FLAME_SEAR: + me->CastCustomSpell(SPELL_FLAME_SEAR, SPELLVALUE_MAX_TARGETS, 5, me, TRIGGERED_NONE); + events.ScheduleEvent(EVENT_SPELL_FLAME_SEAR, 15000); + break; + case EVENT_SPELL_BLAZE: + me->CastSpell(me->GetVictim(), SPELL_BLAZE, false); + events.ScheduleEvent(EVENT_SPELL_BLAZE, 3800); + break; + case EVENT_SPELL_SHADOW_NOVA: { - if (victim->IsPlayer() && urand(0, 1)) - Talk(YELL_SAC_KILL); + Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 1, 100.0f); + if (!target) + target = me->GetVictim(); + me->CastSpell(target, SPELL_SHADOW_NOVA, false); + events.ScheduleEvent(EVENT_SPELL_SHADOW_NOVA, urand(30000, 35000)); + break; } - - void JustDied(Unit* /*killer*/) override + case EVENT_SPELL_CONFLAGRATION: { - events.Reset(); - summons.DespawnAll(); - - if (sisterDied) - { - Talk(YELL_SAC_DEAD); - instance->SetBossState(DATA_EREDAR_TWINS, DONE); - } - else if (Creature* scorlash = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_LADY_SACROLASH))) - scorlash->AI()->DoAction(ACTION_SISTER_DIED); + Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 1, 100.0f); + if (!target) + target = me->GetVictim(); + Talk(EMOTE_CONFLAGRATION, target); + Talk(YELL_CANFLAGRATION); + me->CastSpell(target, SPELL_CONFLAGRATION, false); + events.ScheduleEvent(EVENT_SPELL_CONFLAGRATION, urand(30000, 35000)); + break; + } } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_SPELL_ENRAGE: - Talk(YELL_BERSERK); - me->CastSpell(me, SPELL_ENRAGE, true); - break; - case EVENT_SPELL_PYROGENICS: - me->CastSpell(me, SPELL_PYROGENICS, false); - events.ScheduleEvent(EVENT_SPELL_PYROGENICS, 15000); - break; - case EVENT_SPELL_FLAME_SEAR: - me->CastCustomSpell(SPELL_FLAME_SEAR, SPELLVALUE_MAX_TARGETS, 5, me, TRIGGERED_NONE); - events.ScheduleEvent(EVENT_SPELL_FLAME_SEAR, 15000); - break; - case EVENT_SPELL_BLAZE: - me->CastSpell(me->GetVictim(), SPELL_BLAZE, false); - events.ScheduleEvent(EVENT_SPELL_BLAZE, 3800); - break; - case EVENT_SPELL_SHADOW_NOVA: - { - Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 1, 100.0f); - if (!target) - target = me->GetVictim(); - me->CastSpell(target, SPELL_SHADOW_NOVA, false); - events.ScheduleEvent(EVENT_SPELL_SHADOW_NOVA, urand(30000, 35000)); - break; - } - case EVENT_SPELL_CONFLAGRATION: - { - Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 1, 100.0f); - if (!target) - target = me->GetVictim(); - Talk(EMOTE_CONFLAGRATION, target); - Talk(YELL_CANFLAGRATION); - me->CastSpell(target, SPELL_CONFLAGRATION, false); - events.ScheduleEvent(EVENT_SPELL_CONFLAGRATION, urand(30000, 35000)); - break; - } - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetSunwellPlateauAI(creature); - }; + DoMeleeAttackIfReady(); + } }; class spell_eredar_twins_apply_dark_touched : public SpellScript @@ -496,8 +474,8 @@ public: void AddSC_boss_eredar_twins() { - new boss_sacrolash(); - new boss_alythess(); + RegisterSunwellPlateauCreatureAI(boss_sacrolash); + RegisterSunwellPlateauCreatureAI(boss_alythess); RegisterSpellScript(spell_eredar_twins_apply_dark_touched); RegisterSpellScript(spell_eredar_twins_apply_flame_touched); RegisterSpellScript(spell_eredar_twins_handle_touch); diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp index 0187c46b3..ef67623da 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp @@ -126,356 +126,323 @@ private: Unit* _caster; }; -class boss_felmyst : public CreatureScript +struct boss_felmyst : public BossAI { -public: - boss_felmyst() : CreatureScript("boss_felmyst") { } - - struct boss_felmystAI : public BossAI + boss_felmyst(Creature* creature) : BossAI(creature, DATA_FELMYST) { - boss_felmystAI(Creature* creature) : BossAI(creature, DATA_FELMYST) - { - bool appear = instance->GetBossState(DATA_BRUTALLUS) == DONE; - creature->SetVisible(appear); - creature->SetStandState(UNIT_STAND_STATE_SLEEP); - creature->SetReactState(REACT_PASSIVE); - } + bool appear = instance->GetBossState(DATA_BRUTALLUS) == DONE; + creature->SetVisible(appear); + creature->SetStandState(UNIT_STAND_STATE_SLEEP); + creature->SetReactState(REACT_PASSIVE); + } - EventMap events2; + EventMap events2; - void DoAction(int32 param) override + void DoAction(int32 param) override + { + if (param == ACTION_START_EVENT) { - if (param == ACTION_START_EVENT) - { - me->SetVisible(true); - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - events2.ScheduleEvent(EVENT_INTRO_1, 3000); - } - } - - void Reset() override - { - BossAI::Reset(); - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->SetReactState(REACT_PASSIVE); - me->SetDisableGravity(false); - events2.Reset(); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_FOG_OF_CORRUPTION_CHARM); - } - - void JustEngagedWith(Unit* who) override - { - BossAI::JustEngagedWith(who); + me->SetVisible(true); me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - if (events.Empty() && events2.Empty()) - events2.ScheduleEvent(EVENT_INTRO_2, 3000); + events2.ScheduleEvent(EVENT_INTRO_1, 3000); } + } - void KilledUnit(Unit* victim) override - { - if (victim->IsPlayer() && roll_chance_i(50)) - Talk(YELL_KILL); - } - - void JustDied(Unit* killer) override - { - BossAI::JustDied(killer); - Talk(YELL_DEATH); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_FOG_OF_CORRUPTION_CHARM); - - // Summon Kalecgos (human form of kalecgos fight) - me->SummonCreature(NPC_KALEC, 1526.28f, 700.10f, 60.0f, 4.33f); - } - - void MovementInform(uint32 type, uint32 point) override - { - if (type != POINT_MOTION_TYPE) - return; - - if (point == POINT_GROUND) - { - me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); - me->SetDisableGravity(false); - me->SendMovementFlagUpdate(); - - events.ScheduleEvent(EVENT_RESTORE_COMBAT, 0); - events.ScheduleEvent(EVENT_RESTORE_COMBAT2, 1); - events.ScheduleEvent(EVENT_SPELL_CLEAVE, 7500, 1); - events.ScheduleEvent(EVENT_SPELL_CORROSION, 12000, 1); - events.ScheduleEvent(EVENT_SPELL_GAS_NOVA, 18000, 1); - events.ScheduleEvent(EVENT_SPELL_ENCAPSULATE, 25000, 1); - events.ScheduleEvent(EVENT_FLIGHT, 60000, 1); - } - else if (point == POINT_AIR_BREATH_START1) - { - me->SetTarget(); - me->SetFacingTo(4.71f); - events.ScheduleEvent(EVENT_FLIGHT_EMOTE, 2000); - events.ScheduleEvent(EVENT_CORRUPT_TRIGGERS, 5000); - events.ScheduleEvent(EVENT_FLIGHT_FLYOVER1, 5000); - } - else if (point == POINT_AIR_BREATH_END1) - { - me->RemoveAurasDueToSpell(SPELL_FELMYST_SPEED_BURST); - me->SetFacingTo(1.57f); - if (events.GetNextEventTime(EVENT_FLIGHT_BREATH1) != 0) - events.ScheduleEvent(EVENT_FLIGHT_BREATH2, 2000); - } - else if (point == POINT_AIR_BREATH_START2) - { - me->SetTarget(); - me->SetFacingTo(1.57f); - events.ScheduleEvent(EVENT_FLIGHT_EMOTE, 2000); - events.ScheduleEvent(EVENT_CORRUPT_TRIGGERS, 5000); - events.ScheduleEvent(EVENT_FLIGHT_FLYOVER2, 5000); - } - else if (point == POINT_AIR_BREATH_END2) - { - me->RemoveAurasDueToSpell(SPELL_FELMYST_SPEED_BURST); - me->SetFacingTo(4.71f); - } - } - - void JustSummoned(Creature* summon) override - { - summons.Summon(summon); - } - - void UpdateAI(uint32 diff) override - { - events2.Update(diff); - switch (events2.ExecuteEvent()) - { - case EVENT_INTRO_1: - me->SetStandState(UNIT_STAND_STATE_STAND); - events2.ScheduleEvent(EVENT_INTRO_2, 4000); - break; - case EVENT_INTRO_2: - Talk(YELL_BIRTH); - me->SetDisableGravity(true); - me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); - me->SendMovementFlagUpdate(); - events2.ScheduleEvent(EVENT_INTRO_3, 1500); - break; - case EVENT_INTRO_3: - me->GetMotionMaster()->MovePoint(POINT_AIR, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 10.0f, false, true); - events2.ScheduleEvent(EVENT_INTRO_4, 2000); - break; - case EVENT_INTRO_4: - events.ScheduleEvent(EVENT_LAND, 3000, 1); - events.ScheduleEvent(EVENT_SPELL_BERSERK, 600000); - me->SetInCombatWithZone(); - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->CastSpell(me, SPELL_NOXIOUS_FUMES, true); - me->GetMotionMaster()->MovePoint(POINT_MISC, 1472.18f, 603.38f, 34.0f, false, true); - break; - } - - if (!events2.Empty()) - return; - - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_RESTORE_COMBAT: - me->SetReactState(REACT_AGGRESSIVE); - break; - case EVENT_RESTORE_COMBAT2: - me->SetTarget(me->GetVictim()->GetGUID()); - me->GetMotionMaster()->MoveChase(me->GetVictim()); - break; - case EVENT_LAND: - me->GetMotionMaster()->MovePoint(POINT_GROUND, me->GetPositionX(), me->GetPositionY(), me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()), false, true); - break; - case EVENT_SPELL_BERSERK: - Talk(YELL_BERSERK); - me->CastSpell(me, SPELL_BERSERK, true); - break; - case EVENT_SPELL_CLEAVE: - me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false); - events.ScheduleEvent(EVENT_SPELL_CLEAVE, 7500, 1); - break; - case EVENT_SPELL_CORROSION: - me->CastSpell(me->GetVictim(), SPELL_CORROSION, false); - events.ScheduleEvent(EVENT_SPELL_CORROSION, 20000, 1); - break; - case EVENT_SPELL_GAS_NOVA: - DoCast(me, SPELL_GAS_NOVA, false); - events.ScheduleEvent(EVENT_SPELL_GAS_NOVA, 20000, 1); - break; - case EVENT_SPELL_ENCAPSULATE: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true)) - me->CastSpell(target, SPELL_ENCAPSULATE_CHANNEL, false); - events.ScheduleEvent(EVENT_SPELL_ENCAPSULATE, 25000, 1); - break; - case EVENT_FLIGHT: - events.CancelEventGroup(1); - events.ScheduleEvent(EVENT_FLIGHT_SEQ, 1000); - me->SetReactState(REACT_PASSIVE); - me->StopMoving(); - me->GetMotionMaster()->Clear(); - break; - case EVENT_FLIGHT_SEQ: - Talk(YELL_TAKEOFF); - me->SetTarget(); - me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); - me->SetDisableGravity(true); - me->SendMovementFlagUpdate(); - - events.ScheduleEvent(EVENT_FLIGHT_MOVE_UP, 2000); - events.ScheduleEvent(EVENT_FLIGHT_VAPOR, 8000); - events.ScheduleEvent(EVENT_FLIGHT_VAPOR, 21000); - events.ScheduleEvent(EVENT_FLIGHT_BREATH1, 35000); - events.ScheduleEvent(EVENT_FLIGHT_BREATH1, 72000); - events.ScheduleEvent(EVENT_LAND_FIGHT, 86000); - break; - case EVENT_FLIGHT_MOVE_UP: - me->GetMotionMaster()->MovePoint(POINT_AIR, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 15.0f, false, true); - break; - case EVENT_FLIGHT_VAPOR: - me->CastCustomSpell(SPELL_SUMMON_DEMONIC_VAPOR, SPELLVALUE_MAX_TARGETS, 1, me, true); - break; - case EVENT_FLIGHT_BREATH1: - { - Position pos = {1447.0f + urand(0, 2) * 25.0f, 705.0f, 50.0f, 4.71f}; - me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_START1, pos, false, true); - break; - } - case EVENT_FLIGHT_BREATH2: - { - Position pos = {1447.0f + urand(0, 2) * 25.0f, 515.0f, 50.0f, 1.57f}; - me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_START2, pos, false, true); - break; - } - case EVENT_FLIGHT_EMOTE: - Talk(EMOTE_BREATH); - break; - case EVENT_CORRUPT_TRIGGERS: - Talk(YELL_BREATH); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(0)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(500)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(1000)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(1500)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(2000)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(2500)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(3000)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(3500)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(4000)); - break; - case EVENT_FLIGHT_FLYOVER1: - me->CastSpell(me, SPELL_FELMYST_SPEED_BURST, true); - me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_END1, me->GetPositionX(), me->GetPositionY() - 200.0f, me->GetPositionZ() + 5.0f, false, true); - break; - case EVENT_FLIGHT_FLYOVER2: - me->CastSpell(me, SPELL_FELMYST_SPEED_BURST, true); - me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_END2, me->GetPositionX(), me->GetPositionY() + 200.0f, me->GetPositionZ() + 5.0f, false, true); - break; - case EVENT_LAND_FIGHT: - me->GetMotionMaster()->MovePoint(POINT_GROUND, 1500.0f, 552.8f, 26.52f, false, true); - break; - } - - if (!me->HasUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY)) - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override + void Reset() override { - return GetSunwellPlateauAI(creature); + BossAI::Reset(); + me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + me->SetReactState(REACT_PASSIVE); + me->SetDisableGravity(false); + events2.Reset(); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_FOG_OF_CORRUPTION_CHARM); + } + + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + if (events.Empty() && events2.Empty()) + events2.ScheduleEvent(EVENT_INTRO_2, 3000); + } + + void KilledUnit(Unit* victim) override + { + if (victim->IsPlayer() && roll_chance_i(50)) + Talk(YELL_KILL); + } + + void JustDied(Unit* killer) override + { + BossAI::JustDied(killer); + Talk(YELL_DEATH); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_FOG_OF_CORRUPTION_CHARM); + + // Summon Kalecgos (human form of kalecgos fight) + me->SummonCreature(NPC_KALEC, 1526.28f, 700.10f, 60.0f, 4.33f); + } + + void MovementInform(uint32 type, uint32 point) override + { + if (type != POINT_MOTION_TYPE) + return; + + if (point == POINT_GROUND) + { + me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); + me->SetDisableGravity(false); + me->SendMovementFlagUpdate(); + + events.ScheduleEvent(EVENT_RESTORE_COMBAT, 0); + events.ScheduleEvent(EVENT_RESTORE_COMBAT2, 1); + events.ScheduleEvent(EVENT_SPELL_CLEAVE, 7500, 1); + events.ScheduleEvent(EVENT_SPELL_CORROSION, 12000, 1); + events.ScheduleEvent(EVENT_SPELL_GAS_NOVA, 18000, 1); + events.ScheduleEvent(EVENT_SPELL_ENCAPSULATE, 25000, 1); + events.ScheduleEvent(EVENT_FLIGHT, 60000, 1); + } + else if (point == POINT_AIR_BREATH_START1) + { + me->SetTarget(); + me->SetFacingTo(4.71f); + events.ScheduleEvent(EVENT_FLIGHT_EMOTE, 2000); + events.ScheduleEvent(EVENT_CORRUPT_TRIGGERS, 5000); + events.ScheduleEvent(EVENT_FLIGHT_FLYOVER1, 5000); + } + else if (point == POINT_AIR_BREATH_END1) + { + me->RemoveAurasDueToSpell(SPELL_FELMYST_SPEED_BURST); + me->SetFacingTo(1.57f); + if (events.GetNextEventTime(EVENT_FLIGHT_BREATH1) != 0) + events.ScheduleEvent(EVENT_FLIGHT_BREATH2, 2000); + } + else if (point == POINT_AIR_BREATH_START2) + { + me->SetTarget(); + me->SetFacingTo(1.57f); + events.ScheduleEvent(EVENT_FLIGHT_EMOTE, 2000); + events.ScheduleEvent(EVENT_CORRUPT_TRIGGERS, 5000); + events.ScheduleEvent(EVENT_FLIGHT_FLYOVER2, 5000); + } + else if (point == POINT_AIR_BREATH_END2) + { + me->RemoveAurasDueToSpell(SPELL_FELMYST_SPEED_BURST); + me->SetFacingTo(4.71f); + } + } + + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + } + + void UpdateAI(uint32 diff) override + { + events2.Update(diff); + switch (events2.ExecuteEvent()) + { + case EVENT_INTRO_1: + me->SetStandState(UNIT_STAND_STATE_STAND); + events2.ScheduleEvent(EVENT_INTRO_2, 4000); + break; + case EVENT_INTRO_2: + Talk(YELL_BIRTH); + me->SetDisableGravity(true); + me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + me->SendMovementFlagUpdate(); + events2.ScheduleEvent(EVENT_INTRO_3, 1500); + break; + case EVENT_INTRO_3: + me->GetMotionMaster()->MovePoint(POINT_AIR, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 10.0f, false, true); + events2.ScheduleEvent(EVENT_INTRO_4, 2000); + break; + case EVENT_INTRO_4: + events.ScheduleEvent(EVENT_LAND, 3000, 1); + events.ScheduleEvent(EVENT_SPELL_BERSERK, 600000); + me->SetInCombatWithZone(); + me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + me->CastSpell(me, SPELL_NOXIOUS_FUMES, true); + me->GetMotionMaster()->MovePoint(POINT_MISC, 1472.18f, 603.38f, 34.0f, false, true); + break; + } + + if (!events2.Empty()) + return; + + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_RESTORE_COMBAT: + me->SetReactState(REACT_AGGRESSIVE); + break; + case EVENT_RESTORE_COMBAT2: + me->SetTarget(me->GetVictim()->GetGUID()); + me->GetMotionMaster()->MoveChase(me->GetVictim()); + break; + case EVENT_LAND: + me->GetMotionMaster()->MovePoint(POINT_GROUND, me->GetPositionX(), me->GetPositionY(), me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()), false, true); + break; + case EVENT_SPELL_BERSERK: + Talk(YELL_BERSERK); + me->CastSpell(me, SPELL_BERSERK, true); + break; + case EVENT_SPELL_CLEAVE: + me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false); + events.ScheduleEvent(EVENT_SPELL_CLEAVE, 7500, 1); + break; + case EVENT_SPELL_CORROSION: + me->CastSpell(me->GetVictim(), SPELL_CORROSION, false); + events.ScheduleEvent(EVENT_SPELL_CORROSION, 20000, 1); + break; + case EVENT_SPELL_GAS_NOVA: + DoCast(me, SPELL_GAS_NOVA, false); + events.ScheduleEvent(EVENT_SPELL_GAS_NOVA, 20000, 1); + break; + case EVENT_SPELL_ENCAPSULATE: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true)) + me->CastSpell(target, SPELL_ENCAPSULATE_CHANNEL, false); + events.ScheduleEvent(EVENT_SPELL_ENCAPSULATE, 25000, 1); + break; + case EVENT_FLIGHT: + events.CancelEventGroup(1); + events.ScheduleEvent(EVENT_FLIGHT_SEQ, 1000); + me->SetReactState(REACT_PASSIVE); + me->StopMoving(); + me->GetMotionMaster()->Clear(); + break; + case EVENT_FLIGHT_SEQ: + Talk(YELL_TAKEOFF); + me->SetTarget(); + me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + me->SetDisableGravity(true); + me->SendMovementFlagUpdate(); + + events.ScheduleEvent(EVENT_FLIGHT_MOVE_UP, 2000); + events.ScheduleEvent(EVENT_FLIGHT_VAPOR, 8000); + events.ScheduleEvent(EVENT_FLIGHT_VAPOR, 21000); + events.ScheduleEvent(EVENT_FLIGHT_BREATH1, 35000); + events.ScheduleEvent(EVENT_FLIGHT_BREATH1, 72000); + events.ScheduleEvent(EVENT_LAND_FIGHT, 86000); + break; + case EVENT_FLIGHT_MOVE_UP: + me->GetMotionMaster()->MovePoint(POINT_AIR, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 15.0f, false, true); + break; + case EVENT_FLIGHT_VAPOR: + me->CastCustomSpell(SPELL_SUMMON_DEMONIC_VAPOR, SPELLVALUE_MAX_TARGETS, 1, me, true); + break; + case EVENT_FLIGHT_BREATH1: + { + Position pos = { 1447.0f + urand(0, 2) * 25.0f, 705.0f, 50.0f, 4.71f }; + me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_START1, pos, false, true); + break; + } + case EVENT_FLIGHT_BREATH2: + { + Position pos = { 1447.0f + urand(0, 2) * 25.0f, 515.0f, 50.0f, 1.57f }; + me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_START2, pos, false, true); + break; + } + case EVENT_FLIGHT_EMOTE: + Talk(EMOTE_BREATH); + break; + case EVENT_CORRUPT_TRIGGERS: + Talk(YELL_BREATH); + me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(0)); + me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(500)); + me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(1000)); + me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(1500)); + me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(2000)); + me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(2500)); + me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(3000)); + me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(3500)); + me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(4000)); + break; + case EVENT_FLIGHT_FLYOVER1: + me->CastSpell(me, SPELL_FELMYST_SPEED_BURST, true); + me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_END1, me->GetPositionX(), me->GetPositionY() - 200.0f, me->GetPositionZ() + 5.0f, false, true); + break; + case EVENT_FLIGHT_FLYOVER2: + me->CastSpell(me, SPELL_FELMYST_SPEED_BURST, true); + me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_END2, me->GetPositionX(), me->GetPositionY() + 200.0f, me->GetPositionZ() + 5.0f, false, true); + break; + case EVENT_LAND_FIGHT: + me->GetMotionMaster()->MovePoint(POINT_GROUND, 1500.0f, 552.8f, 26.52f, false, true); + break; + } + + if (!me->HasUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY)) + DoMeleeAttackIfReady(); } }; -class npc_demonic_vapor : public CreatureScript +struct npc_demonic_vapor : public NullCreatureAI { -public: - npc_demonic_vapor() : CreatureScript("npc_demonic_vapor") { } + npc_demonic_vapor(Creature* creature) : NullCreatureAI(creature) { } - CreatureAI* GetAI(Creature* creature) const override + void Reset() override { - return GetSunwellPlateauAI(creature); + me->CastSpell(me, SPELL_DEMONIC_VAPOR_SPAWN_TRIGGER, true); + me->CastSpell(me, SPELL_DEMONIC_VAPOR_PERIODIC, true); } - struct npc_demonic_vaporAI : public NullCreatureAI + void UpdateAI(uint32 /*diff*/) override { - npc_demonic_vaporAI(Creature* creature) : NullCreatureAI(creature) { } - - void Reset() override + if (me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_CONTROLLED) == NULL_MOTION_TYPE) { - me->CastSpell(me, SPELL_DEMONIC_VAPOR_SPAWN_TRIGGER, true); - me->CastSpell(me, SPELL_DEMONIC_VAPOR_PERIODIC, true); - } - - void UpdateAI(uint32 /*diff*/) override - { - if (me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_CONTROLLED) == NULL_MOTION_TYPE) - { - Map::PlayerList const& players = me->GetMap()->GetPlayers(); - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - if (me->GetDistance2d(itr->GetSource()) < 20.0f && itr->GetSource()->IsAlive()) - { - me->GetMotionMaster()->MoveFollow(itr->GetSource(), 0.0f, 0.0f, MOTION_SLOT_CONTROLLED); - break; - } - } - } - }; -}; - -class npc_demonic_vapor_trail : public CreatureScript -{ -public: - npc_demonic_vapor_trail() : CreatureScript("npc_demonic_vapor_trail") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetSunwellPlateauAI(creature); - } - - struct npc_demonic_vapor_trailAI : public NullCreatureAI - { - npc_demonic_vapor_trailAI(Creature* creature) : NullCreatureAI(creature) - { - timer = 1; - } - - uint32 timer; - void Reset() override - { - me->CastSpell(me, SPELL_DEMONIC_VAPOR_TRAIL_PERIODIC, true); - } - - void SpellHitTarget(Unit*, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == SPELL_DEMONIC_VAPOR) - me->CastSpell(me, SPELL_SUMMON_BLAZING_DEAD, true); - } - - void UpdateAI(uint32 diff) override - { - if (timer) - { - timer += diff; - if (timer >= 6000) + Map::PlayerList const& players = me->GetMap()->GetPlayers(); + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + if (me->GetDistance2d(itr->GetSource()) < 20.0f && itr->GetSource()->IsAlive()) { - timer = 0; - me->CastSpell(me, SPELL_SUMMON_BLAZING_DEAD, true); + me->GetMotionMaster()->MoveFollow(itr->GetSource(), 0.0f, 0.0f, MOTION_SLOT_CONTROLLED); + break; } + } + } +}; + +struct npc_demonic_vapor_trail : public NullCreatureAI +{ + npc_demonic_vapor_trail(Creature* creature) : NullCreatureAI(creature) + { + timer = 1; + } + + uint32 timer; + void Reset() override + { + me->CastSpell(me, SPELL_DEMONIC_VAPOR_TRAIL_PERIODIC, true); + } + + void SpellHitTarget(Unit*, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_DEMONIC_VAPOR) + me->CastSpell(me, SPELL_SUMMON_BLAZING_DEAD, true); + } + + void UpdateAI(uint32 diff) override + { + if (timer) + { + timer += diff; + if (timer >= 6000) + { + timer = 0; + me->CastSpell(me, SPELL_SUMMON_BLAZING_DEAD, true); } } + } - void JustSummoned(Creature* summon) override - { - summon->SetInCombatWithZone(); - summon->AI()->AttackStart(summon->AI()->SelectTarget(SelectTargetMethod::Random, 0, 100.0f)); - } - }; + void JustSummoned(Creature* summon) override + { + summon->SetInCombatWithZone(); + summon->AI()->AttackStart(summon->AI()->SelectTarget(SelectTargetMethod::Random, 0, 100.0f)); + } }; class spell_felmyst_fog_of_corruption : public SpellScript @@ -558,9 +525,9 @@ class spell_felmyst_open_brutallus_back_doors : public SpellScript void AddSC_boss_felmyst() { - new boss_felmyst(); - new npc_demonic_vapor(); - new npc_demonic_vapor_trail(); + RegisterSunwellPlateauCreatureAI(boss_felmyst); + RegisterSunwellPlateauCreatureAI(npc_demonic_vapor); + RegisterSunwellPlateauCreatureAI(npc_demonic_vapor_trail); RegisterSpellScript(spell_felmyst_fog_of_corruption); RegisterSpellScript(spell_felmyst_fog_of_corruption_charm_aura); RegisterSpellScript(spell_felmyst_open_brutallus_back_doors); diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp index ea6b27523..92f91e14b 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp @@ -114,250 +114,239 @@ enum kalEvents #define DRAGON_REALM_Z 53.079f -class boss_kalecgos : public CreatureScript +struct boss_kalecgos : public BossAI { -public: - boss_kalecgos() : CreatureScript("boss_kalecgos") { } - - struct boss_kalecgosAI : public BossAI + boss_kalecgos(Creature* creature) : BossAI(creature, DATA_KALECGOS) { - boss_kalecgosAI(Creature* creature) : BossAI(creature, DATA_KALECGOS) + } + + bool sathBanished; + EventMap events2; + + bool CanAIAttack(Unit const* target) const override + { + return target->GetPositionZ() > 50.0f; + } + + void JustReachedHome() override + { + BossAI::JustReachedHome(); + me->SetVisible(true); + } + + void Reset() override + { + BossAI::Reset(); + me->SetHealth(me->GetMaxHealth()); + me->SetStandState(UNIT_STAND_STATE_SLEEP); + me->SetDisableGravity(false); + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + events2.Reset(); + + sathBanished = false; + ClearPlayerAuras(); + } + + void ClearPlayerAuras() const + { + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_CURSE_OF_BOUNDLESS_AGONY); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_CURSE_OF_BOUNDLESS_AGONY_PLR); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SPECTRAL_REALM); + } + + void DoAction(int32 param) override + { + if (param == ACTION_ENRAGE || param == ACTION_ENRAGE_OTHER) { + Talk(param == ACTION_ENRAGE ? SAY_KALEC_ENRAGE_SATH : SAY_SATH_ENRAGE_ME); + me->CastSpell(me, SPELL_CRAZED_RAGE, true); + events.CancelEvent(EVENT_CHECK_HEALTH); + return; } - - bool sathBanished; - EventMap events2; - - bool CanAIAttack(Unit const* target) const override + else if (param == ACTION_BANISH) { - return target->GetPositionZ() > 50.0f; + me->CastSpell(me, SPELL_BANISH, true); + events.Reset(); } - - void JustReachedHome() override + else if (param == ACTION_SATH_BANISH) + sathBanished = true; + else if (param == ACTION_KALEC_DIED) { - BossAI::JustReachedHome(); - me->SetVisible(true); - } - - void Reset() override - { - BossAI::Reset(); - me->SetHealth(me->GetMaxHealth()); - me->SetStandState(UNIT_STAND_STATE_SLEEP); - me->SetDisableGravity(false); - me->SetReactState(REACT_AGGRESSIVE); - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - events2.Reset(); - - sathBanished = false; + events.Reset(); + events2.ScheduleEvent(EVENT_TALK_BAD_1, 0); ClearPlayerAuras(); + return; } - void ClearPlayerAuras() const + if (me->HasAura(SPELL_BANISH) && sathBanished) { - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_CURSE_OF_BOUNDLESS_AGONY); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_CURSE_OF_BOUNDLESS_AGONY_PLR); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SPECTRAL_REALM); - } - - void DoAction(int32 param) override - { - if (param == ACTION_ENRAGE || param == ACTION_ENRAGE_OTHER) + events.Reset(); + events2.ScheduleEvent(EVENT_TALK_GOOD_1, 1000); + ClearPlayerAuras(); + if (Creature* Sath = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_SATHROVARR))) { - Talk(param == ACTION_ENRAGE ? SAY_KALEC_ENRAGE_SATH : SAY_SATH_ENRAGE_ME); - me->CastSpell(me, SPELL_CRAZED_RAGE, true); - events.CancelEvent(EVENT_CHECK_HEALTH); - return; - } - else if (param == ACTION_BANISH) - { - me->CastSpell(me, SPELL_BANISH, true); - events.Reset(); - } - else if (param == ACTION_SATH_BANISH) - sathBanished = true; - else if (param == ACTION_KALEC_DIED) - { - events.Reset(); - events2.ScheduleEvent(EVENT_TALK_BAD_1, 0); - ClearPlayerAuras(); - return; - } - - if (me->HasAura(SPELL_BANISH) && sathBanished) - { - events.Reset(); - events2.ScheduleEvent(EVENT_TALK_GOOD_1, 1000); - ClearPlayerAuras(); - if (Creature* Sath = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_SATHROVARR))) - { - Sath->RemoveAllAuras(); - Sath->GetMotionMaster()->MovementExpired(); - Sath->SetReactState(REACT_PASSIVE); - Sath->NearTeleportTo(1696.20f, 915.0f, DRAGON_REALM_Z, Sath->GetOrientation()); - } + Sath->RemoveAllAuras(); + Sath->GetMotionMaster()->MovementExpired(); + Sath->SetReactState(REACT_PASSIVE); + Sath->NearTeleportTo(1696.20f, 915.0f, DRAGON_REALM_Z, Sath->GetOrientation()); } } + } - void JustDied(Unit* killer) override - { - BossAI::JustDied(killer); - } - - void JustEngagedWith(Unit* who) override - { - BossAI::JustEngagedWith(who); - events.ScheduleEvent(EVENT_ARCANE_BUFFET, 6000); - events.ScheduleEvent(EVENT_FROST_BREATH, 15000); - events.ScheduleEvent(EVENT_WILD_MAGIC, 10000); - events.ScheduleEvent(EVENT_TAIL_LASH, 25000); - events.ScheduleEvent(EVENT_SPECTRAL_BLAST, 20000); - events.ScheduleEvent(EVENT_CHECK_POS, 5000); - events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000); - events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000); - events.ScheduleEvent(EVENT_SPAWN_SPECTRALS, 16000); - - me->SetStandState(UNIT_STAND_STATE_STAND); - Talk(SAY_EVIL_AGGRO); - } - - void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (damage >= me->GetHealth() && attacker != me) - damage = 0; - } - - void KilledUnit(Unit* victim) override - { - if (victim->IsPlayer() && roll_chance_i(50)) - Talk(SAY_EVIL_SLAY); - } - - void UpdateAI(uint32 diff) override - { - events2.Update(diff); - switch (events2.ExecuteEvent()) - { - case EVENT_TALK_GOOD_1: - me->SetRegeneratingHealth(false); - me->RemoveAllAuras(); - me->SetReactState(REACT_PASSIVE); - me->CombatStop(); - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->SetFaction(FACTION_FRIENDLY); - events2.ScheduleEvent(EVENT_TALK_GOOD_2, 1000); - break; - case EVENT_TALK_GOOD_2: - if (Creature* Sath = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_SATHROVARR))) - { - summons.Despawn(Sath); - Unit::Kill(me, Sath); - } - events2.ScheduleEvent(EVENT_TALK_GOOD_3, 8000); - break; - case EVENT_TALK_GOOD_3: - Talk(SAY_GOOD_PLRWIN); - events2.ScheduleEvent(EVENT_TALK_GOOD_4, 10000); - break; - case EVENT_TALK_GOOD_4: - me->SetDisableGravity(true); - me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); - events2.ScheduleEvent(EVENT_TALK_GOOD_5, 10000); - break; - case EVENT_TALK_GOOD_5: - me->SetVisible(false); - me->KillSelf(); - break; - case EVENT_TALK_BAD_1: - me->SetReactState(REACT_PASSIVE); - me->CombatStop(); - me->RemoveAllAuras(); - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - Talk(SAY_EVIL_ENRAGE); - events2.ScheduleEvent(EVENT_TALK_BAD_2, 3000); - break; - case EVENT_TALK_BAD_2: - me->SetDisableGravity(true); - me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); - events2.ScheduleEvent(EVENT_TALK_BAD_3, 15000); - break; - case EVENT_TALK_BAD_3: - me->SetVisible(false); - EnterEvadeMode(); - break; - } - - if (!events2.Empty()) - return; - - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_SPAWN_SPECTRALS: - me->SummonCreature(NPC_KALEC, 1702.21f, 931.7f, -74.56f, 5.07f, TEMPSUMMON_MANUAL_DESPAWN); - me->SummonCreature(NPC_SATHROVARR, 1704.62f, 927.78f, -73.9f, 2.0f, TEMPSUMMON_MANUAL_DESPAWN); - break; - case EVENT_ARCANE_BUFFET: - me->CastSpell(me, SPELL_ARCANE_BUFFET, false); - events.ScheduleEvent(EVENT_ARCANE_BUFFET, 8000); - break; - case EVENT_FROST_BREATH: - me->CastSpell(me->GetVictim(), SPELL_FROST_BREATH, false); - events.ScheduleEvent(EVENT_FROST_BREATH, 15000); - break; - case EVENT_TAIL_LASH: - me->CastSpell(me->GetVictim(), SPELL_TAIL_LASH, false); - events.ScheduleEvent(EVENT_TAIL_LASH, 15000); - break; - case EVENT_WILD_MAGIC: - me->CastCustomSpell(RAND(44978, 45001, 45002, 45004, 45006, 45010), SPELLVALUE_MAX_TARGETS, 1, me, false); - events.ScheduleEvent(EVENT_WILD_MAGIC, 20000); - break; - case EVENT_SPECTRAL_BLAST: - me->CastSpell(me, SPELL_SPECTRAL_BLAST, false); - events.ScheduleEvent(EVENT_SPECTRAL_BLAST, urand(15000, 25000)); - break; - case EVENT_CHECK_POS: - if (me->GetDistance(me->GetHomePosition()) > 50.0f) - { - EnterEvadeMode(); - return; - } - events.ScheduleEvent(EVENT_CHECK_POS, 5000); - break; - case EVENT_CHECK_HEALTH: - if (me->HealthBelowPct(10)) - { - if (Creature* Sath = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_SATHROVARR))) - Sath->AI()->DoAction(ACTION_ENRAGE_OTHER); - DoAction(ACTION_ENRAGE); - break; - } - events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000); - break; - case EVENT_CHECK_HEALTH2: - if (me->HealthBelowPct(1)) - { - DoAction(ACTION_BANISH); - break; - } - events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000); - break; - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override + void JustDied(Unit* killer) override { - return GetSunwellPlateauAI(creature); + BossAI::JustDied(killer); + } + + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + events.ScheduleEvent(EVENT_ARCANE_BUFFET, 6000); + events.ScheduleEvent(EVENT_FROST_BREATH, 15000); + events.ScheduleEvent(EVENT_WILD_MAGIC, 10000); + events.ScheduleEvent(EVENT_TAIL_LASH, 25000); + events.ScheduleEvent(EVENT_SPECTRAL_BLAST, 20000); + events.ScheduleEvent(EVENT_CHECK_POS, 5000); + events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000); + events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000); + events.ScheduleEvent(EVENT_SPAWN_SPECTRALS, 16000); + + me->SetStandState(UNIT_STAND_STATE_STAND); + Talk(SAY_EVIL_AGGRO); + } + + void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (damage >= me->GetHealth() && attacker != me) + damage = 0; + } + + void KilledUnit(Unit* victim) override + { + if (victim->IsPlayer() && roll_chance_i(50)) + Talk(SAY_EVIL_SLAY); + } + + void UpdateAI(uint32 diff) override + { + events2.Update(diff); + switch (events2.ExecuteEvent()) + { + case EVENT_TALK_GOOD_1: + me->SetRegeneratingHealth(false); + me->RemoveAllAuras(); + me->SetReactState(REACT_PASSIVE); + me->CombatStop(); + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + me->SetFaction(FACTION_FRIENDLY); + events2.ScheduleEvent(EVENT_TALK_GOOD_2, 1000); + break; + case EVENT_TALK_GOOD_2: + if (Creature* Sath = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_SATHROVARR))) + { + summons.Despawn(Sath); + Unit::Kill(me, Sath); + } + events2.ScheduleEvent(EVENT_TALK_GOOD_3, 8000); + break; + case EVENT_TALK_GOOD_3: + Talk(SAY_GOOD_PLRWIN); + events2.ScheduleEvent(EVENT_TALK_GOOD_4, 10000); + break; + case EVENT_TALK_GOOD_4: + me->SetDisableGravity(true); + me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + events2.ScheduleEvent(EVENT_TALK_GOOD_5, 10000); + break; + case EVENT_TALK_GOOD_5: + me->SetVisible(false); + me->KillSelf(); + break; + case EVENT_TALK_BAD_1: + me->SetReactState(REACT_PASSIVE); + me->CombatStop(); + me->RemoveAllAuras(); + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + Talk(SAY_EVIL_ENRAGE); + events2.ScheduleEvent(EVENT_TALK_BAD_2, 3000); + break; + case EVENT_TALK_BAD_2: + me->SetDisableGravity(true); + me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + events2.ScheduleEvent(EVENT_TALK_BAD_3, 15000); + break; + case EVENT_TALK_BAD_3: + me->SetVisible(false); + EnterEvadeMode(); + break; + } + + if (!events2.Empty()) + return; + + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_SPAWN_SPECTRALS: + me->SummonCreature(NPC_KALEC, 1702.21f, 931.7f, -74.56f, 5.07f, TEMPSUMMON_MANUAL_DESPAWN); + me->SummonCreature(NPC_SATHROVARR, 1704.62f, 927.78f, -73.9f, 2.0f, TEMPSUMMON_MANUAL_DESPAWN); + break; + case EVENT_ARCANE_BUFFET: + me->CastSpell(me, SPELL_ARCANE_BUFFET, false); + events.ScheduleEvent(EVENT_ARCANE_BUFFET, 8000); + break; + case EVENT_FROST_BREATH: + me->CastSpell(me->GetVictim(), SPELL_FROST_BREATH, false); + events.ScheduleEvent(EVENT_FROST_BREATH, 15000); + break; + case EVENT_TAIL_LASH: + me->CastSpell(me->GetVictim(), SPELL_TAIL_LASH, false); + events.ScheduleEvent(EVENT_TAIL_LASH, 15000); + break; + case EVENT_WILD_MAGIC: + me->CastCustomSpell(RAND(44978, 45001, 45002, 45004, 45006, 45010), SPELLVALUE_MAX_TARGETS, 1, me, false); + events.ScheduleEvent(EVENT_WILD_MAGIC, 20000); + break; + case EVENT_SPECTRAL_BLAST: + me->CastSpell(me, SPELL_SPECTRAL_BLAST, false); + events.ScheduleEvent(EVENT_SPECTRAL_BLAST, urand(15000, 25000)); + break; + case EVENT_CHECK_POS: + if (me->GetDistance(me->GetHomePosition()) > 50.0f) + { + EnterEvadeMode(); + return; + } + events.ScheduleEvent(EVENT_CHECK_POS, 5000); + break; + case EVENT_CHECK_HEALTH: + if (me->HealthBelowPct(10)) + { + if (Creature* Sath = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_SATHROVARR))) + Sath->AI()->DoAction(ACTION_ENRAGE_OTHER); + DoAction(ACTION_ENRAGE); + break; + } + events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000); + break; + case EVENT_CHECK_HEALTH2: + if (me->HealthBelowPct(1)) + { + DoAction(ACTION_BANISH); + break; + } + events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000); + break; + } + + DoMeleeAttackIfReady(); } }; @@ -371,255 +360,233 @@ enum Kalec EVENT_KALEC_SCENE_3 = 103 }; -class boss_kalec : public CreatureScript +struct boss_kalec : public ScriptedAI { -public: - boss_kalec() : CreatureScript("boss_kalec") { } + boss_kalec(Creature* creature) : ScriptedAI(creature) { } - CreatureAI* GetAI(Creature* creature) const override + EventMap events; + EventMap events2; + + void Reset() override { - return GetSunwellPlateauAI(creature); + events.Reset(); + events2.Reset(); + if (me->GetPositionY() < 750.0f) + { + me->SetSpeed(MOVE_RUN, 2.4f); + me->SetDisplayId(MODEL_KALECGOS_DRAGON); + me->SetDisableGravity(true); + me->GetMotionMaster()->MovePoint(0, 1483.30f, 657.99f, 28.0f, false, true); + events2.ScheduleEvent(EVENT_KALEC_SCENE_1, 9000); + events2.ScheduleEvent(EVENT_KALEC_SCENE_2, 16000); + events2.ScheduleEvent(EVENT_KALEC_SCENE_3, 22000); + } + else + me->CastSpell(me, SPELL_SPECTRAL_INVISIBILITY, true); } - struct boss_kalecAI : public ScriptedAI + void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override { - boss_kalecAI(Creature* creature) : ScriptedAI(creature) { } + if (!who || who->GetEntry() != NPC_SATHROVARR) + damage = 0; + } - EventMap events; - EventMap events2; + void JustEngagedWith(Unit*) override + { + events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000); + events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000); + events.ScheduleEvent(EVENT_SPELL_REVITALIZE, 5000); + events.ScheduleEvent(EVENT_SPELL_HEROIC_STRIKE, 3000); + Talk(SAY_GOOD_AGGRO); + } - void Reset() override + void JustDied(Unit*) override + { + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* kalecgos = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS))) + kalecgos->AI()->DoAction(ACTION_KALEC_DIED); + } + + void UpdateAI(uint32 diff) override + { + events2.Update(diff); + switch (events2.ExecuteEvent()) { - events.Reset(); - events2.Reset(); - if (me->GetPositionY() < 750.0f) + case EVENT_KALEC_SCENE_1: + Talk(SAY_GOOD_MADRIGOSA); + me->GetMotionMaster()->MovePoint(0, 1509.0f, 560.0f, 30.0f, false, true); + break; + case EVENT_KALEC_SCENE_2: + me->CastSpell(me, SPELL_OPEN_BRUTALLUS_BACK_DOOR, true); + me->GetInstanceScript()->SetBossState(DATA_FELMYST_DOORS, NOT_STARTED); + me->GetInstanceScript()->SetBossState(DATA_FELMYST_DOORS, DONE); + break; + case EVENT_KALEC_SCENE_3: + me->GetMotionMaster()->MovePoint(0, 1400.0f, 630.0f, 90.0f, false, true); + me->DespawnOrUnsummon(6000); + break; + } + + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_CHECK_HEALTH: + if (me->HealthBelowPct(50)) { - me->SetSpeed(MOVE_RUN, 2.4f); - me->SetDisplayId(MODEL_KALECGOS_DRAGON); - me->SetDisableGravity(true); - me->GetMotionMaster()->MovePoint(0, 1483.30f, 657.99f, 28.0f, false, true); - events2.ScheduleEvent(EVENT_KALEC_SCENE_1, 9000); - events2.ScheduleEvent(EVENT_KALEC_SCENE_2, 16000); - events2.ScheduleEvent(EVENT_KALEC_SCENE_3, 22000); + Talk(SAY_GOOD_NEAR_DEATH); + break; } - else - me->CastSpell(me, SPELL_SPECTRAL_INVISIBILITY, true); - } - - void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (!who || who->GetEntry() != NPC_SATHROVARR) - damage = 0; - } - - void JustEngagedWith(Unit*) override - { events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000); + break; + case EVENT_CHECK_HEALTH2: + if (me->HealthBelowPct(10)) + { + Talk(SAY_GOOD_NEAR_DEATH2); + break; + } events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000); - events.ScheduleEvent(EVENT_SPELL_REVITALIZE, 5000); - events.ScheduleEvent(EVENT_SPELL_HEROIC_STRIKE, 3000); - Talk(SAY_GOOD_AGGRO); + break; + case EVENT_SPELL_REVITALIZE: + me->CastSpell(me, SPELL_REVITALIZE, false); + events.ScheduleEvent(EVENT_SPELL_REVITALIZE, 10000); + break; + case EVENT_SPELL_HEROIC_STRIKE: + me->CastSpell(me->GetVictim(), SPELL_HEROIC_STRIKE, false); + events.ScheduleEvent(EVENT_SPELL_HEROIC_STRIKE, 5000); + break; } - void JustDied(Unit*) override - { - if (InstanceScript* instance = me->GetInstanceScript()) - if (Creature* kalecgos = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS))) - kalecgos->AI()->DoAction(ACTION_KALEC_DIED); - } - - void UpdateAI(uint32 diff) override - { - events2.Update(diff); - switch (events2.ExecuteEvent()) - { - case EVENT_KALEC_SCENE_1: - Talk(SAY_GOOD_MADRIGOSA); - me->GetMotionMaster()->MovePoint(0, 1509.0f, 560.0f, 30.0f, false, true); - break; - case EVENT_KALEC_SCENE_2: - me->CastSpell(me, SPELL_OPEN_BRUTALLUS_BACK_DOOR, true); - me->GetInstanceScript()->SetBossState(DATA_FELMYST_DOORS, NOT_STARTED); - me->GetInstanceScript()->SetBossState(DATA_FELMYST_DOORS, DONE); - break; - case EVENT_KALEC_SCENE_3: - me->GetMotionMaster()->MovePoint(0, 1400.0f, 630.0f, 90.0f, false, true); - me->DespawnOrUnsummon(6000); - break; - } - - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_CHECK_HEALTH: - if (me->HealthBelowPct(50)) - { - Talk(SAY_GOOD_NEAR_DEATH); - break; - } - events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000); - break; - case EVENT_CHECK_HEALTH2: - if (me->HealthBelowPct(10)) - { - Talk(SAY_GOOD_NEAR_DEATH2); - break; - } - events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000); - break; - case EVENT_SPELL_REVITALIZE: - me->CastSpell(me, SPELL_REVITALIZE, false); - events.ScheduleEvent(EVENT_SPELL_REVITALIZE, 10000); - break; - case EVENT_SPELL_HEROIC_STRIKE: - me->CastSpell(me->GetVictim(), SPELL_HEROIC_STRIKE, false); - events.ScheduleEvent(EVENT_SPELL_HEROIC_STRIKE, 5000); - break; - } - - DoMeleeAttackIfReady(); - } - }; + DoMeleeAttackIfReady(); + } }; -class boss_sathrovarr : public CreatureScript +struct boss_sathrovarr : public ScriptedAI { -public: - boss_sathrovarr() : CreatureScript("boss_sathrovarr") { } - - CreatureAI* GetAI(Creature* creature) const override + boss_sathrovarr(Creature* creature) : ScriptedAI(creature) { - return GetSunwellPlateauAI(creature); + instance = creature->GetInstanceScript(); } - struct boss_sathrovarrAI : public ScriptedAI + InstanceScript* instance; + EventMap events; + + bool CanAIAttack(Unit const* target) const override { - boss_sathrovarrAI(Creature* creature) : ScriptedAI(creature) + return target->GetPositionZ() < 50.0f; + } + + void Reset() override + { + events.Reset(); + me->CastSpell(me, SPELL_DEMONIC_VISUAL, true); + me->CastSpell(me, SPELL_SPECTRAL_INVISIBILITY, true); + + events.ScheduleEvent(EVENT_SHADOW_BOLT, 7000); + events.ScheduleEvent(EVENT_AGONY_CURSE, 20000); + events.ScheduleEvent(EVENT_CORRUPTION_STRIKE, 13000); + events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000); + events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000); + } + + void JustEngagedWith(Unit* /*who*/) override + { + Talk(SAY_SATH_AGGRO); + } + + void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (damage >= me->GetHealth() && who != me) + damage = 0; + } + + void KilledUnit(Unit* target) override + { + if (target->IsPlayer()) + Talk(SAY_SATH_SLAY); + } + + void JustDied(Unit* /*killer*/) override + { + Talk(SAY_SATH_DEATH); + } + + void DoAction(int32 param) override + { + if (param == ACTION_ENRAGE || param == ACTION_ENRAGE_OTHER) { - instance = creature->GetInstanceScript(); + me->CastSpell(me, SPELL_CRAZED_RAGE, true); + events.CancelEvent(EVENT_CHECK_HEALTH); } - - InstanceScript* instance; - EventMap events; - - bool CanAIAttack(Unit const* target) const override - { - return target->GetPositionZ() < 50.0f; - } - - void Reset() override + else if (param == ACTION_BANISH) { + me->CastSpell(me, SPELL_BANISH, true); events.Reset(); - me->CastSpell(me, SPELL_DEMONIC_VISUAL, true); - me->CastSpell(me, SPELL_SPECTRAL_INVISIBILITY, true); + } + } - events.ScheduleEvent(EVENT_SHADOW_BOLT, 7000); - events.ScheduleEvent(EVENT_AGONY_CURSE, 20000); - events.ScheduleEvent(EVENT_CORRUPTION_STRIKE, 13000); + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_SHADOW_BOLT: + if (roll_chance_i(20)) + Talk(SAY_SATH_SPELL1); + me->CastSpell(me->GetVictim(), SPELL_SHADOW_BOLT, false); + events.ScheduleEvent(EVENT_SHADOW_BOLT, 9000); + break; + case EVENT_AGONY_CURSE: + me->CastCustomSpell(SPELL_CURSE_OF_BOUNDLESS_AGONY, SPELLVALUE_MAX_TARGETS, 1, me, false); + events.ScheduleEvent(EVENT_AGONY_CURSE, 30000); + break; + case EVENT_CORRUPTION_STRIKE: + if (roll_chance_i(20)) + Talk(SAY_SATH_SPELL2); + me->CastSpell(me->GetVictim(), SPELL_CORRUPTION_STRIKE, false); + events.ScheduleEvent(EVENT_CORRUPTION_STRIKE, 9000); + break; + case EVENT_CHECK_HEALTH: + if (me->HealthBelowPct(10)) + { + if (InstanceScript* instanceScript = me->GetInstanceScript()) + { + if (Creature* kalecgos = ObjectAccessor::GetCreature(*me, instanceScript->GetGuidData( + NPC_KALECGOS))) + { + kalecgos->AI()->DoAction(ACTION_ENRAGE_OTHER); + } + } + DoAction(ACTION_ENRAGE); + break; + } events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000); + break; + case EVENT_CHECK_HEALTH2: + if (me->HealthBelowPct(1)) + { + if (Creature* kalecgos = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS))) + kalecgos->AI()->DoAction(ACTION_SATH_BANISH); + DoAction(ACTION_BANISH); + break; + } events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000); + break; } - void JustEngagedWith(Unit* /*who*/) override - { - Talk(SAY_SATH_AGGRO); - } - - void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (damage >= me->GetHealth() && who != me) - damage = 0; - } - - void KilledUnit(Unit* target) override - { - if (target->IsPlayer()) - Talk(SAY_SATH_SLAY); - } - - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_SATH_DEATH); - } - - void DoAction(int32 param) override - { - if (param == ACTION_ENRAGE || param == ACTION_ENRAGE_OTHER) - { - me->CastSpell(me, SPELL_CRAZED_RAGE, true); - events.CancelEvent(EVENT_CHECK_HEALTH); - } - else if (param == ACTION_BANISH) - { - me->CastSpell(me, SPELL_BANISH, true); - events.Reset(); - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_SHADOW_BOLT: - if (roll_chance_i(20)) - Talk(SAY_SATH_SPELL1); - me->CastSpell(me->GetVictim(), SPELL_SHADOW_BOLT, false); - events.ScheduleEvent(EVENT_SHADOW_BOLT, 9000); - break; - case EVENT_AGONY_CURSE: - me->CastCustomSpell(SPELL_CURSE_OF_BOUNDLESS_AGONY, SPELLVALUE_MAX_TARGETS, 1, me, false); - events.ScheduleEvent(EVENT_AGONY_CURSE, 30000); - break; - case EVENT_CORRUPTION_STRIKE: - if (roll_chance_i(20)) - Talk(SAY_SATH_SPELL2); - me->CastSpell(me->GetVictim(), SPELL_CORRUPTION_STRIKE, false); - events.ScheduleEvent(EVENT_CORRUPTION_STRIKE, 9000); - break; - case EVENT_CHECK_HEALTH: - if (me->HealthBelowPct(10)) - { - if (InstanceScript* instanceScript = me->GetInstanceScript()) - { - if (Creature *kalecgos = ObjectAccessor::GetCreature(*me, instanceScript->GetGuidData( - NPC_KALECGOS))) - { - kalecgos->AI()->DoAction(ACTION_ENRAGE_OTHER); - } - } - DoAction(ACTION_ENRAGE); - break; - } - events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000); - break; - case EVENT_CHECK_HEALTH2: - if (me->HealthBelowPct(1)) - { - if (Creature* kalecgos = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS))) - kalecgos->AI()->DoAction(ACTION_SATH_BANISH); - DoAction(ACTION_BANISH); - break; - } - events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000); - break; - } - - DoMeleeAttackIfReady(); - } - }; + DoMeleeAttackIfReady(); + } }; class SpectralBlastCheck @@ -750,9 +717,9 @@ class spell_kalecgos_spectral_realm_aura : public AuraScript void AddSC_boss_kalecgos() { - new boss_kalecgos(); - new boss_sathrovarr(); - new boss_kalec(); + RegisterSunwellPlateauCreatureAI(boss_kalecgos); + RegisterSunwellPlateauCreatureAI(boss_sathrovarr); + RegisterSunwellPlateauCreatureAI(boss_kalec); RegisterSpellScript(spell_kalecgos_spectral_blast_dummy); RegisterSpellScript(spell_kalecgos_curse_of_boundless_agony_aura); RegisterSpellScript(spell_kalecgos_spectral_realm_dummy); diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp index ecf69c19f..50d05cddb 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp @@ -163,511 +163,489 @@ private: Creature* _caster; }; -class npc_kiljaeden_controller : public CreatureScript +struct npc_kiljaeden_controller : public NullCreatureAI { -public: - npc_kiljaeden_controller() : CreatureScript("npc_kiljaeden_controller") { } - - CreatureAI* GetAI(Creature* creature) const override + npc_kiljaeden_controller(Creature* creature) : NullCreatureAI(creature), summons(me) { - return GetSunwellPlateauAI(creature); + instance = creature->GetInstanceScript(); } - struct npc_kiljaeden_controllerAI : public NullCreatureAI + EventMap events; + InstanceScript* instance; + SummonList summons; + + void ResetOrbs() { - npc_kiljaeden_controllerAI(Creature* creature) : NullCreatureAI(creature), summons(me) + for (uint8 i = 0; i < 4; ++i) + if (GameObject* orb = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_ORB_OF_THE_BLUE_DRAGONFLIGHT_1 + i))) + orb->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE); + } + + void Reset() override + { + instance->SetBossState(DATA_KILJAEDEN, NOT_STARTED); + events.Reset(); + summons.DespawnAll(); + ResetOrbs(); + + me->SummonCreature(NPC_HAND_OF_THE_DECEIVER, 1702.62f, 611.19f, 27.66f, 1.81f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); + me->SummonCreature(NPC_HAND_OF_THE_DECEIVER, 1684.099f, 618.848f, 27.67f, 0.589f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); + me->SummonCreature(NPC_HAND_OF_THE_DECEIVER, 1688.38f, 641.10f, 27.50f, 5.43f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); + me->SummonCreature(NPC_ANVEENA, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 40.0f, 0.0f); + + me->CastSpell(me, SPELL_DESTROY_ALL_DRAKES, true); + me->CastSpell(me, SPELL_ANVEENA_ENERGY_DRAIN, true); + events.ScheduleEvent(EVENT_RANDOM_TALK, 60000); + } + + void JustDied(Unit*) override + { + EntryCheckPredicate kilCheck(NPC_KILJAEDEN); + EntryCheckPredicate kalCheck(NPC_KALECGOS_KJ); + summons.DespawnIf(kilCheck); + summons.DoAction(ACTION_START_POST_EVENT, kalCheck); + summons.DespawnIf(kalCheck); + + me->CastSpell(me, SPELL_DESTROY_ALL_DRAKES, true); + summons.DespawnAll(); + } + + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + if (summon->GetEntry() == NPC_SINISTER_REFLECTION) + summon->SetInCombatWithZone(); + else if (summon->GetEntry() == NPC_KALECGOS_KJ) + summon->setActive(true); + } + + void SummonedCreatureDies(Creature* summon, Unit*) override + { + summons.Despawn(summon); + + if (summon->GetEntry() == NPC_HAND_OF_THE_DECEIVER) { - instance = creature->GetInstanceScript(); - } + instance->SetBossState(DATA_KILJAEDEN, IN_PROGRESS); + events.ScheduleEvent(EVENT_CHECK_PLAYERS, 1000); - EventMap events; - InstanceScript* instance; - SummonList summons; - - void ResetOrbs() - { - for (uint8 i = 0; i < 4; ++i) - if (GameObject* orb = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_ORB_OF_THE_BLUE_DRAGONFLIGHT_1 + i))) - orb->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE); - } - - void Reset() override - { - instance->SetBossState(DATA_KILJAEDEN, NOT_STARTED); - events.Reset(); - summons.DespawnAll(); - ResetOrbs(); - - me->SummonCreature(NPC_HAND_OF_THE_DECEIVER, 1702.62f, 611.19f, 27.66f, 1.81f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); - me->SummonCreature(NPC_HAND_OF_THE_DECEIVER, 1684.099f, 618.848f, 27.67f, 0.589f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); - me->SummonCreature(NPC_HAND_OF_THE_DECEIVER, 1688.38f, 641.10f, 27.50f, 5.43f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); - me->SummonCreature(NPC_ANVEENA, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 40.0f, 0.0f); - - me->CastSpell(me, SPELL_DESTROY_ALL_DRAKES, true); - me->CastSpell(me, SPELL_ANVEENA_ENERGY_DRAIN, true); - events.ScheduleEvent(EVENT_RANDOM_TALK, 60000); - } - - void JustDied(Unit*) override - { - EntryCheckPredicate kilCheck(NPC_KILJAEDEN); - EntryCheckPredicate kalCheck(NPC_KALECGOS_KJ); - summons.DespawnIf(kilCheck); - summons.DoAction(ACTION_START_POST_EVENT, kalCheck); - summons.DespawnIf(kalCheck); - - me->CastSpell(me, SPELL_DESTROY_ALL_DRAKES, true); - summons.DespawnAll(); - } - - void JustSummoned(Creature* summon) override - { - summons.Summon(summon); - if (summon->GetEntry() == NPC_SINISTER_REFLECTION) - summon->SetInCombatWithZone(); - else if (summon->GetEntry() == NPC_KALECGOS_KJ) - summon->setActive(true); - } - - void SummonedCreatureDies(Creature* summon, Unit*) override - { - summons.Despawn(summon); - - if (summon->GetEntry() == NPC_HAND_OF_THE_DECEIVER) + if (!summons.HasEntry(NPC_HAND_OF_THE_DECEIVER)) { - instance->SetBossState(DATA_KILJAEDEN, IN_PROGRESS); - events.ScheduleEvent(EVENT_CHECK_PLAYERS, 1000); - - if (!summons.HasEntry(NPC_HAND_OF_THE_DECEIVER)) - { - me->RemoveAurasDueToSpell(SPELL_ANVEENA_ENERGY_DRAIN); - me->SummonCreature(NPC_KILJAEDEN, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 1.5f, 4.3f, TEMPSUMMON_MANUAL_DESPAWN); - me->SummonCreature(NPC_KALECGOS_KJ, 1726.80f, 661.43f, 138.65f, 3.95f, TEMPSUMMON_MANUAL_DESPAWN); - } + me->RemoveAurasDueToSpell(SPELL_ANVEENA_ENERGY_DRAIN); + me->SummonCreature(NPC_KILJAEDEN, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 1.5f, 4.3f, TEMPSUMMON_MANUAL_DESPAWN); + me->SummonCreature(NPC_KALECGOS_KJ, 1726.80f, 661.43f, 138.65f, 3.95f, TEMPSUMMON_MANUAL_DESPAWN); } } + } - void UpdateAI(uint32 diff) override + void UpdateAI(uint32 diff) override + { + events.Update(diff); + switch (events.ExecuteEvent()) { - events.Update(diff); - switch (events.ExecuteEvent()) + case EVENT_RANDOM_TALK: + if (instance->GetBossState(DATA_KILJAEDEN) == NOT_STARTED) + Talk(SAY_KJ_OFFCOMBAT); + events.ScheduleEvent(EVENT_RANDOM_TALK, urand(90000, 180000)); + break; + case EVENT_CHECK_PLAYERS: { - case EVENT_RANDOM_TALK: - if (instance->GetBossState(DATA_KILJAEDEN) == NOT_STARTED) - Talk(SAY_KJ_OFFCOMBAT); - events.ScheduleEvent(EVENT_RANDOM_TALK, urand(90000, 180000)); - break; - case EVENT_CHECK_PLAYERS: - { - Map::PlayerList const& players = me->GetMap()->GetPlayers(); - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - if (Player* player = itr->GetSource()) - if (!player->IsGameMaster() && me->GetDistance2d(player) < 60.0f && player->IsAlive()) - { - events.ScheduleEvent(EVENT_CHECK_PLAYERS, 1000); - return; - } + Map::PlayerList const& players = me->GetMap()->GetPlayers(); + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + if (Player* player = itr->GetSource()) + if (!player->IsGameMaster() && me->GetDistance2d(player) < 60.0f && player->IsAlive()) + { + events.ScheduleEvent(EVENT_CHECK_PLAYERS, 1000); + return; + } - CreatureAI::EnterEvadeMode(); - break; - } + CreatureAI::EnterEvadeMode(); + break; } } - }; + } }; -class boss_kiljaeden : public CreatureScript +struct boss_kiljaeden : public ScriptedAI { -public: - boss_kiljaeden() : CreatureScript("boss_kiljaeden") { } - - struct boss_kiljaedenAI : public ScriptedAI + boss_kiljaeden(Creature* creature) : ScriptedAI(creature) { - boss_kiljaedenAI(Creature* creature) : ScriptedAI(creature) + instance = creature->GetInstanceScript(); + me->SetReactState(REACT_PASSIVE); + } + + InstanceScript* instance; + EventMap events; + EventMap events2; + uint8 phase; + + void InitializeAI() override + { + ScriptedAI::InitializeAI(); + me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + + phase = PHASE_NORMAL; + events.Reset(); + events2.Reset(); + events2.ScheduleEvent(EVENT_INIT_FIGHT, 11000); + events2.ScheduleEvent(EVENT_REBIRTH, 0); + me->SetVisible(false); + } + + void Reset() override + { + events.Reset(); + } + + void EnterEvadeMode(EvadeReason why) override + { + if (me->GetReactState() == REACT_PASSIVE) + return; + ScriptedAI::EnterEvadeMode(why); + } + + void AttackStart(Unit* who) override + { + if (me->GetReactState() == REACT_PASSIVE) + return; + ScriptedAI::AttackStart(who); + } + + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (damage >= me->GetHealth()) { - instance = creature->GetInstanceScript(); + me->SetTarget(); me->SetReactState(REACT_PASSIVE); - } - - InstanceScript* instance; - EventMap events; - EventMap events2; - uint8 phase; - - void InitializeAI() override - { - ScriptedAI::InitializeAI(); - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - - phase = PHASE_NORMAL; + me->RemoveAllAuras(); + me->GetThreatMgr().ClearAllThreat(); + me->SetRegeneratingHealth(false); + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + me->HandleEmoteCommand(EMOTE_ONESHOT_DROWN); + me->resetAttackTimer(); events.Reset(); events2.Reset(); - events2.ScheduleEvent(EVENT_INIT_FIGHT, 11000); - events2.ScheduleEvent(EVENT_REBIRTH, 0); - me->SetVisible(false); + events2.ScheduleEvent(EVENT_KILL_SELF, 500); + damage = 0; } + } - void Reset() override + void JustDied(Unit* /*killer*/) override + { + Talk(SAY_KJ_DEATH); + instance->SetBossState(DATA_KILJAEDEN, DONE); + if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KILJAEDEN_CONTROLLER))) + Unit::Kill(controller, controller); + } + + void DoAction(int32 param) override + { + if (param == ACTION_NO_KILL_TALK) { - events.Reset(); + events.ScheduleEvent(EVENT_NO_KILL_TALK, 0); + Talk(SAY_KJ_DARKNESS); } + } - void EnterEvadeMode(EvadeReason why) override + void KilledUnit(Unit* victim) override + { + if (victim->IsPlayer() && events.GetNextEventTime(EVENT_NO_KILL_TALK) == 0) + Talk(SAY_KJ_SLAY); + } + + void JustEngagedWith(Unit* /*who*/) override + { + events2.ScheduleEvent(EVENT_TEXT_SPEACH11, 26000, EVENT_GROUP_SPEACH); + Talk(SAY_KJ_EMERGE); + + events.SetTimer(200000); + events.ScheduleEvent(EVENT_CHECK_HEALTH85, 1000); + events.ScheduleEvent(EVENT_CHECK_HEALTH55, 1000); + events.ScheduleEvent(EVENT_CHECK_HEALTH25, 1000); + events.ScheduleEvent(EVENT_SPELL_SOUL_FLAY, 0); + events.ScheduleEvent(EVENT_SPELL_LEGION_LIGHTNING, 7000); + events.ScheduleEvent(EVENT_SPELL_FIRE_BLOOM, 9000); + events.ScheduleEvent(EVENT_SUMMON_ORBS, 10000); + } + + void JustSummoned(Creature* summon) override + { + if (summon->GetEntry() == NPC_ARMAGEDDON_TARGET) { - if (me->GetReactState() == REACT_PASSIVE) - return; - ScriptedAI::EnterEvadeMode(why); + summon->SetCanFly(true); + summon->SetDisableGravity(true); + summon->CastSpell(summon, SPELL_ARMAGEDDON_VISUAL, true); + summon->SetPosition(summon->GetPositionX(), summon->GetPositionY(), summon->GetPositionZ() + 20.0f, 0.0f); + summon->m_Events.AddEvent(new CastArmageddon(summon), summon->m_Events.CalculateTime(6000)); + summon->DespawnOrUnsummon(10000); } + } - void AttackStart(Unit* who) override + void UpdateAI(uint32 diff) override + { + events2.Update(diff); + switch (events2.ExecuteEvent()) { - if (me->GetReactState() == REACT_PASSIVE) - return; - ScriptedAI::AttackStart(who); - } - - void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (damage >= me->GetHealth()) + case EVENT_KILL_SELF: + me->KillSelf(); + break; + case EVENT_REBIRTH: + me->SetVisible(true); + me->CastSpell(me, SPELL_REBIRTH, false); + break; + case EVENT_EMPOWER_ORBS1: + if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ))) + kalec->AI()->Talk(SAY_KALECGOS_READY1); + EmpowerOrb(false); + break; + case EVENT_EMPOWER_ORBS2: + if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ))) + kalec->AI()->Talk(SAY_KALECGOS_READY2); + EmpowerOrb(false); + break; + case EVENT_EMPOWER_ORBS3: + if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ))) + kalec->AI()->Talk(SAY_KALECGOS_READY_ALL); + EmpowerOrb(true); + break; + case EVENT_INIT_FIGHT: + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->SetInCombatWithZone(); + return; + case EVENT_TEXT_SPEACH11: + if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ))) + kalec->AI()->Talk(SAY_KALECGOS_JOIN); + break; + case EVENT_TEXT_SPEACH21: + if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ))) + kalec->AI()->Talk(SAY_KALECGOS_AWAKEN); + break; + case EVENT_TEXT_SPEACH22: + if (Creature* anveena = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ANVEENA))) + sCreatureTextMgr->SendChat(anveena, SAY_ANVEENA_IMPRISONED, nullptr, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_ZONE); + break; + case EVENT_TEXT_SPEACH23: + Talk(SAY_KJ_PHASE3); + break; + case EVENT_TEXT_SPEACH31: + if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ))) + kalec->AI()->Talk(SAY_KALECGOS_LETGO); + break; + case EVENT_TEXT_SPEACH32: + if (Creature* anveena = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ANVEENA))) + sCreatureTextMgr->SendChat(anveena, SAY_ANVEENA_LOST, nullptr, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_ZONE); + break; + case EVENT_TEXT_SPEACH33: + Talk(SAY_KJ_PHASE4); + break; + case EVENT_TEXT_SPEACH41: + if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ))) + kalec->AI()->Talk(SAY_KALECGOS_FOCUS); + break; + case EVENT_TEXT_SPEACH42: + if (Creature* anveena = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ANVEENA))) + sCreatureTextMgr->SendChat(anveena, SAY_ANVEENA_KALEC, nullptr, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_ZONE); + break; + case EVENT_TEXT_SPEACH43: + if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ))) + kalec->AI()->Talk(SAY_KALECGOS_FATE); + break; + case EVENT_TEXT_SPEACH44: + if (Creature* anveena = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ANVEENA))) + sCreatureTextMgr->SendChat(anveena, SAY_ANVEENA_GOODBYE, nullptr, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_ZONE); + break; + case EVENT_TEXT_SPEACH45: + if (Creature* anveena = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ANVEENA))) { - me->SetTarget(); - me->SetReactState(REACT_PASSIVE); - me->RemoveAllAuras(); - me->GetThreatMgr().ClearAllThreat(); - me->SetRegeneratingHealth(false); - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->HandleEmoteCommand(EMOTE_ONESHOT_DROWN); - me->resetAttackTimer(); - events.Reset(); - events2.Reset(); - events2.ScheduleEvent(EVENT_KILL_SELF, 500); - damage = 0; + anveena->RemoveAllAuras(); + anveena->DespawnOrUnsummon(3500); } - } - - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_KJ_DEATH); - instance->SetBossState(DATA_KILJAEDEN, DONE); - if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KILJAEDEN_CONTROLLER))) - Unit::Kill(controller, controller); - } - - void DoAction(int32 param) override - { - if (param == ACTION_NO_KILL_TALK) + break; + case EVENT_TEXT_SPEACH46: + if (Creature* anveena = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ANVEENA))) { - events.ScheduleEvent(EVENT_NO_KILL_TALK, 0); - Talk(SAY_KJ_DARKNESS); + anveena->CastSpell(anveena, SPELL_SACRIFICE_OF_ANVEENA, true); + me->CastSpell(me, SPELL_CUSTOM_08_STATE, true); + me->SetUnitFlag(UNIT_FLAG_PACIFIED); + events.DelayEvents(7001); + events2.ScheduleEvent(EVENT_RESTORE_MELEE, 7000); } + Talk(SAY_KJ_PHASE5); + break; + case EVENT_RESTORE_MELEE: + me->RemoveAurasDueToSpell(SPELL_CUSTOM_08_STATE); + me->RemoveUnitFlag(UNIT_FLAG_PACIFIED); + break; } - void KilledUnit(Unit* victim) override - { - if (victim->IsPlayer() && events.GetNextEventTime(EVENT_NO_KILL_TALK) == 0) - Talk(SAY_KJ_SLAY); - } + if (me->GetReactState() != REACT_AGGRESSIVE) + return; - void JustEngagedWith(Unit* /*who*/) override - { - events2.ScheduleEvent(EVENT_TEXT_SPEACH11, 26000, EVENT_GROUP_SPEACH); - Talk(SAY_KJ_EMERGE); + if (!UpdateVictim()) + return; - events.SetTimer(200000); - events.ScheduleEvent(EVENT_CHECK_HEALTH85, 1000); - events.ScheduleEvent(EVENT_CHECK_HEALTH55, 1000); - events.ScheduleEvent(EVENT_CHECK_HEALTH25, 1000); - events.ScheduleEvent(EVENT_SPELL_SOUL_FLAY, 0); - events.ScheduleEvent(EVENT_SPELL_LEGION_LIGHTNING, 7000); - events.ScheduleEvent(EVENT_SPELL_FIRE_BLOOM, 9000); - events.ScheduleEvent(EVENT_SUMMON_ORBS, 10000); - } + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void JustSummoned(Creature* summon) override + switch (events.ExecuteEvent()) { - if (summon->GetEntry() == NPC_ARMAGEDDON_TARGET) + case EVENT_CHECK_HEALTH85: + if (me->HealthBelowPct(85)) { - summon->SetCanFly(true); - summon->SetDisableGravity(true); - summon->CastSpell(summon, SPELL_ARMAGEDDON_VISUAL, true); - summon->SetPosition(summon->GetPositionX(), summon->GetPositionY(), summon->GetPositionZ() + 20.0f, 0.0f); - summon->m_Events.AddEvent(new CastArmageddon(summon), summon->m_Events.CalculateTime(6000)); - summon->DespawnOrUnsummon(10000); + phase = PHASE_DARKNESS; + events2.CancelEvent(EVENT_GROUP_SPEACH); + events2.ScheduleEvent(EVENT_TEXT_SPEACH21, 16000, EVENT_GROUP_SPEACH); + events2.ScheduleEvent(EVENT_TEXT_SPEACH22, 22000, EVENT_GROUP_SPEACH); + events2.ScheduleEvent(EVENT_TEXT_SPEACH23, 28000, EVENT_GROUP_SPEACH); + events2.RescheduleEvent(EVENT_EMPOWER_ORBS1, 35000); + + events.DelayEvents(2000); + events.ScheduleEvent(EVENT_SPELL_SINISTER_REFLECTION, 500); + events.ScheduleEvent(EVENT_SPELL_SHADOW_SPIKE, 1200); + events.ScheduleEvent(EVENT_SPELL_FLAME_DART, 3000); + events.RescheduleEvent(EVENT_SPELL_DARKNESS, 16000); // will be delayed by 29 secs + break; } - } + events.ScheduleEvent(EVENT_CHECK_HEALTH85, 0); + break; - void UpdateAI(uint32 diff) override - { - events2.Update(diff); - switch (events2.ExecuteEvent()) + case EVENT_CHECK_HEALTH55: + if (me->HealthBelowPct(55)) { - case EVENT_KILL_SELF: - me->KillSelf(); - break; - case EVENT_REBIRTH: - me->SetVisible(true); - me->CastSpell(me, SPELL_REBIRTH, false); - break; - case EVENT_EMPOWER_ORBS1: - if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ))) - kalec->AI()->Talk(SAY_KALECGOS_READY1); - EmpowerOrb(false); - break; - case EVENT_EMPOWER_ORBS2: - if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ))) - kalec->AI()->Talk(SAY_KALECGOS_READY2); - EmpowerOrb(false); - break; - case EVENT_EMPOWER_ORBS3: - if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ))) - kalec->AI()->Talk(SAY_KALECGOS_READY_ALL); - EmpowerOrb(true); - break; - case EVENT_INIT_FIGHT: - me->SetReactState(REACT_AGGRESSIVE); - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->SetInCombatWithZone(); - return; - case EVENT_TEXT_SPEACH11: - if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ))) - kalec->AI()->Talk(SAY_KALECGOS_JOIN); - break; - case EVENT_TEXT_SPEACH21: - if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ))) - kalec->AI()->Talk(SAY_KALECGOS_AWAKEN); - break; - case EVENT_TEXT_SPEACH22: - if (Creature* anveena = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ANVEENA))) - sCreatureTextMgr->SendChat(anveena, SAY_ANVEENA_IMPRISONED, nullptr, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_ZONE); - break; - case EVENT_TEXT_SPEACH23: - Talk(SAY_KJ_PHASE3); - break; - case EVENT_TEXT_SPEACH31: - if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ))) - kalec->AI()->Talk(SAY_KALECGOS_LETGO); - break; - case EVENT_TEXT_SPEACH32: - if (Creature* anveena = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ANVEENA))) - sCreatureTextMgr->SendChat(anveena, SAY_ANVEENA_LOST, nullptr, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_ZONE); - break; - case EVENT_TEXT_SPEACH33: - Talk(SAY_KJ_PHASE4); - break; - case EVENT_TEXT_SPEACH41: - if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ))) - kalec->AI()->Talk(SAY_KALECGOS_FOCUS); - break; - case EVENT_TEXT_SPEACH42: - if (Creature* anveena = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ANVEENA))) - sCreatureTextMgr->SendChat(anveena, SAY_ANVEENA_KALEC, nullptr, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_ZONE); - break; - case EVENT_TEXT_SPEACH43: - if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ))) - kalec->AI()->Talk(SAY_KALECGOS_FATE); - break; - case EVENT_TEXT_SPEACH44: - if (Creature* anveena = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ANVEENA))) - sCreatureTextMgr->SendChat(anveena, SAY_ANVEENA_GOODBYE, nullptr, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_ZONE); - break; - case EVENT_TEXT_SPEACH45: - if (Creature* anveena = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ANVEENA))) - { - anveena->RemoveAllAuras(); - anveena->DespawnOrUnsummon(3500); - } - break; - case EVENT_TEXT_SPEACH46: - if (Creature* anveena = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ANVEENA))) - { - anveena->CastSpell(anveena, SPELL_SACRIFICE_OF_ANVEENA, true); - me->CastSpell(me, SPELL_CUSTOM_08_STATE, true); - me->SetUnitFlag(UNIT_FLAG_PACIFIED); - events.DelayEvents(7001); - events2.ScheduleEvent(EVENT_RESTORE_MELEE, 7000); - } - Talk(SAY_KJ_PHASE5); - break; - case EVENT_RESTORE_MELEE: - me->RemoveAurasDueToSpell(SPELL_CUSTOM_08_STATE); - me->RemoveUnitFlag(UNIT_FLAG_PACIFIED); - break; + phase = PHASE_ARMAGEDDON; + events2.CancelEventGroup(EVENT_GROUP_SPEACH); + events2.ScheduleEvent(EVENT_TEXT_SPEACH31, 16000, EVENT_GROUP_SPEACH); + events2.ScheduleEvent(EVENT_TEXT_SPEACH32, 22000, EVENT_GROUP_SPEACH); + events2.ScheduleEvent(EVENT_TEXT_SPEACH33, 28000, EVENT_GROUP_SPEACH); + events2.RescheduleEvent(EVENT_EMPOWER_ORBS2, 35000); + + events.DelayEvents(2000); + events.ScheduleEvent(EVENT_SPELL_SINISTER_REFLECTION, 500); + events.ScheduleEvent(EVENT_SPELL_SHADOW_SPIKE, 1200); + events.RescheduleEvent(EVENT_SPELL_DARKNESS, 15000); // will be delayed by 29 secs + events.ScheduleEvent(EVENT_SPELL_ARMAGEDDON, 10000); + break; } + events.ScheduleEvent(EVENT_CHECK_HEALTH55, 0); + break; - if (me->GetReactState() != REACT_AGGRESSIVE) - return; - - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) + case EVENT_CHECK_HEALTH25: + if (me->HealthBelowPct(25)) { - case EVENT_CHECK_HEALTH85: - if (me->HealthBelowPct(85)) - { - phase = PHASE_DARKNESS; - events2.CancelEvent(EVENT_GROUP_SPEACH); - events2.ScheduleEvent(EVENT_TEXT_SPEACH21, 16000, EVENT_GROUP_SPEACH); - events2.ScheduleEvent(EVENT_TEXT_SPEACH22, 22000, EVENT_GROUP_SPEACH); - events2.ScheduleEvent(EVENT_TEXT_SPEACH23, 28000, EVENT_GROUP_SPEACH); - events2.RescheduleEvent(EVENT_EMPOWER_ORBS1, 35000); + phase = PHASE_SACRIFICE; + events2.CancelEventGroup(EVENT_GROUP_SPEACH); + events2.ScheduleEvent(EVENT_TEXT_SPEACH41, 8000, EVENT_GROUP_SPEACH); + events2.ScheduleEvent(EVENT_TEXT_SPEACH42, 18000, EVENT_GROUP_SPEACH); + events2.ScheduleEvent(EVENT_TEXT_SPEACH43, 20200, EVENT_GROUP_SPEACH); + events2.ScheduleEvent(EVENT_TEXT_SPEACH44, 25000, EVENT_GROUP_SPEACH); + events2.ScheduleEvent(EVENT_TEXT_SPEACH45, 28000, EVENT_GROUP_SPEACH); + events2.ScheduleEvent(EVENT_TEXT_SPEACH46, 30000, EVENT_GROUP_SPEACH); + events2.RescheduleEvent(EVENT_EMPOWER_ORBS3, 61000); - events.DelayEvents(2000); - events.ScheduleEvent(EVENT_SPELL_SINISTER_REFLECTION, 500); - events.ScheduleEvent(EVENT_SPELL_SHADOW_SPIKE, 1200); - events.ScheduleEvent(EVENT_SPELL_FLAME_DART, 3000); - events.RescheduleEvent(EVENT_SPELL_DARKNESS, 16000); // will be delayed by 29 secs - break; - } - events.ScheduleEvent(EVENT_CHECK_HEALTH85, 0); - break; - - case EVENT_CHECK_HEALTH55: - if (me->HealthBelowPct(55)) - { - phase = PHASE_ARMAGEDDON; - events2.CancelEventGroup(EVENT_GROUP_SPEACH); - events2.ScheduleEvent(EVENT_TEXT_SPEACH31, 16000, EVENT_GROUP_SPEACH); - events2.ScheduleEvent(EVENT_TEXT_SPEACH32, 22000, EVENT_GROUP_SPEACH); - events2.ScheduleEvent(EVENT_TEXT_SPEACH33, 28000, EVENT_GROUP_SPEACH); - events2.RescheduleEvent(EVENT_EMPOWER_ORBS2, 35000); - - events.DelayEvents(2000); - events.ScheduleEvent(EVENT_SPELL_SINISTER_REFLECTION, 500); - events.ScheduleEvent(EVENT_SPELL_SHADOW_SPIKE, 1200); - events.RescheduleEvent(EVENT_SPELL_DARKNESS, 15000); // will be delayed by 29 secs - events.ScheduleEvent(EVENT_SPELL_ARMAGEDDON, 10000); - break; - } - events.ScheduleEvent(EVENT_CHECK_HEALTH55, 0); - break; - - case EVENT_CHECK_HEALTH25: - if (me->HealthBelowPct(25)) - { - phase = PHASE_SACRIFICE; - events2.CancelEventGroup(EVENT_GROUP_SPEACH); - events2.ScheduleEvent(EVENT_TEXT_SPEACH41, 8000, EVENT_GROUP_SPEACH); - events2.ScheduleEvent(EVENT_TEXT_SPEACH42, 18000, EVENT_GROUP_SPEACH); - events2.ScheduleEvent(EVENT_TEXT_SPEACH43, 20200, EVENT_GROUP_SPEACH); - events2.ScheduleEvent(EVENT_TEXT_SPEACH44, 25000, EVENT_GROUP_SPEACH); - events2.ScheduleEvent(EVENT_TEXT_SPEACH45, 28000, EVENT_GROUP_SPEACH); - events2.ScheduleEvent(EVENT_TEXT_SPEACH46, 30000, EVENT_GROUP_SPEACH); - events2.RescheduleEvent(EVENT_EMPOWER_ORBS3, 61000); - - events.CancelEvent(EVENT_SUMMON_ORBS); - events.DelayEvents(4000); - events.ScheduleEvent(EVENT_SPELL_SINISTER_REFLECTION, 500); - events.ScheduleEvent(EVENT_SPELL_SHADOW_SPIKE, 1200); - events.RescheduleEvent(EVENT_SPELL_DARKNESS, 15000); // will be delayed by 29 secs - events.ScheduleEvent(EVENT_SPELL_ARMAGEDDON, 1500); - break; - } - events.ScheduleEvent(EVENT_CHECK_HEALTH25, 0); - break; - case EVENT_SPELL_SOUL_FLAY: - me->CastSpell(me->GetVictim(), SPELL_SOUL_FLAY, false); - events.ScheduleEvent(EVENT_SPELL_SOUL_FLAY, urand(4000, 5000)); - break; - case EVENT_SPELL_LEGION_LIGHTNING: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f, true)) - me->CastSpell(target, SPELL_LEGION_LIGHTNING, false); - events.ScheduleEvent(EVENT_SPELL_LEGION_LIGHTNING, phase == PHASE_SACRIFICE ? 15000 : 30000); - events.RescheduleEvent(EVENT_SPELL_SOUL_FLAY, 2000); - break; - case EVENT_SPELL_FIRE_BLOOM: - me->CastCustomSpell(SPELL_FIRE_BLOOM, SPELLVALUE_MAX_TARGETS, 5, me, TRIGGERED_NONE); - me->SetTarget(me->GetVictim()->GetGUID()); - events.ScheduleEvent(EVENT_SPELL_FIRE_BLOOM, phase == PHASE_SACRIFICE ? 20000 : 40000); - events.RescheduleEvent(EVENT_SPELL_SOUL_FLAY, 1500); - break; - case EVENT_SUMMON_ORBS: - for (uint8 i = 1; i < phase; ++i) - { - float x = me->GetPositionX() + 18.0f * cos((i * 2.0f - 1.0f) * M_PI / 3.0f); - float y = me->GetPositionY() + 18.0f * std::sin((i * 2.0f - 1.0f) * M_PI / 3.0f); - if (Creature* orb = me->SummonCreature(NPC_SHIELD_ORB, x, y, 40.0f, 0, TEMPSUMMON_CORPSE_DESPAWN)) - { - Movement::PointsArray movementArray; - movementArray.push_back(G3D::Vector3(x, y, 40.0f)); - - // generate movement array - for (uint8 j = 1; j < 20; ++j) - { - x = me->GetPositionX() + 18.0f * cos(((i * 2.0f - 1.0f) * M_PI / 3.0f) + (j / 20.0f * 2 * M_PI)); - y = me->GetPositionY() + 18.0f * std::sin(((i * 2.0f - 1.0f) * M_PI / 3.0f) + (j / 20.0f * 2 * M_PI)); - movementArray.push_back(G3D::Vector3(x, y, 40.0f)); - } - - Movement::MoveSplineInit init(orb); - init.MovebyPath(movementArray); - init.SetCyclic(); - init.Launch(); - } - } - events.ScheduleEvent(EVENT_SUMMON_ORBS, 40000); - break; - case EVENT_SPELL_SHADOW_SPIKE: - events.DelayEvents(27000); - me->CastSpell(me, SPELL_SHADOW_SPIKE, false); - break; - case EVENT_SPELL_SINISTER_REFLECTION: - Talk(SAY_KJ_REFLECTION); - me->CastCustomSpell(SPELL_SINISTER_REFLECTION, SPELLVALUE_MAX_TARGETS, 1, me, TRIGGERED_NONE); - me->CastCustomSpell(SPELL_SINISTER_REFLECTION, SPELLVALUE_MAX_TARGETS, 1, me, TRIGGERED_NONE); - me->CastCustomSpell(SPELL_SINISTER_REFLECTION, SPELLVALUE_MAX_TARGETS, 1, me, TRIGGERED_NONE); - me->CastCustomSpell(SPELL_SINISTER_REFLECTION, SPELLVALUE_MAX_TARGETS, 1, me, TRIGGERED_NONE); - break; - case EVENT_SPELL_FLAME_DART: - me->CastSpell(me, SPELL_FLAME_DART, false); - events.ScheduleEvent(EVENT_SPELL_FLAME_DART, 10000); - break; - case EVENT_SPELL_DARKNESS: - Talk(EMOTE_KJ_DARKNESS); - me->CastSpell(me, SPELL_DARKNESS_OF_A_THOUSAND_SOULS, false); - events.ScheduleEvent(EVENT_SPELL_DARKNESS, phase == PHASE_SACRIFICE ? 20000 : 45000); - events.DelayEvents(8000); - break; - case EVENT_SPELL_ARMAGEDDON: - me->CastSpell(me, SPELL_ARMAGEDDON_PERIODIC, true); - events.ScheduleEvent(EVENT_SPELL_ARMAGEDDON, phase == PHASE_SACRIFICE ? 20000 : 40000); - break; + events.CancelEvent(EVENT_SUMMON_ORBS); + events.DelayEvents(4000); + events.ScheduleEvent(EVENT_SPELL_SINISTER_REFLECTION, 500); + events.ScheduleEvent(EVENT_SPELL_SHADOW_SPIKE, 1200); + events.RescheduleEvent(EVENT_SPELL_DARKNESS, 15000); // will be delayed by 29 secs + events.ScheduleEvent(EVENT_SPELL_ARMAGEDDON, 1500); + break; } - - DoMeleeAttackIfReady(); - } - - void EmpowerOrb(bool empowerAll) - { - for (uint8 i = 0; i < 4; ++i) + events.ScheduleEvent(EVENT_CHECK_HEALTH25, 0); + break; + case EVENT_SPELL_SOUL_FLAY: + me->CastSpell(me->GetVictim(), SPELL_SOUL_FLAY, false); + events.ScheduleEvent(EVENT_SPELL_SOUL_FLAY, urand(4000, 5000)); + break; + case EVENT_SPELL_LEGION_LIGHTNING: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f, true)) + me->CastSpell(target, SPELL_LEGION_LIGHTNING, false); + events.ScheduleEvent(EVENT_SPELL_LEGION_LIGHTNING, phase == PHASE_SACRIFICE ? 15000 : 30000); + events.RescheduleEvent(EVENT_SPELL_SOUL_FLAY, 2000); + break; + case EVENT_SPELL_FIRE_BLOOM: + me->CastCustomSpell(SPELL_FIRE_BLOOM, SPELLVALUE_MAX_TARGETS, 5, me, TRIGGERED_NONE); + me->SetTarget(me->GetVictim()->GetGUID()); + events.ScheduleEvent(EVENT_SPELL_FIRE_BLOOM, phase == PHASE_SACRIFICE ? 20000 : 40000); + events.RescheduleEvent(EVENT_SPELL_SOUL_FLAY, 1500); + break; + case EVENT_SUMMON_ORBS: + for (uint8 i = 1; i < phase; ++i) { - if (GameObject* orb = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_ORB_OF_THE_BLUE_DRAGONFLIGHT_1 + i))) + float x = me->GetPositionX() + 18.0f * cos((i * 2.0f - 1.0f) * M_PI / 3.0f); + float y = me->GetPositionY() + 18.0f * std::sin((i * 2.0f - 1.0f) * M_PI / 3.0f); + if (Creature* orb = me->SummonCreature(NPC_SHIELD_ORB, x, y, 40.0f, 0, TEMPSUMMON_CORPSE_DESPAWN)) { - if (orb->HasGameObjectFlag(GO_FLAG_NOT_SELECTABLE)) - { - orb->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); - if (Creature* trigger = me->SummonTrigger(orb->GetPositionX(), orb->GetPositionY(), orb->GetPositionZ(), 0, 10 * MINUTE * IN_MILLISECONDS)) - { - trigger->CastSpell(trigger, SPELL_RING_OF_BLUE_FLAMES, true, nullptr, nullptr, trigger->GetGUID()); - if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KILJAEDEN_CONTROLLER))) - controller->AI()->JustSummoned(trigger); - } + Movement::PointsArray movementArray; + movementArray.push_back(G3D::Vector3(x, y, 40.0f)); - if (!empowerAll) - break; + // generate movement array + for (uint8 j = 1; j < 20; ++j) + { + x = me->GetPositionX() + 18.0f * cos(((i * 2.0f - 1.0f) * M_PI / 3.0f) + (j / 20.0f * 2 * M_PI)); + y = me->GetPositionY() + 18.0f * std::sin(((i * 2.0f - 1.0f) * M_PI / 3.0f) + (j / 20.0f * 2 * M_PI)); + movementArray.push_back(G3D::Vector3(x, y, 40.0f)); } + + Movement::MoveSplineInit init(orb); + init.MovebyPath(movementArray); + init.SetCyclic(); + init.Launch(); + } + } + events.ScheduleEvent(EVENT_SUMMON_ORBS, 40000); + break; + case EVENT_SPELL_SHADOW_SPIKE: + events.DelayEvents(27000); + me->CastSpell(me, SPELL_SHADOW_SPIKE, false); + break; + case EVENT_SPELL_SINISTER_REFLECTION: + Talk(SAY_KJ_REFLECTION); + me->CastCustomSpell(SPELL_SINISTER_REFLECTION, SPELLVALUE_MAX_TARGETS, 1, me, TRIGGERED_NONE); + me->CastCustomSpell(SPELL_SINISTER_REFLECTION, SPELLVALUE_MAX_TARGETS, 1, me, TRIGGERED_NONE); + me->CastCustomSpell(SPELL_SINISTER_REFLECTION, SPELLVALUE_MAX_TARGETS, 1, me, TRIGGERED_NONE); + me->CastCustomSpell(SPELL_SINISTER_REFLECTION, SPELLVALUE_MAX_TARGETS, 1, me, TRIGGERED_NONE); + break; + case EVENT_SPELL_FLAME_DART: + me->CastSpell(me, SPELL_FLAME_DART, false); + events.ScheduleEvent(EVENT_SPELL_FLAME_DART, 10000); + break; + case EVENT_SPELL_DARKNESS: + Talk(EMOTE_KJ_DARKNESS); + me->CastSpell(me, SPELL_DARKNESS_OF_A_THOUSAND_SOULS, false); + events.ScheduleEvent(EVENT_SPELL_DARKNESS, phase == PHASE_SACRIFICE ? 20000 : 45000); + events.DelayEvents(8000); + break; + case EVENT_SPELL_ARMAGEDDON: + me->CastSpell(me, SPELL_ARMAGEDDON_PERIODIC, true); + events.ScheduleEvent(EVENT_SPELL_ARMAGEDDON, phase == PHASE_SACRIFICE ? 20000 : 40000); + break; + } + + DoMeleeAttackIfReady(); + } + + void EmpowerOrb(bool empowerAll) + { + for (uint8 i = 0; i < 4; ++i) + { + if (GameObject* orb = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_ORB_OF_THE_BLUE_DRAGONFLIGHT_1 + i))) + { + if (orb->HasGameObjectFlag(GO_FLAG_NOT_SELECTABLE)) + { + orb->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); + if (Creature* trigger = me->SummonTrigger(orb->GetPositionX(), orb->GetPositionY(), orb->GetPositionZ(), 0, 10 * MINUTE * IN_MILLISECONDS)) + { + trigger->CastSpell(trigger, SPELL_RING_OF_BLUE_FLAMES, true, nullptr, nullptr, trigger->GetGUID()); + if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KILJAEDEN_CONTROLLER))) + controller->AI()->JustSummoned(trigger); + } + + if (!empowerAll) + break; } } } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetSunwellPlateauAI(creature); } }; @@ -772,262 +750,251 @@ private: Creature* _owner; }; -class npc_kalecgos_kj : public CreatureScript +struct npc_kalecgos_kj : public NullCreatureAI { -public: - npc_kalecgos_kj() : CreatureScript("npc_kalecgos_kj") { } - - CreatureAI* GetAI(Creature* creature) const override + npc_kalecgos_kj(Creature* creature) : NullCreatureAI(creature), summons(me) { - return GetSunwellPlateauAI(creature); + instance = creature->GetInstanceScript(); } - struct npc_kalecgos_kjAI : public NullCreatureAI + EventMap events; + InstanceScript* instance; + SummonList summons; + + void Reset() override { - npc_kalecgos_kjAI(Creature* creature) : NullCreatureAI(creature), summons(me) - { - instance = creature->GetInstanceScript(); - } + events.Reset(); + summons.DespawnAll(); + } - EventMap events; - InstanceScript* instance; - SummonList summons; - - void Reset() override + void DoAction(int32 param) override + { + if (param == ACTION_START_POST_EVENT) { - events.Reset(); - summons.DespawnAll(); + me->SetCanFly(false); + me->SetDisableGravity(false); + me->CastSpell(me, SPELL_TELEPORT_AND_TRANSFORM, true); + events.ScheduleEvent(EVENT_SCENE_01, 35000); } + } - void DoAction(int32 param) override + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + if (summon->GetEntry() == NPC_SHATTERED_SUN_RIFTWAKER) { - if (param == ACTION_START_POST_EVENT) + summon->CastSpell(summon, SPELL_TELEPORT_VISUAL, true); + Movement::MoveSplineInit init(summon); + if (summons.size() == 1) { - me->SetCanFly(false); - me->SetDisableGravity(false); - me->CastSpell(me, SPELL_TELEPORT_AND_TRANSFORM, true); - events.ScheduleEvent(EVENT_SCENE_01, 35000); + init.MoveTo(1727.08f, 656.82f, 28.37f, false, true); + init.SetFacing(5.14f); } + else + { + init.MoveTo(1738.84f, 627.32f, 28.26f, false, true); + init.SetFacing(2.0f); + } + init.Launch(); } + else if (summon->GetEntry() == NPC_SHATTRATH_PORTAL_DUMMY) + { + if (Creature* riftwaker = summon->FindNearestCreature(NPC_SHATTERED_SUN_RIFTWAKER, 10.0f)) + riftwaker->CastSpell(summon, SPELL_OPEN_PORTAL_FROM_SHATTRATH, false); + summon->SetWalk(true); + summon->GetMotionMaster()->MovePoint(0, summon->GetPositionX(), summon->GetPositionY(), summon->GetPositionZ() + 30.0f, false, true); + } + else if (summon->GetEntry() == NPC_INERT_PORTAL) + summon->CastSpell(summon, SPELL_BOSS_ARCANE_PORTAL_STATE, true); + else if (summon->GetEntry() == NPC_SHATTERED_SUN_SOLDIER) + summon->CastSpell(summon, SPELL_TELEPORT_VISUAL, true); + else if (summon->GetEntry() == NPC_LADY_LIADRIN) + { + summon->CastSpell(summon, SPELL_TELEPORT_VISUAL, true); + summon->SetWalk(true); + } + else if (summon->GetEntry() == NPC_PROPHET_VELEN) + { + summon->CastSpell(summon, SPELL_TELEPORT_VISUAL, true); + summon->SetWalk(true); + summon->GetMotionMaster()->MovePoint(0, 1710.15f, 639.23f, 27.311f, false, true); + } + else if (summon->GetEntry() == NPC_THE_CORE_OF_ENTROPIUS) + summon->GetMotionMaster()->MovePoint(0, summon->GetPositionX(), summon->GetPositionY(), 30.0f); + } - void JustSummoned(Creature* summon) override + void UpdateAI(uint32 diff) override + { + events.Update(diff); + switch (uint32 eventId = events.ExecuteEvent()) { - summons.Summon(summon); - if (summon->GetEntry() == NPC_SHATTERED_SUN_RIFTWAKER) + case EVENT_SCENE_01: + Talk(SAY_KALECGOS_GOODBYE); + events.ScheduleEvent(eventId + 1, 15000); + break; + case EVENT_SCENE_02: + me->SummonCreature(NPC_SHATTERED_SUN_RIFTWAKER, 1688.42f, 641.82f, 27.60f, 0.67f); + me->SummonCreature(NPC_SHATTERED_SUN_RIFTWAKER, 1712.58f, 616.29f, 27.78f, 0.76f); + events.ScheduleEvent(eventId + 1, 6000); + break; + case EVENT_SCENE_03: + me->SummonCreature(NPC_SHATTRATH_PORTAL_DUMMY, 1727.08f + cos(5.14f), 656.82f + std::sin(5.14f), 28.37f + 2.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 10000); + me->SummonCreature(NPC_SHATTRATH_PORTAL_DUMMY, 1738.84f + cos(2.0f), 627.32f + std::sin(2.0f), 28.26f + 2.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 10000); + events.ScheduleEvent(eventId + 1, 11000); + break; + case EVENT_SCENE_04: + me->SummonCreature(NPC_INERT_PORTAL, 1734.96f, 642.43f, 28.06f, 3.49f); + events.ScheduleEvent(eventId + 1, 4000); + break; + case EVENT_SCENE_05: + if (Creature* first = me->SummonCreature(NPC_SHATTERED_SUN_SOLDIER, 1729.48f, 640.49f, 28.06f, 3.49f)) { - summon->CastSpell(summon, SPELL_TELEPORT_VISUAL, true); - Movement::MoveSplineInit init(summon); - if (summons.size() == 1) - { - init.MoveTo(1727.08f, 656.82f, 28.37f, false, true); - init.SetFacing(5.14f); - } - else - { - init.MoveTo(1738.84f, 627.32f, 28.26f, false, true); - init.SetFacing(2.0f); - } - init.Launch(); + first->m_Events.AddEvent(new MoveDelayed(first, 1718.70f, 607.78f, 28.06f, 2.323f), first->m_Events.CalculateTime(5000)); + first->m_Events.AddEvent(new FixOrientation(first), first->m_Events.CalculateTime(12000)); + for (uint8 i = 0; i < 9; ++i) + if (Creature* follower = me->SummonCreature(NPC_SHATTERED_SUN_SOLDIER, 1729.48f + 5 * cos(i * 2.0f * M_PI / 9), 640.49f + 5 * std::sin(i * 2.0f * M_PI / 9), 28.06f, 3.49f)) + follower->GetMotionMaster()->MoveFollow(first, 3.0f, follower->GetAngle(first)); } - else if (summon->GetEntry() == NPC_SHATTRATH_PORTAL_DUMMY) + events.ScheduleEvent(eventId + 1, 10000); + break; + case EVENT_SCENE_06: + if (Creature* first = me->SummonCreature(NPC_SHATTERED_SUN_SOLDIER, 1729.48f, 640.49f, 28.06f, 3.49f)) { - if (Creature* riftwaker = summon->FindNearestCreature(NPC_SHATTERED_SUN_RIFTWAKER, 10.0f)) - riftwaker->CastSpell(summon, SPELL_OPEN_PORTAL_FROM_SHATTRATH, false); - summon->SetWalk(true); - summon->GetMotionMaster()->MovePoint(0, summon->GetPositionX(), summon->GetPositionY(), summon->GetPositionZ() + 30.0f, false, true); + first->m_Events.AddEvent(new MoveDelayed(first, 1678.69f, 649.27f, 28.06f, 5.46f), first->m_Events.CalculateTime(5000)); + first->m_Events.AddEvent(new FixOrientation(first), first->m_Events.CalculateTime(14500)); + for (uint8 i = 0; i < 9; ++i) + if (Creature* follower = me->SummonCreature(NPC_SHATTERED_SUN_SOLDIER, 1729.48f + 5 * cos(i * 2.0f * M_PI / 9), 640.49f + 5 * std::sin(i * 2.0f * M_PI / 9), 28.06f, 3.49f)) + follower->GetMotionMaster()->MoveFollow(first, 3.0f, follower->GetAngle(first)); } - else if (summon->GetEntry() == NPC_INERT_PORTAL) - summon->CastSpell(summon, SPELL_BOSS_ARCANE_PORTAL_STATE, true); - else if (summon->GetEntry() == NPC_SHATTERED_SUN_SOLDIER) - summon->CastSpell(summon, SPELL_TELEPORT_VISUAL, true); - else if (summon->GetEntry() == NPC_LADY_LIADRIN) + events.ScheduleEvent(eventId + 1, 12000); + break; + case EVENT_SCENE_07: + me->SummonCreature(NPC_LADY_LIADRIN, 1719.87f, 644.265f, 28.06f, 3.83f); + me->SummonCreature(NPC_PROPHET_VELEN, 1717.97f, 646.44f, 28.06f, 3.94f); + events.ScheduleEvent(eventId + 1, 7000); + break; + case EVENT_SCENE_08: + if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) + velen->AI()->Talk(SAY_VELEN_01); + events.ScheduleEvent(eventId + 1, 25000); + break; + case EVENT_SCENE_09: + if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) + velen->AI()->Talk(SAY_VELEN_02); + events.ScheduleEvent(eventId + 1, 14500); + break; + case EVENT_SCENE_10: + if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) + velen->AI()->Talk(SAY_VELEN_03); + events.ScheduleEvent(eventId + 1, 12500); + break; + case EVENT_SCENE_11: + me->SummonCreature(NPC_THE_CORE_OF_ENTROPIUS, 1698.86f, 628.73f, 92.83f, 0.0f); + if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) + velen->CastSpell(velen, SPELL_CALL_ENTROPIUS, false); + events.ScheduleEvent(eventId + 1, 8000); + break; + case EVENT_SCENE_12: + if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) { - summon->CastSpell(summon, SPELL_TELEPORT_VISUAL, true); - summon->SetWalk(true); + velen->InterruptNonMeleeSpells(false); + velen->AI()->Talk(SAY_VELEN_04); } - else if (summon->GetEntry() == NPC_PROPHET_VELEN) + events.ScheduleEvent(eventId + 1, 20000); + break; + case EVENT_SCENE_13: + if (Creature* liadrin = summons.GetCreatureWithEntry(NPC_LADY_LIADRIN)) + liadrin->GetMotionMaster()->MovePoint(0, 1711.28f, 637.29f, 27.29f); + events.ScheduleEvent(eventId + 1, 6000); + break; + case EVENT_SCENE_14: + if (Creature* liadrin = summons.GetCreatureWithEntry(NPC_LADY_LIADRIN)) + liadrin->AI()->Talk(SAY_LIADRIN_01); + events.ScheduleEvent(eventId + 1, 10000); + break; + case EVENT_SCENE_15: + if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) + velen->AI()->Talk(SAY_VELEN_05); + events.ScheduleEvent(eventId + 1, 14000); + break; + case EVENT_SCENE_16: + if (Creature* liadrin = summons.GetCreatureWithEntry(NPC_LADY_LIADRIN)) + liadrin->AI()->Talk(SAY_LIADRIN_02); + events.ScheduleEvent(eventId + 1, 2000); + break; + case EVENT_SCENE_17: + if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) + velen->AI()->Talk(SAY_VELEN_06); + events.ScheduleEvent(eventId + 1, 3000); + break; + case EVENT_SCENE_18: + if (Creature* core = summons.GetCreatureWithEntry(NPC_THE_CORE_OF_ENTROPIUS)) { - summon->CastSpell(summon, SPELL_TELEPORT_VISUAL, true); - summon->SetWalk(true); - summon->GetMotionMaster()->MovePoint(0, 1710.15f, 639.23f, 27.311f, false, true); + core->RemoveAllAuras(); + core->CastSpell(core, SPELL_BLAZE_TO_LIGHT, true); } - else if (summon->GetEntry() == NPC_THE_CORE_OF_ENTROPIUS) - summon->GetMotionMaster()->MovePoint(0, summon->GetPositionX(), summon->GetPositionY(), 30.0f); + events.ScheduleEvent(eventId + 1, 8000); + break; + case EVENT_SCENE_19: + if (Creature* core = summons.GetCreatureWithEntry(NPC_THE_CORE_OF_ENTROPIUS)) + { + core->SetObjectScale(0.75f); + core->GetMotionMaster()->MovePoint(0, core->GetPositionX(), core->GetPositionY(), 28.0f); + } + events.ScheduleEvent(eventId + 1, 2000); + break; + case EVENT_SCENE_20: + if (Creature* core = summons.GetCreatureWithEntry(NPC_THE_CORE_OF_ENTROPIUS)) + core->CastSpell(core, SPELL_SUNWELL_IGNITION, true); + events.ScheduleEvent(eventId + 1, 3000); + break; + case EVENT_SCENE_21: + if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) + velen->AI()->Talk(SAY_VELEN_07); + events.ScheduleEvent(eventId + 1, 15000); + break; + case EVENT_SCENE_22: + if (Creature* liadrin = summons.GetCreatureWithEntry(NPC_LADY_LIADRIN)) + liadrin->AI()->Talk(SAY_LIADRIN_03); + events.ScheduleEvent(eventId + 1, 20000); + break; + case EVENT_SCENE_23: + if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) + velen->AI()->Talk(SAY_VELEN_08); + if (Creature* liadrin = summons.GetCreatureWithEntry(NPC_LADY_LIADRIN)) + liadrin->SetStandState(UNIT_STAND_STATE_KNEEL); + events.ScheduleEvent(eventId + 1, 8000); + break; + case EVENT_SCENE_24: + if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) + velen->AI()->Talk(SAY_VELEN_09); + events.ScheduleEvent(eventId + 1, 5000); + break; + case EVENT_SCENE_25: + if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) + { + velen->GetMotionMaster()->MovePoint(0, 1739.38f, 643.79f, 28.06f); + velen->DespawnOrUnsummon(5000); + } + events.ScheduleEvent(eventId + 1, 3000); + break; + case EVENT_SCENE_26: + for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr) + if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr)) + if (summon->GetEntry() == NPC_SHATTERED_SUN_SOLDIER) + { + summon->GetMotionMaster()->MovePoint(0, 1739.38f, 643.79f, 28.06f); + summon->DespawnOrUnsummon(summon->GetExactDist2d(1734.96f, 642.43f) * 100); + } + events.ScheduleEvent(eventId + 1, 7000); + break; + case EVENT_SCENE_27: + me->setActive(false); + summons.DespawnEntry(NPC_INERT_PORTAL); + summons.DespawnEntry(NPC_SHATTERED_SUN_RIFTWAKER); + break; } - - void UpdateAI(uint32 diff) override - { - events.Update(diff); - switch (uint32 eventId = events.ExecuteEvent()) - { - case EVENT_SCENE_01: - Talk(SAY_KALECGOS_GOODBYE); - events.ScheduleEvent(eventId + 1, 15000); - break; - case EVENT_SCENE_02: - me->SummonCreature(NPC_SHATTERED_SUN_RIFTWAKER, 1688.42f, 641.82f, 27.60f, 0.67f); - me->SummonCreature(NPC_SHATTERED_SUN_RIFTWAKER, 1712.58f, 616.29f, 27.78f, 0.76f); - events.ScheduleEvent(eventId + 1, 6000); - break; - case EVENT_SCENE_03: - me->SummonCreature(NPC_SHATTRATH_PORTAL_DUMMY, 1727.08f + cos(5.14f), 656.82f + std::sin(5.14f), 28.37f + 2.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 10000); - me->SummonCreature(NPC_SHATTRATH_PORTAL_DUMMY, 1738.84f + cos(2.0f), 627.32f + std::sin(2.0f), 28.26f + 2.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 10000); - events.ScheduleEvent(eventId + 1, 11000); - break; - case EVENT_SCENE_04: - me->SummonCreature(NPC_INERT_PORTAL, 1734.96f, 642.43f, 28.06f, 3.49f); - events.ScheduleEvent(eventId + 1, 4000); - break; - case EVENT_SCENE_05: - if (Creature* first = me->SummonCreature(NPC_SHATTERED_SUN_SOLDIER, 1729.48f, 640.49f, 28.06f, 3.49f)) - { - first->m_Events.AddEvent(new MoveDelayed(first, 1718.70f, 607.78f, 28.06f, 2.323f), first->m_Events.CalculateTime(5000)); - first->m_Events.AddEvent(new FixOrientation(first), first->m_Events.CalculateTime(12000)); - for (uint8 i = 0; i < 9; ++i) - if (Creature* follower = me->SummonCreature(NPC_SHATTERED_SUN_SOLDIER, 1729.48f + 5 * cos(i * 2.0f * M_PI / 9), 640.49f + 5 * std::sin(i * 2.0f * M_PI / 9), 28.06f, 3.49f)) - follower->GetMotionMaster()->MoveFollow(first, 3.0f, follower->GetAngle(first)); - } - events.ScheduleEvent(eventId + 1, 10000); - break; - case EVENT_SCENE_06: - if (Creature* first = me->SummonCreature(NPC_SHATTERED_SUN_SOLDIER, 1729.48f, 640.49f, 28.06f, 3.49f)) - { - first->m_Events.AddEvent(new MoveDelayed(first, 1678.69f, 649.27f, 28.06f, 5.46f), first->m_Events.CalculateTime(5000)); - first->m_Events.AddEvent(new FixOrientation(first), first->m_Events.CalculateTime(14500)); - for (uint8 i = 0; i < 9; ++i) - if (Creature* follower = me->SummonCreature(NPC_SHATTERED_SUN_SOLDIER, 1729.48f + 5 * cos(i * 2.0f * M_PI / 9), 640.49f + 5 * std::sin(i * 2.0f * M_PI / 9), 28.06f, 3.49f)) - follower->GetMotionMaster()->MoveFollow(first, 3.0f, follower->GetAngle(first)); - } - events.ScheduleEvent(eventId + 1, 12000); - break; - case EVENT_SCENE_07: - me->SummonCreature(NPC_LADY_LIADRIN, 1719.87f, 644.265f, 28.06f, 3.83f); - me->SummonCreature(NPC_PROPHET_VELEN, 1717.97f, 646.44f, 28.06f, 3.94f); - events.ScheduleEvent(eventId + 1, 7000); - break; - case EVENT_SCENE_08: - if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) - velen->AI()->Talk(SAY_VELEN_01); - events.ScheduleEvent(eventId + 1, 25000); - break; - case EVENT_SCENE_09: - if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) - velen->AI()->Talk(SAY_VELEN_02); - events.ScheduleEvent(eventId + 1, 14500); - break; - case EVENT_SCENE_10: - if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) - velen->AI()->Talk(SAY_VELEN_03); - events.ScheduleEvent(eventId + 1, 12500); - break; - case EVENT_SCENE_11: - me->SummonCreature(NPC_THE_CORE_OF_ENTROPIUS, 1698.86f, 628.73f, 92.83f, 0.0f); - if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) - velen->CastSpell(velen, SPELL_CALL_ENTROPIUS, false); - events.ScheduleEvent(eventId + 1, 8000); - break; - case EVENT_SCENE_12: - if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) - { - velen->InterruptNonMeleeSpells(false); - velen->AI()->Talk(SAY_VELEN_04); - } - events.ScheduleEvent(eventId + 1, 20000); - break; - case EVENT_SCENE_13: - if (Creature* liadrin = summons.GetCreatureWithEntry(NPC_LADY_LIADRIN)) - liadrin->GetMotionMaster()->MovePoint(0, 1711.28f, 637.29f, 27.29f); - events.ScheduleEvent(eventId + 1, 6000); - break; - case EVENT_SCENE_14: - if (Creature* liadrin = summons.GetCreatureWithEntry(NPC_LADY_LIADRIN)) - liadrin->AI()->Talk(SAY_LIADRIN_01); - events.ScheduleEvent(eventId + 1, 10000); - break; - case EVENT_SCENE_15: - if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) - velen->AI()->Talk(SAY_VELEN_05); - events.ScheduleEvent(eventId + 1, 14000); - break; - case EVENT_SCENE_16: - if (Creature* liadrin = summons.GetCreatureWithEntry(NPC_LADY_LIADRIN)) - liadrin->AI()->Talk(SAY_LIADRIN_02); - events.ScheduleEvent(eventId + 1, 2000); - break; - case EVENT_SCENE_17: - if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) - velen->AI()->Talk(SAY_VELEN_06); - events.ScheduleEvent(eventId + 1, 3000); - break; - case EVENT_SCENE_18: - if (Creature* core = summons.GetCreatureWithEntry(NPC_THE_CORE_OF_ENTROPIUS)) - { - core->RemoveAllAuras(); - core->CastSpell(core, SPELL_BLAZE_TO_LIGHT, true); - } - events.ScheduleEvent(eventId + 1, 8000); - break; - case EVENT_SCENE_19: - if (Creature* core = summons.GetCreatureWithEntry(NPC_THE_CORE_OF_ENTROPIUS)) - { - core->SetObjectScale(0.75f); - core->GetMotionMaster()->MovePoint(0, core->GetPositionX(), core->GetPositionY(), 28.0f); - } - events.ScheduleEvent(eventId + 1, 2000); - break; - case EVENT_SCENE_20: - if (Creature* core = summons.GetCreatureWithEntry(NPC_THE_CORE_OF_ENTROPIUS)) - core->CastSpell(core, SPELL_SUNWELL_IGNITION, true); - events.ScheduleEvent(eventId + 1, 3000); - break; - case EVENT_SCENE_21: - if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) - velen->AI()->Talk(SAY_VELEN_07); - events.ScheduleEvent(eventId + 1, 15000); - break; - case EVENT_SCENE_22: - if (Creature* liadrin = summons.GetCreatureWithEntry(NPC_LADY_LIADRIN)) - liadrin->AI()->Talk(SAY_LIADRIN_03); - events.ScheduleEvent(eventId + 1, 20000); - break; - case EVENT_SCENE_23: - if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) - velen->AI()->Talk(SAY_VELEN_08); - if (Creature* liadrin = summons.GetCreatureWithEntry(NPC_LADY_LIADRIN)) - liadrin->SetStandState(UNIT_STAND_STATE_KNEEL); - events.ScheduleEvent(eventId + 1, 8000); - break; - case EVENT_SCENE_24: - if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) - velen->AI()->Talk(SAY_VELEN_09); - events.ScheduleEvent(eventId + 1, 5000); - break; - case EVENT_SCENE_25: - if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN)) - { - velen->GetMotionMaster()->MovePoint(0, 1739.38f, 643.79f, 28.06f); - velen->DespawnOrUnsummon(5000); - } - events.ScheduleEvent(eventId + 1, 3000); - break; - case EVENT_SCENE_26: - for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr) - if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr)) - if (summon->GetEntry() == NPC_SHATTERED_SUN_SOLDIER) - { - summon->GetMotionMaster()->MovePoint(0, 1739.38f, 643.79f, 28.06f); - summon->DespawnOrUnsummon(summon->GetExactDist2d(1734.96f, 642.43f) * 100); - } - events.ScheduleEvent(eventId + 1, 7000); - break; - case EVENT_SCENE_27: - me->setActive(false); - summons.DespawnEntry(NPC_INERT_PORTAL); - summons.DespawnEntry(NPC_SHATTERED_SUN_RIFTWAKER); - break; - } - } - }; + } }; class spell_kiljaeden_shadow_spike_aura : public AuraScript @@ -1248,9 +1215,9 @@ class spell_kiljaeden_dragon_breath : public SpellScript void AddSC_boss_kiljaeden() { - new npc_kiljaeden_controller(); - new boss_kiljaeden(); - new npc_kalecgos_kj(); + RegisterSunwellPlateauCreatureAI(npc_kiljaeden_controller); + RegisterSunwellPlateauCreatureAI(boss_kiljaeden); + RegisterSunwellPlateauCreatureAI(npc_kalecgos_kj); RegisterSpellScript(spell_kiljaeden_shadow_spike_aura); RegisterSpellScript(spell_kiljaeden_sinister_reflection); RegisterSpellScript(spell_kiljaeden_sinister_reflection_clone); diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp index ade6501fa..a53becd5f 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp @@ -72,260 +72,227 @@ enum Misc DATA_NEGATIVE_ENERGY_TARGETS = 2 }; -class boss_muru : public CreatureScript +struct boss_muru : public BossAI { -public: - boss_muru() : CreatureScript("boss_muru") { } + boss_muru(Creature* creature) : BossAI(creature, DATA_MURU) { } - struct boss_muruAI : public BossAI + void Reset() override { - boss_muruAI(Creature* creature) : BossAI(creature, DATA_MURU) { } + BossAI::Reset(); + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->SetVisible(true); + } - void Reset() override + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + me->CastSpell(me, SPELL_NEGATIVE_ENERGY, true); + me->CastSpell(me, SPELL_SUMMON_BLOOD_ELVES_PERIODIC, true); + me->CastSpell(me, SPELL_OPEN_PORTAL_PERIODIC, true); + me->CastSpell(me, SPELL_DARKNESS_PERIODIC, true); + + events.ScheduleEvent(EVENT_SPELL_ENRAGE, 600000); + } + + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (damage >= me->GetHealth()) { - BossAI::Reset(); + damage = 0; + if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) + { + me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->RemoveAllAuras(); + me->CastSpell(me, SPELL_OPEN_ALL_PORTALS, true); + events.ScheduleEvent(EVENT_SUMMON_ENTROPIUS, 7000); + } + } + } + + void JustSummoned(Creature* summon) override + { + if (summon->GetEntry() == NPC_ENTROPIUS) + summon->AI()->SetData(DATA_ENRAGE_TIMER, events.GetNextEventTime(EVENT_SPELL_ENRAGE)); + else + { + if (!summon->IsTrigger()) + summon->SetInCombatWithZone(); + summons.Summon(summon); + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_SPELL_ENRAGE: + me->CastSpell(me, SPELL_ENRAGE, true); + break; + case EVENT_SUMMON_ENTROPIUS: + me->CastSpell(me, SPELL_SUMMON_ENTROPIUS, false); + events.ScheduleEvent(EVENT_SET_INVISIBLE, 1000); + break; + case EVENT_SET_INVISIBLE: + me->SetVisible(false); + break; + } + } +}; + +struct boss_entropius : public ScriptedAI +{ + boss_entropius(Creature* creature) : ScriptedAI(creature) { } + + EventMap events; + EventMap events2; + + void Reset() override + { + events.Reset(); + events2.Reset(); + events2.ScheduleEvent(EVENT_ENTROPIUS_AURAS, 0); + events2.ScheduleEvent(EVENT_ENTROPIUS_COMBAT, 3000); + me->SetReactState(REACT_PASSIVE); + } + + void EnterEvadeMode(EvadeReason why) override + { + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* muru = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_MURU))) + if (!muru->IsInEvadeMode()) + muru->AI()->EnterEvadeMode(why); + + me->DespawnOrUnsummon(); + } + + void JustEngagedWith(Unit* /*who*/) override + { + events.ScheduleEvent(EVENT_SPAWN_BLACK_HOLE, 15000); + events.ScheduleEvent(EVENT_SPAWN_DARKNESS, 10000); + } + + void SetData(uint32 type, uint32 data) override + { + if (type == DATA_ENRAGE_TIMER) + events.ScheduleEvent(EVENT_SPELL_ENRAGE, data); + } + + uint32 GetData(uint32 type) const override + { + if (type == DATA_NEGATIVE_ENERGY_TARGETS) + return 1 + uint32(events.GetTimer() / 12000); + return 0; + } + + void JustDied(Unit* /*killer*/) override + { + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* muru = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_MURU))) + Unit::Kill(muru, muru); + } + + void UpdateAI(uint32 diff) override + { + events2.Update(diff); + switch (events2.ExecuteEvent()) + { + case EVENT_ENTROPIUS_AURAS: + me->CastSpell(me, SPELL_ENTROPIUS_COSMETIC_SPAWN, false); + me->CastSpell(me, SPELL_NEGATIVE_ENERGY_PERIODIC, true); + break; + case EVENT_ENTROPIUS_COMBAT: me->SetReactState(REACT_AGGRESSIVE); - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->SetVisible(true); + me->SetInCombatWithZone(); + AttackStart(SelectTargetFromPlayerList(50.0f)); + break; } - void JustEngagedWith(Unit* who) override - { - BossAI::JustEngagedWith(who); - me->CastSpell(me, SPELL_NEGATIVE_ENERGY, true); - me->CastSpell(me, SPELL_SUMMON_BLOOD_ELVES_PERIODIC, true); - me->CastSpell(me, SPELL_OPEN_PORTAL_PERIODIC, true); - me->CastSpell(me, SPELL_DARKNESS_PERIODIC, true); - - events.ScheduleEvent(EVENT_SPELL_ENRAGE, 600000); - } - - void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (damage >= me->GetHealth()) - { - damage = 0; - if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) - { - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->RemoveAllAuras(); - me->CastSpell(me, SPELL_OPEN_ALL_PORTALS, true); - events.ScheduleEvent(EVENT_SUMMON_ENTROPIUS, 7000); - } - } - } - - void JustSummoned(Creature* summon) override - { - if (summon->GetEntry() == NPC_ENTROPIUS) - summon->AI()->SetData(DATA_ENRAGE_TIMER, events.GetNextEventTime(EVENT_SPELL_ENRAGE)); - else - { - if (!summon->IsTrigger()) - summon->SetInCombatWithZone(); - summons.Summon(summon); - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_SPELL_ENRAGE: - me->CastSpell(me, SPELL_ENRAGE, true); - break; - case EVENT_SUMMON_ENTROPIUS: - me->CastSpell(me, SPELL_SUMMON_ENTROPIUS, false); - events.ScheduleEvent(EVENT_SET_INVISIBLE, 1000); - break; - case EVENT_SET_INVISIBLE: - me->SetVisible(false); - break; - } - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetSunwellPlateauAI(creature); - } -}; - -class boss_entropius : public CreatureScript -{ -public: - boss_entropius() : CreatureScript("boss_entropius") { } - - struct boss_entropiusAI : public ScriptedAI - { - boss_entropiusAI(Creature* creature) : ScriptedAI(creature) { } - - EventMap events; - EventMap events2; - - void Reset() override - { - events.Reset(); - events2.Reset(); - events2.ScheduleEvent(EVENT_ENTROPIUS_AURAS, 0); - events2.ScheduleEvent(EVENT_ENTROPIUS_COMBAT, 3000); - me->SetReactState(REACT_PASSIVE); - } - - void EnterEvadeMode(EvadeReason why) override - { - if (InstanceScript* instance = me->GetInstanceScript()) - if (Creature* muru = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_MURU))) - if (!muru->IsInEvadeMode()) - muru->AI()->EnterEvadeMode(why); - - me->DespawnOrUnsummon(); - } - - void JustEngagedWith(Unit* /*who*/) override + if (!events2.Empty()) + return; + + if (!UpdateVictim()) + return; + + events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { + case EVENT_SPELL_ENRAGE: + me->CastSpell(me, SPELL_ENRAGE, true); + break; + case EVENT_SPAWN_DARKNESS: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true)) + me->CastSpell(target, SPELL_DARKNESS, true); + events.ScheduleEvent(EVENT_SPAWN_DARKNESS, 15000); + break; + case EVENT_SPAWN_BLACK_HOLE: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true)) + me->CastSpell(target, SPELL_BLACK_HOLE, true); events.ScheduleEvent(EVENT_SPAWN_BLACK_HOLE, 15000); - events.ScheduleEvent(EVENT_SPAWN_DARKNESS, 10000); + break; } - void SetData(uint32 type, uint32 data) override - { - if (type == DATA_ENRAGE_TIMER) - events.ScheduleEvent(EVENT_SPELL_ENRAGE, data); - } - - uint32 GetData(uint32 type) const override - { - if (type == DATA_NEGATIVE_ENERGY_TARGETS) - return 1 + uint32(events.GetTimer() / 12000); - return 0; - } - - void JustDied(Unit* /*killer*/) override - { - if (InstanceScript* instance = me->GetInstanceScript()) - if (Creature* muru = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_MURU))) - Unit::Kill(muru, muru); - } - - void UpdateAI(uint32 diff) override - { - events2.Update(diff); - switch (events2.ExecuteEvent()) - { - case EVENT_ENTROPIUS_AURAS: - me->CastSpell(me, SPELL_ENTROPIUS_COSMETIC_SPAWN, false); - me->CastSpell(me, SPELL_NEGATIVE_ENERGY_PERIODIC, true); - break; - case EVENT_ENTROPIUS_COMBAT: - me->SetReactState(REACT_AGGRESSIVE); - me->SetInCombatWithZone(); - AttackStart(SelectTargetFromPlayerList(50.0f)); - break; - } - - if (!events2.Empty()) - return; - - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_SPELL_ENRAGE: - me->CastSpell(me, SPELL_ENRAGE, true); - break; - case EVENT_SPAWN_DARKNESS: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true)) - me->CastSpell(target, SPELL_DARKNESS, true); - events.ScheduleEvent(EVENT_SPAWN_DARKNESS, 15000); - break; - case EVENT_SPAWN_BLACK_HOLE: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true)) - me->CastSpell(target, SPELL_BLACK_HOLE, true); - events.ScheduleEvent(EVENT_SPAWN_BLACK_HOLE, 15000); - break; - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetSunwellPlateauAI(creature); + DoMeleeAttackIfReady(); } }; -class npc_singularity : public CreatureScript +struct npc_singularity : public NullCreatureAI { -public: - npc_singularity() : CreatureScript("npc_singularity") { } - - CreatureAI* GetAI(Creature* creature) const override + npc_singularity(Creature* creature) : NullCreatureAI(creature) { - return GetSunwellPlateauAI(creature); } - struct npc_singularityAI : public NullCreatureAI + EventMap events; + + void Reset() override { - npc_singularityAI(Creature* creature) : NullCreatureAI(creature) - { - } + me->DespawnOrUnsummon(18000); + me->CastSpell(me, SPELL_BLACK_HOLE_SUMMON_VISUAL, true); + me->CastSpell(me, SPELL_BLACK_HOLE_SUMMON_VISUAL2, true); + events.ScheduleEvent(EVENT_START_BLACK_HOLE, 3500); + events.ScheduleEvent(EVENT_SWITCH_BLACK_HOLE_TARGET, 5000); + events.ScheduleEvent(EVENT_SINGULARITY_DEATH, 17000); + } - EventMap events; - - void Reset() override + void UpdateAI(uint32 diff) override + { + events.Update(diff); + switch (events.ExecuteEvent()) { - me->DespawnOrUnsummon(18000); - me->CastSpell(me, SPELL_BLACK_HOLE_SUMMON_VISUAL, true); - me->CastSpell(me, SPELL_BLACK_HOLE_SUMMON_VISUAL2, true); - events.ScheduleEvent(EVENT_START_BLACK_HOLE, 3500); - events.ScheduleEvent(EVENT_SWITCH_BLACK_HOLE_TARGET, 5000); - events.ScheduleEvent(EVENT_SINGULARITY_DEATH, 17000); - } - - void UpdateAI(uint32 diff) override + case EVENT_SINGULARITY_DEATH: + me->KillSelf(); + break; + case EVENT_START_BLACK_HOLE: + me->RemoveAurasDueToSpell(SPELL_BLACK_HOLE_SUMMON_VISUAL2); + me->CastSpell(me, SPELL_BLACK_HOLE_VISUAL2, true); + me->CastSpell(me, SPELL_BLACK_HOLE_PASSIVE, true); + break; + case EVENT_SWITCH_BLACK_HOLE_TARGET: { - events.Update(diff); - switch (events.ExecuteEvent()) - { - case EVENT_SINGULARITY_DEATH: - me->KillSelf(); - break; - case EVENT_START_BLACK_HOLE: - me->RemoveAurasDueToSpell(SPELL_BLACK_HOLE_SUMMON_VISUAL2); - me->CastSpell(me, SPELL_BLACK_HOLE_VISUAL2, true); - me->CastSpell(me, SPELL_BLACK_HOLE_PASSIVE, true); - break; - case EVENT_SWITCH_BLACK_HOLE_TARGET: + Map::PlayerList const& players = me->GetMap()->GetPlayers(); + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + if (Player* player = itr->GetSource()) + if (me->GetDistance2d(player) < 15.0f && player->GetPositionZ() < 72.0f && player->IsAlive() && !player->HasAura(SPELL_BLACK_HOLE_EFFECT)) { - Map::PlayerList const& players = me->GetMap()->GetPlayers(); - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - if (Player* player = itr->GetSource()) - if (me->GetDistance2d(player) < 15.0f && player->GetPositionZ() < 72.0f && player->IsAlive() && !player->HasAura(SPELL_BLACK_HOLE_EFFECT)) - { - me->GetMotionMaster()->MovePoint(0, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), false, true); - events.ScheduleEvent(EVENT_SWITCH_BLACK_HOLE_TARGET, 5000); - return; - } - events.ScheduleEvent(EVENT_SWITCH_BLACK_HOLE_TARGET, 500); - break; + me->GetMotionMaster()->MovePoint(0, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), false, true); + events.ScheduleEvent(EVENT_SWITCH_BLACK_HOLE_TARGET, 5000); + return; } - } + events.ScheduleEvent(EVENT_SWITCH_BLACK_HOLE_TARGET, 500); + break; } - }; + } + } }; class spell_muru_summon_blood_elves_periodic_aura : public AuraScript @@ -475,9 +442,9 @@ class spell_entropius_black_hole_effect : public SpellScript void AddSC_boss_muru() { - new boss_muru(); - new boss_entropius(); - new npc_singularity(); + RegisterSunwellPlateauCreatureAI(boss_muru); + RegisterSunwellPlateauCreatureAI(boss_entropius); + RegisterSunwellPlateauCreatureAI(npc_singularity); RegisterSpellScript(spell_muru_summon_blood_elves_periodic_aura); RegisterSpellScript(spell_muru_darkness_aura); diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h b/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h index d9a3af630..e6e993d64 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/sunwell_plateau.h @@ -105,4 +105,6 @@ inline AI* GetSunwellPlateauAI(T* obj) return GetInstanceAI(obj, SWPScriptName); } +#define RegisterSunwellPlateauCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetSunwellPlateauAI) + #endif // SUNWELL_PLATEAU_H