diff options
Diffstat (limited to 'src')
6 files changed, 2234 insertions, 2023 deletions
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp index 6230ec1a7fa..e529f41a7cf 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp @@ -26,21 +26,24 @@ EndScriptData */ #include "ScriptPCH.h" #include "the_eye.h" -#define SPELL_FLAME_BUFFET 34121 // Flame Buffet - every 1,5 secs in phase 1 if there is no victim in melee range and after Dive Bomb in phase 2 with same conditions -#define SPELL_FLAME_QUILLS 34229 // Randomly after changing position in phase after watching tonns of movies, set probability 20% -#define SPELL_REBIRTH 34342 // Rebirth - beginning of second phase(after loose all health in phase 1) -#define SPELL_REBIRTH_2 35369 // Rebirth(another, without healing to full HP) - after Dive Bomb in phase 2 -#define SPELL_MELT_ARMOR 35410 // Melt Armor - every 60 sec in phase 2 -#define SPELL_CHARGE 35412 // Charge - 30 sec cooldown -#define SPELL_DIVE_BOMB_VISUAL 35367 // Bosskillers says 30 sec cooldown, wowwiki says 30 sec colldown, DBM and BigWigs addons says ~47 sec -#define SPELL_DIVE_BOMB 35181 // after watching tonns of movies, set cooldown to 40+rand()%5. -#define SPELL_BERSERK 45078 // 10 minutes after phase 2 starts(id is wrong, but proper id is unknown) - -#define CREATURE_EMBER_OF_ALAR 19551 // Al'ar summons one Ember of Al'ar every position change in phase 1 and two after Dive Bomb. Also in phase 2 when Ember of Al'ar dies, boss loose 3% health. -#define SPELL_EMBER_BLAST 34133 // When Ember of Al'ar dies, it casts Ember Blast - -#define CREATURE_FLAME_PATCH_ALAR 20602 // Flame Patch - every 30 sec in phase 2 -#define SPELL_FLAME_PATCH 35380 // +enum eSpells +{ + SPELL_FLAME_BUFFET = 34121, // Flame Buffet - every 1,5 secs in phase 1 if there is no victim in melee range and after Dive Bomb in phase 2 with same conditions + SPELL_FLAME_QUILLS = 34229, // Randomly after changing position in phase after watching tonns of movies, set probability 20% + SPELL_REBIRTH = 34342, // Rebirth - beginning of second phase(after loose all health in phase 1) + SPELL_REBIRTH_2 = 35369, // Rebirth(another, without healing to full HP) - after Dive Bomb in phase 2 + SPELL_MELT_ARMOR = 35410, // Melt Armor - every 60 sec in phase 2 + SPELL_CHARGE = 35412, // Charge - 30 sec cooldown + SPELL_DIVE_BOMB_VISUAL = 35367, // Bosskillers says 30 sec cooldown, wowwiki says 30 sec colldown, DBM and BigWigs addons says ~47 sec + SPELL_DIVE_BOMB = 35181, // after watching tonns of movies, set cooldown to 40+rand()%5. + SPELL_BERSERK = 45078, // 10 minutes after phase 2 starts(id is wrong, but proper id is unknown) + + CREATURE_EMBER_OF_ALAR = 19551, // Al'ar summons one Ember of Al'ar every position change in phase 1 and two after Dive Bomb. Also in phase 2 when Ember of Al'ar dies, boss loose 3% health. + SPELL_EMBER_BLAST = 34133, // When Ember of Al'ar dies, it casts Ember Blast + + CREATURE_FLAME_PATCH_ALAR = 20602, // Flame Patch - every 30 sec in phase 2 + SPELL_FLAME_PATCH = 35380, // +}; static float waypoint[6][3] = { @@ -67,459 +70,500 @@ enum WaitEventType WE_SUMMON = 10 }; -struct boss_alarAI : public ScriptedAI +class boss_alar : public CreatureScript { - boss_alarAI(Creature *c) : ScriptedAI(c) - { - pInstance =c->GetInstanceData(); - DefaultMoveSpeedRate = c->GetSpeedRate(MOVE_RUN); - } - - ScriptedInstance *pInstance; - - WaitEventType WaitEvent; - uint32 WaitTimer; - - bool AfterMoving; - - uint32 Platforms_Move_Timer; - uint32 DiveBomb_Timer; - uint32 MeltArmor_Timer; - uint32 Charge_Timer; - uint32 FlamePatch_Timer; - uint32 Berserk_Timer; - - float DefaultMoveSpeedRate; - - bool Phase1; - bool ForceMove; - uint32 ForceTimer; - - int8 cur_wp; - - void Reset() - { - if (pInstance) - pInstance->SetData(DATA_ALAREVENT, NOT_STARTED); - - Berserk_Timer = 1200000; - Platforms_Move_Timer = 0; - - Phase1 = true; - WaitEvent = WE_NONE; - WaitTimer = 0; - AfterMoving = false; - ForceMove = false; - ForceTimer = 5000; - - cur_wp = 4; - - me->SetDisplayId(me->GetNativeDisplayId()); - me->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate); - //me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10); - //me->SetFloatValue(UNIT_FIELD_COMBATREACH, 10); - me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true); - me->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->setActive(false); - } - - void EnterCombat(Unit * /*who*/) - { - if (pInstance) - pInstance->SetData(DATA_ALAREVENT, IN_PROGRESS); - - me->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING); // after enterevademode will be set walk movement - DoZoneInCombat(); - me->setActive(true); - } - - void JustDied(Unit * /*victim*/) - { - if (pInstance) - pInstance->SetData(DATA_ALAREVENT, DONE); - } - - void JustSummoned(Creature *summon) - { - if (summon->GetEntry() == CREATURE_EMBER_OF_ALAR) - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - summon->AI()->AttackStart(pTarget); - } - - void MoveInLineOfSight(Unit * /*who*/) {} - - void AttackStart(Unit* who) - { - if (Phase1) - AttackStartNoMove(who); - else - ScriptedAI::AttackStart(who); - } - - void DamageTaken(Unit* /*pKiller*/, uint32 &damage) - { - if (damage >= me->GetHealth() && Phase1) + public: + + boss_alar() + : CreatureScript("boss_alar") { - damage = 0; - if (!WaitEvent) + } + struct boss_alarAI : public ScriptedAI + { + boss_alarAI(Creature* pCreature) : ScriptedAI(pCreature) { - WaitEvent = WE_DIE; - WaitTimer = 0; - me->SetHealth(0); - me->InterruptNonMeleeSpells(true); - me->RemoveAllAuras(); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->AttackStop(); - me->SetUInt64Value(UNIT_FIELD_TARGET, 0); - me->SetSpeed(MOVE_RUN, 5.0f); - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MovePoint(0, waypoint[5][0], waypoint[5][1], waypoint[5][2]); + pInstance = pCreature->GetInstanceData(); + DefaultMoveSpeedRate = pCreature->GetSpeedRate(MOVE_RUN); } - } - } - void SpellHit(Unit*, const SpellEntry *spell) - { - if (spell->Id == SPELL_DIVE_BOMB_VISUAL) - { - me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true); - me->SetDisplayId(11686); - //me->SendUpdateObjectToAllExcept(NULL); - } - } + ScriptedInstance *pInstance; - void MovementInform(uint32 type, uint32 /*id*/) - { - if (type == POINT_MOTION_TYPE) - { - WaitTimer = 1; - AfterMoving = true; - ForceMove = false; - } - } + WaitEventType WaitEvent; + uint32 WaitTimer; - void UpdateAI(const uint32 diff) - { - if (!me->isInCombat()) // sometimes isincombat but !incombat, faction bug? - return; + bool AfterMoving; - if (Berserk_Timer <= diff) - { - DoCast(me, SPELL_BERSERK, true); - Berserk_Timer = 60000; - } else Berserk_Timer -= diff; + uint32 Platforms_Move_Timer; + uint32 DiveBomb_Timer; + uint32 MeltArmor_Timer; + uint32 Charge_Timer; + uint32 FlamePatch_Timer; + uint32 Berserk_Timer; - if (ForceMove) - { - if (ForceTimer <= diff) + float DefaultMoveSpeedRate; + + bool Phase1; + bool ForceMove; + uint32 ForceTimer; + + int8 cur_wp; + + void Reset() { - me->GetMotionMaster()->MovePoint(0, waypoint[cur_wp][0], waypoint[cur_wp][1], waypoint[cur_wp][2]); + if (pInstance) + pInstance->SetData(DATA_ALAREVENT, NOT_STARTED); + + Berserk_Timer = 1200000; + Platforms_Move_Timer = 0; + + Phase1 = true; + WaitEvent = WE_NONE; + WaitTimer = 0; + AfterMoving = false; + ForceMove = false; ForceTimer = 5000; - } else ForceTimer -= diff; - } - if (WaitEvent) - { - if (WaitTimer) + cur_wp = 4; + + me->SetDisplayId(me->GetNativeDisplayId()); + me->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate); + //me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10); + //me->SetFloatValue(UNIT_FIELD_COMBATREACH, 10); + me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true); + me->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->setActive(false); + } + + void EnterCombat(Unit * /*who*/) + { + if (pInstance) + pInstance->SetData(DATA_ALAREVENT, IN_PROGRESS); + + me->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING); // after enterevademode will be set walk movement + DoZoneInCombat(); + me->setActive(true); + } + + void JustDied(Unit * /*victim*/) + { + if (pInstance) + pInstance->SetData(DATA_ALAREVENT, DONE); + } + + void JustSummoned(Creature *summon) { - if (WaitTimer <= diff) + if (summon->GetEntry() == CREATURE_EMBER_OF_ALAR) + if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + summon->AI()->AttackStart(pTarget); + } + + void MoveInLineOfSight(Unit * /*who*/) {} + + void AttackStart(Unit* who) + { + if (Phase1) + AttackStartNoMove(who); + else + ScriptedAI::AttackStart(who); + } + + void DamageTaken(Unit* /*pKiller*/, uint32 &damage) + { + if (damage >= me->GetHealth() && Phase1) { - if (AfterMoving) + damage = 0; + if (!WaitEvent) { - me->GetMotionMaster()->MoveIdle(); - AfterMoving = false; + WaitEvent = WE_DIE; + WaitTimer = 0; + me->SetHealth(0); + me->InterruptNonMeleeSpells(true); + me->RemoveAllAuras(); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->AttackStop(); + me->SetUInt64Value(UNIT_FIELD_TARGET, 0); + me->SetSpeed(MOVE_RUN, 5.0f); + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MovePoint(0, waypoint[5][0], waypoint[5][1], waypoint[5][2]); } + } + } - switch(WaitEvent) + void SpellHit(Unit*, const SpellEntry *spell) + { + if (spell->Id == SPELL_DIVE_BOMB_VISUAL) + { + me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true); + me->SetDisplayId(11686); + //me->SendUpdateObjectToAllExcept(NULL); + } + } + + void MovementInform(uint32 type, uint32 /*id*/) + { + if (type == POINT_MOTION_TYPE) + { + WaitTimer = 1; + AfterMoving = true; + ForceMove = false; + } + } + + void UpdateAI(const uint32 diff) + { + if (!me->isInCombat()) // sometimes isincombat but !incombat, faction bug? + return; + + if (Berserk_Timer <= diff) + { + DoCast(me, SPELL_BERSERK, true); + Berserk_Timer = 60000; + } + else + Berserk_Timer -= diff; + + if (ForceMove) + { + if (ForceTimer <= diff) { - case WE_PLATFORM: - Platforms_Move_Timer = 30000+rand()%5000; - break; - case WE_QUILL: - DoCast(me, SPELL_FLAME_QUILLS, true); - Platforms_Move_Timer = 1; - WaitTimer = 10000; - WaitEvent = WE_DUMMY; - return; - case WE_DIE: - ForceMove = false; - me->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD); - WaitTimer = 5000; - WaitEvent = WE_REVIVE; - return; - case WE_REVIVE: - me->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND); - me->SetHealth(me->GetMaxHealth()); - me->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - DoZoneInCombat(); - DoCast(me, SPELL_REBIRTH, true); - MeltArmor_Timer = 60000; - Charge_Timer = 7000; - DiveBomb_Timer = 40000+rand()%5000; - FlamePatch_Timer = 30000; - Phase1 = false; - break; - case WE_METEOR: - me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, false); - DoCast(me, SPELL_DIVE_BOMB_VISUAL, false); - WaitEvent = WE_DIVE; - WaitTimer = 4000; + me->GetMotionMaster()->MovePoint(0, waypoint[cur_wp][0], waypoint[cur_wp][1], waypoint[cur_wp][2]); + ForceTimer = 5000; + } + else + ForceTimer -= diff; + + } + if (WaitEvent) + { + if (WaitTimer) + { + if (WaitTimer <= diff) + { + if (AfterMoving) + { + me->GetMotionMaster()->MoveIdle(); + AfterMoving = false; + } + + switch(WaitEvent) + { + case WE_PLATFORM: + Platforms_Move_Timer = 30000+rand()%5000; + break; + case WE_QUILL: + DoCast(me, SPELL_FLAME_QUILLS, true); + Platforms_Move_Timer = 1; + WaitTimer = 10000; + WaitEvent = WE_DUMMY; + return; + case WE_DIE: + ForceMove = false; + me->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD); + WaitTimer = 5000; + WaitEvent = WE_REVIVE; + return; + case WE_REVIVE: + me->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND); + me->SetHealth(me->GetMaxHealth()); + me->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + DoZoneInCombat(); + DoCast(me, SPELL_REBIRTH, true); + MeltArmor_Timer = 60000; + Charge_Timer = 7000; + DiveBomb_Timer = 40000+rand()%5000; + FlamePatch_Timer = 30000; + Phase1 = false; + break; + case WE_METEOR: + me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, false); + DoCast(me, SPELL_DIVE_BOMB_VISUAL, false); + WaitEvent = WE_DIVE; + WaitTimer = 4000; + return; + case WE_DIVE: + if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + { + me->RemoveAurasDueToSpell(SPELL_DIVE_BOMB_VISUAL); + DoCast(pTarget, SPELL_DIVE_BOMB, true); + float dist = 3.0f; + if (me->IsWithinDist3d(pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 5.0f)) + dist = 5.0f; + WaitTimer = 1000 + floor(dist / 80 * 1000.0f); + me->GetMap()->CreatureRelocation(me, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(),0.0f); + me->StopMoving(); + WaitEvent = WE_LAND; + } + else + { + EnterEvadeMode(); + return; + } + case WE_LAND: + WaitEvent = WE_SUMMON; + WaitTimer = 2000; + return; + case WE_SUMMON: + for (uint8 i = 0; i < 2; ++i) + DoSpawnCreature(CREATURE_EMBER_OF_ALAR, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetDisplayId(me->GetNativeDisplayId()); + DoCast(me, SPELL_REBIRTH_2, true); + break; + case WE_DUMMY: + default: + break; + } + + WaitEvent = WE_NONE; + WaitTimer = 0; + } + else + WaitTimer -= diff; + } + return; + } + + if (Phase1) + { + if (me->getThreatManager().getThreatList().empty()) + { + EnterEvadeMode(); return; - case WE_DIVE: - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + } + + if (Platforms_Move_Timer <= diff) + { + if (cur_wp == 4) { - me->RemoveAurasDueToSpell(SPELL_DIVE_BOMB_VISUAL); - DoCast(pTarget, SPELL_DIVE_BOMB, true); - float dist = 3.0f; - if (me->IsWithinDist3d(pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 5.0f)) - dist = 5.0f; - WaitTimer = 1000 + floor(dist / 80 * 1000.0f); - me->GetMap()->CreatureRelocation(me, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(),0.0f); - me->StopMoving(); - WaitEvent = WE_LAND; + cur_wp = 0; + WaitEvent = WE_PLATFORM; } else { - EnterEvadeMode(); - return; + if (urand(0,4)) // next platform + { + DoSpawnCreature(CREATURE_EMBER_OF_ALAR, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + if (cur_wp == 3) + cur_wp = 0; + else + ++cur_wp; + WaitEvent = WE_PLATFORM; + } + else // flame quill + { + cur_wp = 4; + WaitEvent = WE_QUILL; + } } - case WE_LAND: - WaitEvent = WE_SUMMON; - WaitTimer = 2000; + ForceMove = true; + ForceTimer = 5000; + me->GetMotionMaster()->MovePoint(0, waypoint[cur_wp][0], waypoint[cur_wp][1], waypoint[cur_wp][2]); + WaitTimer = 0; return; - case WE_SUMMON: - for (uint8 i = 0; i < 2; ++i) - DoSpawnCreature(CREATURE_EMBER_OF_ALAR, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); - me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetDisplayId(me->GetNativeDisplayId()); - DoCast(me, SPELL_REBIRTH_2, true); - break; - case WE_DUMMY: - default: - break; + } + else + Platforms_Move_Timer -= diff; + } + else + { + if (Charge_Timer <= diff) + { + Unit *pTarget= SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true); + if (pTarget) + DoCast(pTarget, SPELL_CHARGE); + Charge_Timer = 30000; } + else + Charge_Timer -= diff; - WaitEvent = WE_NONE; - WaitTimer = 0; - } else WaitTimer -= diff; - } - return; - } + if (MeltArmor_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_MELT_ARMOR); + MeltArmor_Timer = 60000; + } + else + MeltArmor_Timer -= diff; - if (Phase1) - { - if (me->getThreatManager().getThreatList().empty()) - { - EnterEvadeMode(); - return; + if (DiveBomb_Timer <= diff) + { + me->AttackStop(); + me->GetMotionMaster()->MovePoint(6, waypoint[4][0], waypoint[4][1], waypoint[4][2]); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 50); + WaitEvent = WE_METEOR; + WaitTimer = 0; + DiveBomb_Timer = 40000+rand()%5000; + return; + } + else + DiveBomb_Timer -= diff; + + if (FlamePatch_Timer <= diff) + { + if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + { + Creature* Summoned = me->SummonCreature(CREATURE_FLAME_PATCH_ALAR, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 120000); + if (Summoned) + { + Summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + Summoned->SetFloatValue(OBJECT_FIELD_SCALE_X, Summoned->GetFloatValue(OBJECT_FIELD_SCALE_X)*2.5f); + Summoned->SetDisplayId(11686); + Summoned->setFaction(me->getFaction()); + Summoned->SetLevel(me->getLevel()); + Summoned->CastSpell(Summoned, SPELL_FLAME_PATCH, false); + } + } + FlamePatch_Timer = 30000; + } + else + FlamePatch_Timer -= diff; + } + + DoMeleeAttackIfReady(); } - if (Platforms_Move_Timer <= diff) + void DoMeleeAttackIfReady() { - if (cur_wp == 4) - { - cur_wp = 0; - WaitEvent = WE_PLATFORM; - } - else + if (me->isAttackReady() && !me->IsNonMeleeSpellCasted(false)) { - if (urand(0,4)) // next platform + if (me->IsWithinMeleeRange(me->getVictim())) { - DoSpawnCreature(CREATURE_EMBER_OF_ALAR, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); - if (cur_wp == 3) - cur_wp = 0; - else - ++cur_wp; - WaitEvent = WE_PLATFORM; + me->AttackerStateUpdate(me->getVictim()); + me->resetAttackTimer(); } - else // flame quill + else { - cur_wp = 4; - WaitEvent = WE_QUILL; + Unit *pTarget = NULL; + pTarget = me->SelectNearestTargetInAttackDistance(5); + if (pTarget) + me->AI()->AttackStart(pTarget); + else + { + DoCast(me, SPELL_FLAME_BUFFET, true); + me->setAttackTimer(BASE_ATTACK, 1500); + } } } - ForceMove = true; - ForceTimer = 5000; - me->GetMotionMaster()->MovePoint(0, waypoint[cur_wp][0], waypoint[cur_wp][1], waypoint[cur_wp][2]); - WaitTimer = 0; - return; - } else Platforms_Move_Timer -= diff; + } + }; + + CreatureAI* GetAI(Creature* Creature) const + { + return new boss_alarAI(Creature); + } +}; + +class mob_ember_of_alar : public CreatureScript +{ + public: + + mob_ember_of_alar() + : CreatureScript("mob_ember_of_alar") + { } - else + + struct mob_ember_of_alarAI : public ScriptedAI { - if (Charge_Timer <= diff) + mob_ember_of_alarAI(Creature* pCreature) : ScriptedAI(pCreature) { - Unit *pTarget= SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true); - if (pTarget) - DoCast(pTarget, SPELL_CHARGE); - Charge_Timer = 30000; - } else Charge_Timer -= diff; + pInstance = pCreature->GetInstanceData(); + pCreature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING); + pCreature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true); + } - if (MeltArmor_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_MELT_ARMOR); - MeltArmor_Timer = 60000; - } else MeltArmor_Timer -= diff; + ScriptedInstance *pInstance; + bool toDie; - if (DiveBomb_Timer <= diff) + void Reset() { - me->AttackStop(); - me->GetMotionMaster()->MovePoint(6, waypoint[4][0], waypoint[4][1], waypoint[4][2]); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 50); - WaitEvent = WE_METEOR; - WaitTimer = 0; - DiveBomb_Timer = 40000+rand()%5000; - return; - } else DiveBomb_Timer -= diff; + toDie = false; + } + void EnterCombat(Unit * /*who*/) + { + DoZoneInCombat(); + } + void EnterEvadeMode() + { + me->setDeathState(JUST_DIED); + } - if (FlamePatch_Timer <= diff) + void DamageTaken(Unit* pKiller, uint32 &damage) { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + if (damage >= me->GetHealth() && pKiller != me && !toDie) { - Creature* Summoned = me->SummonCreature(CREATURE_FLAME_PATCH_ALAR, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 120000); - if (Summoned) + damage = 0; + DoCast(me, SPELL_EMBER_BLAST, true); + me->SetDisplayId(11686); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + if (pInstance && pInstance->GetData(DATA_ALAREVENT) == 2) { - Summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - Summoned->SetFloatValue(OBJECT_FIELD_SCALE_X, Summoned->GetFloatValue(OBJECT_FIELD_SCALE_X)*2.5f); - Summoned->SetDisplayId(11686); - Summoned->setFaction(me->getFaction()); - Summoned->SetLevel(me->getLevel()); - Summoned->CastSpell(Summoned, SPELL_FLAME_PATCH, false); + if (Unit* Alar = Unit::GetUnit((*me), pInstance->GetData64(DATA_ALAR))) + { + int AlarHealth = Alar->GetHealth() - Alar->GetMaxHealth()*0.03; + if (AlarHealth > 0) + Alar->SetHealth(AlarHealth); + else + Alar->SetHealth(1); + } } + toDie = true; } - FlamePatch_Timer = 30000; - } else FlamePatch_Timer -= diff; - } - - DoMeleeAttackIfReady(); - } - - void DoMeleeAttackIfReady() - { - if (me->isAttackReady() && !me->IsNonMeleeSpellCasted(false)) - { - if (me->IsWithinMeleeRange(me->getVictim())) - { - me->AttackerStateUpdate(me->getVictim()); - me->resetAttackTimer(); } - else + + void UpdateAI(const uint32 /*diff*/) { - Unit *pTarget = NULL; - pTarget = me->SelectNearestTargetInAttackDistance(5); - if (pTarget) - me->AI()->AttackStart(pTarget); - else + if (!UpdateVictim()) + return; + + if (toDie) { - DoCast(me, SPELL_FLAME_BUFFET, true); - me->setAttackTimer(BASE_ATTACK, 1500); + me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + //me->SetVisibility(VISIBILITY_OFF); } + + DoMeleeAttackIfReady(); } + + }; + + CreatureAI* GetAI(Creature* Creature) const + { + return new mob_ember_of_alarAI(Creature); } - } }; -CreatureAI* GetAI_boss_alar(Creature* pCreature) +class mob_flame_patch_alar : public CreatureScript { - return new boss_alarAI(pCreature); -} + public: -struct mob_ember_of_alarAI : public ScriptedAI -{ - mob_ember_of_alarAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - c->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING); - c->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true); - } - - ScriptedInstance *pInstance; - bool toDie; - - void Reset() {toDie = false;} - void EnterCombat(Unit * /*who*/) {DoZoneInCombat();} - void EnterEvadeMode() {me->setDeathState(JUST_DIED);} - - void DamageTaken(Unit* pKiller, uint32 &damage) - { - if (damage >= me->GetHealth() && pKiller != me && !toDie) + mob_flame_patch_alar() + : CreatureScript("mob_flame_patch_alar") { - damage = 0; - DoCast(me, SPELL_EMBER_BLAST, true); - me->SetDisplayId(11686); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - if (pInstance && pInstance->GetData(DATA_ALAREVENT) == 2) - { - if (Unit* Alar = Unit::GetUnit((*me), pInstance->GetData64(DATA_ALAR))) - { - int AlarHealth = Alar->GetHealth() - Alar->GetMaxHealth()*0.03; - if (AlarHealth > 0) - Alar->SetHealth(AlarHealth); - else - Alar->SetHealth(1); - } - } - toDie = true; } - } - - void UpdateAI(const uint32 /*diff*/) - { - if (!UpdateVictim()) - return; - if (toDie) + struct mob_flame_patch_alarAI : public ScriptedAI { - me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - //me->SetVisibility(VISIBILITY_OFF); + mob_flame_patch_alarAI(Creature* pCreature) : ScriptedAI(pCreature) {} + void Reset() {} + void EnterCombat(Unit * /*who*/) {} + void AttackStart(Unit* /*who*/) {} + void MoveInLineOfSight(Unit* /*who*/) {} + void UpdateAI(const uint32 /*diff*/) {} + }; + + CreatureAI* GetAI(Creature* Creature) const + { + return new mob_flame_patch_alarAI(Creature); } - - DoMeleeAttackIfReady(); - } - -}; - -CreatureAI* GetAI_mob_ember_of_alar(Creature* pCreature) -{ - return new mob_ember_of_alarAI(pCreature); -} - -struct mob_flame_patch_alarAI : public ScriptedAI -{ - mob_flame_patch_alarAI(Creature *c) : ScriptedAI(c) {} - void Reset() {} - void EnterCombat(Unit * /*who*/) {} - void AttackStart(Unit* /*who*/) {} - void MoveInLineOfSight(Unit* /*who*/) {} - void UpdateAI(const uint32 /*diff*/) {} }; -CreatureAI* GetAI_mob_flame_patch_alar(Creature* pCreature) -{ - return new mob_flame_patch_alarAI(pCreature); -} - void AddSC_boss_alar() { - Script *newscript; - - newscript = new Script; - newscript->Name = "boss_alar"; - newscript->GetAI = &GetAI_boss_alar; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_ember_of_alar"; - newscript->GetAI = &GetAI_mob_ember_of_alar; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_flame_patch_alar"; - newscript->GetAI = &GetAI_mob_flame_patch_alar; - newscript->RegisterSelf(); + new boss_alar(); + new mob_ember_of_alar(); + new mob_flame_patch_alar(); } diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp index af311f7f5c2..c3090b6219a 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp @@ -71,398 +71,429 @@ const float PORTAL_Z = 17.005f; // x, y, z, o static float SolarianPos[4] = {432.909, -373.424, 17.9608, 1.06421}; -struct boss_high_astromancer_solarianAI : public ScriptedAI +class boss_high_astromancer_solarian : public CreatureScript { - boss_high_astromancer_solarianAI(Creature *c) : ScriptedAI(c), Summons(me) - { - pInstance = c->GetInstanceData(); - - defaultarmor = c->GetArmor(); - defaultsize = c->GetFloatValue(OBJECT_FIELD_SCALE_X); - } - - ScriptedInstance *pInstance; - SummonList Summons; - - uint8 Phase; - - uint32 ArcaneMissiles_Timer; - uint32 m_uiWrathOfTheAstromancer_Timer; - uint32 BlindingLight_Timer; - uint32 Fear_Timer; - uint32 VoidBolt_Timer; - uint32 Phase1_Timer; - uint32 Phase2_Timer; - uint32 Phase3_Timer; - uint32 AppearDelay_Timer; - uint32 defaultarmor; - uint32 Wrath_Timer; - - float defaultsize; - float Portals[3][3]; - - bool AppearDelay; - bool BlindingLight; - - void Reset() - { - ArcaneMissiles_Timer = 2000; - m_uiWrathOfTheAstromancer_Timer = 15000; - BlindingLight_Timer = 41000; - Fear_Timer = 20000; - VoidBolt_Timer = 10000; - Phase1_Timer = 50000; - Phase2_Timer = 10000; - Phase3_Timer = 15000; - AppearDelay_Timer = 2000; - BlindingLight = false; - AppearDelay = false; - Wrath_Timer = 20000+rand()%5000;//twice in phase one - Phase = 1; - Wrath_Timer = 20000+rand()%5000;//twice in phase one - - if (pInstance) - pInstance->SetData(DATA_HIGHASTROMANCERSOLARIANEVENT, NOT_STARTED); - - me->SetArmor(defaultarmor); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetVisibility(VISIBILITY_ON); - me->SetFloatValue(OBJECT_FIELD_SCALE_X, defaultsize); - me->SetDisplayId(MODEL_HUMAN); - - Summons.DespawnAll(); - } - - void KilledUnit(Unit * /*victim*/) - { - DoScriptText(RAND(SAY_KILL1,SAY_KILL2,SAY_KILL3), me); - } - - void JustDied(Unit * /*victim*/) - { - me->SetFloatValue(OBJECT_FIELD_SCALE_X, defaultsize); - me->SetDisplayId(MODEL_HUMAN); - DoScriptText(SAY_DEATH, me); - - if (pInstance) - pInstance->SetData(DATA_HIGHASTROMANCERSOLARIANEVENT, DONE); - } - - void EnterCombat(Unit * /*who*/) - { - DoScriptText(SAY_AGGRO, me); - DoZoneInCombat(); - - if (pInstance) - pInstance->SetData(DATA_HIGHASTROMANCERSOLARIANEVENT, IN_PROGRESS); - } - - void SummonMinion(uint32 entry, float x, float y, float z) - { - Creature* Summoned = me->SummonCreature(entry, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); - if (Summoned) - { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - Summoned->AI()->AttackStart(pTarget); + public: - Summons.Summon(Summoned); + boss_high_astromancer_solarian() + : CreatureScript("boss_high_astromancer_solarian") + { } - } + + struct boss_high_astromancer_solarianAI : public ScriptedAI + { + boss_high_astromancer_solarianAI(Creature* pCreature) : ScriptedAI(pCreature), Summons(me) + { + pInstance = pCreature->GetInstanceData(); - float Portal_X(float radius) - { - if (urand(0,1)) - radius = -radius; + defaultarmor = pCreature->GetArmor(); + defaultsize = pCreature->GetFloatValue(OBJECT_FIELD_SCALE_X); + } - return radius * (float)(rand()%100)/100.0f + CENTER_X; - } + ScriptedInstance *pInstance; + SummonList Summons; - float Portal_Y(float x, float radius) - { - float z = RAND(1, -1); + uint8 Phase; - return (z*sqrt(radius*radius - (x - CENTER_X)*(x - CENTER_X)) + CENTER_Y); - } + uint32 ArcaneMissiles_Timer; + uint32 m_uiWrathOfTheAstromancer_Timer; + uint32 BlindingLight_Timer; + uint32 Fear_Timer; + uint32 VoidBolt_Timer; + uint32 Phase1_Timer; + uint32 Phase2_Timer; + uint32 Phase3_Timer; + uint32 AppearDelay_Timer; + uint32 defaultarmor; + uint32 Wrath_Timer; - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; + float defaultsize; + float Portals[3][3]; - if (AppearDelay) - { - me->StopMoving(); - me->AttackStop(); - if (AppearDelay_Timer <= diff) + bool AppearDelay; + bool BlindingLight; + + void Reset() { - AppearDelay = false; - if (Phase == 2) - { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetVisibility(VISIBILITY_OFF); - } + ArcaneMissiles_Timer = 2000; + m_uiWrathOfTheAstromancer_Timer = 15000; + BlindingLight_Timer = 41000; + Fear_Timer = 20000; + VoidBolt_Timer = 10000; + Phase1_Timer = 50000; + Phase2_Timer = 10000; + Phase3_Timer = 15000; AppearDelay_Timer = 2000; - } else AppearDelay_Timer -= diff; - } + BlindingLight = false; + AppearDelay = false; + Wrath_Timer = 20000+rand()%5000;//twice in phase one + Phase = 1; + Wrath_Timer = 20000+rand()%5000;//twice in phase one - if (Phase == 1) - { - if (BlindingLight_Timer <= diff) + if (pInstance) + pInstance->SetData(DATA_HIGHASTROMANCERSOLARIANEVENT, NOT_STARTED); + + me->SetArmor(defaultarmor); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetVisibility(VISIBILITY_ON); + me->SetFloatValue(OBJECT_FIELD_SCALE_X, defaultsize); + me->SetDisplayId(MODEL_HUMAN); + + Summons.DespawnAll(); + } + + void KilledUnit(Unit * /*victim*/) { - BlindingLight = true; - BlindingLight_Timer = 45000; - } else BlindingLight_Timer -= diff; + DoScriptText(RAND(SAY_KILL1,SAY_KILL2,SAY_KILL3), me); + } - if (Wrath_Timer <= diff) + void JustDied(Unit * /*victim*/) { - me->InterruptNonMeleeSpells(false); - if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true)) - DoCast(pTarget, SPELL_WRATH_OF_THE_ASTROMANCER, true); - Wrath_Timer = 20000+rand()%5000; - } else Wrath_Timer -= diff; + me->SetFloatValue(OBJECT_FIELD_SCALE_X, defaultsize); + me->SetDisplayId(MODEL_HUMAN); + DoScriptText(SAY_DEATH, me); + if (pInstance) + pInstance->SetData(DATA_HIGHASTROMANCERSOLARIANEVENT, DONE); + } - if (ArcaneMissiles_Timer <= diff) + void EnterCombat(Unit * /*who*/) { - if (BlindingLight) - { - DoCast(me->getVictim(), SPELL_BLINDING_LIGHT); - BlindingLight = false; - }else{ - Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); + DoScriptText(SAY_AGGRO, me); + DoZoneInCombat(); - if (!me->HasInArc(2.5f, pTarget)) - pTarget = me->getVictim(); + if (pInstance) + pInstance->SetData(DATA_HIGHASTROMANCERSOLARIANEVENT, IN_PROGRESS); + } - if (pTarget) - DoCast(pTarget, SPELL_ARCANE_MISSILES); + void SummonMinion(uint32 entry, float x, float y, float z) + { + Creature* Summoned = me->SummonCreature(entry, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + if (Summoned) + { + if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + Summoned->AI()->AttackStart(pTarget); + + Summons.Summon(Summoned); } - ArcaneMissiles_Timer = 3000; - } else ArcaneMissiles_Timer -= diff; + } + + float Portal_X(float radius) + { + if (urand(0,1)) + radius = -radius; + + return radius * (float)(rand()%100)/100.0f + CENTER_X; + } - if (m_uiWrathOfTheAstromancer_Timer <= diff) + float Portal_Y(float x, float radius) { - me->InterruptNonMeleeSpells(false); + float z = RAND(1, -1); - //Target the tank ? - if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1)) - if (pTarget->GetTypeId() == TYPEID_PLAYER) + return (z*sqrt(radius*radius - (x - CENTER_X)*(x - CENTER_X)) + CENTER_Y); + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + if (AppearDelay) + { + me->StopMoving(); + me->AttackStop(); + if (AppearDelay_Timer <= diff) { - DoCast(pTarget, SPELL_WRATH_OF_THE_ASTROMANCER); - m_uiWrathOfTheAstromancer_Timer = 25000; + AppearDelay = false; + if (Phase == 2) + { + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetVisibility(VISIBILITY_OFF); + } + AppearDelay_Timer = 2000; } else - m_uiWrathOfTheAstromancer_Timer = 1000; - } else m_uiWrathOfTheAstromancer_Timer -= diff; - - //Phase1_Timer - if (Phase1_Timer <= diff) - { - Phase = 2; - Phase1_Timer = 50000; - //After these 50 seconds she portals to the middle of the room and disappears, leaving 3 light portals behind. - me->GetMotionMaster()->Clear(); - me->GetMap()->CreatureRelocation(me, CENTER_X, CENTER_Y, CENTER_Z, CENTER_O); - for (uint8 i=0; i <= 2; ++i) + AppearDelay_Timer -= diff; + } + if (Phase == 1) { - if (!i) + if (BlindingLight_Timer <= diff) { - Portals[i][0] = Portal_X(SMALL_PORTAL_RADIUS); - Portals[i][1] = Portal_Y(Portals[i][0], SMALL_PORTAL_RADIUS); - Portals[i][2] = CENTER_Z; + BlindingLight = true; + BlindingLight_Timer = 45000; } else + BlindingLight_Timer -= diff; + + if (Wrath_Timer <= diff) { - Portals[i][0] = Portal_X(LARGE_PORTAL_RADIUS); - Portals[i][1] = Portal_Y(Portals[i][0], LARGE_PORTAL_RADIUS); - Portals[i][2] = PORTAL_Z; + me->InterruptNonMeleeSpells(false); + if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true)) + DoCast(pTarget, SPELL_WRATH_OF_THE_ASTROMANCER, true); + Wrath_Timer = 20000+rand()%5000; } - } - if ((abs(Portals[2][0] - Portals[1][0]) < 7) && (abs(Portals[2][1] - Portals[1][1]) < 7)) - { - int i=1; - if (abs(CENTER_X + 26.0f - Portals[2][0]) < 7) - i = -1; - Portals[2][0] = Portals[2][0]+7*i; - Portals[2][1] = Portal_Y(Portals[2][0], LARGE_PORTAL_RADIUS); - } - for (int i=0; i <= 2; ++i) - { - if (Creature* Summoned = me->SummonCreature(NPC_ASTROMANCER_SOLARIAN_SPOTLIGHT, Portals[i][0], Portals[i][1], Portals[i][2], CENTER_O, TEMPSUMMON_TIMED_DESPAWN, Phase2_Timer+Phase3_Timer+AppearDelay_Timer+1700)) + else + Wrath_Timer -= diff; + + if (ArcaneMissiles_Timer <= diff) + { + if (BlindingLight) + { + DoCast(me->getVictim(), SPELL_BLINDING_LIGHT); + BlindingLight = false; + } + else + { + Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); + if (!me->HasInArc(2.5f, pTarget)) + pTarget = me->getVictim(); + if (pTarget) + DoCast(pTarget, SPELL_ARCANE_MISSILES); + } + ArcaneMissiles_Timer = 3000; + } + else + ArcaneMissiles_Timer -= diff; + + if (m_uiWrathOfTheAstromancer_Timer <= diff) { - Summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - Summoned->CastSpell(Summoned, SPELL_SPOTLIGHT, false); + me->InterruptNonMeleeSpells(false); + //Target the tank ? + if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1)) + { + if (pTarget->GetTypeId() == TYPEID_PLAYER) + { + DoCast(pTarget, SPELL_WRATH_OF_THE_ASTROMANCER); + m_uiWrathOfTheAstromancer_Timer = 25000; + } + else + m_uiWrathOfTheAstromancer_Timer = 1000; + } } + else + m_uiWrathOfTheAstromancer_Timer -= diff; + + //Phase1_Timer + if (Phase1_Timer <= diff) + { + Phase = 2; + Phase1_Timer = 50000; + //After these 50 seconds she portals to the middle of the room and disappears, leaving 3 light portals behind. + me->GetMotionMaster()->Clear(); + me->GetMap()->CreatureRelocation(me, CENTER_X, CENTER_Y, CENTER_Z, CENTER_O); + for (uint8 i=0; i <= 2; ++i) + { + if (!i) + { + Portals[i][0] = Portal_X(SMALL_PORTAL_RADIUS); + Portals[i][1] = Portal_Y(Portals[i][0], SMALL_PORTAL_RADIUS); + Portals[i][2] = CENTER_Z; + } + else + { + Portals[i][0] = Portal_X(LARGE_PORTAL_RADIUS); + Portals[i][1] = Portal_Y(Portals[i][0], LARGE_PORTAL_RADIUS); + Portals[i][2] = PORTAL_Z; + } + } + if ((abs(Portals[2][0] - Portals[1][0]) < 7) && (abs(Portals[2][1] - Portals[1][1]) < 7)) + { + int i=1; + if (abs(CENTER_X + 26.0f - Portals[2][0]) < 7) + i = -1; + Portals[2][0] = Portals[2][0]+7*i; + Portals[2][1] = Portal_Y(Portals[2][0], LARGE_PORTAL_RADIUS); + } + for (int i=0; i <= 2; ++i) + { + if (Creature* Summoned = me->SummonCreature(NPC_ASTROMANCER_SOLARIAN_SPOTLIGHT, Portals[i][0], Portals[i][1], Portals[i][2], CENTER_O, TEMPSUMMON_TIMED_DESPAWN, Phase2_Timer+Phase3_Timer+AppearDelay_Timer+1700)) + { + Summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + Summoned->CastSpell(Summoned, SPELL_SPOTLIGHT, false); + } + } + AppearDelay = true; + } + else + Phase1_Timer-=diff; } - AppearDelay = true; - } else Phase1_Timer-=diff; - } - else if (Phase == 2) - { - //10 seconds after Solarian disappears, 12 mobs spawn out of the three portals. - me->AttackStop(); - me->StopMoving(); - if (Phase2_Timer <= diff) - { - Phase = 3; - for (int i=0; i <= 2; ++i) - for (int j=1; j <= 4; j++) - SummonMinion(NPC_SOLARIUM_AGENT, Portals[i][0], Portals[i][1], Portals[i][2]); + else + if (Phase == 2) + { + //10 seconds after Solarian disappears, 12 mobs spawn out of the three portals. + me->AttackStop(); + me->StopMoving(); + if (Phase2_Timer <= diff) + { + Phase = 3; + for (int i=0; i <= 2; ++i) + for (int j=1; j <= 4; j++) + SummonMinion(NPC_SOLARIUM_AGENT, Portals[i][0], Portals[i][1], Portals[i][2]); + + DoScriptText(SAY_SUMMON1, me); + Phase2_Timer = 10000; + } + else + Phase2_Timer -= diff; + } + else + if (Phase == 3) + { + me->AttackStop(); + me->StopMoving(); + //Check Phase3_Timer + if (Phase3_Timer <= diff) + { + Phase = 1; + //15 seconds later Solarian reappears out of one of the 3 portals. Simultaneously, 2 healers appear in the two other portals. + int i = rand()%3; + me->GetMotionMaster()->Clear(); + me->GetMap()->CreatureRelocation(me, Portals[i][0], Portals[i][1], Portals[i][2], CENTER_O); + + for (int j=0; j <= 2; j++) + if (j != i) + SummonMinion(NPC_SOLARIUM_PRIEST, Portals[j][0], Portals[j][1], Portals[j][2]); + + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetVisibility(VISIBILITY_ON); + + DoScriptText(SAY_SUMMON2, me); + AppearDelay = true; + Phase3_Timer = 15000; + } + else + Phase3_Timer -= diff; + } + else + if (Phase == 4) + { + //Fear_Timer + if (Fear_Timer <= diff) + { + DoCast(me, SPELL_FEAR); + Fear_Timer = 20000; + } + else + Fear_Timer -= diff; + //VoidBolt_Timer + if (VoidBolt_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_VOID_BOLT); + VoidBolt_Timer = 10000; + } + else + VoidBolt_Timer -= diff; + } + //When Solarian reaches 20% she will transform into a huge void walker. + if (Phase != 4 && ((me->GetHealth()*100 / me->GetMaxHealth())<20)) + { + Phase = 4; + //To make sure she wont be invisible or not selecatble + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetVisibility(VISIBILITY_ON); + DoScriptText(SAY_VOIDA, me); + DoScriptText(SAY_VOIDB, me); + me->SetArmor(WV_ARMOR); + me->SetDisplayId(MODEL_VOIDWALKER); + me->SetFloatValue(OBJECT_FIELD_SCALE_X, defaultsize*2.5f); + } + DoMeleeAttackIfReady(); + } + }; - DoScriptText(SAY_SUMMON1, me); - Phase2_Timer = 10000; - } else Phase2_Timer -= diff; - } - else if (Phase == 3) + CreatureAI* GetAI(Creature* creature) const { - me->AttackStop(); - me->StopMoving(); - - //Check Phase3_Timer - if (Phase3_Timer <= diff) - { - Phase = 1; - - //15 seconds later Solarian reappears out of one of the 3 portals. Simultaneously, 2 healers appear in the two other portals. - int i = rand()%3; - me->GetMotionMaster()->Clear(); - me->GetMap()->CreatureRelocation(me, Portals[i][0], Portals[i][1], Portals[i][2], CENTER_O); - - for (int j=0; j <= 2; j++) - if (j != i) - SummonMinion(NPC_SOLARIUM_PRIEST, Portals[j][0], Portals[j][1], Portals[j][2]); + return new boss_high_astromancer_solarianAI (creature); + } +}; - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetVisibility(VISIBILITY_ON); +class mob_solarium_priest : public CreatureScript +{ + public: - DoScriptText(SAY_SUMMON2, me); - AppearDelay = true; - Phase3_Timer = 15000; - } else Phase3_Timer -= diff; + mob_solarium_priest() + : CreatureScript("mob_solarium_priest") + { } - else if (Phase == 4) + + struct mob_solarium_priestAI : public ScriptedAI { - //Fear_Timer - if (Fear_Timer <= diff) - { - DoCast(me, SPELL_FEAR); - Fear_Timer = 20000; - } else Fear_Timer -= diff; - - //VoidBolt_Timer - if (VoidBolt_Timer <= diff) + mob_solarium_priestAI(Creature* pCreature) : ScriptedAI(pCreature) { - DoCast(me->getVictim(), SPELL_VOID_BOLT); - VoidBolt_Timer = 10000; - } else VoidBolt_Timer -= diff; - } + pInstance = pCreature->GetInstanceData(); + } - //When Solarian reaches 20% she will transform into a huge void walker. - if (Phase != 4 && ((me->GetHealth()*100 / me->GetMaxHealth())<20)) - { - Phase = 4; - - //To make sure she wont be invisible or not selecatble - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetVisibility(VISIBILITY_ON); - DoScriptText(SAY_VOIDA, me); - DoScriptText(SAY_VOIDB, me); - me->SetArmor(WV_ARMOR); - me->SetDisplayId(MODEL_VOIDWALKER); - me->SetFloatValue(OBJECT_FIELD_SCALE_X, defaultsize*2.5f); - } + ScriptedInstance *pInstance; - DoMeleeAttackIfReady(); - } -}; + uint32 healTimer; + uint32 holysmiteTimer; + uint32 aoesilenceTimer; -struct mob_solarium_priestAI : public ScriptedAI -{ - mob_solarium_priestAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - } - - ScriptedInstance *pInstance; - - uint32 healTimer; - uint32 holysmiteTimer; - uint32 aoesilenceTimer; - - void Reset() - { - healTimer = 9000; - holysmiteTimer = 1; - aoesilenceTimer = 15000; - } - - void EnterCombat(Unit * /*who*/) - { - } - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - - if (healTimer <= diff) - { - Unit *pTarget = NULL; - - switch (urand(0,1)) + void Reset() { - case 0: - if (pInstance) - pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_ASTROMANCER)); - break; - case 1: - pTarget = me; - break; + healTimer = 9000; + holysmiteTimer = 1; + aoesilenceTimer = 15000; } - if (pTarget) + void EnterCombat(Unit * /*who*/) { - DoCast(pTarget, SPELL_SOLARIUM_GREAT_HEAL); - healTimer = 9000; } - } else healTimer -= diff; - if (holysmiteTimer <= diff) - { - DoCast(me->getVictim(), SPELL_SOLARIUM_HOLY_SMITE); - holysmiteTimer = 4000; - } else holysmiteTimer -= diff; + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; - if (aoesilenceTimer <= diff) - { - DoCast(me->getVictim(), SPELL_SOLARIUM_ARCANE_TORRENT); - aoesilenceTimer = 13000; - } else aoesilenceTimer -= diff; + if (healTimer <= diff) + { + Unit *pTarget = NULL; + switch (urand(0,1)) + { + case 0: + if (pInstance) + pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_ASTROMANCER)); + break; + case 1: + pTarget = me; + break; + } - DoMeleeAttackIfReady(); - } -}; + if (pTarget) + { + DoCast(pTarget, SPELL_SOLARIUM_GREAT_HEAL); + healTimer = 9000; + } + } + else + healTimer -= diff; -CreatureAI* GetAI_mob_solarium_priest(Creature* pCreature) -{ - return new mob_solarium_priestAI (pCreature); -} + if (holysmiteTimer <= diff) + { + DoCast(me->getVictim(), SPELL_SOLARIUM_HOLY_SMITE); + holysmiteTimer = 4000; + } + else + holysmiteTimer -= diff; -CreatureAI* GetAI_boss_high_astromancer_solarian(Creature* pCreature) -{ - return new boss_high_astromancer_solarianAI (pCreature); -} + if (aoesilenceTimer <= diff) + { + DoCast(me->getVictim(), SPELL_SOLARIUM_ARCANE_TORRENT); + aoesilenceTimer = 13000; + } + else + aoesilenceTimer -= diff; + + DoMeleeAttackIfReady(); + } + }; + CreatureAI* GetAI(Creature* Creature) + { + return new mob_solarium_priestAI (Creature); + } +}; void AddSC_boss_high_astromancer_solarian() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_high_astromancer_solarian"; - newscript->GetAI = &GetAI_boss_high_astromancer_solarian; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_solarium_priest"; - newscript->GetAI = &GetAI_mob_solarium_priest; - newscript->RegisterSelf(); + new boss_high_astromancer_solarian(); + new mob_solarium_priest(); } diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index b6cfca4940a..86b6de83377 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -265,1236 +265,1329 @@ struct advisorbase_ai : public ScriptedAI } else DelayRes_Timer -= diff; } } - }; -//Kael'thas AI -struct boss_kaelthasAI : public ScriptedAI + +class boss_kaelthas : public CreatureScript { - boss_kaelthasAI(Creature* pCreature) : ScriptedAI(pCreature), summons(me) - { - m_pInstance = pCreature->GetInstanceData(); - memset(&m_auiAdvisorGuid, 0, sizeof(m_auiAdvisorGuid)); - } + public: - ScriptedInstance* m_pInstance; + boss_kaelthas() + : CreatureScript("boss_kaelthas") + { + } + //Kael'thas AI + struct boss_kaelthasAI : public ScriptedAI + { + boss_kaelthasAI(Creature* pCreature) : ScriptedAI(pCreature), summons(me) + { + m_pInstance = pCreature->GetInstanceData(); + memset(&m_auiAdvisorGuid, 0, sizeof(m_auiAdvisorGuid)); + } - 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 PyrosCasted; - - bool InGravityLapse; - bool IsCastingFireball; - bool ChainPyros; - - SummonList summons; - - uint64 m_auiAdvisorGuid[MAX_ADVISORS]; + ScriptedInstance* m_pInstance; - void Reset() - { - Fireball_Timer = 5000+rand()%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; - PyrosCasted = 0; - Phase = 0; - InGravityLapse = false; - IsCastingFireball = false; - ChainPyros = false; - - if (me->isInCombat()) - PrepareAdvisors(); - - summons.DespawnAll(); + 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 PyrosCasted; - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + bool InGravityLapse; + bool IsCastingFireball; + bool ChainPyros; - if (m_pInstance) - m_pInstance->SetData(DATA_KAELTHASEVENT, 0); - } + SummonList summons; - void PrepareAdvisors() - { - for (uint8 i = 0; i < MAX_ADVISORS; ++i) - { - if (Creature *pCreature = Unit::GetCreature((*me), m_auiAdvisorGuid[i])) + uint64 m_auiAdvisorGuid[MAX_ADVISORS]; + + void Reset() { - pCreature->Respawn(); - pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - pCreature->setFaction(me->getFaction()); - pCreature->AI()->EnterEvadeMode(); + Fireball_Timer = 5000+rand()%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; + PyrosCasted = 0; + Phase = 0; + InGravityLapse = false; + IsCastingFireball = false; + ChainPyros = false; + + if (me->isInCombat()) + PrepareAdvisors(); + + summons.DespawnAll(); + + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + if (m_pInstance) + m_pInstance->SetData(DATA_KAELTHASEVENT, 0); } - } - } - void StartEvent() - { - if (!m_pInstance) - return; + void PrepareAdvisors() + { + for (uint8 i = 0; i < MAX_ADVISORS; ++i) + { + if (Creature *pCreature = Unit::GetCreature((*me), m_auiAdvisorGuid[i])) + { + pCreature->Respawn(); + pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pCreature->setFaction(me->getFaction()); + pCreature->AI()->EnterEvadeMode(); + } + } + } - m_auiAdvisorGuid[0] = m_pInstance->GetData64(DATA_THALADREDTHEDARKENER); - m_auiAdvisorGuid[1] = m_pInstance->GetData64(DATA_LORDSANGUINAR); - m_auiAdvisorGuid[2] = m_pInstance->GetData64(DATA_GRANDASTROMANCERCAPERNIAN); - m_auiAdvisorGuid[3] = m_pInstance->GetData64(DATA_MASTERENGINEERTELONICUS); + void StartEvent() + { + if (!m_pInstance) + return; - if (!m_auiAdvisorGuid[0] || !m_auiAdvisorGuid[1] || !m_auiAdvisorGuid[2] || !m_auiAdvisorGuid[3]) - { - sLog.outError("TSCR: Kael'Thas One or more advisors missing, Skipping Phases 1-3"); + m_auiAdvisorGuid[0] = m_pInstance->GetData64(DATA_THALADREDTHEDARKENER); + m_auiAdvisorGuid[1] = m_pInstance->GetData64(DATA_LORDSANGUINAR); + m_auiAdvisorGuid[2] = m_pInstance->GetData64(DATA_GRANDASTROMANCERCAPERNIAN); + m_auiAdvisorGuid[3] = m_pInstance->GetData64(DATA_MASTERENGINEERTELONICUS); - DoScriptText(SAY_PHASE4_INTRO2, me); + if (!m_auiAdvisorGuid[0] || !m_auiAdvisorGuid[1] || !m_auiAdvisorGuid[2] || !m_auiAdvisorGuid[3]) + { + sLog.outError("TSCR: Kael'Thas One or more advisors missing, Skipping Phases 1-3"); - Phase = 4; + DoScriptText(SAY_PHASE4_INTRO2, me); - m_pInstance->SetData(DATA_KAELTHASEVENT, 4); + Phase = 4; - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_pInstance->SetData(DATA_KAELTHASEVENT, 4); - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - AttackStart(pTarget); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - } - else - { - PrepareAdvisors(); + if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + AttackStart(pTarget); - DoScriptText(SAY_INTRO, me); + } + else + { + PrepareAdvisors(); - m_pInstance->SetData(DATA_KAELTHASEVENT, 1); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + DoScriptText(SAY_INTRO, me); - PhaseSubphase = 0; - Phase_Timer = 23000; - Phase = 1; - } - } + m_pInstance->SetData(DATA_KAELTHASEVENT, 1); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - void MoveInLineOfSight(Unit *who) - { - if (!me->hasUnitState(UNIT_STAT_STUNNED) && who->isTargetableForAttack() && - me->IsHostileTo(who) && who->isInAccessiblePlaceFor(me)) - { - if (!me->canFly() && me->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE) - return; + PhaseSubphase = 0; + Phase_Timer = 23000; + Phase = 1; + } + } - float attackRadius = me->GetAttackDistance(who); - if (me->IsWithinDistInMap(who, attackRadius) && me->IsWithinLOSInMap(who)) + void MoveInLineOfSight(Unit *who) { - if (!me->getVictim() && Phase >= 4) + if (!me->hasUnitState(UNIT_STAT_STUNNED) && who->isTargetableForAttack() && + me->IsHostileTo(who) && who->isInAccessiblePlaceFor(me)) { - who->RemoveAurasByType(SPELL_AURA_MOD_STEALTH); - AttackStart(who); - } - else if (me->GetMap()->IsDungeon()) - { - if (m_pInstance && !m_pInstance->GetData(DATA_KAELTHASEVENT) && !Phase) - StartEvent(); + if (!me->canFly() && me->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE) + return; - who->SetInCombatWith(me); - me->AddThreat(who, 0.0f); + 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 (me->GetMap()->IsDungeon()) + { + if (m_pInstance && !m_pInstance->GetData(DATA_KAELTHASEVENT) && !Phase) + StartEvent(); + + who->SetInCombatWith(me); + me->AddThreat(who, 0.0f); + } + } } } - } - } - void EnterCombat(Unit * /*who*/) - { - if (m_pInstance && !m_pInstance->GetData(DATA_KAELTHASEVENT) && !Phase) - StartEvent(); - } + void EnterCombat(Unit * /*who*/) + { + if (m_pInstance && !m_pInstance->GetData(DATA_KAELTHASEVENT) && !Phase) + StartEvent(); + } - void KilledUnit() - { - DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2,SAY_SLAY3), me); - } + void KilledUnit() + { + DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2,SAY_SLAY3), me); + } - void JustSummoned(Creature* pSummoned) - { - // if not phoenix, then it's one of the 7 weapons - if (pSummoned->GetEntry() != NPC_PHOENIX) - { - if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - pSummoned->AI()->AttackStart(pTarget); + void JustSummoned(Creature* pSummoned) + { + // if not phoenix, then it's one of the 7 weapons + if (pSummoned->GetEntry() != NPC_PHOENIX) + { + if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + pSummoned->AI()->AttackStart(pTarget); - summons.Summon(pSummoned); - } - } + summons.Summon(pSummoned); + } + } - void SummonedCreatureDespawn(Creature *summon) {summons.Despawn(summon);} + void SummonedCreatureDespawn(Creature *summon) {summons.Despawn(summon);} - void JustDied(Unit* /*Killer*/) - { - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + void JustDied(Unit* /*Killer*/) + { + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - DoScriptText(SAY_DEATH, me); + DoScriptText(SAY_DEATH, me); - summons.DespawnAll(); + summons.DespawnAll(); - if (m_pInstance) - m_pInstance->SetData(DATA_KAELTHASEVENT, 0); + if (m_pInstance) + m_pInstance->SetData(DATA_KAELTHASEVENT, 0); - for (uint8 i = 0; i < MAX_ADVISORS; ++i) - { - if (Unit* pAdvisor = Unit::GetUnit((*me), m_auiAdvisorGuid[i])) - pAdvisor->Kill(pAdvisor); - } - } + for (uint8 i = 0; i < MAX_ADVISORS; ++i) + { + if (Unit* pAdvisor = Unit::GetUnit((*me), m_auiAdvisorGuid[i])) + pAdvisor->Kill(pAdvisor); + } + } - void UpdateAI(const uint32 diff) - { - //Phase 1 - switch (Phase) - { - case 1: + void UpdateAI(const uint32 diff) { - Unit *pTarget = NULL; - Creature* Advisor = NULL; - - //Subphase switch - switch(PhaseSubphase) + //Phase 1 + switch (Phase) { - //Subphase 1 - Start - case 0: - if (Phase_Timer <= diff) - { - DoScriptText(SAY_INTRO_THALADRED, me); - - //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 = (Unit::GetCreature((*me), m_auiAdvisorGuid[0])); - - if (Advisor) - { - Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - Advisor->setFaction(me->getFaction()); - - pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); - if (pTarget) - Advisor->AI()->AttackStart(pTarget); - } - - ++PhaseSubphase; - } else Phase_Timer -= diff; - break; - - //Subphase 2 - Start - case 2: - Advisor = (Unit::GetCreature((*me), m_auiAdvisorGuid[0])); - - if (Advisor && (Advisor->getStandState() == UNIT_STAND_STATE_DEAD)) - { - DoScriptText(SAY_INTRO_SANGUINAR, me); - - //start advisor within 12.5 seconds - Phase_Timer = 12500; - ++PhaseSubphase; - } - break; + { + Unit *pTarget = NULL; + Creature* Advisor = NULL; - //Subphase 2 - Unlock advisor - case 3: - if (Phase_Timer <= diff) + //Subphase switch + switch(PhaseSubphase) { - Advisor = (Unit::GetCreature((*me), m_auiAdvisorGuid[1])); + //Subphase 1 - Start + case 0: + if (Phase_Timer <= diff) + { + DoScriptText(SAY_INTRO_THALADRED, me); - if (Advisor) - { - Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - Advisor->setFaction(me->getFaction()); + //start advisor within 7 seconds + Phase_Timer = 7000; + ++PhaseSubphase; + } else Phase_Timer -= diff; + break; - pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); - if (pTarget) - Advisor->AI()->AttackStart(pTarget); - } + //Subphase 1 - Unlock advisor + case 1: + if (Phase_Timer <= diff) + { + Advisor = (Unit::GetCreature((*me), m_auiAdvisorGuid[0])); - ++PhaseSubphase; - } else Phase_Timer -= diff; - break; + if (Advisor) + { + Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + Advisor->setFaction(me->getFaction()); - //Subphase 3 - Start - case 4: - Advisor = (Unit::GetCreature((*me), m_auiAdvisorGuid[1])); + pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); + if (pTarget) + Advisor->AI()->AttackStart(pTarget); + } - if (Advisor && (Advisor->getStandState() == UNIT_STAND_STATE_DEAD)) - { - DoScriptText(SAY_INTRO_CAPERNIAN, me); + ++PhaseSubphase; + } else Phase_Timer -= diff; + break; - //start advisor within 7 seconds - Phase_Timer = 7000; - ++PhaseSubphase; - } - break; + //Subphase 2 - Start + case 2: + Advisor = (Unit::GetCreature((*me), m_auiAdvisorGuid[0])); - //Subphase 3 - Unlock advisor - case 5: - if (Phase_Timer <= diff) - { - Advisor = (Unit::GetCreature((*me), m_auiAdvisorGuid[2])); + if (Advisor && (Advisor->getStandState() == UNIT_STAND_STATE_DEAD)) + { + DoScriptText(SAY_INTRO_SANGUINAR, me); - if (Advisor) - { - Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - Advisor->setFaction(me->getFaction()); + //start advisor within 12.5 seconds + Phase_Timer = 12500; + ++PhaseSubphase; + } + break; - pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); - if (pTarget) - Advisor->AI()->AttackStart(pTarget); - } + //Subphase 2 - Unlock advisor + case 3: + if (Phase_Timer <= diff) + { + Advisor = (Unit::GetCreature((*me), m_auiAdvisorGuid[1])); - ++PhaseSubphase; - } else Phase_Timer -= diff; - break; + if (Advisor) + { + Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + Advisor->setFaction(me->getFaction()); - //Subphase 4 - Start - case 6: - Advisor = (Unit::GetCreature((*me), m_auiAdvisorGuid[2])); + pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); + if (pTarget) + Advisor->AI()->AttackStart(pTarget); + } - if (Advisor && (Advisor->getStandState() == UNIT_STAND_STATE_DEAD)) - { - DoScriptText(SAY_INTRO_TELONICUS, me); + ++PhaseSubphase; + } else Phase_Timer -= diff; + break; - //start advisor within 8.4 seconds - Phase_Timer = 8400; - ++PhaseSubphase; - } - break; + //Subphase 3 - Start + case 4: + Advisor = (Unit::GetCreature((*me), m_auiAdvisorGuid[1])); - //Subphase 4 - Unlock advisor - case 7: - if (Phase_Timer <= diff) - { - Advisor = (Unit::GetCreature((*me), m_auiAdvisorGuid[3])); + if (Advisor && (Advisor->getStandState() == UNIT_STAND_STATE_DEAD)) + { + DoScriptText(SAY_INTRO_CAPERNIAN, me); - if (Advisor) - { - Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - Advisor->setFaction(me->getFaction()); + //start advisor within 7 seconds + Phase_Timer = 7000; + ++PhaseSubphase; + } + break; - pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); - if (pTarget) - Advisor->AI()->AttackStart(pTarget); - } + //Subphase 3 - Unlock advisor + case 5: + if (Phase_Timer <= diff) + { + Advisor = (Unit::GetCreature((*me), m_auiAdvisorGuid[2])); - Phase_Timer = 3000; - ++PhaseSubphase; - } else Phase_Timer -= diff; - break; + if (Advisor) + { + Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + Advisor->setFaction(me->getFaction()); - //End of phase 1 - case 8: - Advisor = (Unit::GetCreature((*me), m_auiAdvisorGuid[3])); + pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); + if (pTarget) + Advisor->AI()->AttackStart(pTarget); + } - if (Advisor && (Advisor->getStandState() == UNIT_STAND_STATE_DEAD)) - { - Phase = 2; - if (m_pInstance) - m_pInstance->SetData(DATA_KAELTHASEVENT, 2); + ++PhaseSubphase; + } else Phase_Timer -= diff; + break; - DoScriptText(SAY_PHASE2_WEAPON, me); + //Subphase 4 - Start + case 6: + Advisor = (Unit::GetCreature((*me), m_auiAdvisorGuid[2])); - PhaseSubphase = 0; - Phase_Timer = 3500; - DoCast(me, SPELL_SUMMON_WEAPONS); - } - break; - } - } - break; + if (Advisor && (Advisor->getStandState() == UNIT_STAND_STATE_DEAD)) + { + DoScriptText(SAY_INTRO_TELONICUS, me); - case 2: - { - if (PhaseSubphase == 0) - { - if (Phase_Timer <= diff) - { - PhaseSubphase = 1; - } else Phase_Timer -= diff; - } + //start advisor within 8.4 seconds + Phase_Timer = 8400; + ++PhaseSubphase; + } + break; - //Spawn weapons - if (PhaseSubphase == 1) - { - DoCast(me, SPELL_SUMMON_WEAPONS, false); + //Subphase 4 - Unlock advisor + case 7: + if (Phase_Timer <= diff) + { + Advisor = (Unit::GetCreature((*me), m_auiAdvisorGuid[3])); - uint8 uiMaxWeapon = sizeof(m_auiSpellSummonWeapon)/sizeof(uint32); + if (Advisor) + { + Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + Advisor->setFaction(me->getFaction()); - for (uint32 i = 0; i < uiMaxWeapon; ++i) - DoCast(me, m_auiSpellSummonWeapon[i], true); + pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); + if (pTarget) + Advisor->AI()->AttackStart(pTarget); + } - PhaseSubphase = 2; - Phase_Timer = TIME_PHASE_2_3; - } + Phase_Timer = 3000; + ++PhaseSubphase; + } else Phase_Timer -= diff; + break; - if (PhaseSubphase == 2) - { - if (Phase_Timer <= diff) - { - DoScriptText(SAY_PHASE3_ADVANCE, me); - if (m_pInstance) - m_pInstance->SetData(DATA_KAELTHASEVENT, 3); - Phase = 3; - PhaseSubphase = 0; - } else Phase_Timer -= diff; - } - } - break; + //End of phase 1 + case 8: + Advisor = (Unit::GetCreature((*me), m_auiAdvisorGuid[3])); - case 3: - { - if (PhaseSubphase == 0) - { - //Respawn advisors - Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); + if (Advisor && (Advisor->getStandState() == UNIT_STAND_STATE_DEAD)) + { + Phase = 2; + if (m_pInstance) + m_pInstance->SetData(DATA_KAELTHASEVENT, 2); - Creature *Advisor; - for (uint8 i = 0; i < MAX_ADVISORS; ++i) - { - Advisor = Unit::GetCreature((*me), m_auiAdvisorGuid[i]); + DoScriptText(SAY_PHASE2_WEAPON, me); - if (!Advisor) - sLog.outError("SD2: Kael'Thas Advisor %u does not exist. Possibly despawned? Incorrectly Killed?", i); - else - CAST_AI(advisorbase_ai, Advisor->AI())->Revive(pTarget); + PhaseSubphase = 0; + Phase_Timer = 3500; + DoCast(me, SPELL_SUMMON_WEAPONS); + } + break; + } } + break; - PhaseSubphase = 1; - Phase_Timer = TIME_PHASE_3_4; - } - - if (Phase_Timer <= diff) - { - DoScriptText(SAY_PHASE4_INTRO2, me); - Phase = 4; - - if (m_pInstance) - m_pInstance->SetData(DATA_KAELTHASEVENT, 4); - - // Sometimes people can collect Aggro in Phase 1-3. Reset threat before releasing Kael. - DoResetThreat(); + case 2: + { + if (PhaseSubphase == 0) + { + if (Phase_Timer <= diff) + { + PhaseSubphase = 1; + } + else + Phase_Timer -= diff; + } - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + //Spawn weapons + if (PhaseSubphase == 1) + { + DoCast(me, SPELL_SUMMON_WEAPONS, false); - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - AttackStart(pTarget); + uint8 uiMaxWeapon = sizeof(m_auiSpellSummonWeapon)/sizeof(uint32); - Phase_Timer = 30000; - } else Phase_Timer -= diff; - } - break; + for (uint32 i = 0; i < uiMaxWeapon; ++i) + DoCast(me, m_auiSpellSummonWeapon[i], true); - case 4: - case 5: - case 6: - { - //Return since we have no target - if (!UpdateVictim()) - return; + PhaseSubphase = 2; + Phase_Timer = TIME_PHASE_2_3; + } - //Fireball_Timer - if (!InGravityLapse && !ChainPyros && Phase != 5) - { - if (Fireball_Timer <= diff) - { - if (!IsCastingFireball) + if (PhaseSubphase == 2) { - if (!me->IsNonMeleeSpellCasted(false)) + if (Phase_Timer <= diff) { - //interruptable - me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false); - int32 dmg = 20000+rand()%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+rand()%10000; + DoScriptText(SAY_PHASE3_ADVANCE, me); + if (m_pInstance) + m_pInstance->SetData(DATA_KAELTHASEVENT, 3); + Phase = 3; + PhaseSubphase = 0; + } + else + Phase_Timer -= diff; } - } else Fireball_Timer -= diff; + } + break; - //ArcaneDisruption_Timer - if (ArcaneDisruption_Timer <= diff) + case 3: { - DoCast(me->getVictim(), SPELL_ARCANE_DISRUPTION, true); - ArcaneDisruption_Timer = 60000; - } else ArcaneDisruption_Timer -= diff; + if (PhaseSubphase == 0) + { + //Respawn advisors + Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); - if (FlameStrike_Timer <= diff) - { - if (Unit* pUnit = SelectUnit(SELECT_TARGET_RANDOM, 0)) - DoCast(pUnit, SPELL_FLAME_STRIKE); + Creature *Advisor; + for (uint8 i = 0; i < MAX_ADVISORS; ++i) + { + Advisor = Unit::GetCreature((*me), m_auiAdvisorGuid[i]); - FlameStrike_Timer = 30000; - } else FlameStrike_Timer -= diff; + if (!Advisor) + sLog.outError("SD2: Kael'Thas Advisor %u does not exist. Possibly despawned? Incorrectly Killed?", i); + else + CAST_AI(advisorbase_ai, Advisor->AI())->Revive(pTarget); + } - if (MindControl_Timer <= diff) - { - if (me->getThreatManager().getThreatList().size() >= 2) - for (uint32 i = 0; i < 3; ++i) - { - sLog.outDebug("SD2: Kael'Thas mind control not supported."); - //DoCast(pUnit, SPELL_MIND_CONTROL); + PhaseSubphase = 1; + Phase_Timer = TIME_PHASE_3_4; } - MindControl_Timer = 60000; - } else MindControl_Timer -= diff; - } + if (Phase_Timer <= diff) + { + DoScriptText(SAY_PHASE4_INTRO2, me); + Phase = 4; - //Phoenix_Timer - if (Phoenix_Timer <= diff) - { - DoCast(me, SPELL_PHOENIX_ANIMATION); - DoScriptText(RAND(SAY_SUMMON_PHOENIX1,SAY_SUMMON_PHOENIX2), me); + if (m_pInstance) + m_pInstance->SetData(DATA_KAELTHASEVENT, 4); - Phoenix_Timer = 60000; - } else Phoenix_Timer -= diff; + // Sometimes people can collect Aggro in Phase 1-3. Reset threat before releasing Kael. + DoResetThreat(); - //Phase 4 specific spells - if (Phase == 4) - { - if (me->GetHealth()*100 / me->GetMaxHealth() < 50) - { - if (m_pInstance) - m_pInstance->SetData(DATA_KAELTHASEVENT, 4); - Phase = 5; - Phase_Timer = 10000; - - DoScriptText(SAY_PHASE5_NUTS, me); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->StopMoving(); - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MoveIdle(); - me->GetMap()->CreatureRelocation(me, afGravityPos[0], afGravityPos[1], afGravityPos[2], 0); - me->SendMonsterMove(afGravityPos[0], afGravityPos[1], afGravityPos[2], 0, 0, 0); + if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + AttackStart(pTarget); - me->InterruptNonMeleeSpells(false); - DoCast(me, SPELL_FULLPOWER); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + Phase_Timer = 30000; + } + else + Phase_Timer -= diff; } + break; - //ShockBarrier_Timer - if (ShockBarrier_Timer <= diff) - { - DoCast(me, SPELL_SHOCK_BARRIER); - ChainPyros = true; - PyrosCasted = 0; - ShockBarrier_Timer = 60000; - } else ShockBarrier_Timer -= diff; - - //Chain Pyros (3 of them max) - if (ChainPyros && !me->IsNonMeleeSpellCasted(false)) + case 4: + case 5: + case 6: { - if (PyrosCasted < 3) - { - DoCast(me->getVictim(), SPELL_PYROBLAST); - ++PyrosCasted; - } - else + //Return since we have no target + if (!UpdateVictim()) + return; + + //Fireball_Timer + if (!InGravityLapse && !ChainPyros && Phase != 5) { - ChainPyros = false; - Fireball_Timer = 2500; - ArcaneDisruption_Timer = 60000; - } - } - } + if (Fireball_Timer <= diff) + { + if (!IsCastingFireball) + { + if (!me->IsNonMeleeSpellCasted(false)) + { + //interruptable + me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false); + int32 dmg = 20000+rand()%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+rand()%10000; + } + } + else + Fireball_Timer -= diff; - if (Phase == 5) - { - if (Phase_Timer <= diff) - { - me->InterruptNonMeleeSpells(false); - me->RemoveAurasDueToSpell(SPELL_FULLPOWER); + //ArcaneDisruption_Timer + if (ArcaneDisruption_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_ARCANE_DISRUPTION, true); + ArcaneDisruption_Timer = 60000; + } + else + ArcaneDisruption_Timer -= diff; - DoCast(me, SPELL_EXPLODE); + if (FlameStrike_Timer <= diff) + { + if (Unit* pUnit = SelectUnit(SELECT_TARGET_RANDOM, 0)) + DoCast(pUnit, SPELL_FLAME_STRIKE); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - Phase = 6; - AttackStart(me->getVictim()); - } else Phase_Timer -= diff; - } + FlameStrike_Timer = 30000; + } + else + FlameStrike_Timer -= diff; - //Phase 5 - if (Phase == 6) - { + if (MindControl_Timer <= diff) + { + if (me->getThreatManager().getThreatList().size() >= 2) + for (uint32 i = 0; i < 3; ++i) + { + sLog.outDebug("SD2: Kael'Thas mind control not supported."); + //DoCast(pUnit, SPELL_MIND_CONTROL); + } - //GravityLapse_Timer - if (GravityLapse_Timer <= diff) - { - std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); - switch (GravityLapse_Phase) + MindControl_Timer = 60000; + } + else + MindControl_Timer -= diff; + } + + //Phoenix_Timer + if (Phoenix_Timer <= diff) { - case 0: + DoCast(me, SPELL_PHOENIX_ANIMATION); + DoScriptText(RAND(SAY_SUMMON_PHOENIX1,SAY_SUMMON_PHOENIX2), me); + + Phoenix_Timer = 60000; + } + else + Phoenix_Timer -= diff; + + //Phase 4 specific spells + if (Phase == 4) + { + if (me->GetHealth()*100 / me->GetMaxHealth() < 50) + { + if (m_pInstance) + m_pInstance->SetData(DATA_KAELTHASEVENT, 4); + Phase = 5; + Phase_Timer = 10000; + + DoScriptText(SAY_PHASE5_NUTS, me); + me->StopMoving(); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveIdle(); me->GetMap()->CreatureRelocation(me, afGravityPos[0], afGravityPos[1], afGravityPos[2], 0); - me->SendMonsterMove(afGravityPos[0], afGravityPos[1], afGravityPos[2], 0, MOVEMENTFLAG_NONE, 0); + me->SendMonsterMove(afGravityPos[0], afGravityPos[1], afGravityPos[2], 0, 0, 0); + + me->InterruptNonMeleeSpells(false); + DoCast(me, SPELL_FULLPOWER); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } - // 1) Kael'thas will portal the whole raid right into his body - for (i = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i) + //ShockBarrier_Timer + if (ShockBarrier_Timer <= diff) + { + DoCast(me, SPELL_SHOCK_BARRIER); + ChainPyros = true; + PyrosCasted = 0; + ShockBarrier_Timer = 60000; + } + else + ShockBarrier_Timer -= diff; + + //Chain Pyros (3 of them max) + if (ChainPyros && !me->IsNonMeleeSpellCasted(false)) + { + if (PyrosCasted < 3) { - Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); - if (pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER)) - { - //Use work around packet to prevent player from being dropped from combat - DoTeleportPlayer(pUnit, afGravityPos[0], afGravityPos[1], afGravityPos[2], pUnit->GetOrientation()); - } + DoCast(me->getVictim(), SPELL_PYROBLAST); + ++PyrosCasted; } - - GravityLapse_Timer = 500; - ++GravityLapse_Phase; - InGravityLapse = true; - ShockBarrier_Timer = 1000; - NetherBeam_Timer = 5000; - break; - - case 1: - DoScriptText(RAND(SAY_GRAVITYLAPSE1,SAY_GRAVITYLAPSE2), me); - - // 2) At that point he will put a Gravity Lapse debuff on everyone - for (i = me->getThreatManager().getThreatList().begin(); i != me->getThreatManager().getThreatList().end(); ++i) + else { - if (Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid())) - { - DoCast(pUnit, SPELL_KNOCKBACK, true); - //Gravity lapse - needs an exception in Spell system to work - - pUnit->CastSpell(pUnit, SPELL_GRAVITY_LAPSE, true, 0, 0, me->GetGUID()); - pUnit->CastSpell(pUnit, SPELL_GRAVITY_LAPSE_AURA, true, 0, 0, me->GetGUID()); - - //Using packet workaround - WorldPacket data(12); - data.SetOpcode(SMSG_MOVE_SET_CAN_FLY); - data.append(pUnit->GetPackGUID()); - data << uint32(0); - pUnit->SendMessageToSet(&data, true); - } + ChainPyros = false; + Fireball_Timer = 2500; + ArcaneDisruption_Timer = 60000; } - GravityLapse_Timer = 10000; - ++GravityLapse_Phase; - break; + } + } - case 2: - //Cast nether vapor aura on self + if (Phase == 5) + { + if (Phase_Timer <= diff) + { me->InterruptNonMeleeSpells(false); - DoCast(me, SPELL_NETHER_VAPOR); + me->RemoveAurasDueToSpell(SPELL_FULLPOWER); - GravityLapse_Timer = 20000; - ++GravityLapse_Phase; - break; - - case 3: - //Remove flight - for (i = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i) - { - if (Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid())) - { - //Using packet workaround - WorldPacket data(12); - data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY); - data.append(pUnit->GetPackGUID()); - data << uint32(0); - pUnit->SendMessageToSet(&data, true); - } - } + DoCast(me, SPELL_EXPLODE); - me->RemoveAurasDueToSpell(SPELL_NETHER_VAPOR); - InGravityLapse = false; - GravityLapse_Timer = 60000; - GravityLapse_Phase = 0; + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + Phase = 6; AttackStart(me->getVictim()); - break; + } + else + Phase_Timer -= diff; } - } else GravityLapse_Timer -= diff; - if (InGravityLapse) - { - //ShockBarrier_Timer - if (ShockBarrier_Timer <= diff) + //Phase 5 + if (Phase == 6) { - DoCast(me, SPELL_SHOCK_BARRIER); - ShockBarrier_Timer = 20000; - } else ShockBarrier_Timer -= diff; - //NetherBeam_Timer - if (NetherBeam_Timer <= diff) - { - if (Unit* pUnit = SelectUnit(SELECT_TARGET_RANDOM, 0)) - DoCast(pUnit, SPELL_NETHER_BEAM); + //GravityLapse_Timer + if (GravityLapse_Timer <= diff) + { + std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); + switch (GravityLapse_Phase) + { + case 0: + me->StopMoving(); + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MoveIdle(); + me->GetMap()->CreatureRelocation(me, afGravityPos[0], afGravityPos[1], afGravityPos[2], 0); + me->SendMonsterMove(afGravityPos[0], afGravityPos[1], afGravityPos[2], 0, MOVEMENTFLAG_NONE, 0); + + // 1) Kael'thas will portal the whole raid right into his body + for (i = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i) + { + Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + if (pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER)) + { + //Use work around packet to prevent player from being dropped from combat + DoTeleportPlayer(pUnit, afGravityPos[0], afGravityPos[1], afGravityPos[2], pUnit->GetOrientation()); + } + } + + GravityLapse_Timer = 500; + ++GravityLapse_Phase; + InGravityLapse = true; + ShockBarrier_Timer = 1000; + NetherBeam_Timer = 5000; + break; + + case 1: + DoScriptText(RAND(SAY_GRAVITYLAPSE1,SAY_GRAVITYLAPSE2), me); + + // 2) At that point he will put a Gravity Lapse debuff on everyone + for (i = me->getThreatManager().getThreatList().begin(); i != me->getThreatManager().getThreatList().end(); ++i) + { + if (Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid())) + { + DoCast(pUnit, SPELL_KNOCKBACK, true); + //Gravity lapse - needs an exception in Spell system to work + + pUnit->CastSpell(pUnit, SPELL_GRAVITY_LAPSE, true, 0, 0, me->GetGUID()); + pUnit->CastSpell(pUnit, SPELL_GRAVITY_LAPSE_AURA, true, 0, 0, me->GetGUID()); + + //Using packet workaround + WorldPacket data(12); + data.SetOpcode(SMSG_MOVE_SET_CAN_FLY); + data.append(pUnit->GetPackGUID()); + data << uint32(0); + pUnit->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 = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i) + { + if (Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid())) + { + //Using packet workaround + WorldPacket data(12); + data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY); + data.append(pUnit->GetPackGUID()); + data << uint32(0); + pUnit->SendMessageToSet(&data, true); + } + } + + me->RemoveAurasDueToSpell(SPELL_NETHER_VAPOR); + InGravityLapse = false; + GravityLapse_Timer = 60000; + GravityLapse_Phase = 0; + AttackStart(me->getVictim()); + break; + } + } + else + GravityLapse_Timer -= diff; - NetherBeam_Timer = 4000; - } else NetherBeam_Timer -= diff; + if (InGravityLapse) + { + //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* pUnit = SelectUnit(SELECT_TARGET_RANDOM, 0)) + DoCast(pUnit, SPELL_NETHER_BEAM); + + NetherBeam_Timer = 4000; + } + else + NetherBeam_Timer -= diff; + } + } + + if (!InGravityLapse) + DoMeleeAttackIfReady(); } } - - if (!InGravityLapse) - DoMeleeAttackIfReady(); } + }; + CreatureAI* GetAI(Creature* Creature) const + { + return new boss_kaelthasAI(Creature); } - } }; //Thaladred the Darkener AI -struct boss_thaladred_the_darkenerAI : public advisorbase_ai +class boss_thaladred_the_darkener : public CreatureScript { - boss_thaladred_the_darkenerAI(Creature* pCreature) : advisorbase_ai(pCreature) {} + public: - uint32 Gaze_Timer; - uint32 Silence_Timer; - uint32 PsychicBlow_Timer; + boss_thaladred_the_darkener() + : CreatureScript("boss_thaladred_the_darkener") + { + } + struct boss_thaladred_the_darkenerAI : public advisorbase_ai + { + boss_thaladred_the_darkenerAI(Creature* pCreature) : advisorbase_ai(pCreature) {} - void Reset() - { - Gaze_Timer = 100; - Silence_Timer = 20000; - PsychicBlow_Timer = 10000; + uint32 Gaze_Timer; + uint32 Silence_Timer; + uint32 PsychicBlow_Timer; - advisorbase_ai::Reset(); - } + void Reset() + { + Gaze_Timer = 100; + Silence_Timer = 20000; + PsychicBlow_Timer = 10000; - void EnterCombat(Unit *who) - { - if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) - return; + advisorbase_ai::Reset(); + } - if (!who || FakeDeath) - return; + void EnterCombat(Unit *who) + { + if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) + return; - DoScriptText(SAY_THALADRED_AGGRO, me); - me->AddThreat(who, 5000000.0f); - } + if (!who || FakeDeath) + return; - void JustDied(Unit* /*pKiller*/) - { - if (m_pInstance && m_pInstance->GetData(DATA_KAELTHASEVENT) == 3) - DoScriptText(SAY_THALADRED_DEATH, me); - } + DoScriptText(SAY_THALADRED_AGGRO, me); + me->AddThreat(who, 5000000.0f); + } - void UpdateAI(const uint32 diff) - { - advisorbase_ai::UpdateAI(diff); + void JustDied(Unit* /*pKiller*/) + { + if (m_pInstance && m_pInstance->GetData(DATA_KAELTHASEVENT) == 3) + DoScriptText(SAY_THALADRED_DEATH, me); + } - //Faking death, don't do anything - if (FakeDeath) - return; + void UpdateAI(const uint32 diff) + { + advisorbase_ai::UpdateAI(diff); - //Return since we have no target - if (!UpdateVictim()) - return; + //Faking death, don't do anything + if (FakeDeath) + return; - //Gaze_Timer - if (Gaze_Timer <= diff) - { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - { - DoResetThreat(); - me->AddThreat(pTarget, 5000000.0f); - DoScriptText(EMOTE_THALADRED_GAZE, me, pTarget); - Gaze_Timer = 8500; - } - } else Gaze_Timer -= diff; + //Return since we have no target + if (!UpdateVictim()) + return; - //Silence_Timer - if (Silence_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_SILENCE); - Silence_Timer = 20000; - } else Silence_Timer -= diff; + //Gaze_Timer + if (Gaze_Timer <= diff) + { + if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + { + DoResetThreat(); + me->AddThreat(pTarget, 5000000.0f); + DoScriptText(EMOTE_THALADRED_GAZE, me, pTarget); + Gaze_Timer = 8500; + } + } + else + Gaze_Timer -= diff; - //PsychicBlow_Timer - if (PsychicBlow_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_PSYCHIC_BLOW); - PsychicBlow_Timer = 20000+rand()%5000; - } else PsychicBlow_Timer -= diff; + //Silence_Timer + if (Silence_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_SILENCE); + Silence_Timer = 20000; + } + else + Silence_Timer -= diff; - DoMeleeAttackIfReady(); - } + //PsychicBlow_Timer + if (PsychicBlow_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_PSYCHIC_BLOW); + PsychicBlow_Timer = 20000+rand()%5000; + } + else + PsychicBlow_Timer -= diff; + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* Creature) const + { + return new boss_thaladred_the_darkenerAI(Creature); + } }; //Lord Sanguinar AI -struct boss_lord_sanguinarAI : public advisorbase_ai +class boss_lord_sanguinar : public CreatureScript { - boss_lord_sanguinarAI(Creature* pCreature) : advisorbase_ai(pCreature) {} + public: - uint32 Fear_Timer; + boss_lord_sanguinar() + : CreatureScript("boss_lord_sanguinar") + { + } + struct boss_lord_sanguinarAI : public advisorbase_ai + { + boss_lord_sanguinarAI(Creature* pCreature) : advisorbase_ai(pCreature) {} - void Reset() - { - Fear_Timer = 20000; - advisorbase_ai::Reset(); - } + uint32 Fear_Timer; - void EnterCombat(Unit *who) - { - if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) - return; + void Reset() + { + Fear_Timer = 20000; + advisorbase_ai::Reset(); + } - if (!who || FakeDeath) - return; + void EnterCombat(Unit *who) + { + if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) + return; - DoScriptText(SAY_SANGUINAR_AGGRO, me); - } + if (!who || FakeDeath) + return; - void JustDied(Unit* /*Killer*/) - { - if (m_pInstance && m_pInstance->GetData(DATA_KAELTHASEVENT) == 3) - DoScriptText(SAY_SANGUINAR_DEATH, me); - } + DoScriptText(SAY_SANGUINAR_AGGRO, me); + } - void UpdateAI(const uint32 diff) - { - advisorbase_ai::UpdateAI(diff); + void JustDied(Unit* /*Killer*/) + { + if (m_pInstance && m_pInstance->GetData(DATA_KAELTHASEVENT) == 3) + DoScriptText(SAY_SANGUINAR_DEATH, me); + } - //Faking death, don't do anything - if (FakeDeath) - return; + void UpdateAI(const uint32 diff) + { + advisorbase_ai::UpdateAI(diff); - //Return since we have no target - if (!UpdateVictim()) - return; + //Faking death, don't do anything + if (FakeDeath) + return; - //Fear_Timer - if (Fear_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_BELLOWING_ROAR); - Fear_Timer = 25000+rand()%10000; //approximately every 30 seconds - } else Fear_Timer -= diff; + //Return since we have no target + if (!UpdateVictim()) + return; - DoMeleeAttackIfReady(); - } -}; + //Fear_Timer + if (Fear_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_BELLOWING_ROAR); + Fear_Timer = 25000+rand()%10000; //approximately every 30 seconds + } + else + Fear_Timer -= diff; + DoMeleeAttackIfReady(); + } + }; + CreatureAI* GetAI(Creature* Creature) const + { + return new boss_lord_sanguinarAI(Creature); + } +}; //Grand Astromancer Capernian AI -struct boss_grand_astromancer_capernianAI : public advisorbase_ai +class boss_grand_astromancer_capernian : public CreatureScript { - boss_grand_astromancer_capernianAI(Creature* pCreature) : advisorbase_ai(pCreature) {} + public: - uint32 Fireball_Timer; - uint32 Conflagration_Timer; - uint32 ArcaneExplosion_Timer; - uint32 Yell_Timer; - bool Yell; + boss_grand_astromancer_capernian() + : CreatureScript("boss_grand_astromancer_capernian") + { + } + struct boss_grand_astromancer_capernianAI : public advisorbase_ai + { + boss_grand_astromancer_capernianAI(Creature* pCreature) : advisorbase_ai(pCreature) {} - void Reset() - { - Fireball_Timer = 2000; - Conflagration_Timer = 20000; - ArcaneExplosion_Timer = 5000; - Yell_Timer = 2000; - Yell = false; + uint32 Fireball_Timer; + uint32 Conflagration_Timer; + uint32 ArcaneExplosion_Timer; + uint32 Yell_Timer; + bool Yell; - advisorbase_ai::Reset(); - } + void Reset() + { + Fireball_Timer = 2000; + Conflagration_Timer = 20000; + ArcaneExplosion_Timer = 5000; + Yell_Timer = 2000; + Yell = false; - void JustDied(Unit* /*pKiller*/) - { - if (m_pInstance && m_pInstance->GetData(DATA_KAELTHASEVENT) == 3) - DoScriptText(SAY_CAPERNIAN_DEATH, me); - } + advisorbase_ai::Reset(); + } - void AttackStart(Unit* who) - { - if (!who || FakeDeath || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) - return; + void JustDied(Unit* /*pKiller*/) + { + if (m_pInstance && m_pInstance->GetData(DATA_KAELTHASEVENT) == 3) + DoScriptText(SAY_CAPERNIAN_DEATH, me); + } - if (me->Attack(who, true)) - { - me->AddThreat(who, 0.0f); - me->SetInCombatWith(who); - who->SetInCombatWith(me); + void AttackStart(Unit* who) + { + if (!who || FakeDeath || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) + return; - me->GetMotionMaster()->MoveChase(who, CAPERNIAN_DISTANCE); - } - } + if (me->Attack(who, true)) + { + me->AddThreat(who, 0.0f); + me->SetInCombatWith(who); + who->SetInCombatWith(me); - void EnterCombat(Unit *who) - { - if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) - return; + me->GetMotionMaster()->MoveChase(who, CAPERNIAN_DISTANCE); + } + } - if (!who || FakeDeath) - return; - } + void EnterCombat(Unit *who) + { + if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) + return; - void UpdateAI(const uint32 diff) - { - advisorbase_ai::UpdateAI(diff); + if (!who || FakeDeath) + return; + } - //Faking Death, don't do anything - if (FakeDeath) - return; + void UpdateAI(const uint32 diff) + { + advisorbase_ai::UpdateAI(diff); - //Return since we have no target - if (!UpdateVictim()) - return; + //Faking Death, don't do anything + if (FakeDeath) + return; - //Yell_Timer - if (!Yell) - { - if (Yell_Timer <= diff) - { - DoScriptText(SAY_CAPERNIAN_AGGRO, me); - Yell = true; - } else Yell_Timer -= diff; - } + //Return since we have no target + if (!UpdateVictim()) + return; - //Fireball_Timer - if (Fireball_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_CAPERNIAN_FIREBALL); - Fireball_Timer = 4000; - } else Fireball_Timer -= diff; + //Yell_Timer + if (!Yell) + { + if (Yell_Timer <= diff) + { + DoScriptText(SAY_CAPERNIAN_AGGRO, me); + Yell = true; + } + else + Yell_Timer -= diff; + } - //Conflagration_Timer - if (Conflagration_Timer <= diff) - { - Unit *pTarget = NULL; - pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); + //Fireball_Timer + if (Fireball_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_CAPERNIAN_FIREBALL); + Fireball_Timer = 4000; + } + else + Fireball_Timer -= diff; + + //Conflagration_Timer + if (Conflagration_Timer <= diff) + { + Unit *pTarget = NULL; + pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); - if (pTarget && me->IsWithinDistInMap(pTarget, 30)) - DoCast(pTarget, SPELL_CONFLAGRATION); - else - DoCast(me->getVictim(), SPELL_CONFLAGRATION); + if (pTarget && me->IsWithinDistInMap(pTarget, 30)) + DoCast(pTarget, SPELL_CONFLAGRATION); + else + DoCast(me->getVictim(), SPELL_CONFLAGRATION); - Conflagration_Timer = 10000+rand()%5000; - } else Conflagration_Timer -= diff; + Conflagration_Timer = 10000+rand()%5000; + } + else + Conflagration_Timer -= diff; - //ArcaneExplosion_Timer - if (ArcaneExplosion_Timer <= diff) - { - bool InMeleeRange = false; - Unit *pTarget = NULL; - std::list<HostileReference*>& m_threatlist = me->getThreatManager().getThreatList(); - for (std::list<HostileReference*>::const_iterator i = m_threatlist.begin(); i!= m_threatlist.end(); ++i) - { - Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); - //if in melee range - if (pUnit && pUnit->IsWithinDistInMap(me, 5)) + //ArcaneExplosion_Timer + if (ArcaneExplosion_Timer <= diff) { - InMeleeRange = true; - pTarget = pUnit; - break; - } - } + bool InMeleeRange = false; + Unit *pTarget = NULL; + std::list<HostileReference*>& m_threatlist = me->getThreatManager().getThreatList(); + for (std::list<HostileReference*>::const_iterator i = m_threatlist.begin(); i!= m_threatlist.end(); ++i) + { + Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + //if in melee range + if (pUnit && pUnit->IsWithinDistInMap(me, 5)) + { + InMeleeRange = true; + pTarget = pUnit; + break; + } + } - if (InMeleeRange) - DoCast(pTarget, SPELL_ARCANE_EXPLOSION); + if (InMeleeRange) + DoCast(pTarget, SPELL_ARCANE_EXPLOSION); - ArcaneExplosion_Timer = 4000+rand()%2000; - } else ArcaneExplosion_Timer -= diff; + ArcaneExplosion_Timer = 4000+rand()%2000; + } + else + ArcaneExplosion_Timer -= diff; - //Do NOT deal any melee damage. - } + //Do NOT deal any melee damage. + } + }; + + CreatureAI* GetAI(Creature* Creature) const + { + return new boss_grand_astromancer_capernianAI(Creature); + } }; //Master Engineer Telonicus AI -struct boss_master_engineer_telonicusAI : public advisorbase_ai +class boss_master_engineer_telonicus : public CreatureScript { - boss_master_engineer_telonicusAI(Creature* pCreature) : advisorbase_ai(pCreature) {} + public: - uint32 Bomb_Timer; - uint32 RemoteToy_Timer; + boss_master_engineer_telonicus() + : CreatureScript("boss_master_engineer_telonicus") + { + } + struct boss_master_engineer_telonicusAI : public advisorbase_ai + { + boss_master_engineer_telonicusAI(Creature* pCreature) : advisorbase_ai(pCreature) {} - void Reset() - { - Bomb_Timer = 10000; - RemoteToy_Timer = 5000; + uint32 Bomb_Timer; + uint32 RemoteToy_Timer; - advisorbase_ai::Reset(); - } + void Reset() + { + Bomb_Timer = 10000; + RemoteToy_Timer = 5000; - void JustDied(Unit* /*pKiller*/) - { - if (m_pInstance && m_pInstance->GetData(DATA_KAELTHASEVENT) == 3) - DoScriptText(SAY_TELONICUS_DEATH, me); - } + advisorbase_ai::Reset(); + } - void EnterCombat(Unit *who) - { - if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) - return; + void JustDied(Unit* /*pKiller*/) + { + if (m_pInstance && m_pInstance->GetData(DATA_KAELTHASEVENT) == 3) + DoScriptText(SAY_TELONICUS_DEATH, me); + } - if (!who || FakeDeath) - return; + void EnterCombat(Unit *who) + { + if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) + return; - DoScriptText(SAY_TELONICUS_AGGRO, me); - } + if (!who || FakeDeath) + return; - void UpdateAI(const uint32 diff) - { - advisorbase_ai::UpdateAI(diff); + DoScriptText(SAY_TELONICUS_AGGRO, me); + } - //Faking Death, do nothing - if (FakeDeath) - return; + void UpdateAI(const uint32 diff) + { + advisorbase_ai::UpdateAI(diff); - //Return since we have no target - if (!UpdateVictim()) - return; + //Faking Death, do nothing + if (FakeDeath) + return; - //Bomb_Timer - if (Bomb_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_BOMB); - Bomb_Timer = 25000; - } else Bomb_Timer -= diff; + //Return since we have no target + if (!UpdateVictim()) + return; - //RemoteToy_Timer - if (RemoteToy_Timer <= diff) - { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - DoCast(pTarget, SPELL_REMOTE_TOY); + //Bomb_Timer + if (Bomb_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_BOMB); + Bomb_Timer = 25000; + } + else + Bomb_Timer -= diff; + + //RemoteToy_Timer + if (RemoteToy_Timer <= diff) + { + if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_REMOTE_TOY); - RemoteToy_Timer = 10000+rand()%5000; - } else RemoteToy_Timer -= diff; + RemoteToy_Timer = 10000+rand()%5000; + } + else + RemoteToy_Timer -= diff; - DoMeleeAttackIfReady(); - } + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* Creature) + { + return new boss_master_engineer_telonicusAI(Creature); + } }; //Flame Strike AI -struct mob_kael_flamestrikeAI : public Scripted_NoMovementAI +class mob_kael_flamestrike : public CreatureScript { - mob_kael_flamestrikeAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature) {} + public: - uint32 Timer; - bool Casting; - bool KillSelf; + mob_kael_flamestrike() + : CreatureScript("mob_kael_flamestrike") + { + } + struct mob_kael_flamestrikeAI : public Scripted_NoMovementAI + { + mob_kael_flamestrikeAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature) {} - void Reset() - { - Timer = 5000; - Casting = false; - KillSelf = false; + uint32 Timer; + bool Casting; + bool KillSelf; - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->setFaction(14); - } + void Reset() + { + Timer = 5000; + Casting = false; + KillSelf = false; - void MoveInLineOfSight(Unit * /*who*/) {} + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->setFaction(14); + } - void EnterCombat(Unit * /*who*/) {} + void MoveInLineOfSight(Unit * /*who*/) {} - void UpdateAI(const uint32 diff) - { - if (!Casting) - { - DoCast(me, SPELL_FLAME_STRIKE_VIS); - Casting = true; - } + void EnterCombat(Unit * /*who*/) {} - //Timer - if (Timer <= diff) - { - if (!KillSelf) + void UpdateAI(const uint32 diff) { - me->InterruptNonMeleeSpells(false); - DoCast(me, SPELL_FLAME_STRIKE_DMG); - } else me->Kill(me); + if (!Casting) + { + DoCast(me, SPELL_FLAME_STRIKE_VIS); + Casting = true; + } - KillSelf = true; - Timer = 1000; - } else Timer -= diff; - } + //Timer + if (Timer <= diff) + { + if (!KillSelf) + { + me->InterruptNonMeleeSpells(false); + DoCast(me, SPELL_FLAME_STRIKE_DMG); + } + else + me->Kill(me); + + KillSelf = true; + Timer = 1000; + } + else + Timer -= diff; + } + }; + + CreatureAI* GetAI(Creature* Creature) + { + return new mob_kael_flamestrikeAI(Creature); + } }; //Phoenix AI -struct mob_phoenix_tkAI : public ScriptedAI +class mob_phoenix_tk : public CreatureScript { - mob_phoenix_tkAI(Creature* pCreature) : ScriptedAI(pCreature) {} + public: + + mob_phoenix_tk() + : CreatureScript("mob_phoenix_tk") + { + } + struct mob_phoenix_tkAI : public ScriptedAI + { + mob_phoenix_tkAI(Creature* pCreature) : ScriptedAI(pCreature) {} - uint32 Cycle_Timer; + uint32 Cycle_Timer; - void Reset() - { - Cycle_Timer = 2000; - DoCast(me, SPELL_BURN, true); - } + void Reset() + { + Cycle_Timer = 2000; + DoCast(me, SPELL_BURN, true); + } - void JustDied(Unit* /*killer*/) - { - //is this spell in use anylonger? - //DoCast(me, SPELL_EMBER_BLAST, true); - me->SummonCreature(NPC_PHOENIX_EGG,me->GetPositionX(),me->GetPositionY(),me->GetPositionZ(),me->GetOrientation(),TEMPSUMMON_TIMED_DESPAWN,16000); - } + void JustDied(Unit* /*killer*/) + { + //is this spell in use anylonger? + //DoCast(me, SPELL_EMBER_BLAST, true); + me->SummonCreature(NPC_PHOENIX_EGG,me->GetPositionX(),me->GetPositionY(),me->GetPositionZ(),me->GetOrientation(),TEMPSUMMON_TIMED_DESPAWN,16000); + } - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + if (Cycle_Timer <= diff) + { + //spell Burn should possible do this, but it doesn't, so do this for now. + uint32 dmg = urand(4500,5500); + if (me->GetHealth() > dmg) + me->SetHealth(uint32(me->GetHealth()-dmg)); + Cycle_Timer = 2000; + } + else + Cycle_Timer -= diff; + + DoMeleeAttackIfReady(); + } + }; - if (Cycle_Timer <= diff) + CreatureAI* GetAI(Creature* Creature) const { - //spell Burn should possible do this, but it doesn't, so do this for now. - uint32 dmg = urand(4500,5500); - if (me->GetHealth() > dmg) - me->SetHealth(uint32(me->GetHealth()-dmg)); - Cycle_Timer = 2000; - } else Cycle_Timer -= diff; - - DoMeleeAttackIfReady(); - } + return new mob_phoenix_tkAI(Creature); + } }; + //Phoenix Egg AI -struct mob_phoenix_egg_tkAI : public ScriptedAI +class mob_phoenix_egg_tk : public CreatureScript { - mob_phoenix_egg_tkAI(Creature* pCreature) : ScriptedAI(pCreature) {} - - uint32 Rebirth_Timer; - - void Reset() - { - Rebirth_Timer = 15000; - } + public: - //ignore any - void MoveInLineOfSight(Unit* /*who*/) {} - - void AttackStart(Unit* who) - { - if (me->Attack(who, false)) + mob_phoenix_egg_tk() + : CreatureScript("mob_phoenix_egg_tk") { - me->SetInCombatWith(who); - who->SetInCombatWith(me); - - DoStartNoMovement(who); } - } - - void JustSummoned(Creature* summoned) - { - summoned->AddThreat(me->getVictim(), 0.0f); - summoned->CastSpell(summoned,SPELL_REBIRTH,false); - } + struct mob_phoenix_egg_tkAI : public ScriptedAI + { + mob_phoenix_egg_tkAI(Creature* pCreature) : ScriptedAI(pCreature) {} - void UpdateAI(const uint32 diff) - { - if (!Rebirth_Timer) - return; + uint32 Rebirth_Timer; - if (Rebirth_Timer <= diff) - { - me->SummonCreature(NPC_PHOENIX,me->GetPositionX(),me->GetPositionY(),me->GetPositionZ(),me->GetOrientation(),TEMPSUMMON_CORPSE_DESPAWN,5000); - Rebirth_Timer = 0; - } else Rebirth_Timer -= diff; - } -}; + void Reset() + { + Rebirth_Timer = 15000; + } -CreatureAI* GetAI_boss_kaelthas(Creature* pCreature) -{ - return new boss_kaelthasAI(pCreature); -} + //ignore any + void MoveInLineOfSight(Unit* /*who*/) {} -CreatureAI* GetAI_boss_thaladred_the_darkener(Creature* pCreature) -{ - return new boss_thaladred_the_darkenerAI(pCreature); -} + void AttackStart(Unit* who) + { + if (me->Attack(who, false)) + { + me->SetInCombatWith(who); + who->SetInCombatWith(me); -CreatureAI* GetAI_boss_lord_sanguinar(Creature* pCreature) -{ - return new boss_lord_sanguinarAI(pCreature); -} + DoStartNoMovement(who); + } + } -CreatureAI* GetAI_boss_grand_astromancer_capernian(Creature* pCreature) -{ - return new boss_grand_astromancer_capernianAI(pCreature); -} + void JustSummoned(Creature* summoned) + { + summoned->AddThreat(me->getVictim(), 0.0f); + summoned->CastSpell(summoned,SPELL_REBIRTH,false); + } -CreatureAI* GetAI_boss_master_engineer_telonicus(Creature* pCreature) -{ - return new boss_master_engineer_telonicusAI(pCreature); -} + void UpdateAI(const uint32 diff) + { + if (!Rebirth_Timer) + return; -CreatureAI* GetAI_mob_kael_flamestrike(Creature* pCreature) -{ - return new mob_kael_flamestrikeAI(pCreature); -} + if (Rebirth_Timer <= diff) + { + me->SummonCreature(NPC_PHOENIX,me->GetPositionX(),me->GetPositionY(),me->GetPositionZ(),me->GetOrientation(),TEMPSUMMON_CORPSE_DESPAWN,5000); + Rebirth_Timer = 0; + } + else + Rebirth_Timer -= diff; + } + }; -CreatureAI* GetAI_mob_phoenix_tk(Creature* pCreature) -{ - return new mob_phoenix_tkAI(pCreature); -} + CreatureAI* GetAI_mob_phoenix_egg_tk(Creature* pCreature) + { + return new mob_phoenix_egg_tkAI(pCreature); + } +}; -CreatureAI* GetAI_mob_phoenix_egg_tk(Creature* pCreature) -{ - return new mob_phoenix_egg_tkAI(pCreature); -} void AddSC_boss_kaelthas() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_kaelthas"; - newscript->GetAI = &GetAI_boss_kaelthas; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "boss_thaladred_the_darkener"; - newscript->GetAI = &GetAI_boss_thaladred_the_darkener; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "boss_lord_sanguinar"; - newscript->GetAI = &GetAI_boss_lord_sanguinar; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "boss_grand_astromancer_capernian"; - newscript->GetAI = &GetAI_boss_grand_astromancer_capernian; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "boss_master_engineer_telonicus"; - newscript->GetAI = &GetAI_boss_master_engineer_telonicus; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_kael_flamestrike"; - newscript->GetAI = &GetAI_mob_kael_flamestrike; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_phoenix_tk"; - newscript->GetAI = &GetAI_mob_phoenix_tk; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_phoenix_egg_tk"; - newscript->GetAI = &GetAI_mob_phoenix_egg_tk; - newscript->RegisterSelf(); + new boss_kaelthas(); + new boss_thaladred_the_darkener(); + new boss_lord_sanguinar(); + new boss_grand_astromancer_capernian(); + new boss_master_engineer_telonicus(); + new mob_kael_flamestrike(); + new mob_phoenix_tk(); + new mob_phoenix_egg_tk(); } diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp index c22c9787a76..0b2656496ad 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp @@ -42,140 +42,144 @@ enum eEnums SPELL_BERSERK = 27680 }; -struct boss_void_reaverAI : public ScriptedAI +class boss_void_reaver : public CreatureScript { - boss_void_reaverAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - } - - ScriptedInstance* pInstance; - - uint32 Pounding_Timer; - uint32 ArcaneOrb_Timer; - uint32 KnockAway_Timer; - uint32 Berserk_Timer; - - bool Enraged; - - void Reset() - { - Pounding_Timer = 15000; - ArcaneOrb_Timer = 3000; - KnockAway_Timer = 30000; - Berserk_Timer = 600000; - - Enraged = false; - - if (pInstance && me->isAlive()) - pInstance->SetData(DATA_VOIDREAVEREVENT, NOT_STARTED); - } - - void KilledUnit(Unit * /*victim*/) - { - DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2,SAY_SLAY3), me); - } - - void JustDied(Unit * /*victim*/) - { - DoScriptText(SAY_DEATH, me); - DoZoneInCombat(); - - if (pInstance) - pInstance->SetData(DATA_VOIDREAVEREVENT, DONE); - } - - void EnterCombat(Unit * /*who*/) - { - DoScriptText(SAY_AGGRO, me); - - if (pInstance) - pInstance->SetData(DATA_VOIDREAVEREVENT, IN_PROGRESS); - } - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - - // Pounding - if (Pounding_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_POUNDING); - - DoScriptText(RAND(SAY_POUNDING1,SAY_POUNDING2), me); - Pounding_Timer = 15000; //cast time(3000) + cooldown time(12000) - } else Pounding_Timer -= diff; + public: - // Arcane Orb - if (ArcaneOrb_Timer <= diff) + boss_void_reaver() + : CreatureScript("boss_void_reaver") + { + } + + struct boss_void_reaverAI : public ScriptedAI { - Unit *pTarget = NULL; - std::list<HostileReference *> t_list = me->getThreatManager().getThreatList(); - std::vector<Unit *> target_list; - for (std::list<HostileReference *>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) + boss_void_reaverAI(Creature* pCreature) : ScriptedAI(pCreature) { - pTarget = Unit::GetUnit(*me, (*itr)->getUnitGuid()); - if (!pTarget) - continue; - - // exclude pets & totems - if (pTarget->GetTypeId() != TYPEID_PLAYER) - continue; - - //18 yard radius minimum - if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER && pTarget->isAlive() && !pTarget->IsWithinDist(me, 18, false)) - target_list.push_back(pTarget); - pTarget = NULL; + pInstance = pCreature->GetInstanceData(); } - if (target_list.size()) - pTarget = *(target_list.begin()+rand()%target_list.size()); - else - pTarget = me->getVictim(); + ScriptedInstance* pInstance; - if (pTarget) - me->CastSpell(pTarget->GetPositionX(),pTarget->GetPositionY(),pTarget->GetPositionZ(), SPELL_ARCANE_ORB, false, NULL, NULL, NULL, pTarget); + uint32 Pounding_Timer; + uint32 ArcaneOrb_Timer; + uint32 KnockAway_Timer; + uint32 Berserk_Timer; - ArcaneOrb_Timer = 3000; - } else ArcaneOrb_Timer -= diff; + bool Enraged; - // Single Target knock back, reduces aggro - if (KnockAway_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_KNOCK_AWAY); + void Reset() + { + Pounding_Timer = 15000; + ArcaneOrb_Timer = 3000; + KnockAway_Timer = 30000; + Berserk_Timer = 600000; - //Drop 25% aggro - if (DoGetThreat(me->getVictim())) - DoModifyThreatPercent(me->getVictim(),-25); + Enraged = false; - KnockAway_Timer = 30000; - } else KnockAway_Timer -= diff; + if (pInstance && me->isAlive()) + pInstance->SetData(DATA_VOIDREAVEREVENT, NOT_STARTED); + } - //Berserk - if (Berserk_Timer < diff && !Enraged) - { - DoCast(me, SPELL_BERSERK); - Enraged = true; - } else Berserk_Timer -= diff; + void KilledUnit(Unit * /*victim*/) + { + DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2,SAY_SLAY3), me); + } - DoMeleeAttackIfReady(); + void JustDied(Unit * /*victim*/) + { + DoScriptText(SAY_DEATH, me); + DoZoneInCombat(); - EnterEvadeIfOutOfCombatArea(diff); - } -}; + if (pInstance) + pInstance->SetData(DATA_VOIDREAVEREVENT, DONE); + } -CreatureAI* GetAI_boss_void_reaver(Creature* pCreature) -{ - return new boss_void_reaverAI (pCreature); -} + void EnterCombat(Unit * /*who*/) + { + DoScriptText(SAY_AGGRO, me); + + if (pInstance) + pInstance->SetData(DATA_VOIDREAVEREVENT, IN_PROGRESS); + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + // Pounding + if (Pounding_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_POUNDING); + DoScriptText(RAND(SAY_POUNDING1,SAY_POUNDING2), me); + Pounding_Timer = 15000; //cast time(3000) + cooldown time(12000) + } + else + Pounding_Timer -= diff; + // Arcane Orb + if (ArcaneOrb_Timer <= diff) + { + Unit *pTarget = NULL; + std::list<HostileReference *> t_list = me->getThreatManager().getThreatList(); + std::vector<Unit *> target_list; + for (std::list<HostileReference *>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) + { + pTarget = Unit::GetUnit(*me, (*itr)->getUnitGuid()); + if (!pTarget) + continue; + // exclude pets & totems + if (pTarget->GetTypeId() != TYPEID_PLAYER) + continue; + //18 yard radius minimum + if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER && pTarget->isAlive() && !pTarget->IsWithinDist(me, 18, false)) + target_list.push_back(pTarget); + pTarget = NULL; + } + + if (target_list.size()) + pTarget = *(target_list.begin()+rand()%target_list.size()); + else + pTarget = me->getVictim(); + + if (pTarget) + me->CastSpell(pTarget->GetPositionX(),pTarget->GetPositionY(),pTarget->GetPositionZ(), SPELL_ARCANE_ORB, false, NULL, NULL, NULL, pTarget); + ArcaneOrb_Timer = 3000; + } + else + ArcaneOrb_Timer -= diff; + // Single Target knock back, reduces aggro + if (KnockAway_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_KNOCK_AWAY); + //Drop 25% aggro + if (DoGetThreat(me->getVictim())) + DoModifyThreatPercent(me->getVictim(),-25); + KnockAway_Timer = 30000; + } + else + KnockAway_Timer -= diff; + //Berserk + if (Berserk_Timer < diff && !Enraged) + { + DoCast(me, SPELL_BERSERK); + Enraged = true; + } + else + Berserk_Timer -= diff; + + DoMeleeAttackIfReady(); + + EnterEvadeIfOutOfCombatArea(diff); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_void_reaverAI(creature); + } +}; void AddSC_boss_void_reaver() { - Script *newscript; - newscript = new Script; - newscript->Name = "boss_void_reaver"; - newscript->GetAI = &GetAI_boss_void_reaver; - newscript->RegisterSelf(); + new boss_void_reaver(); } 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 04c80a0a430..8fee87e39fd 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/instance_the_eye.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/instance_the_eye.cpp @@ -35,144 +35,172 @@ EndScriptData */ 3 - Void Reaver event */ -struct instance_the_eye : public ScriptedInstance +class instance_mechanar : public InstanceMapScript { - instance_the_eye(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; - - uint64 ThaladredTheDarkener; - uint64 LordSanguinar; - uint64 GrandAstromancerCapernian; - uint64 MasterEngineerTelonicus; - uint64 Kaelthas; - uint64 Astromancer; - uint64 Alar; - - uint8 KaelthasEventPhase; - uint8 AlarEventPhase; - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - - void Initialize() - { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - ThaladredTheDarkener = 0; - LordSanguinar = 0; - GrandAstromancerCapernian = 0; - MasterEngineerTelonicus = 0; - Kaelthas = 0; - Astromancer = 0; - Alar = 0; - - KaelthasEventPhase = 0; - AlarEventPhase = 0; - } - - bool IsEncounterInProgress() const - { - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) return true; - - return false; - } - - void OnCreatureCreate(Creature* pCreature, bool /*add*/) - { - switch(pCreature->GetEntry()) + public: + instance_mechanar() + : InstanceMapScript("instance_mechanar") { - case 20064: ThaladredTheDarkener = pCreature->GetGUID(); break; - case 20063: MasterEngineerTelonicus = pCreature->GetGUID(); break; - case 20062: GrandAstromancerCapernian = pCreature->GetGUID(); break; - case 20060: LordSanguinar = pCreature->GetGUID(); break; - case 19622: Kaelthas = pCreature->GetGUID(); break; - case 18805: Astromancer = pCreature->GetGUID(); break; - case 19514: Alar = pCreature->GetGUID(); break; } - } - - uint64 GetData64(uint32 identifier) - { - switch(identifier) - { - case DATA_THALADREDTHEDARKENER: return ThaladredTheDarkener; - case DATA_LORDSANGUINAR: return LordSanguinar; - case DATA_GRANDASTROMANCERCAPERNIAN: return GrandAstromancerCapernian; - case DATA_MASTERENGINEERTELONICUS: return MasterEngineerTelonicus; - case DATA_KAELTHAS: return Kaelthas; - case DATA_ASTROMANCER: return Astromancer; - case DATA_ALAR: return Alar; - } - return 0; - } - - void SetData(uint32 type, uint32 data) - { - switch(type) + + struct instance_the_eye_InstanceMapScript : public ScriptedInstance { - case DATA_ALAREVENT: AlarEventPhase = data; m_auiEncounter[0] = data; break; - case DATA_HIGHASTROMANCERSOLARIANEVENT: m_auiEncounter[1] = data; break; - case DATA_VOIDREAVEREVENT: m_auiEncounter[2] = data; break; - case DATA_KAELTHASEVENT: KaelthasEventPhase = data; m_auiEncounter[3] = data; break; - } - if (data == DONE) - SaveToDB(); - } - - uint32 GetData(uint32 type) - { - switch(type) - { - case DATA_ALAREVENT: return AlarEventPhase; - case DATA_HIGHASTROMANCERSOLARIANEVENT: return m_auiEncounter[1]; - case DATA_VOIDREAVEREVENT: return m_auiEncounter[2]; - case DATA_KAELTHASEVENT: return KaelthasEventPhase; - } - return 0; - } - - std::string GetSaveData() - { - OUT_SAVE_INST_DATA; - std::ostringstream stream; - stream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3]; - char* out = new char[stream.str().length() + 1]; - strcpy(out, stream.str().c_str()); - if (out) + instance_the_eye_InstanceMapScript(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; + + uint64 ThaladredTheDarkener; + uint64 LordSanguinar; + uint64 GrandAstromancerCapernian; + uint64 MasterEngineerTelonicus; + uint64 Kaelthas; + uint64 Astromancer; + uint64 Alar; + uint8 KaelthasEventPhase; + uint8 AlarEventPhase; + + uint32 m_auiEncounter[MAX_ENCOUNTER]; + + void Initialize() + { + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + + ThaladredTheDarkener = 0; + LordSanguinar = 0; + GrandAstromancerCapernian = 0; + MasterEngineerTelonicus = 0; + Kaelthas = 0; + Astromancer = 0; + Alar = 0; + + KaelthasEventPhase = 0; + AlarEventPhase = 0; + } + + bool IsEncounterInProgress() const + { + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + if (m_auiEncounter[i] == IN_PROGRESS) return true; + + return false; + } + + void OnCreatureCreate(Creature* pCreature, bool /*add*/) + { + switch(pCreature->GetEntry()) + { + case 20064: + ThaladredTheDarkener = pCreature->GetGUID(); + break; + case 20063: + MasterEngineerTelonicus = pCreature->GetGUID(); + break; + case 20062: + GrandAstromancerCapernian = pCreature->GetGUID(); + break; + case 20060: + LordSanguinar = pCreature->GetGUID(); + break; + case 19622: + Kaelthas = pCreature->GetGUID(); + break; + case 18805: + Astromancer = pCreature->GetGUID(); + break; + case 19514: + Alar = pCreature->GetGUID(); + break; + } + } + + uint64 GetData64(uint32 identifier) + { + switch(identifier) + { + case DATA_THALADREDTHEDARKENER: return ThaladredTheDarkener; + case DATA_LORDSANGUINAR: return LordSanguinar; + case DATA_GRANDASTROMANCERCAPERNIAN: return GrandAstromancerCapernian; + case DATA_MASTERENGINEERTELONICUS: return MasterEngineerTelonicus; + case DATA_KAELTHAS: return Kaelthas; + case DATA_ASTROMANCER: return Astromancer; + case DATA_ALAR: return Alar; + } + return 0; + } + + void SetData(uint32 type, uint32 data) + { + switch(type) + { + case DATA_ALAREVENT: + AlarEventPhase = data; + m_auiEncounter[0] = data; + break; + case DATA_HIGHASTROMANCERSOLARIANEVENT: + m_auiEncounter[1] = data; + break; + case DATA_VOIDREAVEREVENT: + m_auiEncounter[2] = data; + break; + case DATA_KAELTHASEVENT: + KaelthasEventPhase = data; + m_auiEncounter[3] = data; + break; + } + if (data == DONE) + SaveToDB(); + } + + uint32 GetData(uint32 type) + { + switch(type) + { + case DATA_ALAREVENT: return AlarEventPhase; + case DATA_HIGHASTROMANCERSOLARIANEVENT: return m_auiEncounter[1]; + case DATA_VOIDREAVEREVENT: return m_auiEncounter[2]; + case DATA_KAELTHASEVENT: return KaelthasEventPhase; + } + return 0; + } + + std::string GetSaveData() + { + OUT_SAVE_INST_DATA; + std::ostringstream stream; + stream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3]; + char* out = new char[stream.str().length() + 1]; + strcpy(out, stream.str().c_str()); + if (out) + { + OUT_SAVE_INST_DATA_COMPLETE; + return out; + } + return NULL; + } + + void Load(const char* in) + { + if (!in) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } + OUT_LOAD_INST_DATA(in); + + std::istringstream stream(in); + stream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3]; + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + if (m_auiEncounter[i] == IN_PROGRESS) // Do not load an encounter as "In Progress" - reset it instead. + m_auiEncounter[i] = NOT_STARTED; + OUT_LOAD_INST_DATA_COMPLETE; + } + }; + + InstanceData* GetInstanceData(InstanceMap* pMap) const { - OUT_SAVE_INST_DATA_COMPLETE; - return out; + return new instance_the_eye_InstanceMapScript(pMap); } - return NULL; - } - - void Load(const char* in) - { - if (!in) - { - OUT_LOAD_INST_DATA_FAIL; - return; - } - OUT_LOAD_INST_DATA(in); - std::istringstream stream(in); - stream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3]; - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) // Do not load an encounter as "In Progress" - reset it instead. - m_auiEncounter[i] = NOT_STARTED; - OUT_LOAD_INST_DATA_COMPLETE; - } }; - -InstanceData* GetInstanceData_instance_the_eye(Map* pMap) -{ - return new instance_the_eye(pMap); -} - void AddSC_instance_the_eye() { - Script *newscript; - newscript = new Script; - newscript->Name = "instance_the_eye"; - newscript->GetInstanceData = &GetInstanceData_instance_the_eye; - newscript->RegisterSelf(); + new instance_mechanar; } diff --git a/src/server/scripts/Outland/TempestKeep/Eye/the_eye.cpp b/src/server/scripts/Outland/TempestKeep/Eye/the_eye.cpp index eb5e90bba90..8402f220e62 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/the_eye.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/the_eye.cpp @@ -30,71 +30,82 @@ EndContentData */ #include "ScriptPCH.h" #include "the_eye.h" -#define SPELL_COUNTERCHARGE 35035 -#define SPELL_KNOCKAWAY 22893 - -struct mob_crystalcore_devastatorAI : public ScriptedAI +enum eSpells { - mob_crystalcore_devastatorAI(Creature *c) : ScriptedAI(c) {} - - uint32 Knockaway_Timer; - uint32 Countercharge_Timer; - - void Reset() - { - Countercharge_Timer = 9000; - Knockaway_Timer = 25000; - } - - void EnterCombat(Unit * /*who*/) - { - } + SPELL_COUNTERCHARGE = 35035, + SPELL_KNOCKAWAY = 22893, +}; - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; +class mob_crystalcore_devastator : public CreatureScript +{ + public: - //Check if we have a current target - //Knockaway_Timer - if (Knockaway_Timer <= diff) + mob_crystalcore_devastator() + : CreatureScript("mob_crystalcore_devastator") { - DoCast(me->getVictim(), SPELL_KNOCKAWAY, true); - - // current aggro target is knocked away pick new target - Unit* pTarget = SelectUnit(SELECT_TARGET_TOPAGGRO, 0); - - if (!pTarget || pTarget == me->getVictim()) - pTarget = SelectUnit(SELECT_TARGET_TOPAGGRO, 1); - - if (pTarget) - me->TauntApply(pTarget); - - Knockaway_Timer = 23000; - } else Knockaway_Timer -= diff; - - //Countercharge_Timer - if (Countercharge_Timer <= diff) + } + struct mob_crystalcore_devastatorAI : public ScriptedAI { - DoCast(me, SPELL_COUNTERCHARGE); - Countercharge_Timer = 45000; - } else Countercharge_Timer -= diff; - - DoMeleeAttackIfReady(); - } + mob_crystalcore_devastatorAI(Creature* pCreature) : ScriptedAI(pCreature) {} + + uint32 Knockaway_Timer; + uint32 Countercharge_Timer; + + void Reset() + { + Countercharge_Timer = 9000; + Knockaway_Timer = 25000; + } + + void EnterCombat(Unit * /*who*/) + { + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + //Check if we have a current target + //Knockaway_Timer + if (Knockaway_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_KNOCKAWAY, true); + + // current aggro target is knocked away pick new target + Unit* pTarget = SelectUnit(SELECT_TARGET_TOPAGGRO, 0); + + if (!pTarget || pTarget == me->getVictim()) + pTarget = SelectUnit(SELECT_TARGET_TOPAGGRO, 1); + + if (pTarget) + me->TauntApply(pTarget); + + Knockaway_Timer = 23000; + } + else + Knockaway_Timer -= diff; + + //Countercharge_Timer + if (Countercharge_Timer <= diff) + { + DoCast(me, SPELL_COUNTERCHARGE); + Countercharge_Timer = 45000; + } + else + Countercharge_Timer -= diff; + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new mob_crystalcore_devastatorAI(creature); + } }; - -CreatureAI* GetAI_mob_crystalcore_devastator(Creature* pCreature) -{ - return new mob_crystalcore_devastatorAI (pCreature); -} - void AddSC_the_eye() { - Script *newscript; - newscript = new Script; - newscript->Name = "mob_crystalcore_devastator"; - newscript->GetAI = &GetAI_mob_crystalcore_devastator; - newscript->RegisterSelf(); + new mob_crystalcore_devastator(); } |
