Esempio n. 1
0
    void UpdateAI(const uint32 uiDiff) override
    {
        if (m_uiMovementTimer)
        {
            if (m_uiMovementTimer <= uiDiff)
            {
                m_creature->SetLevitate(true);
                m_creature->GetMotionMaster()->MovePoint(PHASE_GROUND, m_creature->GetPositionX(), m_creature->GetPositionY(), 50.083f, false);
                m_uiMovementTimer = 0;
            }
            else
                m_uiMovementTimer -= uiDiff;
        }

        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        if (m_uiBerserkTimer)
        {
            if (m_uiBerserkTimer <= uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_BERSERK) == CAST_OK)
                {
                    DoScriptText(SAY_BERSERK, m_creature);
                    m_uiBerserkTimer = 0;
                }
            }
            else
                m_uiBerserkTimer -= uiDiff;
        }

        switch (m_uiPhase)
        {
            case PHASE_GROUND:

                if (m_uiCleaveTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK)
                        m_uiCleaveTimer = urand(2000, 5000);
                }
                else
                    m_uiCleaveTimer -= uiDiff;

                if (m_uiCorrosionTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CORROSION) == CAST_OK)
                    {
                        DoScriptText(SAY_BREATH, m_creature);
                        m_uiCorrosionTimer = 30000;
                    }
                }
                else
                    m_uiCorrosionTimer -= uiDiff;

                if (m_uiGasNovaTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_GAS_NOVA) == CAST_OK)
                        m_uiGasNovaTimer = 23000;
                }
                else
                    m_uiGasNovaTimer -= uiDiff;

                if (m_uiEncapsulateTimer < uiDiff)
                {
                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                    {
                        if (DoCastSpellIfCan(pTarget, SPELL_ENCAPSULATE_CHANNEL) == CAST_OK)
                            m_uiEncapsulateTimer = urand(30000, 40000);
                    }
                }
                else
                    m_uiEncapsulateTimer -= uiDiff;

                if (m_uiFlyPhaseTimer < uiDiff)
                {
                    DoScriptText(SAY_TAKEOFF, m_creature);

                    SetCombatMovement(false);
                    m_creature->SetLevitate(true);
                    m_creature->GetMotionMaster()->MoveIdle();
                    m_creature->GetMotionMaster()->MovePoint(PHASE_AIR, m_creature->GetPositionX(), m_creature->GetPositionY(), 50.083f, false);

                    m_uiPhase = PHASE_TRANSITION;
                    m_uiSubPhase = SUBPHASE_VAPOR;
                    m_uiDemonicVaporTimer = 1000;
                    m_uiDemonicVaporCount = 0;
                    m_uiFlyPhaseTimer = 60000;
                }
                else
                    m_uiFlyPhaseTimer -= uiDiff;

                DoMeleeAttackIfReady();

                break;
            case PHASE_AIR:

                switch (m_uiSubPhase)
                {
                    case SUBPHASE_VAPOR:

                        if (m_uiDemonicVaporTimer < uiDiff)
                        {
                            // After the second Demonic Vapor trial, start the breath phase
                            if (m_uiDemonicVaporCount == 2)
                            {
                                if (!m_pInstance)
                                    return;

                                // select the side on which we want to fly
                                m_bIsLeftSide = urand(0, 1) ? true : false;
                                m_uiCorruptionCount = 0;
                                m_uiSubPhase = SUBPHASE_BREATH_PREPARE;
                                if (Creature* pTrigger = m_pInstance->GetSingleCreatureFromStorage(m_bIsLeftSide ? NPC_FLIGHT_TRIGGER_LEFT : NPC_FLIGHT_TRIGGER_RIGHT))
                                    m_creature->GetMotionMaster()->MovePoint(SUBPHASE_VAPOR, pTrigger->GetPositionX(), pTrigger->GetPositionY(), pTrigger->GetPositionZ(), false);
                            }
                            else
                            {
                                if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_VAPOR) == CAST_OK)
                                {
                                    ++m_uiDemonicVaporCount;
                                    m_uiDemonicVaporTimer = 11000;
                                }
                            }
                        }
                        else
                            m_uiDemonicVaporTimer -= uiDiff;

                        break;
                    case SUBPHASE_BREATH_PREPARE:

                        if (m_uiCorruptionTimer)
                        {
                            if (m_uiCorruptionTimer <= uiDiff)
                            {
                                if (!m_pInstance)
                                    return;

                                // Fly to trigger on the same side - choose a random index for the trigger
                                m_uiCorruptionIndex = urand(0, 2);
                                if (Creature* pTrigger = m_creature->GetMap()->GetCreature(m_pInstance->SelectFelmystFlightTrigger(m_bIsLeftSide, m_uiCorruptionIndex)))
                                    m_creature->GetMotionMaster()->MovePoint(SUBPHASE_BREATH_PREPARE, pTrigger->GetPositionX(), pTrigger->GetPositionY(), pTrigger->GetPositionZ(), false);

                                m_uiSubPhase = SUBPHASE_BREATH_MOVE;
                                m_uiCorruptionTimer = 0;
                            }
                            else
                                m_uiCorruptionTimer -= uiDiff;
                        }

                        break;
                    case SUBPHASE_BREATH_MOVE:
                        // nothing here; this is handled in MovementInform
                        break;
                }
                break;
            case PHASE_TRANSITION:
                // nothing here; wait for transition to finish
                break;
        }
    }
