void UpdateAI(const uint32 diff) { if (!UpdateVictim() || me->HasUnitState(UNIT_STATE_CASTING) || !phase) return; if (m_uiPowerTimer <= diff) { if(instance) instance->NormaliseAltPower(); } else m_uiPowerTimer -= diff; if (m_berserkTimer <= diff) { DoCast(me, SPELL_BERSERK); m_berserkTimer = 600000; } else m_berserkTimer -= diff; if (Creature* firelord = me->FindNearestCreature(NPC_FIRE_LORD, 5.0f, true)) // Flame Lord near. { DoCast(me, SPELL_ABSORB_FIRE); firelord->DespawnOrUnsummon(); } if (Creature* shadowlord = me->FindNearestCreature(NPC_SHADOW_LORD, 5.0f, true)) // Shadow Lord near. { DoCast(me, SPELL_ABSORB_SHADOW); shadowlord->DespawnOrUnsummon(); } if (me->HealthBelowPct(26) && !phaseTwo) // Switch phase. { EnterPhaseTwo(); phaseTwo = true; } if (me->HealthBelowPct(3) && IsHeroic()&& !movedMid) // Heroic move mid before platform breaks. { movedMid = true; events.CancelEvent(EVENT_FURY_OF_CHOGALL); events.CancelEvent(EVENT_DARK_CREATIONS); events.CancelEvent(EVENT_CORR_OLD_GOD); events.CancelEvent(EVENT_SUMMON_TENTACLES); me->GetMotionMaster()->MovePoint(1, -1162.254f, -798.731f, 835.844f); } events.Update(diff); if (phase == PHASE_ONE) // First phase { std::list<Unit*> targets; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_CONVERSION: Talk(RAND(SAY_CONV_1, SAY_CONV_2, SAY_CONV_3)); SelectTargetList(targets, NonTankTargetSelector(me), RAID_MODE(1, 2, 2, 4), SELECT_TARGET_RANDOM); if (!targets.empty()) for (std::list<Unit*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) (*itr)->CastSpell(me, SPELL_WORSHIPPING, true); events.ScheduleEvent(EVENT_CONVERSION, urand(30000, 35000), PHASE_ONE); break; case EVENT_FLAME_ORDERS: DoCast(me, SPELL_FLAME_ORDERS); // just once. DoCast(me, SPELL_F_O_PERIODIC); // every 50 sec. break; case EVENT_SHADOW_ORDERS: DoCast(me, SPELL_SHADOW_ORDERS); // just once. DoCast(me, SPELL_S_O_PERIODIC); // every 50 sec. break; case EVENT_FURY_OF_CHOGALL: DoCast(me->GetVictim(), SPELL_FURY_OF_CHOGALL); events.ScheduleEvent(EVENT_FURY_OF_CHOGALL, urand(45000, 49000), PHASE_ONE); break; case EVENT_SUMMON_ADHERENT: Talk(SAY_ADHERENT); Talk(RAND(SAY_ADHER_1, SAY_ADHER_2, SAY_ADHER_3)); DoCast(me, SPELL_SUM_ADHER_SE); // Needs script. events.ScheduleEvent(EVENT_SUMMON_ADHERENT, 90000, PHASE_ONE); break; case EVENT_FESTER_BLOOD: DoCast(me, SPELL_FESTER_BLOOD); // Needs script. events.ScheduleEvent(EVENT_FESTER_BLOOD, 130000, PHASE_ONE); break; } } } else if (phase == PHASE_TWO) // Second phase { std::list<Unit*> targets; if (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_FURY_OF_CHOGALL: DoCast(me->GetVictim(), SPELL_FURY_OF_CHOGALL); events.ScheduleEvent(EVENT_FURY_OF_CHOGALL, urand(45000, 49000), PHASE_TWO); break; case EVENT_DARK_CREATIONS: Talk(RAND(SAY_DARKCR_1, SAY_DARKCR_2, SAY_DARKCR_3, SAY_DARKCR_4, SAY_DARKCR_5)); DoCast(me, SPELL_DARK_CREAT_VIS); for (int i = 0; i < 4; i++) me->SummonCreature(NPC_DARKENED_CREATION, TentacleLocations[i].GetPositionX(), TentacleLocations[i].GetPositionY(), TentacleLocations[i].GetPositionZ(), TEMPSUMMON_CORPSE_DESPAWN); events.ScheduleEvent(EVENT_DARK_CREATIONS, urand(28000, 34000), PHASE_TWO); break; case EVENT_CORR_OLD_GOD: // Needs script. if(Creature* trigger = me->FindNearestCreature(NPC_CHOGALL_COG_TRIGGER, 200.0f, true)) trigger->CastSpell(trigger, SPELL_CORR_OLD_GOD, true); break; case EVENT_SUMMON_TENTACLES: if(Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) me->SummonCreature(NPC_SPIKED_TENTACLE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0.0f, TEMPSUMMON_MANUAL_DESPAWN); events.ScheduleEvent(EVENT_SUMMON_TENTACLES, urand(30000, 35000), PHASE_TWO); break; } } } DoMeleeAttackIfReady(); }
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; } } } }