DragonFire / Dragon

TrinityCore Open Source MMO Framework
http://www.dragonfire-bg.net
GNU General Public License v2.0
28 stars 23 forks source link

Ulduar - Mimiron(Part 2) #1459

Closed TheWhiteShadow closed 10 years ago

TheWhiteShadow commented 11 years ago
                       Продължение на Решението:

{ if (!(rand()%5)) if (instance) if (Creature _pMimiron = me->GetCreature(_me, instance->GetData64(DATA_MIMIRON))) { if (phase == PHASE_LEVIATHAN_SOLO) DoScriptText(RAND(SAY_MKII_SLAY_1, SAY_MKII_SLAY_2), pMimiron); else DoScriptText(RAND(SAY_V07TRON_SLAY_1, SAY_V07TRON_SLAY_2), pMimiron); } }

    void DamageTaken(Unit *who, uint32 &damage)
    {
        if (phase == PHASE_LEVIATHAN_SOLO)
            if (damage >= me->GetHealth())
            {
                damage = 0;
                me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
                me->AttackStop();
                me->SetReactState(REACT_PASSIVE);
                me->RemoveAllAuras();
                me->SetHealth(me->GetMaxHealth());
                events.SetPhase(PHASE_NULL);
                phase = PHASE_NULL;
                if (Creature *pMimiron = me->GetCreature(*me, instance->GetData64(DATA_MIMIRON)))
                    pMimiron->AI()->DoAction(DO_ACTIVATE_VX001);
                if (Creature *turret = CAST_CRE(me->GetVehicleKit()->GetPassenger(3)))
                    turret->Kill(turret, false);
                me->SetSpeed(MOVE_RUN, 1.5f, true);
                me->GetMotionMaster()->MovePoint(0, 2790.11f, 2595.83f, 364.32f);
            }

        if (phase == PHASE_LEVIATHAN_ASSEMBLED)
            if (damage >= me->GetHealth())
            {
                damage = 0;
                me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
                me->AttackStop();
                me->SetReactState(REACT_PASSIVE);
                me->RemoveAllAuras();
                me->SetHealth(me->GetMaxHealth());
                me->SetStandState(UNIT_STAND_STATE_DEAD);
                events.SetPhase(PHASE_NULL);
                phase = PHASE_NULL;
                if (Creature *pMimiron = me->GetCreature(*me, instance->GetData64(DATA_MIMIRON)))
                    pMimiron->AI()->DoAction(DO_ACTIVATE_DEATH_TIMER);
            }
    }

    void EnterCombat(Unit *who)
    {
        if (MimironHardMode)
        {
            DoCast(me, SPELL_EMERGENCY_MODE);
            events.ScheduleEvent(EVENT_FLAME_SUPPRESSANT, 60000, 0, PHASE_LEVIATHAN_SOLO);
        }

        if (Creature *turret = CAST_CRE(me->GetVehicleKit()->GetPassenger(3)))
        {
            turret->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
            turret->SetReactState(REACT_AGGRESSIVE);
            turret->AI()->DoZoneInCombat();
        }

        events.ScheduleEvent(EVENT_PROXIMITY_MINE, 1000);
        events.ScheduleEvent(EVENT_PLASMA_BLAST, 10000, 0, PHASE_LEVIATHAN_SOLO);
    }

    void DoAction(const int32 action)
    {
        switch(action)
        {
            case DO_START_ENCOUNTER:
                me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
                me->SetReactState(REACT_AGGRESSIVE);
                phase = PHASE_LEVIATHAN_SOLO;
                events.SetPhase(PHASE_LEVIATHAN_SOLO);
                DoZoneInCombat();
                break;
            case DO_LEVIATHAN_ASSEMBLED:
                if (MimironHardMode)
                    DoCast(me, SPELL_EMERGENCY_MODE);
                me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
                me->SetReactState(REACT_AGGRESSIVE);
                me->SetHealth(int32(me->GetMaxHealth() / 2));
                me->SetSpeed(MOVE_RUN, 1.0f, true);
                me->SetStandState(UNIT_STAND_STATE_STAND);
                phase = PHASE_LEVIATHAN_ASSEMBLED;
                events.SetPhase(PHASE_LEVIATHAN_ASSEMBLED);
                events.RescheduleEvent(EVENT_PROXIMITY_MINE, 1000);
                events.RescheduleEvent(EVENT_SHOCK_BLAST, 30000);
                break;
            case DO_ENTER_ENRAGE:
                DoCast(me, SPELL_BERSERK, true);
                break;
        }
    }

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

        events.Update(diff);

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

        if (phase == PHASE_LEVIATHAN_SOLO || phase == PHASE_LEVIATHAN_ASSEMBLED)
        {
            while (uint32 eventId = events.ExecuteEvent())
            {
                switch(eventId)
                {
                    case EVENT_PROXIMITY_MINE:
                        for (int i = 0; i < 10; i++)
                            DoCast(SPELL_MINES_SPAWN);
                        DoCast(SPELL_PROXIMITY_MINES);
                        events.RescheduleEvent(EVENT_PROXIMITY_MINE, 35000);
                        break;
                    case EVENT_PLASMA_BLAST:
                        me->MonsterTextEmote(EMOTE_LEVIATHAN, 0, true);
                        DoCast(SPELL_PLASMA_BLAST);
                        events.RescheduleEvent(EVENT_PLASMA_BLAST, urand(30000, 35000), 0, PHASE_LEVIATHAN_SOLO);
                        events.RescheduleEvent(EVENT_SHOCK_BLAST, urand(6000, 10000));
                        break;
                    case EVENT_SHOCK_BLAST:
                        DoCastAOE(SPELL_SHOCK_BLAST);
                        events.RescheduleEvent(EVENT_SHOCK_BLAST, 35000);
                        break;
                    case EVENT_FLAME_SUPPRESSANT:
                        DoCastAOE(SPELL_FLAME_SUPPRESSANT_1);
                        for (int8 n = 0; n < 2; n++)
                        {
                            uint32 npc;
                            if (n == 0)
                                npc = NPC_FLAME;
                            else 
                                npc = NPC_FLAME_SPREAD;
                            std::list<Creature*> m_pCreatures;
                            GetCreatureListWithEntryInGrid(m_pCreatures, me, npc, 100);
                            if (!m_pCreatures.empty())
                                for(std::list<Creature*>::iterator iter = m_pCreatures.begin(); iter != m_pCreatures.end(); ++iter)
                                    (*iter)->ForcedDespawn(3000);
                        }
                        events.CancelEvent(EVENT_FLAME_SUPPRESSANT);
                        break;
                }
            }
        }

        DoMeleeAttackIfReady();
    }
};

};

