aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp446
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp717
2 files changed, 551 insertions, 612 deletions
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp
index 09aff3b741f..33a133b37cf 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp
@@ -64,284 +64,268 @@ enum Spells
SPELL_INTRO_ENCAPSULATE_CHANELLING = 45661
};
-class boss_brutallus : public CreatureScript
+struct boss_brutallus : public BossAI
{
-public:
- boss_brutallus() : CreatureScript("boss_brutallus") { }
+ boss_brutallus(Creature* creature) : BossAI(creature, DATA_BRUTALLUS)
+ {
+ Initialize();
+ Intro = true;
+ }
- struct boss_brutallusAI : public ScriptedAI
+ void Initialize()
{
- boss_brutallusAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- Intro = true;
- }
+ SlashTimer = 11000;
+ StompTimer = 30000;
+ BurnTimer = 60000;
+ BerserkTimer = 360000;
- void Initialize()
- {
- SlashTimer = 11000;
- StompTimer = 30000;
- BurnTimer = 60000;
- BerserkTimer = 360000;
+ IntroPhase = 0;
+ IntroPhaseTimer = 0;
+ IntroFrostBoltTimer = 0;
- IntroPhase = 0;
- IntroPhaseTimer = 0;
- IntroFrostBoltTimer = 0;
+ IsIntro = false;
+ Enraged = false;
+ }
- IsIntro = false;
- Enraged = false;
- }
+ uint32 SlashTimer;
+ uint32 BurnTimer;
+ uint32 StompTimer;
+ uint32 BerserkTimer;
- InstanceScript* instance;
+ uint32 IntroPhase;
+ uint32 IntroPhaseTimer;
+ uint32 IntroFrostBoltTimer;
- uint32 SlashTimer;
- uint32 BurnTimer;
- uint32 StompTimer;
- uint32 BerserkTimer;
+ bool Intro;
+ bool IsIntro;
+ bool Enraged;
- uint32 IntroPhase;
- uint32 IntroPhaseTimer;
- uint32 IntroFrostBoltTimer;
+ void Reset() override
+ {
+ Initialize();
- bool Intro;
- bool IsIntro;
- bool Enraged;
+ DoCast(me, SPELL_DUAL_WIELD, true);
- void Reset() override
- {
- Initialize();
+ BossAI::Reset();
+ }
- DoCast(me, SPELL_DUAL_WIELD, true);
+ void JustEngagedWith(Unit* who) override
+ {
+ Talk(YELL_AGGRO);
- instance->SetBossState(DATA_BRUTALLUS, NOT_STARTED);
- }
+ BossAI::JustEngagedWith(who);
+ }
- void JustEngagedWith(Unit* /*who*/) override
- {
- Talk(YELL_AGGRO);
+ void KilledUnit(Unit* /*victim*/) override
+ {
+ Talk(YELL_KILL);
+ }
- instance->SetBossState(DATA_BRUTALLUS, IN_PROGRESS);
- }
+ void JustDied(Unit* killer) override
+ {
+ Talk(YELL_DEATH);
- void KilledUnit(Unit* /*victim*/) override
- {
- Talk(YELL_KILL);
- }
+ instance->SetBossState(DATA_FELMYST, SPECIAL);
+ BossAI::JustDied(killer);
+ }
- void JustDied(Unit* /*killer*/) override
- {
- Talk(YELL_DEATH);
+ void EnterEvadeMode(EvadeReason why) override
+ {
+ if (!Intro)
+ BossAI::EnterEvadeMode(why);
+ }
- instance->SetBossState(DATA_BRUTALLUS, DONE);
- float x, y, z;
- me->GetPosition(x, y, z);
- me->SummonCreature(NPC_FELMYST, x, y, z + 30, me->GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN);
- }
+ void StartIntro()
+ {
+ if (!Intro || IsIntro)
+ return;
- void EnterEvadeMode(EvadeReason why) override
+ if (Creature* Madrigosa = instance->GetCreature(DATA_MADRIGOSA))
{
- if (!Intro)
- ScriptedAI::EnterEvadeMode(why);
+ Madrigosa->Respawn();
+ Madrigosa->setActive(true);
+ Madrigosa->SetFarVisible(true);
+ IsIntro = true;
+ Madrigosa->SetMaxHealth(me->GetMaxHealth());
+ Madrigosa->SetHealth(me->GetMaxHealth());
+ me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
+ me->Attack(Madrigosa, true);
+ Madrigosa->Attack(me, true);
}
-
- void StartIntro()
+ else
{
- if (!Intro || IsIntro)
- return;
-
- if (Creature* Madrigosa = instance->GetCreature(DATA_MADRIGOSA))
- {
- Madrigosa->Respawn();
- Madrigosa->setActive(true);
- Madrigosa->SetFarVisible(true);
- IsIntro = true;
- Madrigosa->SetMaxHealth(me->GetMaxHealth());
- Madrigosa->SetHealth(me->GetMaxHealth());
- me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
- me->Attack(Madrigosa, true);
- Madrigosa->Attack(me, true);
- }
- else
- {
- // Madrigosa not found, end intro
- TC_LOG_ERROR("scripts", "Madrigosa was not found");
- EndIntro();
- }
+ // Madrigosa not found, end intro
+ TC_LOG_ERROR("scripts", "Madrigosa was not found");
+ EndIntro();
}
+ }
- void EndIntro()
- {
- me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
- Intro = false;
- IsIntro = false;
- }
+ void EndIntro()
+ {
+ me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
+ Intro = false;
+ IsIntro = false;
+ }
- void AttackStart(Unit* who) override
- {
- if (!who || Intro || IsIntro)
- return;
- ScriptedAI::AttackStart(who);
- }
+ void AttackStart(Unit* who) override
+ {
+ if (!who || Intro || IsIntro)
+ return;
+ BossAI::AttackStart(who);
+ }
- void DoIntro()
- {
- Creature* Madrigosa = instance->GetCreature(DATA_MADRIGOSA);
- if (!Madrigosa)
- return;
+ void DoIntro()
+ {
+ Creature* Madrigosa = instance->GetCreature(DATA_MADRIGOSA);
+ if (!Madrigosa)
+ return;
- switch (IntroPhase)
- {
- case 0:
- Madrigosa->AI()->Talk(YELL_MADR_ICE_BARRIER);
- IntroPhaseTimer = 7000;
- ++IntroPhase;
- break;
- case 1:
- me->SetFacingToObject(Madrigosa);
- Madrigosa->SetFacingToObject(me);
- Madrigosa->AI()->Talk(YELL_MADR_INTRO, me);
- IntroPhaseTimer = 9000;
- ++IntroPhase;
- break;
- case 2:
- Talk(YELL_INTRO, Madrigosa);
- IntroPhaseTimer = 13000;
- ++IntroPhase;
- break;
- case 3:
- DoCast(me, SPELL_INTRO_FROST_BLAST);
- Madrigosa->SetDisableGravity(true);
- me->AttackStop();
- Madrigosa->AttackStop();
- IntroFrostBoltTimer = 3000;
- IntroPhaseTimer = 28000;
- ++IntroPhase;
- break;
- case 4:
- Talk(YELL_INTRO_BREAK_ICE);
- IntroPhaseTimer = 6000;
- ++IntroPhase;
- break;
- case 5:
- Madrigosa->CastSpell(me, SPELL_INTRO_ENCAPSULATE_CHANELLING, false);
- Madrigosa->AI()->Talk(YELL_MADR_TRAP);
- DoCast(me, SPELL_INTRO_ENCAPSULATE);
- IntroPhaseTimer = 11000;
- ++IntroPhase;
- break;
- case 6:
- Talk(YELL_INTRO_CHARGE);
- IntroPhaseTimer = 5000;
- ++IntroPhase;
- break;
- case 7:
- Unit::Kill(me, Madrigosa);
- Madrigosa->AI()->Talk(YELL_MADR_DEATH);
- me->SetFullHealth();
- me->AttackStop();
- IntroPhaseTimer = 4000;
- ++IntroPhase;
- break;
- case 8:
- Talk(YELL_INTRO_KILL_MADRIGOSA);
- me->SetOrientation(0.14f);
- me->StopMoving();
- Madrigosa->setDeathState(CORPSE);
- IntroPhaseTimer = 8000;
- ++IntroPhase;
- break;
- case 9:
- Talk(YELL_INTRO_TAUNT);
- IntroPhaseTimer = 5000;
- ++IntroPhase;
- break;
- case 10:
- EndIntro();
- break;
- }
+ switch (IntroPhase)
+ {
+ case 0:
+ Madrigosa->AI()->Talk(YELL_MADR_ICE_BARRIER);
+ IntroPhaseTimer = 7000;
+ ++IntroPhase;
+ break;
+ case 1:
+ me->SetFacingToObject(Madrigosa);
+ Madrigosa->SetFacingToObject(me);
+ Madrigosa->AI()->Talk(YELL_MADR_INTRO, me);
+ IntroPhaseTimer = 9000;
+ ++IntroPhase;
+ break;
+ case 2:
+ Talk(YELL_INTRO, Madrigosa);
+ IntroPhaseTimer = 13000;
+ ++IntroPhase;
+ break;
+ case 3:
+ DoCast(me, SPELL_INTRO_FROST_BLAST);
+ Madrigosa->SetDisableGravity(true);
+ me->AttackStop();
+ Madrigosa->AttackStop();
+ IntroFrostBoltTimer = 3000;
+ IntroPhaseTimer = 28000;
+ ++IntroPhase;
+ break;
+ case 4:
+ Talk(YELL_INTRO_BREAK_ICE);
+ IntroPhaseTimer = 6000;
+ ++IntroPhase;
+ break;
+ case 5:
+ Madrigosa->CastSpell(me, SPELL_INTRO_ENCAPSULATE_CHANELLING, false);
+ Madrigosa->AI()->Talk(YELL_MADR_TRAP);
+ DoCast(me, SPELL_INTRO_ENCAPSULATE);
+ IntroPhaseTimer = 11000;
+ ++IntroPhase;
+ break;
+ case 6:
+ Talk(YELL_INTRO_CHARGE);
+ IntroPhaseTimer = 5000;
+ ++IntroPhase;
+ break;
+ case 7:
+ Unit::Kill(me, Madrigosa);
+ Madrigosa->AI()->Talk(YELL_MADR_DEATH);
+ me->SetFullHealth();
+ me->AttackStop();
+ IntroPhaseTimer = 4000;
+ ++IntroPhase;
+ break;
+ case 8:
+ Talk(YELL_INTRO_KILL_MADRIGOSA);
+ me->SetOrientation(0.14f);
+ me->StopMoving();
+ Madrigosa->setDeathState(CORPSE);
+ IntroPhaseTimer = 8000;
+ ++IntroPhase;
+ break;
+ case 9:
+ Talk(YELL_INTRO_TAUNT);
+ IntroPhaseTimer = 5000;
+ ++IntroPhase;
+ break;
+ case 10:
+ EndIntro();
+ break;
}
+ }
- void MoveInLineOfSight(Unit* who) override
- {
- if (!me->IsValidAttackTarget(who))
- return;
+ void MoveInLineOfSight(Unit* who) override
+ {
+ if (!me->IsValidAttackTarget(who))
+ return;
- if (Intro)
- instance->SetBossState(DATA_BRUTALLUS, SPECIAL);
+ if (Intro)
+ instance->SetBossState(DATA_BRUTALLUS, SPECIAL);
- if (Intro && !IsIntro)
- StartIntro();
+ if (Intro && !IsIntro)
+ StartIntro();
- if (!Intro)
- ScriptedAI::MoveInLineOfSight(who);
- }
+ if (!Intro)
+ BossAI::MoveInLineOfSight(who);
+ }
- void UpdateAI(uint32 diff) override
+ void UpdateAI(uint32 diff) override
+ {
+ if (IsIntro)
{
- if (IsIntro)
- {
- if (IntroPhaseTimer <= diff)
- DoIntro();
- else IntroPhaseTimer -= diff;
+ if (IntroPhaseTimer <= diff)
+ DoIntro();
+ else IntroPhaseTimer -= diff;
- if (IntroPhase == 3 + 1)
+ if (IntroPhase == 3 + 1)
+ {
+ if (IntroFrostBoltTimer <= diff)
{
- if (IntroFrostBoltTimer <= diff)
+ if (Creature* Madrigosa = instance->GetCreature(DATA_MADRIGOSA))
{
- if (Creature* Madrigosa = instance->GetCreature(DATA_MADRIGOSA))
- {
- Madrigosa->CastSpell(me, SPELL_INTRO_FROSTBOLT, true);
- IntroFrostBoltTimer = 2000;
- }
+ Madrigosa->CastSpell(me, SPELL_INTRO_FROSTBOLT, true);
+ IntroFrostBoltTimer = 2000;
}
- else
- IntroFrostBoltTimer -= diff;
}
-
- if (!UpdateVictim())
- return;
-
- DoMeleeAttackIfReady();
+ else
+ IntroFrostBoltTimer -= diff;
}
- if (!UpdateVictim() || IsIntro)
+ if (!UpdateVictim())
return;
- if (SlashTimer <= diff)
- {
- DoCastVictim(SPELL_METEOR_SLASH);
- SlashTimer = 11000;
- } else SlashTimer -= diff;
+ DoMeleeAttackIfReady();
+ }
- if (StompTimer <= diff)
- {
- Talk(YELL_LOVE);
- DoCastVictim(SPELL_STOMP);
- StompTimer = 30000;
- } else StompTimer -= diff;
+ if (!UpdateVictim() || IsIntro)
+ return;
- if (BurnTimer <= diff)
- {
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true, true, -SPELL_BURN))
- target->CastSpell(target, SPELL_BURN, true);
- BurnTimer = urand(60000, 180000);
- } else BurnTimer -= diff;
+ if (SlashTimer <= diff)
+ {
+ DoCastVictim(SPELL_METEOR_SLASH);
+ SlashTimer = 11000;
+ } else SlashTimer -= diff;
- if (BerserkTimer < diff && !Enraged)
- {
- Talk(YELL_BERSERK);
- DoCast(me, SPELL_BERSERK);
- Enraged = true;
- } else BerserkTimer -= diff;
+ if (StompTimer <= diff)
+ {
+ Talk(YELL_LOVE);
+ DoCastVictim(SPELL_STOMP);
+ StompTimer = 30000;
+ } else StompTimer -= diff;
- DoMeleeAttackIfReady();
- }
- };
+ if (BurnTimer <= diff)
+ {
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true, true, -SPELL_BURN))
+ target->CastSpell(target, SPELL_BURN, true);
+ BurnTimer = urand(60000, 180000);
+ } else BurnTimer -= diff;
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetSunwellPlateauAI<boss_brutallusAI>(creature);
+ if (BerserkTimer < diff && !Enraged)
+ {
+ Talk(YELL_BERSERK);
+ DoCast(me, SPELL_BERSERK);
+ Enraged = true;
+ } else BerserkTimer -= diff;
+
+ DoMeleeAttackIfReady();
}
};
@@ -385,7 +369,7 @@ class spell_brutallus_stomp : public SpellScript
void AddSC_boss_brutallus()
{
- new boss_brutallus();
+ RegisterSunwellPlateauCreatureAI(boss_brutallus);
RegisterSpellScript(spell_brutallus_burn);
RegisterSpellScript(spell_brutallus_stomp);
}
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp
index ebaf536ccdb..90f959b4667 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp
@@ -22,12 +22,11 @@ SDComment:
EndScriptData */
#include "ScriptMgr.h"
-#include "CellImpl.h"
-#include "GridNotifiersImpl.h"
#include "InstanceScript.h"
#include "MotionMaster.h"
#include "ObjectAccessor.h"
#include "ScriptedCreature.h"
+#include "SpellInfo.h"
#include "sunwell_plateau.h"
#include "TemporarySummon.h"
@@ -109,472 +108,428 @@ enum EventFelmyst
EVENT_SUMMON_FOG
};
-class boss_felmyst : public CreatureScript
+struct boss_felmyst : public BossAI
{
-public:
- boss_felmyst() : CreatureScript("boss_felmyst") { }
+ boss_felmyst(Creature* creature) : BossAI(creature, DATA_FELMYST)
+ {
+ Initialize();
+ uiBreathCount = 0;
+ breathX = 0.f;
+ breathY = 0.f;
+ }
- struct boss_felmystAI : public ScriptedAI
+ void Initialize()
{
- boss_felmystAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- uiBreathCount = 0;
- breathX = 0.f;
- breathY = 0.f;
- }
+ phase = PHASE_NONE;
+ uiFlightCount = 0;
+ }
- void Initialize()
- {
- phase = PHASE_NONE;
- uiFlightCount = 0;
- }
+ PhaseFelmyst phase;
- InstanceScript* instance;
- PhaseFelmyst phase;
- EventMap events;
+ uint32 uiFlightCount;
+ uint32 uiBreathCount;
- uint32 uiFlightCount;
- uint32 uiBreathCount;
+ float breathX, breathY;
- float breathX, breathY;
+ void Reset() override
+ {
+ Initialize();
- void Reset() override
- {
- Initialize();
+ BossAI::Reset();
- events.Reset();
+ me->SetDisableGravity(true);
+ me->SetBoundingRadius(10);
+ me->SetCombatReach(10);
+ }
- me->SetDisableGravity(true);
- me->SetBoundingRadius(10);
- me->SetCombatReach(10);
+ void JustEngagedWith(Unit* who) override
+ {
+ BossAI::JustEngagedWith(who);
- DespawnSummons(NPC_VAPOR_TRAIL);
- me->setActive(false);
+ events.ScheduleEvent(EVENT_BERSERK, 10min);
- instance->SetBossState(DATA_FELMYST, NOT_STARTED);
- }
+ DoCast(me, AURA_SUNWELL_RADIANCE, true);
+ DoCast(me, AURA_NOXIOUS_FUMES, true);
+ EnterPhase(PHASE_GROUND);
+ }
- void JustEngagedWith(Unit* /*who*/) override
- {
- events.ScheduleEvent(EVENT_BERSERK, 10min);
+ void AttackStart(Unit* who) override
+ {
+ if (phase != PHASE_FLIGHT)
+ BossAI::AttackStart(who);
+ }
- me->setActive(true);
- DoZoneInCombat();
- DoCast(me, AURA_SUNWELL_RADIANCE, true);
- DoCast(me, AURA_NOXIOUS_FUMES, true);
- EnterPhase(PHASE_GROUND);
+ void MoveInLineOfSight(Unit* who) override
+ {
+ if (phase != PHASE_FLIGHT)
+ BossAI::MoveInLineOfSight(who);
+ }
- instance->SetBossState(DATA_FELMYST, IN_PROGRESS);
- }
+ void KilledUnit(Unit* /*victim*/) override
+ {
+ Talk(YELL_KILL);
+ }
- void AttackStart(Unit* who) override
- {
- if (phase != PHASE_FLIGHT)
- ScriptedAI::AttackStart(who);
- }
+ void JustAppeared() override
+ {
+ Talk(YELL_BIRTH);
+ }
- void MoveInLineOfSight(Unit* who) override
- {
- if (phase != PHASE_FLIGHT)
- ScriptedAI::MoveInLineOfSight(who);
- }
+ void JustDied(Unit* killer) override
+ {
+ Talk(YELL_DEATH);
- void KilledUnit(Unit* /*victim*/) override
- {
- Talk(YELL_KILL);
- }
+ BossAI::JustDied(killer);
+ }
- void JustAppeared() override
- {
- Talk(YELL_BIRTH);
- }
+ void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override
+ {
+ Unit* unitCaster = caster->ToUnit();
+ if (!unitCaster)
+ return;
- void JustDied(Unit* /*killer*/) override
+ // workaround for linked aura
+ /*if (spell->Id == SPELL_VAPOR_FORCE)
{
- Talk(YELL_DEATH);
-
- instance->SetBossState(DATA_FELMYST, DONE);
- }
-
- void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override
+ caster->CastSpell(caster, SPELL_VAPOR_TRIGGER, true);
+ }*/
+ // workaround for mind control
+ if (spellInfo->Id == SPELL_FOG_INFORM)
{
- Unit* unitCaster = caster->ToUnit();
- if (!unitCaster)
- return;
-
- // workaround for linked aura
- /*if (spell->Id == SPELL_VAPOR_FORCE)
- {
- caster->CastSpell(caster, SPELL_VAPOR_TRIGGER, true);
- }*/
- // workaround for mind control
- if (spellInfo->Id == SPELL_FOG_INFORM)
+ float x, y, z;
+ unitCaster->GetPosition(x, y, z);
+ if (Unit* summon = me->SummonCreature(NPC_DEAD, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s))
{
- float x, y, z;
- unitCaster->GetPosition(x, y, z);
- if (Unit* summon = me->SummonCreature(NPC_DEAD, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s))
- {
- summon->SetMaxHealth(unitCaster->GetMaxHealth());
- summon->SetHealth(unitCaster->GetMaxHealth());
- summon->CastSpell(summon, SPELL_FOG_CHARM, true);
- summon->CastSpell(summon, SPELL_FOG_CHARM2, true);
- }
- Unit::DealDamage(me, unitCaster, unitCaster->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ summon->SetMaxHealth(unitCaster->GetMaxHealth());
+ summon->SetHealth(unitCaster->GetMaxHealth());
+ summon->CastSpell(summon, SPELL_FOG_CHARM, true);
+ summon->CastSpell(summon, SPELL_FOG_CHARM2, true);
}
+ Unit::DealDamage(me, unitCaster, unitCaster->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
}
+ }
- void JustSummoned(Creature* summon) override
+ void JustSummoned(Creature* summon) override
+ {
+ if (summon->GetEntry() == NPC_DEAD)
{
- if (summon->GetEntry() == NPC_DEAD)
- {
- summon->AI()->AttackStart(SelectTarget(SelectTargetMethod::Random));
- DoZoneInCombat(summon);
- summon->CastSpell(summon, SPELL_DEAD_PASSIVE, true);
- }
+ summon->AI()->AttackStart(SelectTarget(SelectTargetMethod::Random));
+ DoZoneInCombat(summon);
+ summon->CastSpell(summon, SPELL_DEAD_PASSIVE, true);
}
- void MovementInform(uint32, uint32) override
- {
- if (phase == PHASE_FLIGHT)
- events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 1ms);
- }
+ BossAI::JustSummoned(summon);
+ }
- void DamageTaken(Unit*, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
+ void MovementInform(uint32, uint32) override
+ {
+ if (phase == PHASE_FLIGHT)
+ events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 1ms);
+ }
+
+ void DamageTaken(Unit*, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
+ {
+ if (phase != PHASE_GROUND && damage >= me->GetHealth())
+ damage = 0;
+ }
+
+ void EnterPhase(PhaseFelmyst NextPhase)
+ {
+ switch (NextPhase)
{
- if (phase != PHASE_GROUND && damage >= me->GetHealth())
- damage = 0;
+ case PHASE_GROUND:
+ me->CastStop(SPELL_FOG_BREATH);
+ me->RemoveAurasDueToSpell(SPELL_FOG_BREATH);
+ me->StopMoving();
+ me->SetSpeedRate(MOVE_RUN, 2.0f);
+
+ events.ScheduleEvent(EVENT_CLEAVE, 5s, 10s);
+ events.ScheduleEvent(EVENT_CORROSION, 10s, 20s);
+ events.ScheduleEvent(EVENT_GAS_NOVA, 15s, 20s);
+ events.ScheduleEvent(EVENT_ENCAPSULATE, 20s, 25s);
+ events.ScheduleEvent(EVENT_FLIGHT, 1min);
+ break;
+ case PHASE_FLIGHT:
+ me->SetDisableGravity(true);
+ events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 1s);
+ uiFlightCount = 0;
+ uiBreathCount = 0;
+ break;
+ default:
+ break;
}
+ phase = NextPhase;
+ }
- void EnterPhase(PhaseFelmyst NextPhase)
+ void HandleFlightSequence()
+ {
+ switch (uiFlightCount)
{
- switch (NextPhase)
+ case 0:
+ //me->AttackStop();
+ me->GetMotionMaster()->Clear();
+ me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
+ me->StopMoving();
+ Talk(YELL_TAKEOFF);
+ events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 2s);
+ break;
+ case 1:
+ me->GetMotionMaster()->MovePoint(0, me->GetPositionX()+1, me->GetPositionY(), me->GetPositionZ()+10);
+ break;
+ case 2:
{
- case PHASE_GROUND:
- me->CastStop(SPELL_FOG_BREATH);
- me->RemoveAurasDueToSpell(SPELL_FOG_BREATH);
- me->StopMoving();
- me->SetSpeedRate(MOVE_RUN, 2.0f);
+ Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 150, true);
+ if (!target)
+ target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_PLAYER_GUID));
- events.ScheduleEvent(EVENT_CLEAVE, 5s, 10s);
- events.ScheduleEvent(EVENT_CORROSION, 10s, 20s);
- events.ScheduleEvent(EVENT_GAS_NOVA, 15s, 20s);
- events.ScheduleEvent(EVENT_ENCAPSULATE, 20s, 25s);
- events.ScheduleEvent(EVENT_FLIGHT, 1min);
- break;
- case PHASE_FLIGHT:
- me->SetDisableGravity(true);
- events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 1s);
- uiFlightCount = 0;
- uiBreathCount = 0;
- break;
- default:
- break;
- }
- phase = NextPhase;
- }
+ if (!target)
+ {
+ EnterEvadeMode();
+ return;
+ }
- void HandleFlightSequence()
- {
- switch (uiFlightCount)
- {
- case 0:
- //me->AttackStop();
- me->GetMotionMaster()->Clear();
- me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
- me->StopMoving();
- Talk(YELL_TAKEOFF);
- events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 2s);
- break;
- case 1:
- me->GetMotionMaster()->MovePoint(0, me->GetPositionX()+1, me->GetPositionY(), me->GetPositionZ()+10);
- break;
- case 2:
+ if (Creature* Vapor = me->SummonCreature(NPC_VAPOR, target->GetPositionX() - 5 + rand32() % 10, target->GetPositionY() - 5 + rand32() % 10, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 9s))
{
- Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 150, true);
- if (!target)
- target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_PLAYER_GUID));
+ Vapor->AI()->AttackStart(target);
+ me->InterruptNonMeleeSpells(false);
+ DoCast(Vapor, SPELL_VAPOR_CHANNEL, false); // core bug
+ Vapor->CastSpell(Vapor, SPELL_VAPOR_TRIGGER, true);
+ }
- if (!target)
- {
- EnterEvadeMode();
- return;
- }
+ events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 10s);
+ break;
+ }
+ case 3:
+ {
+ DespawnSummons(NPC_VAPOR_TRAIL);
+ //DoCast(me, SPELL_VAPOR_SELECT); need core support
- if (Creature* Vapor = me->SummonCreature(NPC_VAPOR, target->GetPositionX() - 5 + rand32() % 10, target->GetPositionY() - 5 + rand32() % 10, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 9s))
- {
- Vapor->AI()->AttackStart(target);
- me->InterruptNonMeleeSpells(false);
- DoCast(Vapor, SPELL_VAPOR_CHANNEL, false); // core bug
- Vapor->CastSpell(Vapor, SPELL_VAPOR_TRIGGER, true);
- }
+ Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 150, true);
+ if (!target)
+ target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_PLAYER_GUID));
- events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 10s);
- break;
- }
- case 3:
+ if (!target)
{
- DespawnSummons(NPC_VAPOR_TRAIL);
- //DoCast(me, SPELL_VAPOR_SELECT); need core support
-
- Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 150, true);
- if (!target)
- target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_PLAYER_GUID));
+ EnterEvadeMode();
+ return;
+ }
- if (!target)
- {
- EnterEvadeMode();
- return;
- }
+ //target->CastSpell(target, SPELL_VAPOR_SUMMON, true); need core support
+ if (Creature* pVapor = me->SummonCreature(NPC_VAPOR, target->GetPositionX() - 5 + rand32() % 10, target->GetPositionY() - 5 + rand32() % 10, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 9s))
+ {
+ if (pVapor->AI())
+ pVapor->AI()->AttackStart(target);
+ me->InterruptNonMeleeSpells(false);
+ DoCast(pVapor, SPELL_VAPOR_CHANNEL, false); // core bug
+ pVapor->CastSpell(pVapor, SPELL_VAPOR_TRIGGER, true);
+ }
- //target->CastSpell(target, SPELL_VAPOR_SUMMON, true); need core support
- if (Creature* pVapor = me->SummonCreature(NPC_VAPOR, target->GetPositionX() - 5 + rand32() % 10, target->GetPositionY() - 5 + rand32() % 10, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 9s))
- {
- if (pVapor->AI())
- pVapor->AI()->AttackStart(target);
- me->InterruptNonMeleeSpells(false);
- DoCast(pVapor, SPELL_VAPOR_CHANNEL, false); // core bug
- pVapor->CastSpell(pVapor, SPELL_VAPOR_TRIGGER, true);
- }
+ events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 10s);
+ break;
+ }
+ case 4:
+ DespawnSummons(NPC_VAPOR_TRAIL);
+ events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 1ms);
+ break;
+ case 5:
+ {
+ Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 150, true);
+ if (!target)
+ target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_PLAYER_GUID));
- events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 10s);
- break;
+ if (!target)
+ {
+ EnterEvadeMode();
+ return;
}
- case 4:
- DespawnSummons(NPC_VAPOR_TRAIL);
- events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 1ms);
- break;
- case 5:
+
+ breathX = target->GetPositionX();
+ breathY = target->GetPositionY();
+ float x, y, z;
+ target->GetContactPoint(me, x, y, z, 70);
+ me->GetMotionMaster()->MovePoint(0, x, y, z+10);
+ break;
+ }
+ case 6:
+ me->SetFacingTo(me->GetAbsoluteAngle(breathX, breathY));
+ //DoTextEmote("takes a deep breath.", nullptr);
+ events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 10s);
+ break;
+ case 7:
+ {
+ DoCast(me, SPELL_FOG_BREATH, true);
+ float x, y, z;
+ me->GetPosition(x, y, z);
+ x = 2 * breathX - x;
+ y = 2 * breathY - y;
+ me->GetMotionMaster()->MovePoint(0, x, y, z);
+ events.ScheduleEvent(EVENT_SUMMON_FOG, 1ms);
+ break;
+ }
+ case 8:
+ me->CastStop(SPELL_FOG_BREATH);
+ me->RemoveAurasDueToSpell(SPELL_FOG_BREATH);
+ ++uiBreathCount;
+ events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 1ms);
+ if (uiBreathCount < 3)
+ uiFlightCount = 4;
+ break;
+ case 9:
+ if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat))
+ DoStartMovement(target);
+ else
{
- Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 150, true);
- if (!target)
- target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_PLAYER_GUID));
+ EnterEvadeMode();
+ return;
+ }
+ break;
+ case 10:
+ me->SetDisableGravity(false);
+ me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
+ EnterPhase(PHASE_GROUND);
+ AttackStart(SelectTarget(SelectTargetMethod::MaxThreat));
+ break;
+ }
+ ++uiFlightCount;
+ }
- if (!target)
- {
- EnterEvadeMode();
- return;
- }
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ {
+ if (phase == PHASE_FLIGHT && !me->IsInEvadeMode())
+ EnterEvadeMode();
+ return;
+ }
+
+ events.Update(diff);
- breathX = target->GetPositionX();
- breathY = target->GetPositionY();
- float x, y, z;
- target->GetContactPoint(me, x, y, z, 70);
- me->GetMotionMaster()->MovePoint(0, x, y, z+10);
+ if (me->IsNonMeleeSpellCast(false))
+ return;
+
+ if (phase == PHASE_GROUND)
+ {
+ switch (events.ExecuteEvent())
+ {
+ case EVENT_BERSERK:
+ Talk(YELL_BERSERK);
+ DoCast(me, SPELL_BERSERK, true);
+ events.ScheduleEvent(EVENT_BERSERK, 10s);
break;
- }
- case 6:
- me->SetFacingTo(me->GetAbsoluteAngle(breathX, breathY));
- //DoTextEmote("takes a deep breath.", nullptr);
- events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 10s);
+ case EVENT_CLEAVE:
+ DoCastVictim(SPELL_CLEAVE, false);
+ events.ScheduleEvent(EVENT_CLEAVE, 5s, 10s);
break;
- case 7:
- {
- DoCast(me, SPELL_FOG_BREATH, true);
- float x, y, z;
- me->GetPosition(x, y, z);
- x = 2 * breathX - x;
- y = 2 * breathY - y;
- me->GetMotionMaster()->MovePoint(0, x, y, z);
- events.ScheduleEvent(EVENT_SUMMON_FOG, 1ms);
+ case EVENT_CORROSION:
+ DoCastVictim(SPELL_CORROSION, false);
+ events.ScheduleEvent(EVENT_CORROSION, 20s, 30s);
break;
- }
- case 8:
- me->CastStop(SPELL_FOG_BREATH);
- me->RemoveAurasDueToSpell(SPELL_FOG_BREATH);
- ++uiBreathCount;
- events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 1ms);
- if (uiBreathCount < 3)
- uiFlightCount = 4;
+ case EVENT_GAS_NOVA:
+ DoCast(me, SPELL_GAS_NOVA, false);
+ events.ScheduleEvent(EVENT_GAS_NOVA, 20s, 25s);
break;
- case 9:
- if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat))
- DoStartMovement(target);
- else
- {
- EnterEvadeMode();
- return;
- }
+ case EVENT_ENCAPSULATE:
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 150, true))
+ DoCast(target, SPELL_ENCAPSULATE_CHANNEL, false);
+ events.ScheduleEvent(EVENT_ENCAPSULATE, 25s, 30s);
break;
- case 10:
- me->SetDisableGravity(false);
- me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
- EnterPhase(PHASE_GROUND);
- AttackStart(SelectTarget(SelectTargetMethod::MaxThreat));
+ case EVENT_FLIGHT:
+ EnterPhase(PHASE_FLIGHT);
+ break;
+ default:
+ DoMeleeAttackIfReady();
break;
}
- ++uiFlightCount;
}
- void UpdateAI(uint32 diff) override
+ if (phase == PHASE_FLIGHT)
{
- if (!UpdateVictim())
+ switch (events.ExecuteEvent())
{
- if (phase == PHASE_FLIGHT && !me->IsInEvadeMode())
- EnterEvadeMode();
- return;
- }
-
- events.Update(diff);
-
- if (me->IsNonMeleeSpellCast(false))
- return;
-
- if (phase == PHASE_GROUND)
- {
- switch (events.ExecuteEvent())
- {
- case EVENT_BERSERK:
- Talk(YELL_BERSERK);
- DoCast(me, SPELL_BERSERK, true);
- events.ScheduleEvent(EVENT_BERSERK, 10s);
- break;
- case EVENT_CLEAVE:
- DoCastVictim(SPELL_CLEAVE, false);
- events.ScheduleEvent(EVENT_CLEAVE, 5s, 10s);
- break;
- case EVENT_CORROSION:
- DoCastVictim(SPELL_CORROSION, false);
- events.ScheduleEvent(EVENT_CORROSION, 20s, 30s);
- break;
- case EVENT_GAS_NOVA:
- DoCast(me, SPELL_GAS_NOVA, false);
- events.ScheduleEvent(EVENT_GAS_NOVA, 20s, 25s);
- break;
- case EVENT_ENCAPSULATE:
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 150, true))
- DoCast(target, SPELL_ENCAPSULATE_CHANNEL, false);
- events.ScheduleEvent(EVENT_ENCAPSULATE, 25s, 30s);
- break;
- case EVENT_FLIGHT:
- EnterPhase(PHASE_FLIGHT);
- break;
- default:
- DoMeleeAttackIfReady();
- break;
- }
- }
-
- if (phase == PHASE_FLIGHT)
- {
- switch (events.ExecuteEvent())
- {
- case EVENT_BERSERK:
- Talk(YELL_BERSERK);
- DoCast(me, SPELL_BERSERK, true);
- break;
- case EVENT_FLIGHT_SEQUENCE:
- HandleFlightSequence();
- break;
- case EVENT_SUMMON_FOG:
+ case EVENT_BERSERK:
+ Talk(YELL_BERSERK);
+ DoCast(me, SPELL_BERSERK, true);
+ break;
+ case EVENT_FLIGHT_SEQUENCE:
+ HandleFlightSequence();
+ break;
+ case EVENT_SUMMON_FOG:
+ {
+ float x, y, z;
+ me->GetPosition(x, y, z);
+ me->UpdateGroundPositionZ(x, y, z);
+ if (Creature* Fog = me->SummonCreature(NPC_VAPOR_TRAIL, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN, 10s))
{
- float x, y, z;
- me->GetPosition(x, y, z);
- me->UpdateGroundPositionZ(x, y, z);
- if (Creature* Fog = me->SummonCreature(NPC_VAPOR_TRAIL, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN, 10s))
- {
- Fog->RemoveAurasDueToSpell(SPELL_TRAIL_TRIGGER);
- Fog->CastSpell(Fog, SPELL_FOG_TRIGGER, true);
- me->CastSpell(Fog, SPELL_FOG_FORCE, true);
- }
+ Fog->RemoveAurasDueToSpell(SPELL_TRAIL_TRIGGER);
+ Fog->CastSpell(Fog, SPELL_FOG_TRIGGER, true);
+ me->CastSpell(Fog, SPELL_FOG_FORCE, true);
}
- events.ScheduleEvent(EVENT_SUMMON_FOG, 1s);
- break;
- }
+ }
+ events.ScheduleEvent(EVENT_SUMMON_FOG, 1s);
+ break;
}
}
+ }
- void DespawnSummons(uint32 entry)
+ void DespawnSummons(uint32 entry)
+ {
+ summons.DespawnIf([&](ObjectGuid guid)
{
- std::list<Creature*> templist;
- float x, y, z;
- me->GetPosition(x, y, z);
-
- Trinity::AllCreaturesOfEntryInRange check(me, entry, 100);
- Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(me, templist, check);
- Cell::VisitGridObjects(me, searcher, me->GetGridActivationRange());
+ if (guid.GetEntry() != entry)
+ return false;
- for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end(); ++i)
+ if (guid.GetEntry() == NPC_VAPOR_TRAIL && phase == PHASE_FLIGHT)
{
- if (entry == NPC_VAPOR_TRAIL && phase == PHASE_FLIGHT)
- {
- (*i)->GetPosition(x, y, z);
- me->SummonCreature(NPC_DEAD, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
- }
- (*i)->SetVisible(false);
- (*i)->DespawnOrUnsummon();
- }
- }
- };
+ Position const* pos = ObjectAccessor::GetCreature(*me, guid);
+ if (!pos)
+ pos = me;
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetSunwellPlateauAI<boss_felmystAI>(creature);
+ me->SummonCreature(NPC_DEAD, *pos, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
+ }
+ return true;
+ });
}
};
-class npc_felmyst_vapor : public CreatureScript
+struct npc_felmyst_vapor : public ScriptedAI
{
-public:
- npc_felmyst_vapor() : CreatureScript("npc_felmyst_vapor") { }
+ npc_felmyst_vapor(Creature* creature) : ScriptedAI(creature) { }
- CreatureAI* GetAI(Creature* creature) const override
+ void Reset() override { }
+ void JustEngagedWith(Unit* /*who*/) override
{
- return GetSunwellPlateauAI<npc_felmyst_vaporAI>(creature);
+ DoZoneInCombat();
+ //DoCast(me, SPELL_VAPOR_FORCE, true); core bug
}
- struct npc_felmyst_vaporAI : public ScriptedAI
+ void UpdateAI(uint32 /*diff*/) override
{
- npc_felmyst_vaporAI(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset() override { }
- void JustEngagedWith(Unit* /*who*/) override
- {
- DoZoneInCombat();
- //DoCast(me, SPELL_VAPOR_FORCE, true); core bug
- }
-
- void UpdateAI(uint32 /*diff*/) override
- {
- if (!me->GetVictim())
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
- AttackStart(target);
- }
- };
+ if (!me->GetVictim())
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
+ AttackStart(target);
+ }
};
-class npc_felmyst_trail : public CreatureScript
+struct npc_felmyst_trail : public ScriptedAI
{
-public:
- npc_felmyst_trail() : CreatureScript("npc_felmyst_trail") { }
-
- CreatureAI* GetAI(Creature* creature) const override
+ npc_felmyst_trail(Creature* creature) : ScriptedAI(creature)
{
- return GetSunwellPlateauAI<npc_felmyst_trailAI>(creature);
+ DoCast(me, SPELL_TRAIL_TRIGGER, true);
+ me->SetTarget(me->GetGUID());
+ me->SetBoundingRadius(0.01f); // core bug
}
- struct npc_felmyst_trailAI : public ScriptedAI
- {
- npc_felmyst_trailAI(Creature* creature) : ScriptedAI(creature)
- {
- DoCast(me, SPELL_TRAIL_TRIGGER, true);
- me->SetTarget(me->GetGUID());
- me->SetBoundingRadius(0.01f); // core bug
- }
-
- void Reset() override { }
- void JustEngagedWith(Unit* /*who*/) override { }
- void AttackStart(Unit* /*who*/) override { }
- void MoveInLineOfSight(Unit* /*who*/) override { }
+ void Reset() override { }
+ void JustEngagedWith(Unit* /*who*/) override { }
+ void AttackStart(Unit* /*who*/) override { }
+ void MoveInLineOfSight(Unit* /*who*/) override { }
- void UpdateAI(uint32 /*diff*/) override { }
- };
+ void UpdateAI(uint32 /*diff*/) override { }
};
void AddSC_boss_felmyst()
{
- new boss_felmyst();
- new npc_felmyst_vapor();
- new npc_felmyst_trail();
+ RegisterSunwellPlateauCreatureAI(boss_felmyst);
+ RegisterSunwellPlateauCreatureAI(npc_felmyst_vapor);
+ RegisterSunwellPlateauCreatureAI(npc_felmyst_trail);
}