Exemple #1
0
        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;
                    }
                }
            }            
        }