class boss_leviathan_mk_turret : public CreatureScript { public: boss_leviathan_mk_turret() : CreatureScript("boss_leviathan_mk_turret") { }

CreatureAI* GetAI(Creature* pCreature) const
{
    return new boss_leviathan_mk_turretAI (pCreature);
}

struct boss_leviathan_mk_turretAI : public ScriptedAI
{
    boss_leviathan_mk_turretAI(Creature *c) : ScriptedAI(c) 
    {
        me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
        me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_GRIP, true);
        uiNapalmShell = urand(4000, 8000);
    }

    uint32 uiNapalmShell;

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

        if (uiNapalmShell <= diff)
        {
            if (Unit *pTarget = SelectTarget(SELECT_TARGET_FARTHEST, 0))
                if (!me->IsWithinDist(pTarget, 12))
                    DoCast(pTarget, SPELL_NAPALM_SHELL);
            uiNapalmShell = urand(8000, 12000);
        }
        else uiNapalmShell -= diff;
    }
};

};

class npc_proximity_mine : public CreatureScript { public: npc_proximity_mine() : CreatureScript("npc_proximity_mine") { }

CreatureAI* GetAI(Creature* pCreature) const
{
    return new npc_proximity_mineAI (pCreature);
}

struct npc_proximity_mineAI : public Scripted_NoMovementAI
{
    npc_proximity_mineAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature)
    {
       me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
       uiBoomTimer = 35000;
       Boom = false;
    }

    uint32 uiBoomTimer;
    bool Boom;

    void MoveInLineOfSight(Unit *who)
    {
        if (!Boom && me->IsWithinDistInMap(who, 0.5f) && who->ToPlayer() && !who->ToPlayer()->isGameMaster())
        {
            DoCastAOE(SPELL_EXPLOSION);
            me->ForcedDespawn(1000);
            Boom = true;
        }
    }

