void UpdateAI(uint32 diff) { if (!UpdateVictim() || me->HasUnitState(UNIT_STATE_CASTING)) return; if (!phase) return; if (m_uiPowerTimer <= diff) { instance->NormaliseAltPower(); } else m_uiPowerTimer -= diff; events.Update(diff); if (phase == PHASE_GROUND) // Ground phase { ThreatContainer::StorageType const &threatlist = me->getThreatManager().getThreatList(); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_AGGRO_NEF: if (Creature* nefarianHelperheroic = me->FindNearestCreature(NPC_NEFARIAN_HELPER_HEROIC, 150.0f, true)) nefarianHelperheroic->AI()->Talk(28); return; case EVENT_SONAR_PULSE: DoCast(me, SPELL_SONAR_PULSE); me->SummonCreature(NPC_SONAR_PULSES, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 1.5f, TEMPSUMMON_TIMED_DESPAWN, 30000); me->SummonCreature(NPC_SONAR_PULSES, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 3.0f, TEMPSUMMON_TIMED_DESPAWN, 30000); me->SummonCreature(NPC_SONAR_PULSES, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 4.5f, TEMPSUMMON_TIMED_DESPAWN, 30000); me->SummonCreature(NPC_SONAR_PULSES, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 6.0f, TEMPSUMMON_TIMED_DESPAWN, 30000); events.ScheduleEvent(EVENT_SONAR_PULSE, 50000); break; case EVENT_MODULATION: DoCast(me, SPELL_MODULATION); for (ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr) if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) unit->SetPower(POWER_ALTERNATE_POWER, unit->GetPower(POWER_ALTERNATE_POWER) + 7); events.ScheduleEvent(EVENT_MODULATION, 20000); break; case EVENT_SONIC_BREATH: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) { target->AddAura(SPELL_TRACKING, target); DoCast(target, SPELL_SONIC_BREATH); } events.ScheduleEvent(EVENT_REMOVE_TRACKING, 8500); events.ScheduleEvent(EVENT_SONIC_BREATH, 40000); break; case EVENT_REMOVE_TRACKING: if(instance) instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_TRACKING); return; case EVENT_SEARING_FLAMES: Talk(SAY_SEARING); DoCast(me, SPELL_SEARING_FLAMES); events.ScheduleEvent(EVENT_SEARING_FLAMES, 50000); break; case EVENT_LIFTOFF: Talk(SAY_AIR_PHASE); me->HandleEmote(EMOTE_ONESHOT_LIFTOFF); me->SetDisableGravity(true); events.ScheduleEvent(EVENT_FLIGHT, 1500); events.ScheduleEvent(EVENT_AIR, 2000); return; case EVENT_FLIGHT: me->SetReactState(REACT_PASSIVE); me->AttackStop(); me->GetMotionMaster()->MovePoint(1, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 20.0f); return; case EVENT_AIR: EnterPhaseAir(); return; case EVENT_FIEND: me->SummonCreature(NPC_OBNOXIOUS_FIEND, 93.767f, -224.105f, 74.911f, 6.26f, TEMPSUMMON_CORPSE_DESPAWN, 3000); if (Creature* nefarianHelperheroic = me->FindNearestCreature(NPC_NEFARIAN_HELPER_HEROIC, 150.0f, true)) nefarianHelperheroic->AI()->Talk(27); events.ScheduleEvent(EVENT_FIEND, 38500); break; } } DoMeleeAttackIfReady(); } else if (phase == PHASE_FLIGHT) // Air phase { std::list<Unit*> targets; ThreatContainer::StorageType const &m_threatlist = me->getThreatManager().getThreatList(); // if has vertigo, remove all roaring flame npc's wait 8 sec then get player who rang gong. if (me->HasAura(SPELL_VERTIGO)) events.ScheduleEvent(EVENT_ROARING_FLAME_SUMMON, 8000, PHASE_FLIGHT); if (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_ROARING_FLAME_SUMMON: for (ThreatContainer::StorageType::const_iterator i = m_threatlist.begin(); i != m_threatlist.end(); ++i) { Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid()); if (unit && unit->HasAura(SPELL_NOISY)) // You rang? :) { me->SummonCreature(NPC_ROARING_FLAME_TARGET, unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 30000); } else { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) me->SummonCreature(NPC_ROARING_FLAME_TARGET, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 30000); } } events.ScheduleEvent(EVENT_ROARING_FLAME, 500); return; case EVENT_ROARING_FLAME: if (Unit* roaring = me->FindNearestCreature(NPC_ROARING_FLAME_TARGET, 100.0f)) DoCast(roaring, SPELL_ROARING_FLAME_BREATH_DUMMY); return; case EVENT_SONAR_BOMB: SelectTargetList(targets, RAID_MODE(3, 6), SELECT_TARGET_RANDOM, 100.0f, true); if (!targets.empty()) for (std::list<Unit*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) DoCast(*itr, SPELL_SONAR_BOMB); events.ScheduleEvent(EVENT_SONAR_BOMB, 18000); break; case EVENT_LAND: me->HandleEmote(EMOTE_ONESHOT_LAND); me->SetDisableGravity(false); events.ScheduleEvent(EVENT_RETURN, 1000); events.ScheduleEvent(EVENT_GROUND, 1500); return; case EVENT_RETURN: me->SetReactState(REACT_PASSIVE); me->AttackStop(); me->GetMotionMaster()->MovePoint(1, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() - 20.0f); return; case EVENT_GROUND: EnterPhaseGround(); return; } } } }
void UpdateAI(const uint32 diff) { if (!UpdateVictim() || me->HasUnitState(UNIT_STATE_CASTING)) return; if (Creature* Onyxia = me->FindNearestCreature(NPC_ONYXIA, 150.0f, true)) if (Onyxia && !Onyxia->isInCombat() && said == false) { Talk(SAY_AVOID_WIPE); said = true; } if (phase == PHASE_GROUND && m_uiDistanceCheckTimer <= diff) { if (me->FindNearestCreature(NPC_ONYXIA, 50.0f, true) && onyxiaAlive && !me->HasAura(SPELL_CHILDREN_OF_DEATHWING_ONY)) me->AddAura(SPELL_CHILDREN_OF_DEATHWING_ONY, me); else if (!me->FindNearestCreature(NPC_ONYXIA, 50.0f, true) && onyxiaAlive) if(me->HasAura(SPELL_CHILDREN_OF_DEATHWING_ONY)) me->RemoveAura(SPELL_CHILDREN_OF_DEATHWING_ONY); m_uiDistanceCheckTimer = 5000; } else m_uiDistanceCheckTimer -= diff; if (phase == PHASE_GROUND && m_uiOnyxiaCheckTimer <= diff && !secondPhase) { if (me->FindNearestCreature(NPC_ONYXIA, 150.0f, true)) onyxiaAlive = true; else { onyxiaAlive = false; Talk(SAY_AIR_PHASE); if(me->HasAura(SPELL_CHILDREN_OF_DEATHWING_ONY)) me->RemoveAura(SPELL_CHILDREN_OF_DEATHWING_ONY); events.ScheduleEvent(EVENT_LIFTOFF, 5000, PHASE_GROUND); secondPhase = true; } m_uiOnyxiaCheckTimer = 5000; } else m_uiOnyxiaCheckTimer -= diff; if (phase == PHASE_FLIGHT && m_uiChromaticCheckTimer <= diff && !finalPhase) { if (!me->FindNearestCreature(NPC_CHROMATIC_PROTO, 150.0f, true)) events.ScheduleEvent(EVENT_LAND, 2000, PHASE_FLIGHT); finalPhase = true; m_uiChromaticCheckTimer = 5000; } else m_uiChromaticCheckTimer -= diff; events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_ELECTROCUTE: if(electrocute == true) { DoCast(me, SPELL_ELECTROCUTE); electrocute = false; } break; case EVENT_INTRO: me->HandleEmote(EMOTE_ONESHOT_LIFTOFF); me->SetDisableGravity(true); me->SendMovementFlagUpdate(); me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02); me->GetMotionMaster()->MovePoint(1, -126.518f, -233.342f, 36.358f); // Position on top of raid. break; case EVENT_INTRO2: Talk(SAY_AGGRO); events.ScheduleEvent(EVENT_HAIL_OF_BONES, 100); break; case EVENT_HAIL_OF_BONES: DoCast(me, SPELL_HAIL_OF_BONES); break; case EVENT_MOVE: me->GetMotionMaster()->MovePoint(1, -100.123f, -221.522f, 7.156f); // Move down. events.ScheduleEvent(EVENT_LANDING, 8000); break; case EVENT_LANDING: me->HandleEmote(EMOTE_ONESHOT_LAND); me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02); me->SetDisableGravity(false); me->SendMovementFlagUpdate(); EnterPhaseGround(); me->GetMotionMaster()->MoveChase(me->GetVictim()); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); break; case EVENT_SHADOWFLAME_BREATH: Talk(SAY_SHADOWFLAME); DoCastVictim(SPELL_SHADOWFLAME_BREATH); events.ScheduleEvent(EVENT_SHADOWFLAME_BREATH, urand(10000, 12000)); break; case EVENT_SHADOW_COWARDICE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) DoCast(target, SPELL_SHADOW_COWARDICE); events.ScheduleEvent(EVENT_SHADOW_COWARDICE, urand(9000, 10000)); break; case EVENT_LIFTOFF: Talk(SAY_AIR_PHASE_2); if(GameObject* elevator = me->FindNearestGameObject(207834, 200.0f)) elevator->SetGoState(GO_STATE_READY); me->HandleEmote(EMOTE_ONESHOT_LIFTOFF); me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02); me->SetDisableGravity(true); me->SendMovementFlagUpdate(); events.ScheduleEvent(EVENT_FLIGHT, 1500); events.ScheduleEvent(EVENT_AIR, 2000); break; case EVENT_FLIGHT: me->SetReactState(REACT_PASSIVE); me->AttackStop(); me->GetMotionMaster()->MovePoint(1, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 30.0f); break; case EVENT_AIR: EnterPhaseAir(); break; case EVENT_SUMMON_CHROMATIC: me->SummonCreature(NPC_CHROMATIC_PROTO, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN); break; case EVENT_SHADOWFLAME_BARRAGE: if(Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true)) DoCast(target, SPELL_SHADOWFLAME_BARRAGE); events.ScheduleEvent(EVENT_SHADOWFLAME_BARRAGE, urand(8000, 11000)); break; case EVENT_LAND: me->HandleEmote(EMOTE_ONESHOT_LAND); me->SetDisableGravity(false); me->SendMovementFlagUpdate(); me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02); events.ScheduleEvent(EVENT_RETURN, 1000); events.ScheduleEvent(EVENT_GROUND, 1500); break; case EVENT_RETURN: me->SetReactState(REACT_PASSIVE); me->AttackStop(); me->GetMotionMaster()->MovePoint(1, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() - 30.0f); break; case EVENT_GROUND: EnterPhaseFinal(); me->SetReactState(REACT_AGGRESSIVE); AttackStart(me->GetVictim()); me->GetMotionMaster()->MoveChase(me->GetVictim()); if(GameObject* elevator = me->FindNearestGameObject(207834, 200.0f)) elevator->SetGoState(GO_STATE_ACTIVE); Talk(SAY_FINAL_PHASE); break; case EVENT_TAIL_LASH: DoCast(me, SPELL_TAIL_LASH); events.ScheduleEvent(EVENT_TAIL_LASH, urand(8000, 11000)); break; case EVENT_SHADOWBLAZE: if(Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true)) DoCast(target, SPELL_SHADOWBLAZE_SPARK); events.ScheduleEvent(EVENT_TAIL_LASH, urand(18000, 21000)); break; case EVENT_REVIVE_SKELETONS: { std::list<Creature*> creatures; GetCreatureListWithEntryInGrid(creatures, me, 41918, 200.0f); if (!creatures.empty()) for (std::list<Creature*>::iterator iter = creatures.begin(); iter != creatures.end(); ++iter) { DoCast((*iter), SPELL_ANIMATE_BONES, true); (*iter)->SetReactState(REACT_AGGRESSIVE); (*iter)->RemoveAura(SPELL_DIE_VISUAL); } } break; } } if (phase == PHASE_GROUND || phase == PHASE_FINAL) DoMeleeAttackIfReady(); }