void UpdateAI(const uint32 diff)
    {
        if (!UpdateVictim())
            return;

        if (ShadowBoltVolley_Timer < diff)
        {
            DoCast(me,SPELL_SHADOWBOLT_VOLLEY);
            ShadowBoltVolley_Timer = 15000;
        }
        else
            ShadowBoltVolley_Timer -= diff;

        if (HeroicMode && banish_Timer < diff)
        {
            Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0,30,false);
            if (target)
            {
                DoCast(target,SPELL_BANISH);
                banish_Timer = 16000;
            }
        }
        else
            banish_Timer -= diff;

        if ( DrawShadows_Timer < diff)
        {
            Map *map = me->GetMap();
            Map::PlayerList const &PlayerList = map->GetPlayers();
            for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                if (Player* i_pl = i->getSource())
                    if (i_pl->isAlive() && !i_pl->HasAura(SPELL_BANISH,0) && !i_pl->isGameMaster())
                        i_pl->TeleportTo(me->GetMapId(), VorpilPosition[0],VorpilPosition[1],VorpilPosition[2], 0, TELE_TO_NOT_LEAVE_COMBAT);

            me->Relocate(VorpilPosition[0],VorpilPosition[1],VorpilPosition[2]);
            DoCast(me,SPELL_DRAW_SHADOWS,true);

            DoCast(me,HeroicMode?H_SPELL_RAIN_OF_FIRE:SPELL_RAIN_OF_FIRE);

            ShadowBoltVolley_Timer = 6000;
            DrawShadows_Timer = 30000;
        }
        else
            DrawShadows_Timer -= diff;

        if ( summonTraveler_Timer < diff)
        {
            spawnVoidTraveler();
            summonTraveler_Timer = 10000;
            //enrage at 20%
            if((me->GetHealth()*5) < me->GetMaxHealth())
                summonTraveler_Timer = 5000;
        }
        else
            summonTraveler_Timer -=diff;

        DoMeleeAttackIfReady();
    }
            void UpdateAI(uint32 diff) override
            {
                if (!UpdateVictim())
                    return;

                events.Update(diff);

                if (me->HasUnitState(UNIT_STATE_CASTING))
                    return;

                while (uint32 eventId = events.ExecuteEvent())
                {
                    switch (eventId)
                    {
                        case EVENT_SHADOWBOLT_VOLLEY:
                            DoCast(me, SPELL_SHADOWBOLT_VOLLEY);
                            events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, urand(15000, 30000));
                            break;
                        case EVENT_BANISH:
                            if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, false))
                                 DoCast(target, SPELL_BANISH);
                            events.ScheduleEvent(EVENT_BANISH, 16000);
                            break;
                        case EVENT_DRAW_SHADOWS:
                            {
                                Map::PlayerList const &PlayerList = me->GetMap()->GetPlayers();
                                for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                                    if (Player* i_pl = i->GetSource())
                                        if (i_pl->IsAlive() && !i_pl->HasAura(SPELL_BANISH))
                                            i_pl->TeleportTo(me->GetMapId(), VorpilPosition.GetPositionX(), VorpilPosition.GetPositionY(), VorpilPosition.GetPositionZ(), VorpilPosition.GetOrientation(), TELE_TO_NOT_LEAVE_COMBAT);

                                me->SetPosition(VorpilPosition);
                                DoCast(me, SPELL_DRAW_SHADOWS, true);
                                DoCast(me, SPELL_RAIN_OF_FIRE);
                                events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, 6000);
                                events.ScheduleEvent(EVENT_DRAW_SHADOWS, 30000);
                                break;
                            }
                        case EVENT_SUMMON_TRAVELER:
                            spawnVoidTraveler();
                            events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 10000);
                            // enrage at 20%
                            if (HealthBelowPct(20))
                                events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 5000);
                            break;
                    }

                    if (me->HasUnitState(UNIT_STATE_CASTING))
                        return;
                }

                DoMeleeAttackIfReady();
            }
        void UpdateAI(uint32 const diff)
        {
            if (!UpdateVictim())
                return;

            if (ShadowBoltVolley_Timer <= diff)
            {
                DoCast(me, SPELL_SHADOWBOLT_VOLLEY);
                ShadowBoltVolley_Timer = 15000 + rand()%15000;
            } else ShadowBoltVolley_Timer -= diff;

            if (IsHeroic() && banish_Timer <= diff)
            {
                Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 30, false);
                if (pTarget)
                {
                    DoCast(pTarget, SPELL_BANISH);
                    banish_Timer = 16000;
                }
            } else banish_Timer -= diff;

            if (DrawShadows_Timer <= diff)
            {
                Map* pMap = me->GetMap();
                Map::PlayerList const &PlayerList = pMap->GetPlayers();
                for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                    if (Player* i_pl = i->getSource())
                        if (i_pl->isAlive() && !i_pl->HasAura(SPELL_BANISH))
                            i_pl->TeleportTo(me->GetMapId(), VorpilPosition[0], VorpilPosition[1], VorpilPosition[2], 0, TELE_TO_NOT_LEAVE_COMBAT);

                me->GetMap()->CreatureRelocation(me, VorpilPosition[0], VorpilPosition[1], VorpilPosition[2], 0.0f);
                DoCast(me, SPELL_DRAW_SHADOWS, true);

                DoCast(me, SPELL_RAIN_OF_FIRE);

                ShadowBoltVolley_Timer = 6000;
                DrawShadows_Timer = 30000;
            } else DrawShadows_Timer -= diff;

            if (summonTraveler_Timer <= diff)
            {
                spawnVoidTraveler();
                summonTraveler_Timer = 10000;
                //enrage at 20%
                if (HealthBelowPct(20))
                    summonTraveler_Timer = 5000;
            } else summonTraveler_Timer -=diff;

            DoMeleeAttackIfReady();
        }
        void UpdateAI(uint32 diff)
        {
            if (!UpdateVictim())
                return;

            events.Update(diff);
            switch (events.GetEvent())
            {
                case EVENT_SPELL_SHADOWBOLT:
                    me->CastSpell(me, SPELL_SHADOWBOLT_VOLLEY, false);
                    events.RepeatEvent(urand(15000, 30000));
                    break;
                case EVENT_SPELL_BANISH:
                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30, false))
                        me->CastSpell(target, SPELL_BANISH, false);
                    events.RepeatEvent(16000);
                    break;
                case EVENT_SUMMON_TRAVELER:
                    spawnVoidTraveler();
                    events.RepeatEvent(HealthBelowPct(20) ? 5000: 10000);
                    break;
                case EVENT_SPELL_DRAWSHADOWS:
                {
                    Map* map = me->GetMap();
                    Map::PlayerList const &PlayerList = map->GetPlayers();
                    for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                        if (Player* player = i->GetSource())
                            if (player->IsAlive() && !player->HasAura(SPELL_BANISH))
                                player->TeleportTo(me->GetMapId(), VorpilPosition[0], VorpilPosition[1], VorpilPosition[2], 0, TELE_TO_NOT_LEAVE_COMBAT);

                    me->NearTeleportTo(VorpilPosition[0], VorpilPosition[1], VorpilPosition[2], 0.0f);
                    me->CastSpell(me, SPELL_DRAW_SHADOWS, true);
                    me->CastSpell(me, SPELL_RAIN_OF_FIRE_N);

                    events.RepeatEvent(24000);
                    events.DelayEvents(6000);
                    break;
                }
            }

            DoMeleeAttackIfReady();
        }
    void UpdateAI(const uint32 diff)
    {

        if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
            return;
        
        if (!sumportals)
        if (sumportals_Timer < diff)
        {
            DoScriptText(SAY_HELP, m_creature);
            summonPortals();
            sumportals_Timer = 1000000;
                    
        }else sumportals_Timer -= diff;

        if (ShadowBoltVolley_Timer < diff)
        {
            DoCast(m_creature,SPELL_SHADOWBOLT_VOLLEY);
            ShadowBoltVolley_Timer = 15000;
        }else ShadowBoltVolley_Timer -= diff;

        if ( DrawnShadows_Timer < diff)
        {
            DoTeleportAll(VorpilPosition[0][0],VorpilPosition[0][1],VorpilPosition[0][2],0);
            m_creature->Relocate(VorpilPosition[0][0],VorpilPosition[0][1],VorpilPosition[0][2],0);
            DoCast(m_creature,SPELL_DRAWN_SHADOWS,true);

            if(!HeroicMode) DoCast(m_creature,SPELL_RAIN_OF_FIRE);
            else DoCast(m_creature,H_SPELL_RAIN_OF_FIRE);

            ShadowBoltVolley_Timer = 6000;
            DrawnShadows_Timer = 45000;    
        }else DrawnShadows_Timer -= diff;

        if ( summonTraveler_Timer < diff)
        {
            spawnVoidTraveler();
            summonTraveler_Timer = 10000;
        }else summonTraveler_Timer -=diff;

        DoMeleeAttackIfReady();
    }