    void UpdateAI(const uint32 diff)
    {
        if (uiBoomTimer <= diff)
        {
            if (!Boom)
            {
                DoCastAOE(SPELL_EXPLOSION);
                me->ForcedDespawn(1000);
                Boom = true;
            }
        }
        else uiBoomTimer -= diff;
    }
};

};

/---------------------------------------------

class boss_vx_001 : public CreatureScript { public: boss_vx_001() : CreatureScript("boss_vx_001") { }

CreatureAI* GetAI(Creature* pCreature) const
{
    return new boss_vx_001AI(pCreature);
}

struct boss_vx_001AI : public BossAI
{
    boss_vx_001AI(Creature *pCreature) : BossAI(pCreature, BOSS_MIMIRON), vehicle(me->GetVehicleKit()), phase(PHASE_NULL)
    {
        me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
        me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_GRIP, true);
        me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_ROCKET_STRIKE_DMG, true);
    }

    Vehicle* vehicle;
    Phases phase;
    EventMap events;

    void Reset()
    {
        events.Reset();
        me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_DISABLE_MOVE);
        me->SetReactState(REACT_PASSIVE);
        me->SetStandState(UNIT_STAND_STATE_STAND);
        //me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STAND);
        me->SetVisible(false);
        me->RemoveAllAuras();
        phase = PHASE_NULL;
        events.SetPhase(PHASE_NULL);
    }

    void KilledUnit(Unit *who)
    {
        if (!(rand()%5))
            if (instance)
                if (Creature *pMimiron = me->GetCreature(*me, instance->GetData64(DATA_MIMIRON)))
                {
                    if (phase == PHASE_VX001_SOLO)
                        DoScriptText(RAND(SAY_VX001_SLAY_1, SAY_VX001_SLAY_2), pMimiron);
                    else
                        DoScriptText(RAND(SAY_V07TRON_SLAY_1, SAY_V07TRON_SLAY_2), pMimiron);
                }
    }

    void EnterCombat(Unit *who)
    {
        if (MimironHardMode)
        {
            DoCast(me, SPELL_EMERGENCY_MODE);
            events.ScheduleEvent(EVENT_FROST_BOMB, 15000);
        }

        events.ScheduleEvent(EVENT_RAPID_BURST, 500, 0, PHASE_VX001_SOLO);
        events.ScheduleEvent(EVENT_PRE_LASER_BARRAGE, urand(35000, 40000), 0, PHASE_VX001_SOLO); // Not works in phase 4 :(
        events.ScheduleEvent(EVENT_ROCKET_STRIKE, 20000);
        events.ScheduleEvent(EVENT_HEAT_WAVE, urand(8000, 10000), 0, PHASE_VX001_SOLO);
        events.ScheduleEvent(EVENT_HAND_PULSE, 15000, 0, PHASE_VX001_ASSEMBLED);
    }

    void DoAction(const int32 action)
    {
        switch(action)
        {
            case DO_START_VX001:
                me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
                phase = PHASE_VX001_SOLO;
                events.SetPhase(PHASE_VX001_SOLO);
                DoZoneInCombat();
                break;
            case DO_VX001_ASSEMBLED:
                me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
                me->SetHealth(int32(me->GetMaxHealth() / 2));
                me->SetStandState(UNIT_STAND_STATE_STAND);
                phase = PHASE_VX001_ASSEMBLED;
                events.SetPhase(PHASE_VX001_ASSEMBLED);
                events.RescheduleEvent(EVENT_PRE_LASER_BARRAGE, urand(35000, 40000), 0, PHASE_VX001_SOLO); // not works in phase 4
                events.RescheduleEvent(EVENT_ROCKET_STRIKE, 20000);
                events.RescheduleEvent(EVENT_HAND_PULSE, 15000, 0, PHASE_VX001_ASSEMBLED);
                if (MimironHardMode)
                {
                    DoCast(me, SPELL_EMERGENCY_MODE);
                    events.RescheduleEvent(EVENT_FROST_BOMB, 15000);
                }
                break;
            case DO_ENTER_ENRAGE:
                DoCast(me, SPELL_BERSERK, true);
                break;
        }
    }

    void DamageTaken(Unit *who, uint32 &damage)
    {
        if (phase == PHASE_VX001_SOLO)
            if (damage >= me->GetHealth())
            {
                damage = 0;
                me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
                me->AttackStop();
                me->GetMotionMaster()->Initialize();
                me->RemoveAllAuras();
                me->SetHealth(me->GetMaxHealth());
                me->SetStandState(UNIT_STAND_STATE_DEAD);
                phase = PHASE_NULL;
                events.SetPhase(PHASE_NULL);
                if (Creature *pMimiron = me->GetCreature(*me, instance->GetData64(DATA_MIMIRON)))
                    pMimiron->AI()->DoAction(DO_ACTIVATE_AERIAL);
            }

        if (phase == PHASE_VX001_ASSEMBLED)
            if (damage >= me->GetHealth())
            {
                damage = 0;
                me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
                me->AttackStop();
                me->RemoveAllAuras();
                me->SetHealth(me->GetMaxHealth());
                me->SetStandState(UNIT_STAND_STATE_DEAD);
                events.SetPhase(PHASE_NULL);
                phase = PHASE_NULL;
                if (Creature *pMimiron = me->GetCreature(*me, instance->GetData64(DATA_MIMIRON)))
                    pMimiron->AI()->DoAction(DO_ACTIVATE_DEATH_TIMER);
            }
    }

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

        events.Update(diff);

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

        if (phase == PHASE_VX001_SOLO || phase == PHASE_VX001_ASSEMBLED)
        {
            while (uint32 eventId = events.ExecuteEvent())
            {
                switch(eventId)
                {
                    case EVENT_RAPID_BURST:
                        me->GetMotionMaster()->Initialize();
                        if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                            if (Creature *BurstTarget = me->SummonCreature(NPC_BURST_TARGET, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 3000))
                                DoCast(BurstTarget, SPELL_RAPID_BURST);
                        events.RescheduleEvent(EVENT_RAPID_BURST, 3000, 0, PHASE_VX001_SOLO);
                        break;
                    case EVENT_PRE_LASER_BARRAGE:
                        DoCast(SPELL_SPINNING_UP);
                        me->GetMotionMaster()->MoveRotate(40000, rand()%2 ? ROTATE_DIRECTION_LEFT : ROTATE_DIRECTION_RIGHT);
                        events.DelayEvents(14000);
                        events.RescheduleEvent(EVENT_PRE_LASER_BARRAGE, 40000, 0, PHASE_VX001_SOLO);
                        events.RescheduleEvent(EVENT_LASER_BARRAGE, 3000);
                        break;
                    case EVENT_LASER_BARRAGE:
                        DoCastAOE(SPELL_LASER_BARRAGE);
                        events.CancelEvent(EVENT_LASER_BARRAGE);
                        break;
                    case EVENT_ROCKET_STRIKE:
                        if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                            if (Creature *missile = CAST_CRE(me->GetVehicleKit()->GetPassenger(5)))
                                missile->CastSpell(pTarget, SPELL_ROCKET_STRIKE, true);
                        if (phase == PHASE_VX001_ASSEMBLED)
                            if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                                if (Creature *missile = CAST_CRE(me->GetVehicleKit()->GetPassenger(6)))
                                    missile->CastSpell(pTarget, SPELL_ROCKET_STRIKE, true);
                        events.RescheduleEvent(EVENT_ROCKET_STRIKE, urand(20000, 25000));
                        break;
                    case EVENT_HEAT_WAVE:
                        DoCastAOE(SPELL_HEAT_WAVE);
                        events.RescheduleEvent(EVENT_HEAT_WAVE, 10000, 0, PHASE_VX001_SOLO);
                        break;
                    case EVENT_HAND_PULSE:
                        if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                            DoCast(pTarget, SPELL_HAND_PULSE);
                        events.RescheduleEvent(EVENT_HAND_PULSE, urand(10000, 12000));
                        break;
                    case EVENT_FROST_BOMB:
                        me->SummonCreature(NPC_FROST_BOMB, SummonPos[rand()%9], TEMPSUMMON_TIMED_DESPAWN, 11000);
                        events.RescheduleEvent(EVENT_FROST_BOMB, 45000);
                        break;
                }
            }
        }
    }
};

};

