aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp1471
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/instance_the_eye.cpp42
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/the_eye.h21
3 files changed, 697 insertions, 837 deletions
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp
index 93521f3b235..c837edcdaf1 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp
@@ -25,115 +25,235 @@ EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
+#include "Spell.h"
#include "the_eye.h"
-#include "WorldPacket.h"
-#include "Opcodes.h"
enum Yells
{
// Kael'thas Speech
- SAY_INTRO = 0,
- SAY_INTRO_CAPERNIAN = 1,
- SAY_INTRO_TELONICUS = 2,
- SAY_INTRO_THALADRED = 3,
- SAY_INTRO_SANGUINAR = 4,
- SAY_PHASE2_WEAPON = 5,
- SAY_PHASE3_ADVANCE = 6,
- SAY_PHASE4_INTRO2 = 7,
- SAY_PHASE5_NUTS = 8,
- SAY_SLAY = 9,
- SAY_MINDCONTROL = 10,
- SAY_GRAVITYLAPSE = 11,
- SAY_SUMMON_PHOENIX = 12,
- SAY_DEATH = 13,
+ SAY_INTRO = 0,
+ SAY_INTRO_CAPERNIAN = 1,
+ SAY_INTRO_TELONICUS = 2,
+ SAY_INTRO_THALADRED = 3,
+ SAY_INTRO_SANGUINAR = 4,
+ SAY_PHASE2_WEAPON = 5,
+ SAY_PHASE3_ADVANCE = 6,
+ SAY_PHASE4_INTRO2 = 7,
+ SAY_PHASE5_NUTS = 8,
+ SAY_SLAY = 9,
+ SAY_MIND_CONTROL = 10,
+ SAY_GRAVITY_LAPSE = 11,
+ SAY_SUMMON_PHOENIX = 12,
+ SAY_DEATH = 13,
+ EMOTE_PYROBLAST = 14,
// Thaladred the Darkener speech
- SAY_THALADRED_AGGRO = 0,
- SAY_THALADRED_DEATH = 1,
- EMOTE_THALADRED_GAZE = 2,
+ SAY_THALADRED_AGGRO = 0,
+ SAY_THALADRED_DEATH = 1,
+ EMOTE_THALADRED_GAZE = 2,
//Lord Sanguinar speech
- SAY_SANGUINAR_AGGRO = 0,
- SAY_SANGUINAR_DEATH = 1,
+ SAY_SANGUINAR_AGGRO = 0,
+ SAY_SANGUINAR_DEATH = 1,
// Grand Astromancer Capernian speech
- SAY_CAPERNIAN_AGGRO = 0,
- SAY_CAPERNIAN_DEATH = 1,
+ SAY_CAPERNIAN_AGGRO = 0,
+ SAY_CAPERNIAN_DEATH = 1,
// Master Engineer Telonicus speech
- SAY_TELONICUS_AGGRO = 0,
- SAY_TELONICUS_DEATH = 1
+ SAY_TELONICUS_AGGRO = 0,
+ SAY_TELONICUS_DEATH = 1
};
enum Spells
{
// Phase 2 spells
- SPELL_SUMMON_WEAPONS = 36976,
- SPELL_SUMMON_WEAPONA = 36958,
- SPELL_SUMMON_WEAPONB = 36959,
- SPELL_SUMMON_WEAPONC = 36960,
- SPELL_SUMMON_WEAPOND = 36961,
- SPELL_SUMMON_WEAPONE = 36962,
- SPELL_SUMMON_WEAPONF = 36963,
- SPELL_SUMMON_WEAPONG = 36964,
- SPELL_RES_VISUAL = 24171,
+ SPELL_SUMMON_WEAPONS = 36976,
+ SPELL_SUMMON_WEAPONA = 36958,
+ SPELL_SUMMON_WEAPONB = 36959,
+ SPELL_SUMMON_WEAPONC = 36960,
+ SPELL_SUMMON_WEAPOND = 36961,
+ SPELL_SUMMON_WEAPONE = 36962,
+ SPELL_SUMMON_WEAPONF = 36963,
+ SPELL_SUMMON_WEAPONG = 36964,
+ SPELL_RESSURECTION = 36450,
// Phase 4 spells
- SPELL_FIREBALL = 22088, //wrong but works with CastCustomSpell
- SPELL_PYROBLAST = 36819,
- SPELL_FLAME_STRIKE = 36735,
- SPELL_FLAME_STRIKE_VIS = 36730,
- SPELL_FLAME_STRIKE_DMG = 36731,
- SPELL_ARCANE_DISRUPTION = 36834,
- SPELL_SHOCK_BARRIER = 36815,
- SPELL_PHOENIX_ANIMATION = 36723,
- SPELL_MIND_CONTROL = 32830,
+ SPELL_FIREBALL = 36805,
+ SPELL_PYROBLAST = 36819,
+ SPELL_FLAME_STRIKE = 36735,
+ SPELL_FLAME_STRIKE_VIS = 36730,
+ SPELL_FLAME_STRIKE_DMG = 36731,
+ SPELL_ARCANE_DISRUPTION = 36834,
+ SPELL_SHOCK_BARRIER = 36815,
+ SPELL_PHOENIX_ANIMATION = 36723,
+ //SPELL_MIND_CONTROL = 32830,
+ SPELL_MIND_CONTROL = 36797,
+ SPELL_BANISH = 40370, // Cast on Phoenix
// Phase 5 spells
- SPELL_EXPLODE = 36092,
- SPELL_FULLPOWER = 36187,
- SPELL_KNOCKBACK = 11027,
- SPELL_GRAVITY_LAPSE = 34480,
- SPELL_GRAVITY_LAPSE_AURA = 39432,
- SPELL_NETHER_BEAM = 35873,
+ SPELL_KAEL_GAINING_POWER = 36091,
+ SPELL_KAEL_EXPLODES = 36373,
+ SPELL_KAEL_EXPLODES2 = 36375,
+ SPELL_KAEL_EXPLODES3 = 36092,
+ SPELL_KAEL_EXPLODES4 = 36354,
+ SPELL_KAEL_STUNNED = 36185,
+ SPELL_FULLPOWER = 36187,
+ SPELL_NETHER_BEAM = 35873,
+ SPELL_PURE_NETHER_BEAM = 36196,
+ SPELL_SUMMON_NETHER_VAPOR = 35865,
+
+ // Visual, phase transition spells
+ SPELL_NETHER_BEAM_VISUAL = 36089, // Channeled by trigger on Kael'thas.
+ SPELL_NETHER_BEAM_VISUAL2 = 36090, // Channeled by trigger on Kael'thas.
+ SPELL_NETHER_BEAM_VISUAL3 = 36364, // Cast by Kael'thas on himself, purple glowing effect.
+
+ // Gravity Lapse spells
+ SPELL_GRAVITY_LAPSE = 35941,
+ SPELL_GRAVITY_LAPSE_PERIODIC = 34480,
+ SPELL_GRAVITY_LAPSE_FLIGHT_AURA = 39432, // Cast by players on themselves, allows flight
+
+ // 25 teleport spells, one for each raid member...
+ SPELL_GRAVITY_LAPSE_TELE_FRONT = 35966,
+ SPELL_GRAVITY_LAPSE_TELE_FRONT_RIGHT = 35967,
+ SPELL_GRAVITY_LAPSE_TELE_FRONT_LEFT = 35968,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK_RIGHT = 35969,
+ SPELL_GRAVITY_LAPSE_TELE_BACK = 35970,
+ SPELL_GRAVITY_LAPSE_TELE_TO_CASTER = 35971,
+ SPELL_GRAVITY_LAPSE_TELE_BACK_LEFT = 35972,
+ SPELL_GRAVITY_LAPSE_TELE_FRONT_LEFT2 = 35973,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_LEFT = 35974,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_LEFT2 = 35975,
+ SPELL_GRAVITY_LAPSE_TELE_FRONT_LEFT3 = 35976,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK_LEFT = 35977,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_FRONT = 35978,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK = 35979,
+ SPELL_GRAVITY_LAPSE_TELE_FRONT_RIGHT2 = 35980,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_RIGHT = 35981,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_FRONT_RIGHT = 35982,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_FRONT2 = 35983,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_FRONT_LEFT = 35984,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_LEFT3 = 35985,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK_LEFT2 = 35986,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK2 = 35987,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK_RIGHT2 = 35988,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_RIGHT2 = 35989,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK_RIGHT3 = 35990,
// Thaladred the Darkener spells
- SPELL_PSYCHIC_BLOW = 10689,
- SPELL_SILENCE = 30225,
+ SPELL_PSYCHIC_BLOW = 10689,
+ SPELL_SILENCE = 30225,
// Lord Sanguinar spells
- SPELL_BELLOWING_ROAR = 40636,
+ SPELL_BELLOWING_ROAR = 40636,
// Grand Astromancer Capernian spells
- SPELL_CAPERNIAN_FIREBALL = 36971,
- SPELL_CONFLAGRATION = 37018,
- SPELL_ARCANE_EXPLOSION = 36970,
+ SPELL_CAPERNIAN_FIREBALL = 36971,
+ SPELL_CONFLAGRATION = 37018,
+ SPELL_ARCANE_EXPLOSION = 36970,
//Master Engineer Telonicus spells
- SPELL_BOMB = 37036,
- SPELL_REMOTE_TOY = 37027,
+ SPELL_BOMB = 37036,
+ SPELL_REMOTE_TOY = 37027,
//Nether Vapor spell
- SPELL_NETHER_VAPOR = 35859,
+ SPELL_NETHER_VAPOR = 35859,
//Phoenix spell
- SPELL_BURN = 36720,
- SPELL_EMBER_BLAST = 34341,
- SPELL_REBIRTH = 41587
+ SPELL_BURN = 36720,
+ SPELL_EMBER_BLAST = 34341,
+ SPELL_REBIRTH = 41587
};
enum Creatures
{
- NPC_PHOENIX = 21362,
- NPC_PHOENIX_EGG = 21364
+ NPC_PHOENIX = 21362,
+ NPC_PHOENIX_EGG = 21364
};
enum Models
{
//Phoenix egg and phoenix model
- MODEL_ID_PHOENIX = 19682,
- MODEL_ID_PHOENIX_EGG = 20245
+ MODEL_ID_PHOENIX = 19682,
+ MODEL_ID_PHOENIX_EGG = 20245
};
-enum Misc
+enum Actions
{
- MAX_ADVISORS = 4
+ ACTION_START_ENCOUNTER,
+ ACTION_REVIVE_ADVISORS,
+ ACTION_PREPARE_ADVISORS,
+ ACTION_ACTIVE_ADVISOR,
+ ACTION_SCHEDULE_COMBAT_EVENTS
+};
+
+enum Advisors
+{
+ ADVISOR_THALADRED,
+ ADVISOR_SANGUINAR,
+ ADVISOR_CAPERNIAN,
+ ADVISOR_TELONICUS,
+ MAX_ADVISORS = 4,
+
+ MAX_DEFEATED_ADVISORS = 4,
+ MAX_KILLED_ADVISORS = 8
+};
+
+enum Events
+{
+ EVENT_START_ENCOUNTER = 1,
+ EVENT_ACTIVE_ADVISOR,
+ EVENT_SUMMON_WEAPONS,
+ EVENT_REVIVE_ADVISORS,
+ EVENT_ENGAGE_COMBAT,
+ EVENT_FULL_POWER,
+ EVENT_FIREBALL,
+ EVENT_ARCANE_DISRUPTION,
+ EVENT_FLAMESTRIKE,
+ EVENT_MIND_CONTROL,
+ EVENT_SUMMON_PHOENIX,
+ EVENT_SHOCK_BARRIER,
+ EVENT_PYROBLAST,
+ EVENT_PYROBLAST_CAST,
+ EVENT_GAINING_POWER,
+ EVENT_END_TRANSITION,
+ EVENT_GRAVITY_LAPSE,
+ EVENT_NETHER_BEAM,
+
+ // Movement updates
+ EVENT_TRANSITION_1,
+ EVENT_TRANSITION_2,
+ EVENT_TRANSITION_3,
+ EVENT_TRANSITION_4,
+ EVENT_TRANSITION_5,
+ EVENT_TRANSITION_6,
+
+ // Phase transition
+ EVENT_SIZE_INCREASE,
+ EVENT_EXPLODE,
+ EVENT_RESUME_COMBAT,
+
+ // Advisors
+ EVENT_DELAYED_RESSURECTION,
+
+ // Event groups
+ EVENT_GROUP_COMBAT = 1, // Default abilities
+ EVENT_GROUP_SPECIAL = 2 // Special abilities (Pyroblast, Nether Beam, Shock Barrier)
+};
+
+enum Phases
+{
+ PHASE_NONE,
+ PHASE_INTRO,
+ PHASE_REVIVED_ADVISORS,
+ PHASE_COMBAT,
+ PHASE_TRANSITION
+};
+
+enum MovementPoints
+{
+ POINT_START_TRANSITION = 1,
+ POINT_TRANSITION_CENTER_ASCENDING = 2,
+ POINT_TRANSITION_HALFWAY_ASCENDING = 3,
+ POINT_TRANSITION_TOP = 4,
+ POINT_TRANSITION_HALFWAY_DESCENDING = 5,
+ POINT_END_TRANSITION = 6
};
uint32 m_auiSpellSummonWeapon[]=
@@ -142,61 +262,83 @@ uint32 m_auiSpellSummonWeapon[]=
SPELL_SUMMON_WEAPONE, SPELL_SUMMON_WEAPONF, SPELL_SUMMON_WEAPONG
};
+uint32 GravityLapseSpells[] =
+{
+ SPELL_GRAVITY_LAPSE_TELE_FRONT,
+ SPELL_GRAVITY_LAPSE_TELE_FRONT_RIGHT,
+ SPELL_GRAVITY_LAPSE_TELE_FRONT_LEFT,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK_RIGHT,
+ SPELL_GRAVITY_LAPSE_TELE_BACK,
+ SPELL_GRAVITY_LAPSE_TELE_TO_CASTER,
+ SPELL_GRAVITY_LAPSE_TELE_BACK_LEFT,
+ SPELL_GRAVITY_LAPSE_TELE_FRONT_LEFT2,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_LEFT,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_LEFT2,
+ SPELL_GRAVITY_LAPSE_TELE_FRONT_LEFT3,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK_LEFT,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_FRONT,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK,
+ SPELL_GRAVITY_LAPSE_TELE_FRONT_RIGHT2,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_RIGHT,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_FRONT_RIGHT,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_FRONT2,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_FRONT_LEFT,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_LEFT3,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK_LEFT2,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK2,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK_RIGHT2,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_RIGHT2,
+ SPELL_GRAVITY_LAPSE_TELE_CASTER_BACK_RIGHT3
+};
+
const float CAPERNIAN_DISTANCE = 20.0f; //she casts away from the target
//const float KAEL_VISIBLE_RANGE = 50.0f;
-const float afGravityPos[3] = {795.0f, 0.0f, 70.0f};
+Position const afGravityPos = {795.0f, 0.0f, 70.0f};
-#define TIME_PHASE_2_3 120000
-#define TIME_PHASE_3_4 180000
+Position const TransitionPos[6] =
+{
+ // First two values are not static, they seem to differ on each sniff.
+ { 794.0522f, -0.96732f, 48.97848f, 0.0f },
+ { 796.641f, -0.5888171f, 48.72847f, 3.176499f },
+ { 795.007f, -0.471827f, 75.0f, 0.0f },
+ { 795.007f, -0.471827f, 75.0f, 3.133458f },
+ { 792.419f, -0.504778f, 50.0505f, 0.0f },
+ { 792.419f, -0.504778f, 50.0505f, 3.130386f }
+};
-//Base AI for Advisors
struct advisorbase_ai : public ScriptedAI
{
advisorbase_ai(Creature* creature) : ScriptedAI(creature)
{
Initialize();
instance = creature->GetInstanceScript();
- m_bDoubled_Health = false;
}
void Initialize()
{
- FakeDeath = false;
- DelayRes_Timer = 0;
+ _hasRessurrected = false;
+ _inFakeDeath = false;
DelayRes_Target.Clear();
}
- InstanceScript* instance;
- bool FakeDeath;
- bool m_bDoubled_Health;
- uint32 DelayRes_Timer;
- ObjectGuid DelayRes_Target;
-
void Reset() override
{
- if (m_bDoubled_Health)
- {
- me->SetMaxHealth(me->GetMaxHealth() / 2);
- m_bDoubled_Health = false;
- }
-
Initialize();
me->SetStandState(UNIT_STAND_STATE_STAND);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
//reset encounter
- if (instance->GetData(DATA_KAELTHASEVENT) == 1 || instance->GetData(DATA_KAELTHASEVENT) == 3)
+ if (instance->GetBossState(DATA_KAELTHAS) == IN_PROGRESS)
if (Creature* Kaelthas = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KAELTHAS)))
Kaelthas->AI()->EnterEvadeMode();
}
void MoveInLineOfSight(Unit* who) override
-
{
- if (!who || FakeDeath || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ if (!who || _inFakeDeath || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
return;
ScriptedAI::MoveInLineOfSight(who);
@@ -204,69 +346,61 @@ struct advisorbase_ai : public ScriptedAI
void AttackStart(Unit* who) override
{
- if (!who || FakeDeath || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ if (!who || _inFakeDeath || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
return;
ScriptedAI::AttackStart(who);
}
- void Revive(Unit* /*Target*/)
+ void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
{
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- // double health for phase 3
- me->SetMaxHealth(me->GetMaxHealth() * 2);
- m_bDoubled_Health = true;
- me->SetFullHealth();
- me->SetStandState(UNIT_STAND_STATE_STAND);
-
- DoCast(me, SPELL_RES_VISUAL, false);
- DelayRes_Timer = 2000;
+ if (spell->Id == SPELL_RESSURECTION)
+ {
+ _hasRessurrected = true;
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ events.ScheduleEvent(EVENT_DELAYED_RESSURECTION, 2000);
+ }
}
void DamageTaken(Unit* killer, uint32 &damage) override
{
- if (damage < me->GetHealth())
- return;
-
- //Prevent glitch if in fake death
- if (FakeDeath && instance->GetData(DATA_KAELTHASEVENT) != 0)
- {
- damage = 0;
- return;
- }
-
- //Don't really die in phase 1 & 3, only die after that
- if (instance->GetData(DATA_KAELTHASEVENT) != 0)
+ if (damage >= me->GetHealth() && !_inFakeDeath && !_hasRessurrected)
{
//prevent death
damage = 0;
- FakeDeath = true;
+ _inFakeDeath = true;
me->InterruptNonMeleeSpells(false);
me->SetHealth(0);
- me->StopMoving();
me->ClearComboPointHolders();
me->RemoveAllAurasOnDeath();
me->ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false);
me->ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, false);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->ClearAllReactives();
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
me->SetTarget(ObjectGuid::Empty);
- me->GetMotionMaster()->Clear();
- me->GetMotionMaster()->MoveIdle();
me->SetStandState(UNIT_STAND_STATE_DEAD);
+ me->GetMotionMaster()->Clear();
JustDied(killer);
}
}
+ void JustDied(Unit* /*killer*/) override
+ {
+ if (Creature* kael = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KAELTHAS)))
+ kael->AI()->DoAction(ACTION_ACTIVE_ADVISOR);
+ }
+
void UpdateAI(uint32 diff) override
{
- if (DelayRes_Timer)
+ if (_hasRessurrected)
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
{
- if (DelayRes_Timer <= diff)
+ if (eventId == EVENT_DELAYED_RESSURECTION)
{
- DelayRes_Timer = 0;
- FakeDeath = false;
+ _inFakeDeath = false;
Unit* Target = ObjectAccessor::GetUnit(*me, DelayRes_Target);
if (!Target)
@@ -277,9 +411,15 @@ struct advisorbase_ai : public ScriptedAI
me->GetMotionMaster()->Clear();
me->GetMotionMaster()->MoveChase(Target);
me->AddThreat(Target, 0.0f);
- } else DelayRes_Timer -= diff;
+ }
}
}
+ public:
+ EventMap events;
+ InstanceScript* instance;
+ bool _hasRessurrected;
+ bool _inFakeDeath;
+ ObjectGuid DelayRes_Target;
};
class boss_kaelthas : public CreatureScript
@@ -293,150 +433,199 @@ class boss_kaelthas : public CreatureScript
boss_kaelthasAI(Creature* creature) : BossAI(creature, DATA_KAELTHAS)
{
Initialize();
- PhaseSubphase = 0;
- Phase_Timer = 0;
}
void Initialize()
{
- Fireball_Timer = 5000 + rand32() % 10000;
- ArcaneDisruption_Timer = 45000;
- MindControl_Timer = 40000;
- Phoenix_Timer = 50000;
- ShockBarrier_Timer = 60000;
- FlameStrike_Timer = 30000;
- GravityLapse_Timer = 20000;
- GravityLapse_Phase = 0;
- NetherBeam_Timer = 8000;
- NetherVapor_Timer = 10000;
- PyrosCast = 0;
- Phase = 0;
- InGravityLapse = false;
- IsCastingFireball = false;
- ChainPyros = false;
+ _advisorCounter = 0;
+ _pyrosCast = 0;
+ _netherbeamsCast = 0;
+ _phase = PHASE_NONE;
+ _scaleStage = 0;
+ _hasFullPower = false;
}
- uint32 Fireball_Timer;
- uint32 ArcaneDisruption_Timer;
- uint32 Phoenix_Timer;
- uint32 ShockBarrier_Timer;
- uint32 GravityLapse_Timer;
- uint32 GravityLapse_Phase;
- uint32 NetherBeam_Timer;
- uint32 NetherVapor_Timer;
- uint32 FlameStrike_Timer;
- uint32 MindControl_Timer;
- uint32 Phase;
- uint32 PhaseSubphase; //generic
- uint32 Phase_Timer; //generic timer
- uint32 PyrosCast;
-
- bool InGravityLapse;
- bool IsCastingFireball;
- bool ChainPyros;
-
- ObjectGuid m_auiAdvisorGuid[MAX_ADVISORS];
-
void Reset() override
{
Initialize();
+ DoAction(ACTION_PREPARE_ADVISORS);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
+ me->SetDisableGravity(false);
+ me->SetTarget(ObjectGuid::Empty);
+ me->SetObjectScale(1.0f);
+ BossAI::Reset();
+ }
- if (me->IsInCombat())
- PrepareAdvisors();
+ void JustReachedHome() override
+ {
+ BossAI::JustReachedHome();
- _Reset();
+ // Rebuild the surrounding environment.
+ if (GameObject* statue = instance->GetGameObject(DATA_KAEL_STATUE_LEFT))
+ statue->ResetDoorOrButton();
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (GameObject* statue = instance->GetGameObject(DATA_KAEL_STATUE_RIGHT))
+ statue->ResetDoorOrButton();
- instance->SetData(DATA_KAELTHASEVENT, 0);
+ if (GameObject* window = instance->GetGameObject(DATA_TEMPEST_BRIDGE_WINDOW))
+ window->ResetDoorOrButton();
}
- void PrepareAdvisors()
+ void DoAction(int32 action) override
{
- for (uint8 i = 0; i < MAX_ADVISORS; ++i)
+ switch (action)
{
- if (Creature* creature = ObjectAccessor::GetCreature(*me, m_auiAdvisorGuid[i]))
- {
- creature->Respawn();
- creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- creature->setFaction(me->getFaction());
- creature->AI()->EnterEvadeMode();
- }
+ case ACTION_START_ENCOUNTER:
+ Talk(SAY_INTRO);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+
+ _advisorGuid[ADVISOR_THALADRED] = instance->GetGuidData(DATA_THALADREDTHEDARKENER);
+ _advisorGuid[ADVISOR_SANGUINAR] = instance->GetGuidData(DATA_LORDSANGUINAR);
+ _advisorGuid[ADVISOR_CAPERNIAN] = instance->GetGuidData(DATA_GRANDASTROMANCERCAPERNIAN);
+ _advisorGuid[ADVISOR_TELONICUS] = instance->GetGuidData(DATA_MASTERENGINEERTELONICUS);
+
+ _phase = PHASE_INTRO;
+ instance->SetBossState(DATA_KAELTHAS, IN_PROGRESS);
+ events.ScheduleEvent(EVENT_START_ENCOUNTER, 23000);
+ break;
+ case ACTION_PREPARE_ADVISORS:
+ for (uint8 i = 0; i < MAX_ADVISORS; ++i)
+ {
+ if (Creature* creature = ObjectAccessor::GetCreature(*me, _advisorGuid[i]))
+ {
+ creature->Respawn(true);
+ creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ creature->AI()->EnterEvadeMode();
+ }
+ }
+ break;
+ case ACTION_ACTIVE_ADVISOR:
+ // They have already been active, so we are not handling new ones, just counting their death.
+ if (_phase == PHASE_REVIVED_ADVISORS)
+ ++_advisorCounter;
+
+ switch (_advisorCounter)
+ {
+ case ADVISOR_THALADRED:
+ Talk(SAY_INTRO_THALADRED);
+ events.ScheduleEvent(EVENT_ACTIVE_ADVISOR, 7000);
+ break;
+ case ADVISOR_SANGUINAR:
+ Talk(SAY_INTRO_SANGUINAR);
+ events.ScheduleEvent(EVENT_ACTIVE_ADVISOR, 12500);
+ break;
+ case ADVISOR_CAPERNIAN:
+ Talk(SAY_INTRO_CAPERNIAN);
+ events.ScheduleEvent(EVENT_ACTIVE_ADVISOR, 7000);
+ break;
+ case ADVISOR_TELONICUS:
+ Talk(SAY_INTRO_TELONICUS);
+ events.ScheduleEvent(EVENT_ACTIVE_ADVISOR, 8400);
+ break;
+ case MAX_DEFEATED_ADVISORS:
+ // Every advisor defeated - Phase 2 starts.
+ Talk(SAY_PHASE2_WEAPON);
+ events.ScheduleEvent(EVENT_SUMMON_WEAPONS, 3500);
+ break;
+ case MAX_KILLED_ADVISORS:
+ // Every advisor killed - Phase 3 starts.
+ events.ScheduleEvent(EVENT_ENGAGE_COMBAT, 5000);
+ break;
+ default:
+ break;
+ }
+ break;
+ case ACTION_SCHEDULE_COMBAT_EVENTS:
+ _phase = PHASE_COMBAT;
+ events.SetPhase(PHASE_COMBAT);
+ events.ScheduleEvent(EVENT_FIREBALL, 1000, EVENT_GROUP_COMBAT, PHASE_COMBAT);
+ events.ScheduleEvent(EVENT_ARCANE_DISRUPTION, 45000, EVENT_GROUP_COMBAT, PHASE_COMBAT);
+ events.ScheduleEvent(EVENT_FLAMESTRIKE, 30000, EVENT_GROUP_COMBAT, PHASE_COMBAT);
+ events.ScheduleEvent(EVENT_MIND_CONTROL, 40000, EVENT_GROUP_COMBAT, PHASE_COMBAT);
+ events.ScheduleEvent(EVENT_SUMMON_PHOENIX, 50000, EVENT_GROUP_COMBAT, PHASE_COMBAT);
+ break;
+ default:
+ break;
}
}
- void StartEvent()
+ void MoveInLineOfSight(Unit* who) override
{
- m_auiAdvisorGuid[0] = instance->GetGuidData(DATA_THALADREDTHEDARKENER);
- m_auiAdvisorGuid[1] = instance->GetGuidData(DATA_LORDSANGUINAR);
- m_auiAdvisorGuid[2] = instance->GetGuidData(DATA_GRANDASTROMANCERCAPERNIAN);
- m_auiAdvisorGuid[3] = instance->GetGuidData(DATA_MASTERENGINEERTELONICUS);
-
- if (!m_auiAdvisorGuid[0] || !m_auiAdvisorGuid[1] || !m_auiAdvisorGuid[2] || !m_auiAdvisorGuid[3])
- {
- TC_LOG_ERROR("scripts", "Kael'Thas One or more advisors missing, Skipping Phases 1-3");
-
- Talk(SAY_PHASE4_INTRO2);
-
- Phase = 4;
-
- instance->SetData(DATA_KAELTHASEVENT, 4);
-
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- AttackStart(target);
- }
- else
+ if (_phase == PHASE_NONE && me->IsValidAttackTarget(who) && me->IsWithinDistInMap(who, 30.0f))
{
- PrepareAdvisors();
-
- Talk(SAY_INTRO);
-
- instance->SetData(DATA_KAELTHASEVENT, 1);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-
- PhaseSubphase = 0;
- Phase_Timer = 23000;
- Phase = 1;
+ DoAction(ACTION_START_ENCOUNTER);
+ who->SetInCombatWith(me);
+ me->AddThreat(who, 0.0f);
+ me->SetTarget(who->GetGUID());
}
}
- void MoveInLineOfSight(Unit* who) override
+ void DamageTaken(Unit* attacker, uint32& damage) override
{
- if (!me->HasUnitState(UNIT_STATE_STUNNED) && me->CanCreatureAttack(who))
+ if (_phase == PHASE_NONE)
{
- if (!me->CanFly() && me->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
- return;
-
- float attackRadius = me->GetAttackDistance(who);
- if (me->IsWithinDistInMap(who, attackRadius) && me->IsWithinLOSInMap(who))
- {
- if (!me->GetVictim() && Phase >= 4)
- {
- who->RemoveAurasByType(SPELL_AURA_MOD_STEALTH);
- AttackStart(who);
- }
- else
- {
- if (!instance->GetData(DATA_KAELTHASEVENT) && !Phase)
- StartEvent();
+ DoAction(ACTION_START_ENCOUNTER);
+ me->SetTarget(attacker->GetGUID());
+ }
- who->SetInCombatWith(me);
- me->AddThreat(who, 0.0f);
- }
- }
+ if (!_hasFullPower && me->HealthBelowPctDamaged(50, damage))
+ {
+ _hasFullPower = true;
+ me->AttackStop();
+ me->InterruptNonMeleeSpells(false);
+ events.CancelEventGroup(EVENT_GROUP_COMBAT);
+ events.CancelEventGroup(EVENT_GROUP_SPECIAL);
+ events.SetPhase(PHASE_TRANSITION);
+ me->SetReactState(REACT_PASSIVE);
+ me->GetMotionMaster()->MovePoint(POINT_START_TRANSITION, TransitionPos[0]);
}
}
- void EnterCombat(Unit* /*who*/) override
+ void MovementInform(uint32 type, uint32 point) override
{
- if (!instance->GetData(DATA_KAELTHASEVENT) && !Phase)
- StartEvent();
+ if (type != POINT_MOTION_TYPE)
+ return;
+
+ switch (point)
+ {
+ case POINT_START_TRANSITION:
+ events.ScheduleEvent(EVENT_TRANSITION_1, 1000);
+ break;
+ case POINT_TRANSITION_CENTER_ASCENDING:
+ me->SetFacingTo(float(M_PI));
+ Talk(SAY_PHASE5_NUTS);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetDisableGravity(true);
+ //me->SetHover(true); -- Set in sniffs, but breaks his visual.
+ events.ScheduleEvent(EVENT_TRANSITION_2, 2000);
+ events.ScheduleEvent(EVENT_SIZE_INCREASE, 5000);
+ break;
+ case POINT_TRANSITION_HALFWAY_ASCENDING:
+ DoCast(me, SPELL_NETHER_BEAM_VISUAL3, true);
+ events.ScheduleEvent(EVENT_TRANSITION_3, 1000);
+ break;
+ case POINT_TRANSITION_TOP:
+ events.ScheduleEvent(EVENT_EXPLODE, 10000);
+ break;
+ case POINT_TRANSITION_HALFWAY_DESCENDING:
+ events.ScheduleEvent(EVENT_TRANSITION_5, 2000);
+ break;
+ case POINT_END_TRANSITION:
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->InterruptNonMeleeSpells(false);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->RemoveAurasDueToSpell(SPELL_FULLPOWER);
- instance->SetBossState(DATA_KAELTHAS, IN_PROGRESS);
+ if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 0))
+ AttackStart(target);
+
+ DoAction(ACTION_SCHEDULE_COMBAT_EVENTS);
+ events.ScheduleEvent(EVENT_GRAVITY_LAPSE, 10000, EVENT_GROUP_COMBAT, PHASE_COMBAT);
+ break;
+ default:
+ break;
+ }
}
void KilledUnit(Unit* /*victim*/) override
@@ -456,556 +645,224 @@ class boss_kaelthas : public CreatureScript
}
}
- void JustDied(Unit* /*killer*/) override
+ void JustDied(Unit* killer) override
{
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-
Talk(SAY_DEATH);
-
- instance->SetData(DATA_KAELTHASEVENT, 0);
-
- for (uint8 i = 0; i < MAX_ADVISORS; ++i)
- {
- if (Unit* pAdvisor = ObjectAccessor::GetUnit(*me, m_auiAdvisorGuid[i]))
- pAdvisor->Kill(pAdvisor);
- }
- _JustDied();
+ BossAI::JustDied(killer);
}
void UpdateAI(uint32 diff) override
{
- //Phase 1
- switch (Phase)
- {
- case 1:
- {
- Unit* target = NULL;
- Creature* Advisor = NULL;
-
- //Subphase switch
- switch (PhaseSubphase)
- {
- //Subphase 1 - Start
- case 0:
- if (Phase_Timer <= diff)
- {
- Talk(SAY_INTRO_THALADRED);
-
- //start advisor within 7 seconds
- Phase_Timer = 7000;
- ++PhaseSubphase;
- } else Phase_Timer -= diff;
- break;
-
- //Subphase 1 - Unlock advisor
- case 1:
- if (Phase_Timer <= diff)
- {
- Advisor = (ObjectAccessor::GetCreature(*me, m_auiAdvisorGuid[0]));
-
- if (Advisor)
- {
- Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- Advisor->setFaction(me->getFaction());
-
- target = SelectTarget(SELECT_TARGET_RANDOM, 0);
- if (target)
- Advisor->AI()->AttackStart(target);
- }
-
- ++PhaseSubphase;
- } else Phase_Timer -= diff;
- break;
-
- //Subphase 2 - Start
- case 2:
- Advisor = (ObjectAccessor::GetCreature(*me, m_auiAdvisorGuid[0]));
-
- if (Advisor && (Advisor->GetStandState() == UNIT_STAND_STATE_DEAD))
- {
- Talk(SAY_INTRO_SANGUINAR);
-
- //start advisor within 12.5 seconds
- Phase_Timer = 12500;
- ++PhaseSubphase;
- }
- break;
-
- //Subphase 2 - Unlock advisor
- case 3:
- if (Phase_Timer <= diff)
- {
- Advisor = (ObjectAccessor::GetCreature(*me, m_auiAdvisorGuid[1]));
-
- if (Advisor)
- {
- Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- Advisor->setFaction(me->getFaction());
-
- target = SelectTarget(SELECT_TARGET_RANDOM, 0);
- if (target)
- Advisor->AI()->AttackStart(target);
- }
-
- ++PhaseSubphase;
- } else Phase_Timer -= diff;
- break;
-
- //Subphase 3 - Start
- case 4:
- Advisor = (ObjectAccessor::GetCreature(*me, m_auiAdvisorGuid[1]));
-
- if (Advisor && (Advisor->GetStandState() == UNIT_STAND_STATE_DEAD))
- {
- Talk(SAY_INTRO_CAPERNIAN);
-
- //start advisor within 7 seconds
- Phase_Timer = 7000;
- ++PhaseSubphase;
- }
- break;
-
- //Subphase 3 - Unlock advisor
- case 5:
- if (Phase_Timer <= diff)
- {
- Advisor = (ObjectAccessor::GetCreature(*me, m_auiAdvisorGuid[2]));
-
- if (Advisor)
- {
- Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- Advisor->setFaction(me->getFaction());
-
- target = SelectTarget(SELECT_TARGET_RANDOM, 0);
- if (target)
- Advisor->AI()->AttackStart(target);
- }
-
- ++PhaseSubphase;
- } else Phase_Timer -= diff;
- break;
-
- //Subphase 4 - Start
- case 6:
- Advisor = (ObjectAccessor::GetCreature(*me, m_auiAdvisorGuid[2]));
-
- if (Advisor && (Advisor->GetStandState() == UNIT_STAND_STATE_DEAD))
- {
- Talk(SAY_INTRO_TELONICUS);
-
- //start advisor within 8.4 seconds
- Phase_Timer = 8400;
- ++PhaseSubphase;
- }
- break;
-
- //Subphase 4 - Unlock advisor
- case 7:
- if (Phase_Timer <= diff)
- {
- Advisor = (ObjectAccessor::GetCreature(*me, m_auiAdvisorGuid[3]));
-
- if (Advisor)
- {
- Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- Advisor->setFaction(me->getFaction());
-
- target = SelectTarget(SELECT_TARGET_RANDOM, 0);
- if (target)
- Advisor->AI()->AttackStart(target);
- }
-
- Phase_Timer = 3000;
- ++PhaseSubphase;
- } else Phase_Timer -= diff;
- break;
-
- //End of phase 1
- case 8:
- Advisor = (ObjectAccessor::GetCreature(*me, m_auiAdvisorGuid[3]));
-
- if (Advisor && (Advisor->GetStandState() == UNIT_STAND_STATE_DEAD))
- {
- Phase = 2;
- instance->SetData(DATA_KAELTHASEVENT, 2);
+ if (_phase == PHASE_COMBAT)
+ if (!UpdateVictim())
+ return;
- Talk(SAY_PHASE2_WEAPON);
+ events.Update(diff);
- PhaseSubphase = 0;
- Phase_Timer = 3500;
- DoCast(me, SPELL_SUMMON_WEAPONS);
- }
- break;
- }
- }
- break;
+ // SPELL_KAEL_GAINING_POWER and SPELL_KAEL_STUNNED are channeling spells that need to be interrupted during his transition.
+ if (me->HasUnitState(UNIT_STATE_CASTING) && !me->FindCurrentSpellBySpellId(SPELL_KAEL_GAINING_POWER) && !me->FindCurrentSpellBySpellId(SPELL_KAEL_STUNNED))
+ return;
- case 2:
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
{
- if (PhaseSubphase == 0)
- {
- if (Phase_Timer <= diff)
+ case EVENT_START_ENCOUNTER:
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
+ DoAction(ACTION_ACTIVE_ADVISOR);
+ break;
+ case EVENT_ACTIVE_ADVISOR:
+ if (Creature* advisor = ObjectAccessor::GetCreature(*me, _advisorGuid[_advisorCounter]))
{
- PhaseSubphase = 1;
- }
- else
- Phase_Timer -= diff;
- }
+ advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- //Spawn weapons
- if (PhaseSubphase == 1)
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ advisor->AI()->AttackStart(target);
+ }
+ ++_advisorCounter;
+ break;
+ case EVENT_SUMMON_WEAPONS:
{
DoCast(me, SPELL_SUMMON_WEAPONS, false);
- uint8 uiMaxWeapon = sizeof(m_auiSpellSummonWeapon)/sizeof(uint32);
+ uint8 uiMaxWeapon = sizeof(m_auiSpellSummonWeapon) / sizeof(uint32);
for (uint32 i = 0; i < uiMaxWeapon; ++i)
DoCast(me, m_auiSpellSummonWeapon[i], true);
- PhaseSubphase = 2;
- Phase_Timer = TIME_PHASE_2_3;
- }
-
- if (PhaseSubphase == 2)
- {
- if (Phase_Timer <= diff)
- {
- Talk(SAY_PHASE3_ADVANCE);
- instance->SetData(DATA_KAELTHASEVENT, 3);
- Phase = 3;
- PhaseSubphase = 0;
- }
- else
- Phase_Timer -= diff;
- }
- }
- break;
-
- case 3:
- {
- if (PhaseSubphase == 0)
- {
- //Respawn advisors
- Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0);
-
- for (uint8 i = 0; i < MAX_ADVISORS; ++i)
- {
- Creature* Advisor = ObjectAccessor::GetCreature(*me, m_auiAdvisorGuid[i]);
-
- if (!Advisor)
- TC_LOG_ERROR("scripts", "SD2: Kael'Thas Advisor %u does not exist. Possibly despawned? Incorrectly Killed?", i);
- else
- ENSURE_AI(advisorbase_ai, Advisor->AI())->Revive(target);
- }
-
- PhaseSubphase = 1;
- Phase_Timer = TIME_PHASE_3_4;
+ events.ScheduleEvent(EVENT_REVIVE_ADVISORS, 120000);
+ break;
}
-
- if (Phase_Timer <= diff)
- {
+ case EVENT_REVIVE_ADVISORS:
+ _phase = PHASE_REVIVED_ADVISORS;
+ Talk(SAY_PHASE3_ADVANCE);
+ DoCast(me, SPELL_RESSURECTION);
+ break;
+ case EVENT_ENGAGE_COMBAT:
Talk(SAY_PHASE4_INTRO2);
- Phase = 4;
-
- instance->SetData(DATA_KAELTHASEVENT, 4);
// Sometimes people can collect Aggro in Phase 1-3. Reset threat before releasing Kael.
DoResetThreat();
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
AttackStart(target);
- Phase_Timer = 30000;
- }
- else
- Phase_Timer -= diff;
- }
- break;
-
- case 4:
- case 5:
- case 6:
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- //Fireball_Timer
- if (!InGravityLapse && !ChainPyros && Phase != 5)
- {
- if (Fireball_Timer <= diff)
- {
- if (!IsCastingFireball)
- {
- if (!me->IsNonMeleeSpellCast(false))
- {
- //interruptable
- me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false);
- int32 dmg = 20000 + rand32() % 5000;
- me->CastCustomSpell(me->GetVictim(), SPELL_FIREBALL, &dmg, 0, 0, false);
- IsCastingFireball = true;
- Fireball_Timer = 2500;
- }
- }
- else
- {
- //apply resistance
- me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true);
- IsCastingFireball = false;
- Fireball_Timer = 5000 + rand32() % 10000;
- }
- }
- else
- Fireball_Timer -= diff;
+ DoAction(ACTION_SCHEDULE_COMBAT_EVENTS);
+ events.ScheduleEvent(EVENT_PYROBLAST, 60000, EVENT_GROUP_COMBAT, PHASE_COMBAT);
+ break;
+ case EVENT_FIREBALL:
+ DoCastVictim(SPELL_FIREBALL);
+ events.ScheduleEvent(EVENT_FIREBALL, 2500, EVENT_GROUP_COMBAT, PHASE_COMBAT);
+ break;
+ case EVENT_ARCANE_DISRUPTION:
+ DoCastVictim(SPELL_ARCANE_DISRUPTION, true);
+ events.ScheduleEvent(EVENT_ARCANE_DISRUPTION, 60000, EVENT_GROUP_COMBAT, PHASE_COMBAT);
+ break;
+ case EVENT_FLAMESTRIKE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_FLAME_STRIKE);
- //ArcaneDisruption_Timer
- if (ArcaneDisruption_Timer <= diff)
+ events.ScheduleEvent(EVENT_FLAMESTRIKE, 30000, EVENT_GROUP_COMBAT, PHASE_COMBAT);
+ break;
+ case EVENT_MIND_CONTROL:
+ Talk(SAY_MIND_CONTROL);
+ DoCastAOE(SPELL_MIND_CONTROL, true);
+ events.ScheduleEvent(EVENT_MIND_CONTROL, 60000, EVENT_GROUP_COMBAT, PHASE_COMBAT);
+ break;
+ case EVENT_SUMMON_PHOENIX:
+ DoCast(me, SPELL_PHOENIX_ANIMATION);
+ Talk(SAY_SUMMON_PHOENIX);
+ events.ScheduleEvent(EVENT_SUMMON_PHOENIX, urand(45000, 60000), EVENT_GROUP_COMBAT, PHASE_COMBAT);
+ break;
+ case EVENT_END_TRANSITION:
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
+ DoCast(SPELL_FULLPOWER);
+ events.ScheduleEvent(EVENT_TRANSITION_4, 2000);
+ break;
+ case EVENT_PYROBLAST:
+ _pyrosCast = 0;
+ Talk(EMOTE_PYROBLAST);
+ DoCast(me, SPELL_SHOCK_BARRIER);
+ events.DelayEvents(10000, EVENT_GROUP_COMBAT);
+ events.ScheduleEvent(EVENT_PYROBLAST_CAST, 1000, EVENT_GROUP_SPECIAL, PHASE_COMBAT);
+ break;
+ case EVENT_PYROBLAST_CAST:
+ if (_pyrosCast < 3)
{
- DoCastVictim(SPELL_ARCANE_DISRUPTION, true);
- ArcaneDisruption_Timer = 60000;
+ DoCastVictim(SPELL_PYROBLAST);
+ events.ScheduleEvent(EVENT_PYROBLAST_CAST, 3000);
+ _pyrosCast++;
}
else
- ArcaneDisruption_Timer -= diff;
-
- if (FlameStrike_Timer <= diff)
+ events.ScheduleEvent(EVENT_PYROBLAST, 60000, EVENT_GROUP_COMBAT, PHASE_COMBAT);
+ break;
+ case EVENT_GRAVITY_LAPSE:
+ Talk(SAY_GRAVITY_LAPSE);
+ DoCastAOE(SPELL_GRAVITY_LAPSE);
+ DoCast(me, SPELL_NETHER_VAPOR);
+ events.DelayEvents(24000, EVENT_GROUP_COMBAT);
+ events.ScheduleEvent(EVENT_NETHER_BEAM, 3000, EVENT_GROUP_SPECIAL, PHASE_COMBAT);
+ events.ScheduleEvent(EVENT_SHOCK_BARRIER, 1000, EVENT_GROUP_SPECIAL, PHASE_COMBAT);
+ events.ScheduleEvent(EVENT_GRAVITY_LAPSE, 30000, EVENT_GROUP_SPECIAL, PHASE_COMBAT);
+ break;
+ case EVENT_NETHER_BEAM:
+ if (_netherbeamsCast <= 8)
{
if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(unit, SPELL_FLAME_STRIKE);
+ DoCast(unit, SPELL_NETHER_BEAM);
- FlameStrike_Timer = 30000;
+ _netherbeamsCast++;
+ events.ScheduleEvent(EVENT_NETHER_BEAM, 3000);
}
else
- FlameStrike_Timer -= diff;
-
- if (MindControl_Timer <= diff)
- {
- if (me->getThreatManager().getThreatList().size() >= 2)
- for (uint32 i = 0; i < 3; ++i)
- {
- TC_LOG_DEBUG("scripts", "Kael'Thas mind control not supported.");
- //DoCast(unit, SPELL_MIND_CONTROL);
- }
-
- MindControl_Timer = 60000;
- }
- else
- MindControl_Timer -= diff;
- }
-
- //Phoenix_Timer
- if (Phoenix_Timer <= diff)
- {
- DoCast(me, SPELL_PHOENIX_ANIMATION);
- Talk(SAY_SUMMON_PHOENIX);
-
- Phoenix_Timer = 60000;
- }
- else
- Phoenix_Timer -= diff;
-
- //Phase 4 specific spells
- if (Phase == 4)
- {
- if (HealthBelowPct(50))
- {
- instance->SetData(DATA_KAELTHASEVENT, 4);
- Phase = 5;
- Phase_Timer = 10000;
-
- Talk(SAY_PHASE5_NUTS);
-
- me->StopMoving();
- me->GetMotionMaster()->Clear();
- me->GetMotionMaster()->MoveIdle();
- me->SetPosition(afGravityPos[0], afGravityPos[1], afGravityPos[2], 0);
- me->MonsterMoveWithSpeed(afGravityPos[0], afGravityPos[1], afGravityPos[2], 1);
-
- me->InterruptNonMeleeSpells(false);
- DoCast(me, SPELL_FULLPOWER);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- }
-
- //ShockBarrier_Timer
- if (ShockBarrier_Timer <= diff)
- {
- DoCast(me, SPELL_SHOCK_BARRIER);
- ChainPyros = true;
- PyrosCast = 0;
- ShockBarrier_Timer = 60000;
- }
- else
- ShockBarrier_Timer -= diff;
-
- //Chain Pyros (3 of them max)
- if (ChainPyros && !me->IsNonMeleeSpellCast(false))
- {
- if (PyrosCast < 3)
- {
- DoCastVictim(SPELL_PYROBLAST);
- ++PyrosCast;
- }
- else
- {
- ChainPyros = false;
- Fireball_Timer = 2500;
- ArcaneDisruption_Timer = 60000;
- }
- }
- }
-
- if (Phase == 5)
- {
- if (Phase_Timer <= diff)
- {
- me->InterruptNonMeleeSpells(false);
- me->RemoveAurasDueToSpell(SPELL_FULLPOWER);
+ _netherbeamsCast = 0;
+ break;
+ case EVENT_TRANSITION_1:
+ me->GetMotionMaster()->MovePoint(POINT_TRANSITION_CENTER_ASCENDING, TransitionPos[1]);
+ break;
+ case EVENT_TRANSITION_2:
+ DoCast(me, SPELL_KAEL_GAINING_POWER);
+ me->GetMotionMaster()->Clear();
+ me->RemoveUnitMovementFlag(MOVEMENTFLAG_ROOT);
+ me->GetMotionMaster()->MovePoint(POINT_TRANSITION_HALFWAY_ASCENDING, TransitionPos[2], false);
+ break;
+ case EVENT_TRANSITION_3:
+ me->GetMotionMaster()->MovePoint(POINT_TRANSITION_TOP, TransitionPos[3], false);
+ break;
+ case EVENT_TRANSITION_4:
+ me->GetMotionMaster()->MovePoint(POINT_TRANSITION_HALFWAY_DESCENDING, TransitionPos[4], false);
+ break;
+ case EVENT_TRANSITION_5:
+ me->GetMotionMaster()->MovePoint(POINT_END_TRANSITION, TransitionPos[5], false);
+ break;
+ case EVENT_EXPLODE:
+ me->InterruptNonMeleeSpells(false);
+ me->RemoveAurasDueToSpell(SPELL_NETHER_BEAM_VISUAL3);
+ DoCast(me, SPELL_KAEL_EXPLODES3, true);
+ DoCast(me, SPELL_KAEL_STUNNED); // Core doesn't handle the emote properly while flying.
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_DROWNED);
- DoCast(me, SPELL_EXPLODE);
+ // Destroy the surrounding environment.
+ if (GameObject* statue = instance->GetGameObject(DATA_KAEL_STATUE_LEFT))
+ statue->UseDoorOrButton();
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- Phase = 6;
- AttackStart(me->GetVictim());
- }
- else
- Phase_Timer -= diff;
- }
+ if (GameObject* statue = instance->GetGameObject(DATA_KAEL_STATUE_RIGHT))
+ statue->UseDoorOrButton();
- //Phase 5
- if (Phase == 6)
- {
- //GravityLapse_Timer
- if (GravityLapse_Timer <= diff)
- {
- ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
- ThreatContainer::StorageType::const_iterator i = threatlist.begin();
-
- switch (GravityLapse_Phase)
- {
- case 0:
- me->StopMoving();
- me->GetMotionMaster()->Clear();
- me->GetMotionMaster()->MoveIdle();
- me->SetPosition(afGravityPos[0], afGravityPos[1], afGravityPos[2], 0);
- me->MonsterMoveWithSpeed(afGravityPos[0], afGravityPos[1], afGravityPos[2], 0);
-
- // 1) Kael'thas will portal the whole raid right into his body
- for (i = threatlist.begin(); i != threatlist.end(); ++i)
- {
- Unit* unit = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid());
- if (unit && (unit->GetTypeId() == TYPEID_PLAYER))
- {
- //Use work around packet to prevent player from being dropped from combat
- DoTeleportPlayer(unit, afGravityPos[0], afGravityPos[1], afGravityPos[2], unit->GetOrientation());
- }
- }
-
- GravityLapse_Timer = 500;
- ++GravityLapse_Phase;
- InGravityLapse = true;
- ShockBarrier_Timer = 1000;
- NetherBeam_Timer = 5000;
- break;
-
- case 1:
- Talk(SAY_GRAVITYLAPSE);
-
- // 2) At that point he will put a Gravity Lapse debuff on everyone
- for (i = threatlist.begin(); i != threatlist.end(); ++i)
- {
- if (Unit* unit = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid()))
- {
- DoCast(unit, SPELL_KNOCKBACK, true);
- //Gravity lapse - needs an exception in Spell system to work
-
- unit->CastSpell(unit, SPELL_GRAVITY_LAPSE, true, 0, 0, me->GetGUID());
- unit->CastSpell(unit, SPELL_GRAVITY_LAPSE_AURA, true, 0, 0, me->GetGUID());
-
- //Using packet workaround
- WorldPacket data(SMSG_MOVE_SET_CAN_FLY, 12);
- data << unit->GetPackGUID();
- data << uint32(0);
- unit->SendMessageToSet(&data, true);
- }
- }
- GravityLapse_Timer = 10000;
- ++GravityLapse_Phase;
- break;
-
- case 2:
- //Cast nether vapor aura on self
- me->InterruptNonMeleeSpells(false);
- DoCast(me, SPELL_NETHER_VAPOR);
-
- GravityLapse_Timer = 20000;
- ++GravityLapse_Phase;
- break;
-
- case 3:
- //Remove flight
- for (i = threatlist.begin(); i != threatlist.end(); ++i)
- {
- if (Unit* unit = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid()))
- {
- //Using packet workaround
- WorldPacket data(SMSG_MOVE_UNSET_CAN_FLY, 12);
- data << unit->GetPackGUID();
- data << uint32(0);
- unit->SendMessageToSet(&data, true);
- }
- }
-
- me->RemoveAurasDueToSpell(SPELL_NETHER_VAPOR);
- InGravityLapse = false;
- GravityLapse_Timer = 60000;
- GravityLapse_Phase = 0;
- AttackStart(me->GetVictim());
- break;
- }
- }
- else
- GravityLapse_Timer -= diff;
+ if (GameObject* window = instance->GetGameObject(DATA_TEMPEST_BRIDGE_WINDOW))
+ window->UseDoorOrButton();
- if (InGravityLapse)
+ events.ScheduleEvent(EVENT_END_TRANSITION, 10000);
+ break;
+ case EVENT_SIZE_INCREASE:
+ switch (_scaleStage)
{
- //ShockBarrier_Timer
- if (ShockBarrier_Timer <= diff)
- {
- DoCast(me, SPELL_SHOCK_BARRIER);
- ShockBarrier_Timer = 20000;
- }
- else
- ShockBarrier_Timer -= diff;
-
- //NetherBeam_Timer
- if (NetherBeam_Timer <= diff)
- {
- if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(unit, SPELL_NETHER_BEAM);
-
- NetherBeam_Timer = 4000;
- }
- else
- NetherBeam_Timer -= diff;
+ case 0:
+ me->SetObjectScale(1.4f);
+ events.ScheduleEvent(EVENT_SIZE_INCREASE, 5000);
+ break;
+ case 1:
+ me->SetObjectScale(1.8f);
+ events.ScheduleEvent(EVENT_SIZE_INCREASE, 3000);
+ break;
+ case 2:
+ me->SetObjectScale(2.0f);
+ events.ScheduleEvent(EVENT_SIZE_INCREASE, 1000);
+ break;
+ case 3:
+ me->SetObjectScale(2.2f);
+ break;
+ default:
+ break;
}
- }
-
- if (!InGravityLapse)
- DoMeleeAttackIfReady();
+ ++_scaleStage;
+ break;
+ default:
+ break;
}
}
+
+ if (events.IsInPhase(PHASE_COMBAT))
+ DoMeleeAttackIfReady();
}
+ private:
+ uint8 _advisorCounter;
+ uint8 _phase;
+ uint8 _pyrosCast;
+ uint8 _scaleStage;
+ uint8 _netherbeamsCast;
+ bool _hasFullPower;
+ ObjectGuid _advisorGuid[MAX_ADVISORS];
};
+
CreatureAI* GetAI(Creature* creature) const override
{
return GetInstanceAI<boss_kaelthasAI>(creature);
}
};
-//Thaladred the Darkener AI
class boss_thaladred_the_darkener : public CreatureScript
{
public:
@@ -1039,32 +896,23 @@ class boss_thaladred_the_darkener : public CreatureScript
void EnterCombat(Unit* who) override
{
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- return;
-
- if (!who || FakeDeath)
- return;
-
Talk(SAY_THALADRED_AGGRO);
me->AddThreat(who, 5000000.0f);
}
- void JustDied(Unit* /*killer*/) override
+ void JustDied(Unit* killer) override
{
- if (instance->GetData(DATA_KAELTHASEVENT) == 3)
+ if (_hasRessurrected)
Talk(SAY_THALADRED_DEATH);
+
+ advisorbase_ai::JustDied(killer);
}
void UpdateAI(uint32 diff) override
{
advisorbase_ai::UpdateAI(diff);
- //Faking death, don't do anything
- if (FakeDeath)
- return;
-
- //Return since we have no target
- if (!UpdateVictim())
+ if (!UpdateVictim() || _inFakeDeath)
return;
//Gaze_Timer
@@ -1109,7 +957,6 @@ class boss_thaladred_the_darkener : public CreatureScript
}
};
-//Lord Sanguinar AI
class boss_lord_sanguinar : public CreatureScript
{
public:
@@ -1136,33 +983,24 @@ class boss_lord_sanguinar : public CreatureScript
advisorbase_ai::Reset();
}
- void EnterCombat(Unit* who) override
+ void EnterCombat(Unit* /*who*/) override
{
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- return;
-
- if (!who || FakeDeath)
- return;
-
Talk(SAY_SANGUINAR_AGGRO);
}
- void JustDied(Unit* /*killer*/) override
+ void JustDied(Unit* killer) override
{
- if (instance->GetData(DATA_KAELTHASEVENT) == 3)
+ if (_hasRessurrected)
Talk(SAY_SANGUINAR_DEATH);
+
+ advisorbase_ai::JustDied(killer);
}
void UpdateAI(uint32 diff) override
{
advisorbase_ai::UpdateAI(diff);
- //Faking death, don't do anything
- if (FakeDeath)
- return;
-
- //Return since we have no target
- if (!UpdateVictim())
+ if (!UpdateVictim() || _inFakeDeath)
return;
//Fear_Timer
@@ -1182,7 +1020,7 @@ class boss_lord_sanguinar : public CreatureScript
return GetInstanceAI<boss_lord_sanguinarAI>(creature);
}
};
-//Grand Astromancer Capernian AI
+
class boss_grand_astromancer_capernian : public CreatureScript
{
public:
@@ -1218,15 +1056,17 @@ class boss_grand_astromancer_capernian : public CreatureScript
advisorbase_ai::Reset();
}
- void JustDied(Unit* /*killer*/) override
+ void JustDied(Unit* killer) override
{
- if (instance->GetData(DATA_KAELTHASEVENT) == 3)
+ if (_hasRessurrected)
Talk(SAY_CAPERNIAN_DEATH);
+
+ advisorbase_ai::JustDied(killer);
}
void AttackStart(Unit* who) override
{
- if (!who || FakeDeath || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ if (!who || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
return;
if (me->Attack(who, true))
@@ -1239,39 +1079,18 @@ class boss_grand_astromancer_capernian : public CreatureScript
}
}
- void EnterCombat(Unit* who) override
+ void EnterCombat(Unit* /*who*/) override
{
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- return;
-
- if (!who || FakeDeath)
- return;
+ Talk(SAY_CAPERNIAN_AGGRO);
}
void UpdateAI(uint32 diff) override
{
advisorbase_ai::UpdateAI(diff);
- //Faking Death, don't do anything
- if (FakeDeath)
+ if (!UpdateVictim() || _inFakeDeath)
return;
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- //Yell_Timer
- if (!Yell)
- {
- if (Yell_Timer <= diff)
- {
- Talk(SAY_CAPERNIAN_AGGRO);
- Yell = true;
- }
- else
- Yell_Timer -= diff;
- }
-
//Fireball_Timer
if (Fireball_Timer <= diff)
{
@@ -1333,7 +1152,6 @@ class boss_grand_astromancer_capernian : public CreatureScript
}
};
-//Master Engineer Telonicus AI
class boss_master_engineer_telonicus : public CreatureScript
{
public:
@@ -1363,20 +1181,16 @@ class boss_master_engineer_telonicus : public CreatureScript
advisorbase_ai::Reset();
}
- void JustDied(Unit* /*killer*/) override
+ void JustDied(Unit* killer) override
{
- if (instance->GetData(DATA_KAELTHASEVENT) == 3)
+ if (_hasRessurrected)
Talk(SAY_TELONICUS_DEATH);
+
+ advisorbase_ai::JustDied(killer);
}
- void EnterCombat(Unit* who) override
+ void EnterCombat(Unit* /*who*/) override
{
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- return;
-
- if (!who || FakeDeath)
- return;
-
Talk(SAY_TELONICUS_AGGRO);
}
@@ -1384,12 +1198,7 @@ class boss_master_engineer_telonicus : public CreatureScript
{
advisorbase_ai::UpdateAI(diff);
- //Faking Death, do nothing
- if (FakeDeath)
- return;
-
- //Return since we have no target
- if (!UpdateVictim())
+ if (!UpdateVictim() || _inFakeDeath)
return;
//Bomb_Timer
@@ -1422,7 +1231,6 @@ class boss_master_engineer_telonicus : public CreatureScript
}
};
-//Flame Strike AI
class npc_kael_flamestrike : public CreatureScript
{
public:
@@ -1493,7 +1301,6 @@ class npc_kael_flamestrike : public CreatureScript
}
};
-//Phoenix AI
class npc_phoenix_tk : public CreatureScript
{
public:
@@ -1553,7 +1360,6 @@ class npc_phoenix_tk : public CreatureScript
}
};
-//Phoenix Egg AI
class npc_phoenix_egg_tk : public CreatureScript
{
public:
@@ -1620,6 +1426,54 @@ class npc_phoenix_egg_tk : public CreatureScript
}
};
+// 35941 - Gravity Lapse
+class spell_kael_gravity_lapse : public SpellScriptLoader
+{
+ public:
+ spell_kael_gravity_lapse() : SpellScriptLoader("spell_kael_gravity_lapse") { }
+
+ class spell_kael_gravity_lapse_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_kael_gravity_lapse_SpellScript);
+
+ public:
+ spell_kael_gravity_lapse_SpellScript()
+ {
+ _targetCount = 0;
+ }
+
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ for (uint8 i = 0; i < 25; ++i)
+ if (!sSpellMgr->GetSpellInfo(GravityLapseSpells[i]))
+ return false;
+
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ GetCaster()->CastSpell(GetHitUnit(), GravityLapseSpells[_targetCount], true);
+ GetHitUnit()->CastSpell(GetHitUnit(), SPELL_GRAVITY_LAPSE_PERIODIC, true);
+ GetHitUnit()->CastSpell(GetHitUnit(), SPELL_GRAVITY_LAPSE_FLIGHT_AURA, true);
+ _targetCount++;
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_kael_gravity_lapse_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+
+ private:
+ uint8 _targetCount;
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_kael_gravity_lapse_SpellScript();
+ }
+};
+
void AddSC_boss_kaelthas()
{
new boss_kaelthas();
@@ -1630,4 +1484,5 @@ void AddSC_boss_kaelthas()
new npc_kael_flamestrike();
new npc_phoenix_tk();
new npc_phoenix_egg_tk();
+ new spell_kael_gravity_lapse();
}
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/instance_the_eye.cpp b/src/server/scripts/Outland/TempestKeep/Eye/instance_the_eye.cpp
index c421b9974ce..173e0596bea 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/instance_the_eye.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/instance_the_eye.cpp
@@ -34,6 +34,21 @@ EndScriptData */
3 - Void Reaver event
*/
+DoorData const doorData[] =
+{
+ { GO_ARCANE_DOOR_LEFT, DATA_KAELTHAS, DOOR_TYPE_ROOM, BOUNDARY_SW },
+ { GO_ARCANE_DOOR_RIGHT, DATA_KAELTHAS, DOOR_TYPE_ROOM, BOUNDARY_SE },
+ { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+};
+
+ObjectData const gameObjectData[] =
+{
+ { GO_KAEL_STATUE_RIGHT, DATA_KAEL_STATUE_RIGHT },
+ { GO_KAEL_STATUE_LEFT, DATA_KAEL_STATUE_LEFT },
+ { GO_TEMPEST_BRIDDGE_WINDOW, DATA_TEMPEST_BRIDGE_WINDOW },
+ { 0, 0 } // END
+};
+
class instance_the_eye : public InstanceMapScript
{
public:
@@ -45,8 +60,8 @@ class instance_the_eye : public InstanceMapScript
{
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
-
- KaelthasEventPhase = 0;
+ LoadDoorData(doorData);
+ LoadObjectData(nullptr, gameObjectData);
}
ObjectGuid ThaladredTheDarkener;
@@ -56,7 +71,6 @@ class instance_the_eye : public InstanceMapScript
ObjectGuid Kaelthas;
ObjectGuid Astromancer;
ObjectGuid Alar;
- uint8 KaelthasEventPhase;
void OnCreatureCreate(Creature* creature) override
{
@@ -102,28 +116,6 @@ class instance_the_eye : public InstanceMapScript
}
return ObjectGuid::Empty;
}
-
- void SetData(uint32 type, uint32 data) override
- {
- switch (type)
- {
- case DATA_KAELTHASEVENT:
- KaelthasEventPhase = data;
- break;
- default:
- break;
- }
- }
-
- uint32 GetData(uint32 type) const override
- {
- switch (type)
- {
- case DATA_KAELTHASEVENT:
- return KaelthasEventPhase;
- }
- return 0;
- }
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/the_eye.h b/src/server/scripts/Outland/TempestKeep/Eye/the_eye.h
index c46fe408274..ca60e14e923 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/the_eye.h
+++ b/src/server/scripts/Outland/TempestKeep/Eye/the_eye.h
@@ -33,10 +33,14 @@ enum DataTypes
DATA_ASTROMANCER = 4,
DATA_GRANDASTROMANCERCAPERNIAN = 5,
- DATA_KAELTHASEVENT = 6,
- DATA_LORDSANGUINAR = 7,
- DATA_MASTERENGINEERTELONICUS = 8,
- DATA_THALADREDTHEDARKENER = 9
+ DATA_LORDSANGUINAR = 6,
+ DATA_MASTERENGINEERTELONICUS = 7,
+ DATA_THALADREDTHEDARKENER = 8,
+
+ // Additional Data
+ DATA_KAEL_STATUE_LEFT = 9,
+ DATA_KAEL_STATUE_RIGHT = 10,
+ DATA_TEMPEST_BRIDGE_WINDOW = 11
};
enum CreatureIds
@@ -50,4 +54,13 @@ enum CreatureIds
NPC_ALAR = 19514
};
+enum GameObjectIds
+{
+ GO_TEMPEST_BRIDDGE_WINDOW = 184069,
+ GO_KAEL_STATUE_RIGHT = 184596,
+ GO_KAEL_STATUE_LEFT = 184597,
+ GO_ARCANE_DOOR_LEFT = 184324,
+ GO_ARCANE_DOOR_RIGHT = 184325
+};
+
#endif