diff --git a/src/game/AI/ScriptDevAI/scripts/outland/tempest_keep/the_eye/boss_kaelthas.cpp b/src/game/AI/ScriptDevAI/scripts/outland/tempest_keep/the_eye/boss_kaelthas.cpp index 80a1d6d513..a9138174c2 100644 --- a/src/game/AI/ScriptDevAI/scripts/outland/tempest_keep/the_eye/boss_kaelthas.cpp +++ b/src/game/AI/ScriptDevAI/scripts/outland/tempest_keep/the_eye/boss_kaelthas.cpp @@ -256,6 +256,13 @@ enum KaelThasActions KAEL_ACTION_MELEE_MODE, KAEL_ACTION_FIREBALL, KAEL_ACTION_MAX, + KAEL_PHASE_ONE, + KAEL_PHASE_TWO, + KAEL_PHASE_THREE, + KAEL_PHASE_TRANSITION, + KAEL_PHASE_TRANSITION_GROWTH, + KAEL_PHASE_TRANSITION_NETHER_BEAM, + KAEL_WEAPON_ATTACK, }; struct boss_kaelthasAI : public CombatAI @@ -263,6 +270,17 @@ struct boss_kaelthasAI : public CombatAI boss_kaelthasAI(Creature* creature) : CombatAI(creature, KAEL_ACTION_MAX), m_instance(static_cast(creature->GetInstanceData())) { AddOnKillText(SAY_SLAY1, SAY_SLAY2, SAY_SLAY3); +#ifdef FAST_TIMERS + AddCustomAction(KAEL_PHASE_ONE, 5000u, [&]() { HandlePhaseOne(); }, TIMER_COMBAT_COMBAT); +#else + AddCustomAction(KAEL_PHASE_ONE, 23000u, [&]() { HandlePhaseOne(); }, TIMER_COMBAT_COMBAT); +#endif + AddCustomAction(KAEL_WEAPON_ATTACK, true, [&]() { HandleWeaponAttack(); }, TIMER_COMBAT_COMBAT); + AddCustomAction(KAEL_PHASE_TWO, true, [&]() { HandlePhaseTwo(); }, TIMER_COMBAT_COMBAT); + AddCustomAction(KAEL_PHASE_THREE, true, [&]() { HandlePhaseThree(); }, TIMER_COMBAT_COMBAT); + AddCustomAction(KAEL_PHASE_TRANSITION, true, [&]() { HandlePhaseTransition(); }, TIMER_COMBAT_COMBAT); + AddCustomAction(KAEL_PHASE_TRANSITION_GROWTH, true, [&]() { HandlePhaseTransitionGrowth(); }, TIMER_COMBAT_COMBAT); + AddCustomAction(KAEL_PHASE_TRANSITION_NETHER_BEAM, true, [&]() { HandlePhaseTransitionNetherBeam(); }, TIMER_COMBAT_COMBAT); } ScriptedInstance* m_instance; @@ -283,16 +301,12 @@ struct boss_kaelthasAI : public CombatAI uint32 m_uiNetherVaporTimer; uint8 m_uiGravityIndex; - uint32 m_uiPhaseTimer; uint8 m_uiPhase; uint8 m_uiPhaseSubphase; - uint32 m_phaseTransitionTimer; uint32 m_phaseTransitionStage; - uint32 m_phaseTransitionGrowthTimer; uint32 m_phaseTransitionGrowthStage; - uint32 m_phaseTransitionPureNetherBeamTimer; uint32 m_phaseTransitionPureNetherBeamStage; GuidVector m_worldTriggersFirstStage; @@ -302,7 +316,6 @@ struct boss_kaelthasAI : public CombatAI GuidVector m_netherVapor; GuidList m_summonedGuidList; GuidVector m_weapons; - uint32 m_weaponAttackTimer; GuidSet m_charmTargets; @@ -312,14 +325,13 @@ struct boss_kaelthasAI : public CombatAI void Reset() override { + CombatAI::Reset(); // Phases m_uiPhase = PHASE_0_NOT_BEGUN; #ifdef FAST_TIMERS m_uiPhaseSubphase = 0; - m_uiPhaseTimer = 5000; #else m_uiPhaseSubphase = 0; - m_uiPhaseTimer = 23000; #endif // Spells @@ -338,13 +350,10 @@ struct boss_kaelthasAI : public CombatAI m_uiNetherVaporTimer = 10000; m_uiGravityIndex = 0; - m_phaseTransitionGrowthTimer = 0; m_phaseTransitionGrowthStage = 0; m_phaseTransitionPureNetherBeamStage = 0; - m_phaseTransitionPureNetherBeamTimer = 0; - m_phaseTransitionTimer = 0; m_phaseTransitionStage = 0; m_attackDistance = 30.0f; @@ -482,7 +491,7 @@ struct boss_kaelthasAI : public CombatAI default: // Weapons { m_weapons.push_back(summoned->GetObjectGuid()); - m_weaponAttackTimer = 2000; + ResetTimer(KAEL_WEAPON_ATTACK, 2000); summoned->AI()->SetReactState(REACT_PASSIVE); summoned->SetCorpseDelay(60); break; @@ -501,14 +510,14 @@ struct boss_kaelthasAI : public CombatAI DoCastSpellIfCan(m_creature, i, CAST_TRIGGERED); m_uiPhase = PHASE_2_WEAPON; + uint32 timer = 120000; #ifdef FAST_TIMERS - m_uiPhaseTimer = 10000; -#else - m_uiPhaseTimer = 120000; -#endif -#ifdef PRENERF_2_0_3 - m_uiPhaseTimer = 90000; // very early pre 2.1 - 90s (90000), later 120s (120000); + timer = 10000; +#elseif PRENERF_2_0_3 + timer = 90000; // very early pre 2.1 - 90s (90000), later 120s (120000); #endif + ResetTimer(KAEL_PHASE_TWO, timer); + } } @@ -546,7 +555,7 @@ struct boss_kaelthasAI : public CombatAI DoBroadcastText(SAY_PHASE5_NUTS, m_creature); m_creature->SetFacingTo(3.176499f); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE); - m_phaseTransitionTimer = 2000; + ResetTimer(KAEL_PHASE_TRANSITION, 2000); if (m_worldTriggersFirstStage.empty()) { @@ -600,9 +609,9 @@ struct boss_kaelthasAI : public CombatAI // Handle phase 1 end if (uiEntry == NPC_TELONICUS) - m_uiPhaseTimer = 3000; + ResetTimer(KAEL_PHASE_ONE, 3000); else - m_uiPhaseTimer = 1000; + ResetTimer(KAEL_PHASE_ONE, 1000); } void ExecuteActions() @@ -641,6 +650,7 @@ struct boss_kaelthasAI : public CombatAI m_creature->GetMotionMaster()->MovePoint(POINT_ID_CENTER, aCenterPos[0], aCenterPos[1], aCenterPos[2], FORCED_MOVEMENT_RUN); + ResetTimer(KAEL_PHASE_TRANSITION, 30000); m_uiPhase = PHASE_TRANSITION; m_actionReadyStatus[i] = false; return; @@ -817,189 +827,315 @@ struct boss_kaelthasAI : public CombatAI } } - void UpdateAI(const uint32 uiDiff) override + void HandlePhaseOne() { - switch (m_uiPhase) - { - // ***** Advisors phase ******** - case PHASE_1_ADVISOR: - { - if (!m_uiPhaseTimer) - return; - - if (m_uiPhaseTimer <= uiDiff) - { - if (!m_instance) - return; + if (!m_instance) + return; - switch (m_uiPhaseSubphase) - { - case 0: - DoBroadcastText(SAY_INTRO_THALADRED, m_creature); + uint32 timer = 0; + switch (m_uiPhaseSubphase) + { + case 0: + DoBroadcastText(SAY_INTRO_THALADRED, m_creature); #ifdef FAST_TIMERS - m_uiPhaseTimer = 1000; + timer = 1000; #else - m_uiPhaseTimer = 7000; + timer = 7000; #endif - break; - case 1: - if (Creature* advisor = m_instance->GetSingleCreatureFromStorage(NPC_THALADRED)) - { - advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PLAYER); - advisor->SetInCombatWithZone(); - advisor->AI()->AttackClosestEnemy(); - } - m_uiPhaseTimer = 0; - break; - case 2: - DoBroadcastText(SAY_INTRO_SANGUINAR, m_creature); + break; + case 1: + if (Creature* advisor = m_instance->GetSingleCreatureFromStorage(NPC_THALADRED)) + { + advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PLAYER); + advisor->SetInCombatWithZone(); + advisor->AI()->AttackClosestEnemy(); + } + break; + case 2: + DoBroadcastText(SAY_INTRO_SANGUINAR, m_creature); #ifdef FAST_TIMERS - m_uiPhaseTimer = 1000; + timer = 1000; #else - m_uiPhaseTimer = 12500; + timer = 12500; #endif - break; - case 3: - if (Creature* advisor = m_instance->GetSingleCreatureFromStorage(NPC_SANGUINAR)) - { - advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PLAYER); - advisor->SetInCombatWithZone(); - advisor->AI()->AttackClosestEnemy(); - } - m_uiPhaseTimer = 0; - break; - case 4: - DoBroadcastText(SAY_INTRO_CAPERNIAN, m_creature); + break; + case 3: + if (Creature* advisor = m_instance->GetSingleCreatureFromStorage(NPC_SANGUINAR)) + { + advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PLAYER); + advisor->SetInCombatWithZone(); + advisor->AI()->AttackClosestEnemy(); + } + break; + case 4: + DoBroadcastText(SAY_INTRO_CAPERNIAN, m_creature); #ifdef FAST_TIMERS - m_uiPhaseTimer = 1000; + timer = 1000; #else - m_uiPhaseTimer = 7000; + timer = 7000; #endif - break; - case 5: - if (Creature* advisor = m_instance->GetSingleCreatureFromStorage(NPC_CAPERNIAN)) - { - advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PLAYER); - advisor->SetInCombatWithZone(); - advisor->AI()->AttackClosestEnemy(); - } - m_uiPhaseTimer = 0; - break; - case 6: - DoBroadcastText(SAY_INTRO_TELONICUS, m_creature); + break; + case 5: + if (Creature* advisor = m_instance->GetSingleCreatureFromStorage(NPC_CAPERNIAN)) + { + advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PLAYER); + advisor->SetInCombatWithZone(); + advisor->AI()->AttackClosestEnemy(); + } + break; + case 6: + DoBroadcastText(SAY_INTRO_TELONICUS, m_creature); #ifdef FAST_TIMERS - m_uiPhaseTimer = 1000; + timer = 1000; #else - m_uiPhaseTimer = 8400; + timer = 8400; #endif - break; - case 7: - if (Creature* advisor = m_instance->GetSingleCreatureFromStorage(NPC_TELONICUS)) - { - advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PLAYER); - advisor->SetInCombatWithZone(); - advisor->AI()->AttackClosestEnemy(); - } - m_uiPhaseTimer = 0; - break; - case 8: - if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_WEAPONS) == CAST_OK) - DoBroadcastText(SAY_PHASE2_WEAPON, m_creature); - m_uiPhaseTimer = 0; - break; - } - - ++m_uiPhaseSubphase; + break; + case 7: + if (Creature* advisor = m_instance->GetSingleCreatureFromStorage(NPC_TELONICUS)) + { + advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PLAYER); + advisor->SetInCombatWithZone(); + advisor->AI()->AttackClosestEnemy(); } - else - m_uiPhaseTimer -= uiDiff; - break; - } + case 8: + if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_WEAPONS) == CAST_OK) + DoBroadcastText(SAY_PHASE2_WEAPON, m_creature); + break; + } + + ++m_uiPhaseSubphase; + if (timer) + ResetTimer(KAEL_PHASE_ONE, timer); + } - // ***** Weapons phase ******** - case PHASE_2_WEAPON: + void HandleWeaponAttack() + { + for (ObjectGuid& guid : m_weapons) + { + if (Creature* weapon = m_creature->GetMap()->GetCreature(guid)) { - if (m_weaponAttackTimer) // attack delay for weapons - { - if (m_weaponAttackTimer <= uiDiff) - { - m_weaponAttackTimer = 0; - for (ObjectGuid& guid : m_weapons) - { - if (Creature* weapon = m_creature->GetMap()->GetCreature(guid)) - { - weapon->AI()->SetReactState(REACT_AGGRESSIVE); - weapon->SetInCombatWithZone(); - weapon->AI()->AttackClosestEnemy(); - } - } - } - else - m_weaponAttackTimer -= uiDiff; - } + weapon->AI()->SetReactState(REACT_AGGRESSIVE); + weapon->SetInCombatWithZone(); + weapon->AI()->AttackClosestEnemy(); + } + } + } - if (m_uiPhaseTimer <= uiDiff) // Start text and set delay for rezzurect + void HandlePhaseTwo() + { + DoBroadcastText(SAY_PHASE3_ADVANCE, m_creature); + m_uiPhase = PHASE_3_ADVISOR_ALL; + m_uiPhaseSubphase = 0; +#ifdef FAST_TIMERS + ResetTimer(KAEL_PHASE_TWO, 1000); +#else + ResetTimer(KAEL_PHASE_TWO, 6000); +#endif + } + + void HandlePhaseThree() + { + uint32 timer = 0; + switch (m_uiPhaseSubphase) + { + case 0: + { + // Rezzurect all advisors + if (DoCastSpellIfCan(m_creature, SPELL_RESURRECTION) == CAST_OK) { - DoBroadcastText(SAY_PHASE3_ADVANCE, m_creature); - m_uiPhase = PHASE_3_ADVISOR_ALL; - m_uiPhaseSubphase = 0; + m_uiPhaseSubphase = 1; #ifdef FAST_TIMERS - m_uiPhaseTimer = 1000; + timer = 10000; +#elseif PRENERF_2_0_3 + timer = 120000; #else - m_uiPhaseTimer = 6000; + timer = 180000; #endif } - else - m_uiPhaseTimer -= uiDiff; - break; } + case 1: + { + DoBroadcastText(SAY_PHASE4_INTRO2, m_creature); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE); + DoResetThreat(); + SetCombatScriptStatus(false); + SetCombatMovement(true, true); + m_uiPhase = PHASE_4_SOLO; + m_uiPhaseSubphase = 0; + break; + } + } + if (timer) + ResetTimer(KAEL_PHASE_THREE, timer); + } - // ***** All advisors phase ******** - case PHASE_3_ADVISOR_ALL: + void HandlePhaseTransition() + { + uint32 timer = 0; + switch (m_phaseTransitionStage) + { + case 0: { - if (m_uiPhaseTimer <= uiDiff) - { - switch (m_uiPhaseSubphase) - { - case 0: - { - // Rezzurect all advisors - if (DoCastSpellIfCan(m_creature, SPELL_RESURRECTION) == CAST_OK) - { - m_uiPhaseSubphase = 1; -#ifdef FAST_TIMERS - m_uiPhaseTimer = 10000; + m_creature->CastSpell(nullptr, SPELL_KAEL_GAIN_POWER, TRIGGERED_NONE); + m_creature->PlayDirectSound(SOUND_PHASE_TRANSITION1); + m_creature->PlayDirectSound(SOUND_PHASE_TRANSITION2); + + timer = 1000; + m_phaseTransitionStage = 1; + break; + } + case 1: + { + m_creature->SetLevitate(true); + m_creature->SetHover(true); + m_creature->GetMotionMaster()->MovePoint(POINT_ID_AIR, flightPos[0], flightPos[1], flightPos[2], FORCED_MOVEMENT_WALK); + m_phaseTransitionStage = 2; + timer = 16000; + ResetTimer(KAEL_PHASE_TRANSITION_GROWTH, 500); + break; + } + case 2: + { + m_creature->RemoveAurasDueToSpell(SPELL_KAEL_GAIN_POWER); + m_creature->RemoveAurasDueToSpell(SPELL_NETHERBEAM_GLOW3); + m_creature->CastSpell(nullptr, SPELL_EXPLODE, TRIGGERED_NONE); + m_creature->RemoveAurasDueToSpell(SPELL_NETHERBEAM_EXPLODE); + m_creature->RemoveAurasDueToSpell(SPELL_NETHERBEAM); + m_instance->DoUseDoorOrButton(GO_KAEL_STATUE_RIGHT); + m_instance->DoUseDoorOrButton(GO_BRIDGE_WINDOW); + m_instance->DoUseDoorOrButton(GO_KAEL_STATUE_LEFT); +#ifdef FAST_TRANSITION_TIMERS + timer = 500; #else - m_uiPhaseTimer = 180000; + timer = 13500; + ResetTimer(KAEL_PHASE_TRANSITION_NETHER_BEAM, 4000); #endif -#ifdef PRENERF_2_0_3 - m_uiPhaseTimer = 120000; + m_phaseTransitionStage = 3; + break; + } + case 3: + { + m_creature->RemoveAurasDueToSpell(SPELL_KAEL_STUN); + m_creature->RemoveAurasDueToSpell(SPELL_FLOATING_DROWNED); + m_creature->SetOrientation(3.228787f); + m_creature->CastSpell(nullptr, SPELL_KAEL_FULL_POWER, TRIGGERED_NONE); +#ifdef FAST_TRANSITION_TIMERS + timer = 2000; +#else + timer = 3500; #endif - } - break; - } - case 1: - { - DoBroadcastText(SAY_PHASE4_INTRO2, m_creature); - m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE); - DoResetThreat(); - SetCombatScriptStatus(false); - SetCombatMovement(true, true); - m_uiPhase = PHASE_4_SOLO; - m_uiPhaseTimer = 30000; - m_uiPhaseSubphase = 0; - break; - } - } + m_phaseTransitionStage = 4; + break; + } + case 4: + { + m_creature->GetMotionMaster()->MovePoint(POINT_ID_LAND, landPos[0], landPos[1], landPos[2], FORCED_MOVEMENT_WALK); + break; + } + } + if (timer) + ResetTimer(KAEL_PHASE_THREE, timer); + } + + void HandlePhaseTransitionGrowth() + { + static uint32 timers[] = { 3600,400,2000,400,4500,4000,4000,4000,0 }; + switch (m_phaseTransitionGrowthStage) + { + case 0: + { + if (Creature* trigger = m_creature->GetMap()->GetCreature(m_worldTriggersFirstStage[0])) + trigger->CastSpell(nullptr, SPELL_NETHERBEAM_EXPLODE, TRIGGERED_NONE); + if (Creature* trigger = m_creature->GetMap()->GetCreature(m_worldTriggersFirstStage[1])) + trigger->CastSpell(nullptr, SPELL_NETHERBEAM, TRIGGERED_NONE); + break; + } + case 1: + { + if (Creature* trigger = m_creature->GetMap()->GetCreature(m_worldTriggersFirstStage[2])) + trigger->CastSpell(nullptr, SPELL_NETHERBEAM, TRIGGERED_NONE); + break; + } + case 2: + { + if (Creature* trigger = m_creature->GetMap()->GetCreature(m_worldTriggersFirstStage[3])) + trigger->CastSpell(nullptr, SPELL_NETHERBEAM_EXPLODE, TRIGGERED_NONE); + break; + } + case 3: + { + if (Creature* trigger = m_creature->GetMap()->GetCreature(m_worldTriggersFirstStage[4])) + trigger->CastSpell(nullptr, SPELL_NETHERBEAM, TRIGGERED_NONE); + break; + } + case 4: + { + if (Creature* trigger = m_creature->GetMap()->GetCreature(m_worldTriggersFirstStage[5])) + trigger->CastSpell(nullptr, SPELL_NETHERBEAM_EXPLODE, TRIGGERED_NONE); + break; + } + case 5: // explosions + case 6: + case 7: + case 8: + { + uint32 spellId; + switch (m_phaseTransitionGrowthStage) + { + case 5: spellId = SPELL_EXPLODE_4; break; + case 6: spellId = SPELL_EXPLODE_2; break; + case 7: spellId = SPELL_EXPLODE_3; break; + case 8: spellId = SPELL_EXPLODE_1; break; } - else - m_uiPhaseTimer -= uiDiff; + for (ObjectGuid& guid : m_worldTriggersExplosions) + if (Creature* trigger = m_creature->GetMap()->GetCreature(guid)) + trigger->CastSpell(nullptr, spellId, TRIGGERED_NONE); break; } + } + uint32 timer = timers[m_phaseTransitionGrowthStage]; + if (timer) + ResetTimer(KAEL_PHASE_TRANSITION_GROWTH, timer); + ++m_phaseTransitionGrowthStage; + } + + void HandlePhaseTransitionNetherBeam() + { + switch (m_phaseTransitionPureNetherBeamStage % 3) + { + case 0: + for (uint32 i = 0; i < TRIGGERS_GROUP_ONE; ++i) + if (urand(0, 1)) // 50% chance per trigger + if (Creature* trigger = m_creature->GetMap()->GetCreature(m_worldTriggersSecondStage[groupOneIndices[i]])) + trigger->CastSpell(nullptr, triggerSpellIds[groupOneIndices[i]], TRIGGERED_NONE); + break; + case 1: + for (uint32 i = 0; i < TRIGGERS_GROUP_TWO; ++i) + if (urand(0, 1)) // 50% chance per trigger + if (Creature* trigger = m_creature->GetMap()->GetCreature(m_worldTriggersSecondStage[groupTwoIndices[i]])) + trigger->CastSpell(nullptr, triggerSpellIds[groupTwoIndices[i]], TRIGGERED_NONE); + break; + case 2: + for (uint32 i = 0; i < TRIGGERS_GROUP_THREE; ++i) + if (urand(0, 1)) // 50% chance per trigger + if (Creature* trigger = m_creature->GetMap()->GetCreature(m_worldTriggersSecondStage[groupThreeIndices[i]])) + trigger->CastSpell(nullptr, triggerSpellIds[groupThreeIndices[i]], TRIGGERED_NONE); + break; + } + ++m_phaseTransitionPureNetherBeamStage; + if (m_phaseTransitionPureNetherBeamStage < 30) // 30 pure nether beam cycles on retail + ResetTimer(KAEL_PHASE_TRANSITION_NETHER_BEAM, 400); + } + + void UpdateAI(const uint32 uiDiff) override + { + switch (m_uiPhase) + { // ***** Solo phases ******** case PHASE_4_SOLO: case PHASE_5_GRAVITY: @@ -1154,184 +1290,6 @@ struct boss_kaelthasAI : public CombatAI DoMeleeAttackIfReady(); break; } - // ***** Phase transition ******** - case PHASE_TRANSITION: - { - // Handle phase 4 to 5 transition - if (m_phaseTransitionTimer) - { - if (m_phaseTransitionTimer <= uiDiff) - { - switch (m_phaseTransitionStage) - { - case 0: - { - m_creature->CastSpell(nullptr, SPELL_KAEL_GAIN_POWER, TRIGGERED_NONE); - m_creature->PlayDirectSound(SOUND_PHASE_TRANSITION1); - m_creature->PlayDirectSound(SOUND_PHASE_TRANSITION2); - m_uiPhaseTimer = 0; - - m_phaseTransitionTimer = 1000; - m_phaseTransitionStage = 1; - break; - } - case 1: - { - m_creature->SetLevitate(true); - m_creature->SetHover(true); - m_creature->GetMotionMaster()->MovePoint(POINT_ID_AIR, flightPos[0], flightPos[1], flightPos[2], FORCED_MOVEMENT_WALK); - m_phaseTransitionTimer = 0; - m_phaseTransitionStage = 2; - m_phaseTransitionTimer = 16000; - m_phaseTransitionGrowthTimer = 500; - break; - } - case 2: - { - m_creature->RemoveAurasDueToSpell(SPELL_KAEL_GAIN_POWER); - m_creature->RemoveAurasDueToSpell(SPELL_NETHERBEAM_GLOW3); - m_creature->CastSpell(nullptr, SPELL_EXPLODE, TRIGGERED_NONE); - m_creature->RemoveAurasDueToSpell(SPELL_NETHERBEAM_EXPLODE); - m_creature->RemoveAurasDueToSpell(SPELL_NETHERBEAM); - m_instance->DoUseDoorOrButton(GO_KAEL_STATUE_RIGHT); - m_instance->DoUseDoorOrButton(GO_BRIDGE_WINDOW); - m_instance->DoUseDoorOrButton(GO_KAEL_STATUE_LEFT); -#ifdef FAST_TRANSITION_TIMERS - m_phaseTransitionTimer = 500; -#else - m_phaseTransitionTimer = 13500; - m_phaseTransitionPureNetherBeamTimer = 4000; // start pure nether beams -#endif - m_phaseTransitionStage = 3; - break; - } - case 3: - { - m_creature->RemoveAurasDueToSpell(SPELL_KAEL_STUN); - m_creature->RemoveAurasDueToSpell(SPELL_FLOATING_DROWNED); - m_creature->SetOrientation(3.228787f); - m_creature->CastSpell(nullptr, SPELL_KAEL_FULL_POWER, TRIGGERED_NONE); -#ifdef FAST_TRANSITION_TIMERS - m_phaseTransitionTimer = 2000; -#else - m_phaseTransitionTimer = 3500; -#endif - m_phaseTransitionStage = 4; - break; - } - case 4: - { - m_creature->GetMotionMaster()->MovePoint(POINT_ID_LAND, landPos[0], landPos[1], landPos[2], FORCED_MOVEMENT_WALK); - m_phaseTransitionTimer = 0; - break; - } - } - } - else - m_phaseTransitionTimer -= uiDiff; - } - - if (m_phaseTransitionGrowthTimer) - { - if (m_phaseTransitionGrowthTimer <= uiDiff) - { - static uint32 timers[] = { 3600,400,2000,400,4500,4000,4000,4000,0 }; - switch (m_phaseTransitionGrowthStage) - { - case 0: - { - if (Creature* trigger = m_creature->GetMap()->GetCreature(m_worldTriggersFirstStage[0])) - trigger->CastSpell(nullptr, SPELL_NETHERBEAM_EXPLODE, TRIGGERED_NONE); - if (Creature* trigger = m_creature->GetMap()->GetCreature(m_worldTriggersFirstStage[1])) - trigger->CastSpell(nullptr, SPELL_NETHERBEAM, TRIGGERED_NONE); - break; - } - case 1: - { - if (Creature* trigger = m_creature->GetMap()->GetCreature(m_worldTriggersFirstStage[2])) - trigger->CastSpell(nullptr, SPELL_NETHERBEAM, TRIGGERED_NONE); - break; - } - case 2: - { - if (Creature* trigger = m_creature->GetMap()->GetCreature(m_worldTriggersFirstStage[3])) - trigger->CastSpell(nullptr, SPELL_NETHERBEAM_EXPLODE, TRIGGERED_NONE); - break; - } - case 3: - { - if (Creature* trigger = m_creature->GetMap()->GetCreature(m_worldTriggersFirstStage[4])) - trigger->CastSpell(nullptr, SPELL_NETHERBEAM, TRIGGERED_NONE); - break; - } - case 4: - { - if (Creature* trigger = m_creature->GetMap()->GetCreature(m_worldTriggersFirstStage[5])) - trigger->CastSpell(nullptr, SPELL_NETHERBEAM_EXPLODE, TRIGGERED_NONE); - break; - } - case 5: // explosions - case 6: - case 7: - case 8: - { - uint32 spellId; - switch (m_phaseTransitionGrowthStage) - { - case 5: spellId = SPELL_EXPLODE_4; break; - case 6: spellId = SPELL_EXPLODE_2; break; - case 7: spellId = SPELL_EXPLODE_3; break; - case 8: spellId = SPELL_EXPLODE_1; break; - } - - for (ObjectGuid& guid : m_worldTriggersExplosions) - if (Creature* trigger = m_creature->GetMap()->GetCreature(guid)) - trigger->CastSpell(nullptr, spellId, TRIGGERED_NONE); - break; - } - } - m_phaseTransitionGrowthTimer = timers[m_phaseTransitionGrowthStage]; - ++m_phaseTransitionGrowthStage; - } - else m_phaseTransitionGrowthTimer -= uiDiff; - } - - if (m_phaseTransitionPureNetherBeamTimer) - { - if (m_phaseTransitionPureNetherBeamTimer <= uiDiff) - { - switch (m_phaseTransitionPureNetherBeamStage % 3) - { - case 0: - for (uint32 i = 0; i < TRIGGERS_GROUP_ONE; ++i) - if (urand(0, 1)) // 50% chance per trigger - if (Creature* trigger = m_creature->GetMap()->GetCreature(m_worldTriggersSecondStage[groupOneIndices[i]])) - trigger->CastSpell(nullptr, triggerSpellIds[groupOneIndices[i]], TRIGGERED_NONE); - break; - case 1: - for (uint32 i = 0; i < TRIGGERS_GROUP_TWO; ++i) - if (urand(0, 1)) // 50% chance per trigger - if (Creature* trigger = m_creature->GetMap()->GetCreature(m_worldTriggersSecondStage[groupTwoIndices[i]])) - trigger->CastSpell(nullptr, triggerSpellIds[groupTwoIndices[i]], TRIGGERED_NONE); - break; - case 2: - for (uint32 i = 0; i < TRIGGERS_GROUP_THREE; ++i) - if (urand(0, 1)) // 50% chance per trigger - if (Creature* trigger = m_creature->GetMap()->GetCreature(m_worldTriggersSecondStage[groupThreeIndices[i]])) - trigger->CastSpell(nullptr, triggerSpellIds[groupThreeIndices[i]], TRIGGERED_NONE); - break; - } - - ++m_phaseTransitionPureNetherBeamStage; - if (m_phaseTransitionPureNetherBeamStage < 30) // 30 pure nether beam cycles on retail - m_phaseTransitionPureNetherBeamTimer = std::max(0, 400 - int32(uiDiff)); // need to roll over timer to achieve blizzlike behaviour - else - m_phaseTransitionPureNetherBeamTimer = 0; - } - else m_phaseTransitionPureNetherBeamTimer -= uiDiff; - } - break; - } } } };