class npc_rocket_strike : public CreatureScript { public: npc_rocket_strike() : CreatureScript("npc_rocket_strike") { }

CreatureAI* GetAI(Creature* pCreature) const
{
    return new npc_rocket_strikeAI (pCreature);
}

struct npc_rocket_strikeAI : public Scripted_NoMovementAI
{
    npc_rocket_strikeAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature)
    {
        me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
        me->ForcedDespawn(10000);
        DoCast(me, SPELL_ROCKET_STRIKE_AURA);
    }
};

};

/---------------------------------------------

class boss_aerial_unit : public CreatureScript { public: boss_aerial_unit() : CreatureScript("boss_aerial_unit") { }

CreatureAI* GetAI(Creature* pCreature) const
{
    return new boss_aerial_unitAI(pCreature);
}

struct boss_aerial_unitAI : public BossAI
{
    boss_aerial_unitAI(Creature *pCreature) : BossAI(pCreature, BOSS_MIMIRON), vehicle(me->GetVehicleKit()), phase(PHASE_NULL)
    {
        me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
        me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_GRIP, true);
        me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_ROCKET_STRIKE_DMG, true);
    }

    Vehicle* vehicle;
    Phases phase;
    EventMap events;
    uint8 spawnedAdds;

    void Reset()
    {
        events.Reset();
        me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_DISABLE_MOVE);
        me->SetReactState(REACT_PASSIVE);
        me->SetStandState(UNIT_STAND_STATE_STAND);
        me->SetVisible(false);
        me->RemoveAllAuras();
        me->SetFlying(true);
        phase = PHASE_NULL;
        events.SetPhase(PHASE_NULL);
        summons.DespawnAll();
        spawnedAdds = 0;
    }

    void KilledUnit(Unit *who)
    {
        if (!(rand()%5))
            if (instance)
                if (Creature *pMimiron = me->GetCreature(*me, instance->GetData64(DATA_MIMIRON)))
                {
                    if (phase == PHASE_AERIAL_SOLO)
                        DoScriptText(RAND(SAY_AERIAL_SLAY_1, SAY_AERIAL_SLAY_2), pMimiron);
                    else
                        DoScriptText(RAND(SAY_V07TRON_SLAY_1, SAY_V07TRON_SLAY_2), pMimiron);
                }
    }

    void EnterCombat(Unit *who)
    {
        if (MimironHardMode)
            DoCast(me, SPELL_EMERGENCY_MODE);

        events.ScheduleEvent(EVENT_PLASMA_BALL, 1000);
        events.ScheduleEvent(EVENT_SUMMON_BOTS, 10000, 0, PHASE_AERIAL_SOLO);
    }

    void DoAction(const int32 action)
    {
        switch(action)
        {
            case DO_START_AERIAL:
                me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
                me->SetReactState(REACT_AGGRESSIVE);
                phase = PHASE_AERIAL_SOLO;
                events.SetPhase(PHASE_AERIAL_SOLO);
                DoZoneInCombat();
                break;
            case DO_DISABLE_AERIAL:
                me->CastStop();
                me->SetReactState(REACT_PASSIVE);
                me->GetMotionMaster()->Clear(true);
                DoCast(me, SPELL_MAGNETIC_CORE);
                DoCast(me, SPELL_MAGNETIC_CORE_VISUAL);
                if (Creature *pMagneticCore = me->GetCreature(*me, instance->GetData64(DATA_MAGNETIC_CORE)))
                    if (pMagneticCore->isAlive())
                        me->NearTeleportTo(pMagneticCore->GetPositionX(), pMagneticCore->GetPositionY(), 368.965f, 0, false);
                events.RescheduleEvent(EVENT_PLASMA_BALL, 22000, 0, PHASE_AERIAL_SOLO);
                events.RescheduleEvent(EVENT_SUMMON_BOTS, 24000, 0, PHASE_AERIAL_SOLO);
                events.ScheduleEvent(EVENT_REACTIVATE_AERIAL, 20000, 0, PHASE_AERIAL_SOLO);
                break;
            case DO_AERIAL_ASSEMBLED:
                if (MimironHardMode)
                    DoCast(me, SPELL_EMERGENCY_MODE);
                me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
                me->SetReactState(REACT_AGGRESSIVE);
                me->SetHealth(int32(me->GetMaxHealth() / 2));
                me->SetStandState(UNIT_STAND_STATE_STAND);
                phase = PHASE_AERIAL_ASSEMBLED;
                events.SetPhase(PHASE_AERIAL_ASSEMBLED);
                events.RescheduleEvent(EVENT_PLASMA_BALL, 2000);
                break;
            case DO_ENTER_ENRAGE:
                DoCast(me, SPELL_BERSERK, true);
                break;
        }
    }

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

        events.Update(diff);

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

        if (phase == PHASE_AERIAL_SOLO || phase == PHASE_AERIAL_ASSEMBLED)
        {
            while (uint32 eventId = events.ExecuteEvent())
            {
                switch(eventId)
                {
                    case EVENT_PLASMA_BALL:
                        if (phase == PHASE_AERIAL_SOLO && me->getVictim())
                        {
                            float x = me->getVictim()->GetPositionX();
                            float y = me->getVictim()->GetPositionY();
                            float z = me->getVictim()->GetPositionZ();
                            if (me->IsWithinDist3d(x, y, z, 30))
                            {
                                me->GetMotionMaster()->Initialize();
                                DoCastVictim(SPELL_PLASMA_BALL);
                            }
                            else me->GetMotionMaster()->MovePoint(0, x, y, 380.04f);
                        }
                        else if (phase == PHASE_AERIAL_ASSEMBLED && me->getVictim())
                        {
                            if (me->getVictim()->IsWithinDist3d(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 35))
                                DoCastVictim(SPELL_PLASMA_BALL);
                            else if (Unit *pTarget = SelectUnit(SELECT_TARGET_NEAREST, 0))
                                DoCast(pTarget, SPELL_PLASMA_BALL);
                        }
                        events.RescheduleEvent(EVENT_PLASMA_BALL, 2000);
                        break;
                    case EVENT_REACTIVATE_AERIAL:
                        me->RemoveAurasDueToSpell(SPELL_MAGNETIC_CORE_VISUAL);
                        me->NearTeleportTo(me->GetPositionX(), me->GetPositionY(), 380.04f, 3.14159f, false);
                        me->SetReactState(REACT_AGGRESSIVE);
                        events.CancelEvent(EVENT_REACTIVATE_AERIAL);
                        break;
                    case EVENT_SUMMON_BOTS:
                        if (phase == PHASE_AERIAL_SOLO)
                        {
                            spawnAdd();
                            events.RescheduleEvent(EVENT_SUMMON_BOTS, 10000, 0, PHASE_AERIAL_SOLO);
                        }
                        break;
                }
            }
        }
    }

    void spawnAdd()
    {
        switch(spawnedAdds)
        {
            case 0:
                for(uint8 n = 0; n < 2; n++)
                    me->SummonCreature(NPC_JUNK_BOT, SummonPos[rand()%9], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000);
                break;
            case 1:
                me->SummonCreature(NPC_ASSAULT_BOT, SummonPos[rand()%9], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
                if (MimironHardMode)
                    for (uint8 i = 0; i < 2; ++i)
                        me->SummonCreature(NPC_EMERGENCY_BOT, SummonPos[rand()%9], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000);
                break;
            case 2:
                me->SummonCreature(NPC_BOOM_BOT, 2744.65f, 2569.46f, 364.397f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000);
                break;
        }

        spawnedAdds++;
        if(spawnedAdds > 2)
        {
            spawnedAdds = 0;
        }
    }

    void JustSummoned(Creature *summon)
    {
        summons.Summon(summon);

        if (summon->GetEntry() == NPC_EMERGENCY_BOT)
            return;

        summon->AI()->DoZoneInCombat();
        if (MimironHardMode)
            DoCast(me, SPELL_EMERGENCY_MODE, true);
    }

    void DamageTaken(Unit *who, uint32 &damage)
    {
        if (phase == PHASE_AERIAL_SOLO)
            if (damage >= me->GetHealth())
            {
                damage = 0;
                me->GetMotionMaster()->Clear(true);
                me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
                me->SetReactState(REACT_PASSIVE);
                me->AttackStop();
                me->RemoveAllAuras();
                me->SetHealth(me->GetMaxHealth());
                events.CancelEvent(EVENT_SUMMON_BOTS);
                phase = PHASE_NULL;
                events.SetPhase(PHASE_NULL);
                if (Creature *pMimiron = me->GetCreature(*me, instance->GetData64(DATA_MIMIRON)))
                    pMimiron->AI()->DoAction(DO_ACTIVATE_V0L7R0N);
            }

        if (phase == PHASE_AERIAL_ASSEMBLED)
            if (damage >= me->GetHealth())
            {
                damage = 0;
                me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
                me->AttackStop();
                me->SetReactState(REACT_PASSIVE);
                me->RemoveAllAuras();
                me->SetHealth(me->GetMaxHealth());
                me->SetStandState(UNIT_STAND_STATE_DEAD);
                events.SetPhase(PHASE_NULL);
                phase = PHASE_NULL;
                if (Creature *pMimiron = me->GetCreature(*me, instance->GetData64(DATA_MIMIRON)))
                    pMimiron->AI()->DoAction(DO_ACTIVATE_DEATH_TIMER);
            }
    }
};

};