Esempio n. 2
0
    void MovementInform(uint32 uiMoveType, uint32 uiPointId) override
    {
        if (uiMoveType != POINT_MOTION_TYPE)
            return;

        switch (uiPointId)
        {
            case PHASE_GROUND:
                m_creature->SetWalk(false);
                // ToDo: start WP movement here. Currently disabled because of some MMaps issues
                // m_creature->GetMotionMaster()->MoveWaypoint();
                break;
            case PHASE_AIR:
                // switch from ground transition to flight phase
                m_uiPhase = PHASE_AIR;
                break;
            case SUBPHASE_VAPOR:
                // After the third breath land and resume phase 1
                if (m_uiCorruptionCount == 3)
                {
                    m_uiPhase = PHASE_TRANSITION;
                    float fGroundZ = m_creature->GetMap()->GetHeight(m_creature->GetPhaseMask(), m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ());
                    m_creature->GetMotionMaster()->MovePoint(PHASE_TRANSITION, m_creature->getVictim()->GetPositionX(), m_creature->getVictim()->GetPositionY(), fGroundZ, false);
                    return;
                }

                // prepare to move to flight trigger
                ++m_uiCorruptionCount;
                m_uiCorruptionTimer = 5000;
                m_uiSubPhase = SUBPHASE_BREATH_PREPARE;
                break;
            case SUBPHASE_BREATH_PREPARE:
                // move across the arena
                if (!m_pInstance)
                    return;

                // Fly to the other side, casting the breath. Keep the same trigger index
                if (Creature* pTrigger = m_creature->GetMap()->GetCreature(m_pInstance->SelectFelmystFlightTrigger(!m_bIsLeftSide, m_uiCorruptionIndex)))
                {
                    DoScriptText(EMOTE_DEEP_BREATH, m_creature);
                    DoCastSpellIfCan(m_creature, SPELL_SPEED_BURST, CAST_TRIGGERED);
                    DoCastSpellIfCan(m_creature, SPELL_FOG_CORRUPTION, CAST_TRIGGERED);
                    m_creature->GetMotionMaster()->MovePoint(SUBPHASE_BREATH_MOVE, pTrigger->GetPositionX(), pTrigger->GetPositionY(), pTrigger->GetPositionZ(), false);
                }
                break;
            case SUBPHASE_BREATH_MOVE:
                if (!m_pInstance)
                    return;

                // remove speed aura
                m_creature->RemoveAurasDueToSpell(SPELL_SPEED_BURST);

                // Get to the flight trigger on the same side of the arena
                if (Creature* pTrigger = m_pInstance->GetSingleCreatureFromStorage(!m_bIsLeftSide ? NPC_FLIGHT_TRIGGER_LEFT : NPC_FLIGHT_TRIGGER_RIGHT))
                    m_creature->GetMotionMaster()->MovePoint(SUBPHASE_VAPOR, pTrigger->GetPositionX(), pTrigger->GetPositionY(), pTrigger->GetPositionZ(), false);

                // switch sides
                m_bIsLeftSide = !m_bIsLeftSide;
                break;
            case PHASE_TRANSITION:
                // switch back to ground combat from flight transition
                m_uiPhase = PHASE_GROUND;
                SetCombatMovement(true);
                m_creature->SetLevitate(false);
                DoStartMovement(m_creature->getVictim());
                break;
        }
    }