void ChangeState(uint64 guid,bool active,bool finalphase)
 {
     Creature * creature = instance->GetCreature(guid);
     uint16 talkid;
     uint16 wayid;
     if (finalphase)
     {
         switch (creature->GetEntry())
         {
         case BOSS_FELUDIUS:
             talkid = SAY_PHASE3_FELUDIUS;
             wayid = WALK_FELUDIUS;
             break;
         }
         creature->AI()->Talk(talkid);
         creature->UpdateWaypointID(wayid);
     }
     if (active)
     {
         creature->RemoveAura(creature->GetAura(8611,guid));
     }
     else
     {
         creature->AddAura(8611,creature);
     }
 }
    void UpdateAI(const uint32 diff)
    {
        if (!pInstance)
            return;

        if (!VashjGUID)
            return;

        Creature *Vashj = Unit::GetCreature(*me, VashjGUID);

        if (move <= diff)
        {
            me->SetUnitMovementFlags(MOVEFLAG_WALK_MODE);
            if (phase == 1)
                me->GetMotionMaster()->MovePoint(0, x, y, z);
            if (phase == 1 && me->GetDistance(x,y,z) < 0.1f)
                phase = 2;
            if (phase == 2)
            {
                me->GetMotionMaster()->MovePoint(0, MIDDLE_X, MIDDLE_Y, MIDDLE_Z);
                phase = 3;
            }
            if (phase == 3)
            {
                me->GetMotionMaster()->MovePoint(0, MIDDLE_X, MIDDLE_Y, MIDDLE_Z);
                if (me->GetDistance(MIDDLE_X, MIDDLE_Y, MIDDLE_Z) < 3)
                {
                    SpellEntry *spell = (SpellEntry *)GetSpellStore()->LookupEntry(SPELL_SURGE);
                    if (spell)
                    {
                        for (uint8 i = 0; i < 3; ++i)
                        {
                            if (!spell->Effect[i])
                                continue;

                            if (Vashj)
                                Vashj->AddAura(new VashjSurgeAura(spell, i, NULL, Vashj, Vashj));
                        }
                    }
                    me->Kill(me);
                }
            }
            if (Vashj)
            {
                if (!Vashj->isInCombat() || CAST_AI(boss_lady_vashjAI, Vashj->AI())->Phase != 2 || Vashj->isDead())
                {
                    //call Unsummon()
                    me->Kill(me);
                }
            }
            move = 1000;
        } else move -= diff;
    }
        void DoWork()
        {
            switch (m_phase)
            {
            case 0: // Time: 07/03/2015 11:08:09.619
                if (Creature* npc_trigger = me->FindNearestCreature(50373, 20.0f))
                    if (m_npc = me->SummonCreature(50414, npc_trigger->GetPosition(), TEMPSUMMON_TIMED_DESPAWN, 40000))
                    {
                        Position pos = me->GetNearPosition(1.5f, 1.72f);
                        m_npc->GetMotionMaster()->MovePoint(0, pos, true);
                    }

                m_phase = 1;
                break;
            case 1: // Time: 07/03/2015 11:08:10.539
                Talk(0);
                m_timer = 3000;
                m_phase = 2;
                break;
            case 2: // Time: 07/03/2015 11:08:13.253 Number: 5796
                if (m_npc && m_npc->IsAlive())
                {
                    m_npc->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_KNEEL);
                    m_npc->SetFacingToObject(me);
                }

                m_timer = 750;
                m_phase = 3;
                break;
            case 3: // Time: 07/03/2015 11:08:14.080 Number: 5805
                me->HandleEmoteState(EMOTE_STATE_USE_STANDING);
                m_timer = 6000;
                m_phase = 4;
                break;
            case 4: // Time: 07/03/2015 11:08:20.133 Number: 5875
                me->HandleEmoteState(EMOTE_ONESHOT_NONE);
                m_timer = 750;
                m_phase = 5;
                break;
            case 5: // Time: 07/03/2015 11:08:21.350 Number: 5891
                me->HandleEmote(EMOTE_ONESHOT_POINT);
                m_timer = 2500;
                m_phase = 6;
                break;
            case 6: // Time: 07/03/2015 11:08:23.908 Number: 5934
                Talk(1);
                m_timer = 250;
                m_phase = 7;
                break;
            case 7: // 07/03/2015 11:08:24.189 Number: 5935
                if (m_npc && m_npc->IsAlive())
                {
                    m_npc->AddAura(93460, m_npc);
                    m_npc->CastSpell(m_npc, 93460);
                    m_npc->SetDisplayId(36775);
                    m_npc->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND);
                }

                m_timer = 2500;
                m_phase = 8;
                break;
            case 8: // Time: 07/03/2015 11:08:26.607 Number: 5967
                if (m_npc && m_npc->IsAlive())
                {
                    m_npc->HandleEmote(EMOTE_ONESHOT_TALK);
                    m_npc->AI()->Talk(0);
                }

                m_timer = 3750;
                m_phase = 9;
                break;
            case 9: // Time: 07/03/2015 11:08:30.257 Number: 6015
                if (m_npc && m_npc->IsAlive())
                    m_npc->HandleEmote(EMOTE_ONESHOT_SALUTE);

                m_timer = 2500;
                m_phase = 10;
                break;
            case 10: // Time: 07/03/2015 11:08:32.691 Number: 6043
                if (m_npc && m_npc->IsAlive())
                    m_npc->GetMotionMaster()->MovePath(5041401, false);

                m_timer = 45000;
                m_phase = 11;
                break;
            case 11: // Time: 07/03/2015 11:09:15.139 Number: 6405
                if (m_npc && m_npc->IsAlive())
                    m_npc->DespawnOrUnsummon();

                m_timer = urand(15000, 45000);;
                m_phase = 0;
                break;
            }
        }
        void UpdateAI(uint32 diff) 
        {
            if (timer <= diff)
            {

                if(eventStep == 0)
                {
                    timer = times[eventStep];

                    if (Player* target = me->FindNearestPlayer(40.0f, true))
                        if (target && target->GetDistance(me) < 35.0f  && !eventProcessed)
                        {
                            atramedes = me->FindNearestCreature(NPC_PRE_ATRAMEDES, 100.0f, true);
                            eventStep = 1;
                            eventProcessed = true;
                            nefarian = me->FindNearestCreature(NPC_PRE_NEFARIAN, 100.0f, true);
                            maloriak = me->FindNearestCreature(NPC_PRE_MALORIAK, 100.0f, true);
                            // Ghost visual.
                            atramedes->AddAura(SPELL_GHOST_VISUAL, atramedes);
                            nefarian->AddAura(SPELL_GHOST_VISUAL, nefarian);
                            maloriak->AddAura(SPELL_GHOST_VISUAL, maloriak);
                        }
                }else
                {
                    switch(eventStep)
                    {
                        // Nefarian
                    case 1:   nefarian->AI()->Talk(0);  break;
                    case 3:   nefarian->AI()->Talk(1);  break;
                    case 9:   nefarian->AI()->Talk(2);  break;
                    case 10:  nefarian->AI()->Talk(3);  break;
                    case 12:  nefarian->AI()->Talk(4);  break;
                    case 13:  nefarian->AI()->Talk(5);  break;
                    case 14:  nefarian->AI()->Talk(6);  break;

                        // Maloriak
                    case 2:   maloriak->AI()->Talk(0);  break;
                    case 4:   maloriak->AI()->Talk(1);  break;
                    case 5:   maloriak->AI()->Talk(2);  break;
                    case 6:   maloriak->AI()->Talk(3);  break;
                    case 7:   maloriak->AI()->Talk(4);  break;

                    case 8:
                        atramedes->AddAura(SPELL_GLOW_ORANGE, atramedes); 
                        atramedes->AddAura(SPELL_BLIND_WHELP, atramedes);
                        atramedes->GetMotionMaster()->MovePoint(0,121.493f, -225.428f, 75.4535f);
                        maloriak->AI()->Talk(5);
                        break;
                    case 11:
                        maloriak->AI()->Talk(6);
                        break;
                    case 15:
                        atramedes->RemoveAura(SPELL_GLOW_ORANGE);
                        atramedes->RemoveAura(SPELL_BLIND_WHELP);
                        maloriak->AI()->Talk(7);
                        break;

                    // Both
                    case 16:
                        atramedes->DespawnOrUnsummon();
                        nefarian->DespawnOrUnsummon();
                        maloriak->DespawnOrUnsummon();

                        if(GameObject* throne = me->FindNearestGameObject(GOB_NEFARIANS_THRONE, 100.0f))
                            throne->Delete();

                        me->DespawnOrUnsummon(100);
                        break;
                    }

                    timer = times[eventStep];

                    if(eventStep<16)
                        eventStep++;
                }

            } else timer -= diff;
        }
            void UpdateAI(const uint32 diff)
            {
                if (!UpdateVictim())
                    return;

                events.Update(diff);

                // Wise Mari don't rotate
                if (me->GetUInt32Value(UNIT_FIELD_TARGET))
                    me->SetUInt32Value(UNIT_FIELD_TARGET, 0);

                if (me->HasUnitState(UNIT_STATE_CASTING) && phase != 2)
                    return;

                while (uint32 eventId = events.ExecuteEvent())
                {
                    switch (eventId)
                    {
                        case EVENT_CALL_WATER:
                        {
                            if (phase != 1)
                                break;

                            Talk(TEXT_CALL_WATER);

                            Creature* trigger = me->GetCreature(*me, foutainTrigger[++foutainCount]);
                            if (trigger)
                            {
                                me->CastSpell(trigger, SPELL_CALL_WATER, true);
                                trigger->AddAura(SPELL_CORRUPTED_FOUTAIN, trigger);
                            }

                            if (foutainCount == 4)
                            {
                                phase = 2;
                                events.ScheduleEvent(EVENT_SWITCH_PHASE_TWO, TIMER_SWITCH_PHASE_TWO);
                                break;
                            }
                            events.ScheduleEvent(EVENT_CALL_WATER, TIMER_CALL_WATTER + rand() % 6000);
                            break;
                        }

                        case EVENT_HYDROLANCE_START:
                        {
                            if (phase != 1)
                                break;

                            float facing = 0.00f;
                            events.ScheduleEvent(EVENT_HYDROLANCE, TIMER_HYDROLANCE);
                            switch (hydrolancePhase)
                            {
                                case HYDROLANCE_BOTTOM:
                                    {
                                        std::list<Creature*> trigger;
                                        me->GetCreatureListWithEntryInGrid(trigger,CREATURE_HYDROLANCE_BOTTOM_TRIGGER, 50.0f);
                                        for (auto itr : trigger)
                                            itr->CastSpell(itr, SPELL_HYDROLANCE_PRECAST, true);
                                        facing = 1.23f;
                                        break;
                                    }
                                case HYDROLANCE_RIGHT:
                                    for (int i = 0; i < 5; i++)
                                        me->CastSpell(hydrolanceRightTrigger[i][0], hydrolanceRightTrigger[i][1], hydrolanceRightTrigger[i][2], SPELL_HYDROLANCE_PRECAST, true);
                                    facing = 3.55f;
                                    break;
                                case HYDROLANCE_LEFT:
                                    for (int i = 0; i < 5; i++)
                                        me->CastSpell(hydrolanceLeftTrigger[i][0], hydrolanceLeftTrigger[i][1], hydrolanceLeftTrigger[i][2], SPELL_HYDROLANCE_PRECAST, true);
                                    facing = 5.25f;
                                    break;
                            }
                            me->CastSpell(me, SPELL_HYDROLANCE_VISUAL, false);
                            me->UpdatePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), facing);
                            me->SetFacingTo(facing);
                            break;
                        }

                        case EVENT_HYDROLANCE:
                        {
                            if (phase != 1)
                                break;
                            switch (hydrolancePhase)
                            {
                                case HYDROLANCE_BOTTOM:
                                {
                                    std::list<Creature*> trigger;
                                    me->GetCreatureListWithEntryInGrid(trigger,CREATURE_HYDROLANCE_BOTTOM_TRIGGER, 50.0f);
                                    for (auto itr : trigger)
                                        itr->CastSpell(itr->GetPositionX(), itr->GetPositionY(), itr->GetPositionZ(), SPELL_HYDROLANCE_DMG_BOTTOM, true);
                                    break;
                                }
                                case HYDROLANCE_RIGHT:
                                    for (int i = 0; i < 5; i++)
                                        me->CastSpell(hydrolanceRightTrigger[i][0], hydrolanceRightTrigger[i][1], hydrolanceRightTrigger[i][2], SPELL_HYDROLANCE_DMG, true);
                                    break;
                                case HYDROLANCE_LEFT:
                                    for (int i = 0; i < 5; i++)
                                        me->CastSpell(hydrolanceLeftTrigger[i][0], hydrolanceLeftTrigger[i][1], hydrolanceLeftTrigger[i][2], SPELL_HYDROLANCE_DMG, true);
                                    break;
                            }

                            if( hydrolancePhase == HYDROLANCE_RIGHT)
                                hydrolancePhase = HYDROLANCE_BOTTOM;
                            else
                                hydrolancePhase++;

                            events.ScheduleEvent(EVENT_HYDROLANCE_START, TIMER_HYDROLANCE_START);
                            break;

                        }

                        case EVENT_SWITCH_PHASE_TWO:
                        {
                            if (phase !=2)
                                break;

                            Talk(TEXT_PHASE_SWITCH);

                            me->RemoveAurasDueToSpell(SPELL_WATER_BUBBLE);
                            float facing = me->GetOrientation();
                            facing += M_PI/48;

                            if(facing > M_PI*2)
                                facing -= M_PI*2;

                            //me->UpdatePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), facing);
                            me->SetOrientation(facing);
                            me->SetFacingTo(facing);
                            me->CastSpell(me, SPELL_WASH_AWAY, true);
                            events.ScheduleEvent(EVENT_WASH_AWAY, TIMER_WASH_AWAY);
                            break;
                        }

                        case EVENT_WASH_AWAY:
                        {
                            if (phase !=2)
                                break;

                            float facing = me->GetOrientation();
                            facing += M_PI/48;

                            if(facing > M_PI*2)
                                facing -= M_PI*2;

                            me->SetOrientation(facing);
                            me->SetFacingTo(facing);

                            events.ScheduleEvent(EVENT_WASH_AWAY, TIMER_WASH_AWAY);
                            break;
                        }
                    }
                }

            }