class npc_magnetic_core : public CreatureScript { public: npc_magnetic_core() : CreatureScript("npc_magnetic_core") { }

CreatureAI* GetAI(Creature* pCreature) const
{
    return new npc_magnetic_coreAI (pCreature);
}

struct npc_magnetic_coreAI : public Scripted_NoMovementAI
{
    npc_magnetic_coreAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature)
    {
        DoCast(SPELL_MAGNETIC_CORE);
        me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
        me->ForcedDespawn(21000);
        if (Creature *pAerialUnit = me->FindNearestCreature(NPC_AERIAL_UNIT, 20, true))
            pAerialUnit->AI()->DoAction(DO_DISABLE_AERIAL);
    }
};

};

class npc_assault_bot : public CreatureScript { public: npc_assault_bot() : CreatureScript("npc_assault_bot") { }

CreatureAI* GetAI(Creature* pCreature) const
{
    return new npc_assault_botAI (pCreature);
}

struct npc_assault_botAI : public ScriptedAI
{
    npc_assault_botAI(Creature *pCreature) : ScriptedAI(pCreature)
    {
        pInstance = pCreature->GetInstanceScript();
    }

    InstanceScript* pInstance;
    uint32 uiFieldTimer;

    void Reset()
    {
        uiFieldTimer = urand(4000, 6000);
    }

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

