void JustReachedHome() override { // Allow real Halion to evade if (m_pInstance) { if (Creature* pHalion = m_pInstance->GetSingleCreatureFromStorage(NPC_HALION_REAL)) pHalion->AI()->EnterEvadeMode(); } }
void JustDied(Unit* /*pKiller*/) override { // ToDo: handle the damage sharing! DoScriptText(SAY_DEATH, m_creature); // Allow real Halion to remove all phase aura from player. if (m_pInstance) { if (Creature* pHalion = m_pInstance->GetSingleCreatureFromStorage(NPC_HALION_REAL)) m_creature->AI()->SendAIEvent(AI_EVENT_CUSTOM_A, m_creature, pHalion); } }
void DoPrepareTwilightPhase() { if (!m_pInstance) return; // Spawn the orbs and the carriers. Use the twilight Halion version to preserve the phase if (Creature* pHalion = m_pInstance->GetSingleCreatureFromStorage(NPC_HALION_TWILIGHT)) { // Set current Halion hp pHalion->SetHealth(m_creature->GetHealth()); // NOTE: the spawn coords seem to be totally off, compared to the actual map layout - requires additional research!!! // Spawn the rotation focus first // pHalion->SummonCreature(NPC_ORB_ROTATION_FOCUS, aRotationFocusPosition[0], aRotationFocusPosition[1], aRotationFocusPosition[2], aRotationFocusPosition[3], TEMPSPAWN_DEAD_DESPAWN, 0); // Then spawn the orb carriers and the shadow orbs. ToDo: research if it's possible to make this dynamic // pHalion->SummonCreature(NPC_ORB_CARRIER, aOrbCarrierPosition1[0], aOrbCarrierPosition1[1], aOrbCarrierPosition1[2], 0, TEMPSPAWN_DEAD_DESPAWN, 0); // pHalion->SummonCreature(NPC_ORB_CARRIER, aOrbCarrierPosition2[0], aOrbCarrierPosition2[1], aOrbCarrierPosition2[2], 0, TEMPSPAWN_DEAD_DESPAWN, 0); // pHalion->SummonCreature(NPC_SHADOW_ORB_1, aOrbCarrierPosition1[0], aOrbCarrierPosition1[1], aOrbCarrierPosition1[2], 0, TEMPSPAWN_DEAD_DESPAWN, 0); // pHalion->SummonCreature(NPC_SHADOW_ORB_2, aOrbCarrierPosition2[0], aOrbCarrierPosition2[1], aOrbCarrierPosition2[2], 0, TEMPSPAWN_DEAD_DESPAWN, 0); } }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; switch (m_uiPhase) { case PHASE_PHISYCAL_REALM: // nothing here - phase not handled by this npc break; case PHASE_BOTH_REALMS: // ToDo: handle corporeality // no break; case PHASE_TWILIGHT_REALM: if (m_uiTailLashTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_TAIL_LASH) == CAST_OK) m_uiTailLashTimer = urand(15000, 25000); } else m_uiTailLashTimer -= uiDiff; if (m_uiCleaveTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK) m_uiCleaveTimer = urand(10000, 15000); } else m_uiCleaveTimer -= uiDiff; if (m_uiDarkBreathTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_DARK_BREATH) == CAST_OK) m_uiDarkBreathTimer = urand(15000, 20000); } else m_uiDarkBreathTimer -= uiDiff; if (m_uiSoulConsumptionTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_SOUL_CONSUMPTION, SELECT_FLAG_PLAYER)) { if (DoCastSpellIfCan(pTarget, SPELL_SOUL_CONSUMPTION) == CAST_OK) m_uiSoulConsumptionTimer = 25000; } } else m_uiSoulConsumptionTimer -= uiDiff; // Switch to phase 3 if (m_creature->GetHealthPercent() < 50.0f && m_uiPhase == PHASE_TWILIGHT_REALM) { if (DoCastSpellIfCan(m_creature, SPELL_TWILIGHT_DIVISION, CAST_INTERRUPT_PREVIOUS) == CAST_OK) { if (m_pInstance) { // ToDo: Update world states and spawn the exit portals // Set the real Halion health, so it can also begin phase 3 if (Creature* pHalion = m_pInstance->GetSingleCreatureFromStorage(NPC_HALION_REAL)) pHalion->SetHealth(m_creature->GetHealth()); } DoScriptText(SAY_PHASE_3, m_creature); m_uiPhase = PHASE_BOTH_REALMS; } } break; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiBerserkTimer) { if (m_uiBerserkTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_BERSERK) == CAST_OK) { // Do the same for the Twilight halion if (m_pInstance) { if (Creature* pHalion = m_pInstance->GetSingleCreatureFromStorage(NPC_HALION_TWILIGHT, true)) pHalion->CastSpell(pHalion, SPELL_BERSERK, TRIGGERED_OLD_TRIGGERED); } DoScriptText(SAY_BERSERK, m_creature); m_uiBerserkTimer = 0; } } else m_uiBerserkTimer -= uiDiff; } switch (m_uiPhase) { case PHASE_BOTH_REALMS: // ToDo: handle corporeality // no break; case PHASE_PHISYCAL_REALM: if (m_uiTailLashTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_TAIL_LASH) == CAST_OK) m_uiTailLashTimer = urand(15000, 25000); } else m_uiTailLashTimer -= uiDiff; if (m_uiCleaveTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK) m_uiCleaveTimer = urand(10000, 15000); } else m_uiCleaveTimer -= uiDiff; if (m_uiFlameBreathTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_FLAME_BREATH) == CAST_OK) m_uiFlameBreathTimer = urand(15000, 20000); } else m_uiFlameBreathTimer -= uiDiff; if (m_uiFieryCombustionTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_FIERY_COMBUSTION, SELECT_FLAG_PLAYER)) { if (DoCastSpellIfCan(pTarget, SPELL_FIERY_COMBUSTION) == CAST_OK) m_uiFieryCombustionTimer = 25000; } } else m_uiFieryCombustionTimer -= uiDiff; if (m_uiMeteorTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) { if (DoCastSpellIfCan(pTarget, SPELL_METEOR_SUMMON) == CAST_OK) { DoScriptText(SAY_FIREBALL, m_creature); m_uiMeteorTimer = 40000; } } } else m_uiMeteorTimer -= uiDiff; // Switch to phase 2 if (m_creature->GetHealthPercent() < 75.0f && m_uiPhase == PHASE_PHISYCAL_REALM) { if (DoCastSpellIfCan(m_creature, SPELL_TWILIGHT_PHASING, CAST_INTERRUPT_PREVIOUS) == CAST_OK) { DoCastSpellIfCan(m_creature, SPELL_SUMMON_PORTAL, CAST_TRIGGERED); DoScriptText(SAY_PHASE_2, m_creature); DoPrepareTwilightPhase(); m_uiPhase = PHASE_TWILIGHT_REALM; } } break; case PHASE_TWILIGHT_REALM: // Switch to phase 3 if (m_creature->GetHealthPercent() < 50.0f) { m_creature->RemoveAurasDueToSpell(SPELL_TWILIGHT_PHASING); DoScriptText(SAY_PHASE_3, m_creature); m_uiPhase = PHASE_BOTH_REALMS; } break; } DoMeleeAttackIfReady(); }