        if (uiFieldTimer <= uiDiff)
        {
            DoCastVictim(SPELL_MAGNETIC_FIELD);
            uiFieldTimer = urand(15000, 20000);
        }
        else uiFieldTimer -= uiDiff;

        DoMeleeAttackIfReady();
    }

    void SpellHit(Unit *caster, const SpellEntry *spell)
    {
        // Achievement Not-So-Friendly Fire
        if (spell->Id == 63041 && pInstance)
            pInstance->DoCompleteAchievement(ACHIEVEMENT_NOT_SO_FRIENDLY_FIRE);
    }
};

};

class npc_emergency_bot : public CreatureScript { public: npc_emergency_bot() : CreatureScript("npc_emergency_bot") { }

CreatureAI* GetAI(Creature* pCreature) const
{
    return new npc_emergency_botAI (pCreature);
}

struct npc_emergency_botAI : public ScriptedAI
{
    npc_emergency_botAI(Creature *pCreature) : ScriptedAI(pCreature)
    {
        me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
        me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_GRIP, true);
        me->SetReactState(REACT_PASSIVE);
        me->GetMotionMaster()->MoveRandom(15);
        uiSprayTimer = 5000;
    }

    uint32 uiSprayTimer;

    void UpdateAI(const uint32 uiDiff)
    {
        if (uiSprayTimer <= uiDiff)
        {
            DoCast(SPELL_WATER_SPRAY);
            for (int8 n = 0; n < 2; n++)
            {
                uint32 npc;
                if (n == 0)
                    npc = NPC_FLAME;
                else 
                    npc = NPC_FLAME_SPREAD;
                std::list<Creature*> m_pCreatures;
                GetCreatureListWithEntryInGrid(m_pCreatures, me, npc, 12);
                if (!m_pCreatures.empty())
                    for(std::list<Creature*>::iterator iter = m_pCreatures.begin(); iter != m_pCreatures.end(); ++iter)
                        (*iter)->ForcedDespawn();
            }
            uiSprayTimer = 5000;
        }
        else uiSprayTimer -= uiDiff;
    }
};

};

/---------------------------------------------

class go_not_push_button : public GameObjectScript { public: go_not_push_button() : GameObjectScript("go_not_push_button") { }

bool OnGossipHello(Player* pPlayer, GameObject* pGo)
{
    InstanceScript* pInstance = pGo->GetInstanceScript();

    if (!pInstance)
        return false;

    if ((pInstance->GetBossState(BOSS_MIMIRON) != IN_PROGRESS || pInstance->GetBossState(BOSS_MIMIRON) != DONE) && pPlayer)
        if (Creature *pMimiron = pPlayer->GetCreature((*pPlayer), pInstance->GetData64(DATA_MIMIRON)))
            pMimiron->AI()->DoAction(DO_ACTIVATE_HARD_MODE);

    return true;
}

};

class npc_mimiron_flame_trigger : public CreatureScript { public: npc_mimiron_flame_trigger() : CreatureScript("npc_mimiron_flame_trigger") { }

CreatureAI* GetAI(Creature* pCreature) const
{
    return new npc_mimiron_flame_triggerAI (pCreature);
}

struct npc_mimiron_flame_triggerAI : public ScriptedAI
{
    npc_mimiron_flame_triggerAI(Creature* pCreature) : ScriptedAI(pCreature)
    {
        me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
        DoCast(me, SPELL_FLAME, true);
        uiFlameTimer = 8000;
    }

    uint32 uiFlameTimer;

    void UpdateAI(const uint32 diff)
    {
        if (uiFlameTimer <= diff)
        {
            me->SummonCreature(NPC_FLAME_SPREAD, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
            uiFlameTimer = 8000;
        }
        else uiFlameTimer -= diff;
    }
};

};

class npc_mimiron_flame_spread : public CreatureScript { public: npc_mimiron_flame_spread() : CreatureScript("npc_mimiron_flame_spread") { }

CreatureAI* GetAI(Creature* pCreature) const
{
    return new npc_mimiron_flame_spreadAI (pCreature);
}

struct npc_mimiron_flame_spreadAI : public Scripted_NoMovementAI
{
    npc_mimiron_flame_spreadAI(Creature *pCreature) : Scripted_NoMovementAI(pCreature)
    {
        pInstance = pCreature->GetInstanceScript();
        me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
        me->SetReactState(REACT_PASSIVE);
        DoCast(me, SPELL_FLAME, true);
    }

    InstanceScript* pInstance;

    void UpdateAI(const uint32 uiDiff)
    {
        if (pInstance && pInstance->GetBossState(BOSS_MIMIRON) != IN_PROGRESS)
            me->ForcedDespawn();
    }
};

};

class npc_frost_bomb : public CreatureScript { public: npc_frost_bomb() : CreatureScript("npc_frost_bomb") { }

CreatureAI* GetAI(Creature* pCreature) const
{
    return new npc_frost_bombAI (pCreature);
}

struct npc_frost_bombAI : public Scripted_NoMovementAI
{
    npc_frost_bombAI(Creature *pCreature) : Scripted_NoMovementAI(pCreature)
    {
        me->SetReactState(REACT_PASSIVE);
        me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
        DoCast(me, SPELL_FROST_BOMB);
        uiFrostTimer = 10000;
    }

    uint32 uiFrostTimer;

    void UpdateAI(const uint32 diff)
    {
        if (uiFrostTimer <= diff)
        {
            DoCastAOE(SPELL_FLAME_SUPPRESSANT_2);
            for (int8 n = 0; n < 2; n++)
            {
                uint32 npc;
                if (n == 0)
                    npc = NPC_FLAME;
                else 
                    npc = NPC_FLAME_SPREAD;
                std::list<Creature*> m_pCreatures;
                GetCreatureListWithEntryInGrid(m_pCreatures, me, npc, 25);
                if (!m_pCreatures.empty())
                    for(std::list<Creature*>::iterator iter = m_pCreatures.begin(); iter != m_pCreatures.end(); ++iter)
                        (*iter)->ForcedDespawn(1000);
            }
            uiFrostTimer = 10000;
        }
        else uiFrostTimer -= diff;
    }
};

};

void AddSC_boss_mimiron() { new boss_mimiron(); new boss_leviathan_mk(); new boss_leviathan_mk_turret(); new npc_proximity_mine(); new boss_vx_001(); new npc_rocket_strike(); new boss_aerial_unit(); new npc_magnetic_core(); new npc_assault_bot(); new npc_emergency_bot(); new go_not_push_button(); new npc_mimiron_flame_trigger(); new npc_mimiron_flame_spread(); new npc_frost_bomb(); }