void UpdateAI(const uint32 uiDiff) override
    {
        if (m_creature->GetMapId() != MAP_ID_BWL)
            return;

        DialogueUpdate(uiDiff);

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

        // Only do this if we haven't spawned nef yet
        if (m_uiSpawnedAdds < MAX_DRAKE_SUMMONS)
        {
            // Shadowbolt Timer
            if (m_uiShadowBoltTimer < uiDiff)
            {
                if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                {
                    if (DoCastSpellIfCan(pTarget, SPELL_SHADOWBOLT) == CAST_OK)
                        m_uiShadowBoltTimer = urand(2000, 4000);
                }
            }
            else
                m_uiShadowBoltTimer -= uiDiff;

            // Fear Timer
            if (m_uiFearTimer < uiDiff)
            {
                if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
                {
                    if (DoCastSpellIfCan(pTarget, SPELL_FEAR) == CAST_OK)
                        m_uiFearTimer = urand(10000, 20000);
                }
            }
            else
                m_uiFearTimer -= uiDiff;

            // Shadowbolt Volley
            if (m_uiShadowboltVolleyTimer < uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_SHADOWBOLT_VOLLEY) == CAST_OK)
                    m_uiShadowboltVolleyTimer = urand(19000, 28000);
            }
            else
                m_uiShadowboltVolleyTimer -= uiDiff;

            // Silence
            if (m_uiSilenceTimer < uiDiff)
            {
                if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                {
                    if (DoCastSpellIfCan(pTarget, SPELL_SILENCE) == CAST_OK)
                        m_uiSilenceTimer = urand(14000, 23000);
                }
            }
            else
                m_uiSilenceTimer -= uiDiff;

            // Shadow Command
            if (m_uiShadowCommandTimer < uiDiff)
            {
                if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
                {
                    if (DoCastSpellIfCan(pTarget, SPELL_SHADOW_COMMAND) == CAST_OK)
                        m_uiShadowCommandTimer = urand(24000, 30000);
                }
            }
            else
                m_uiShadowCommandTimer -= uiDiff;

            // ShadowBlink
            if (m_uiShadowBlinkTimer < uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_SHADOWBLINK) == CAST_OK)
                    m_uiShadowBlinkTimer = urand(30000, 40000);
            }
            else
                m_uiShadowBlinkTimer -= uiDiff;

            // Add spawning mechanism
            if (m_uiAddSpawnTimer < uiDiff)
            {
                // Spawn 2 random types of creatures at the 2 locations
                uint32 uiCreatureId = 0;

                // 1 in 3 chance it will be a chromatic
                uiCreatureId = urand(0, 2) ? m_uiDrakeTypeOne : uint32(NPC_CHROMATIC_DRAKANOID);
                m_creature->SummonCreature(uiCreatureId, aNefarianLocs[0].m_fX, aNefarianLocs[0].m_fY, aNefarianLocs[0].m_fZ, 5.000f, TEMPSUMMON_TIMED_OOC_OR_CORPSE_DESPAWN, 30000);

                // 1 in 3 chance it will be a chromatic
                uiCreatureId = urand(0, 2) ? m_uiDrakeTypeTwo : uint32(NPC_CHROMATIC_DRAKANOID);
                m_creature->SummonCreature(uiCreatureId, aNefarianLocs[1].m_fX, aNefarianLocs[1].m_fY, aNefarianLocs[1].m_fZ, 5.000, TEMPSUMMON_TIMED_OOC_OR_CORPSE_DESPAWN, 30000);

                // Begin phase 2 by spawning Nefarian
                if (m_uiSpawnedAdds >= MAX_DRAKE_SUMMONS)
                {
                    // Inturrupt any spell casting
                    m_creature->InterruptNonMeleeSpells(false);

                    // Make super invis
                    if (m_creature->GetVisibility() != VISIBILITY_OFF)
                        m_creature->SetVisibility(VISIBILITY_OFF);

                    // Spawn Nefarian
                    // Summon as active, to be able to work proper!
                    m_creature->SummonCreature(NPC_NEFARIAN, aNefarianLocs[2].m_fX, aNefarianLocs[2].m_fY, aNefarianLocs[2].m_fZ, 0, TEMPSUMMON_DEAD_DESPAWN, 0, true);
                }

                m_uiAddSpawnTimer = 4000;
            }
            else
                m_uiAddSpawnTimer -= uiDiff;
        }
    }
Beispiel #2
0
    void UpdateAI(const uint32 uiDiff) override
    {
        DialogueUpdate(uiDiff);

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

        switch (m_uiPhase)
        {
            // arena phase abilities
            case PHASE_ARENA:

                if (m_uiBerserkTimer)
                {
                    if (m_uiBerserkTimer <= uiDiff)
                    {
                        if (DoCastSpellIfCan(m_creature, SPELL_BERSERK_1) == CAST_OK)
                        {
                            DoCastSpellIfCan(m_creature, SPELL_SUMMON_LIGHTNING_ORB, CAST_TRIGGERED);
                            DoScriptText(SAY_ARENA_WIPE, m_creature);
                            m_uiBerserkTimer = 0;
                        }
                    }
                    else
                        m_uiBerserkTimer -= uiDiff;
                }

                if (m_uiArenaDwarfTimer < uiDiff)
                {
                    DoSpawnArenaDwarf();
                    m_uiArenaDwarfTimer = 10000;
                }
                else
                    m_uiArenaDwarfTimer -= uiDiff;

                if (m_uiChargeOrbTimer < uiDiff)
                {
                    // this spell has AoE target, but we need to be very specific with the selected targets
                    if (Creature* pTarget = m_creature->GetMap()->GetCreature(SelectRandomOrbGuid()))
                    {
                        if (DoCastSpellIfCan(pTarget, SPELL_CHARGE_ORB) == CAST_OK)
                            m_uiChargeOrbTimer = 20000;
                    }
                }
                else
                    m_uiChargeOrbTimer -= uiDiff;

                if (m_uiStormHammerTimer < uiDiff)
                {
                    if (Unit* pTarget = GetRandomArenaPlayer())
                    {
                        if (DoCastSpellIfCan(pTarget, SPELL_STORMHAMMER) == CAST_OK)
                            m_uiStormHammerTimer = 15000;
                    }
                }
                else
                    m_uiStormHammerTimer -= uiDiff;

                break;
                // solo phase abilities
            case PHASE_SOLO:

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

                if (m_uiAttackTimer)
                {
                    if (m_uiAttackTimer <= uiDiff)
                    {
                        // Add some small delay to combat movement because Jump triggers before it's actually finished
                        DoResetThreat();
                        SetCombatMovement(true);
                        DoStartMovement(m_creature->getVictim());
                        m_uiAttackTimer = 0;
                    }
                    else
                        m_uiAttackTimer -= uiDiff;
                }

                if (m_uiChargeOrbTimer < uiDiff)
                {
                    // this spell requires very specific targets
                    if (Creature* pTarget = m_creature->GetMap()->GetCreature(SelectRandomOrbGuid()))
                    {
                        pTarget->CastSpell(pTarget, SPELL_LIGHTNING_ORG_CHARGED, true);

                        // charge the lower orb as well
                        if (Unit* pOrb = GetClosestCreatureWithEntry(pTarget, NPC_THUNDER_ORB, 25.0f, true, false, true))
                            pTarget->CastSpell(pOrb, SPELL_LIGHTNING_PILLAR, true);

                        m_uiChargeOrbTimer = 20000;
                    }
                }
                else
                    m_uiChargeOrbTimer -= uiDiff;

                if (m_uiChainLightningTimer < uiDiff)
                {
                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                    {
                        if (DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_CHAIN_LIGHTNING : SPELL_CHAIN_LIGHTNING_H) == CAST_OK)
                            m_uiChainLightningTimer = urand(10000, 15000);
                    }
                }
                else
                    m_uiChainLightningTimer -= uiDiff;

                if (m_uiUnbalancingStrikeTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_UNBALANCING_STRIKE) == CAST_OK)
                        m_uiUnbalancingStrikeTimer = 25000;
                }
                else
                    m_uiUnbalancingStrikeTimer -= uiDiff;

                DoMeleeAttackIfReady();
                break;
                // transition phase; nothing here, wait for transition to finish
            case PHASE_TRANSITION:
                break;
        }
    }
Beispiel #3
0
 void UpdateAI(const uint32 uiDiff) override
 {
     DialogueUpdate(uiDiff);
 }
Beispiel #4
0
    void UpdateAI(const uint32 uiDiff) override
    {
        DialogueUpdate(uiDiff);

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

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

        switch (m_uiPhase)
        {
        case PHASE_FLOOR:

            /* ToDo: Enable this when the spells are properly supported in core
            if (m_uiVortexTimer < uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_VORTEX) == CAST_OK)
                {
                    DoScriptText(SAY_VORTEX, m_creature);
                    m_uiVortexTimer = 60000;
                }
            }
            else
                m_uiVortexTimer -= uiDiff;
            */

            if (m_uiArcaneBreathTimer < uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_ARCANE_BREATH : SPELL_ARCANE_BREATH_H) == CAST_OK)
                    m_uiArcaneBreathTimer = urand(13000, 16000);
            }
            else
                m_uiArcaneBreathTimer -= uiDiff;

            if (m_uiPowerSparkTimer < uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_SPARK) == CAST_OK)
                {
                    DoScriptText(SAY_EMOTE_SPARK, m_creature);
                    m_uiPowerSparkTimer = 30000;
                }
            }
            else
                m_uiPowerSparkTimer -= uiDiff;

            if (m_creature->GetHealthPercent() < 50.0f)
            {
                SetCombatMovement(false);
                m_creature->SetLevitate(true);
                m_creature->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_UNK_2);
                // Move idle first, so we can avoid evading, because of the waypoint movement
                m_creature->GetMotionMaster()->MoveIdle();
                m_creature->GetMotionMaster()->MovePoint(0, aCenterMovePos[0], aCenterMovePos[1], aCenterMovePos[2] + 30.0f);

                StartNextDialogueText(SAY_END_PHASE_1);
                m_uiPhase = PHASE_TRANSITION_1;
            }

            DoMeleeAttackIfReady();

            break;
        case PHASE_DISCS:

            if (m_uiOverloadTimer < uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_ARCANE_BOMB) == CAST_OK)
                {
                    if (!urand(0, 3))
                        DoScriptText(SAY_SHELL, m_creature);

                    m_uiOverloadTimer = urand(16000, 19000);
                }
            }
            else
                m_uiOverloadTimer -= uiDiff;

            // Note: the boss should move in certain points before he does the breath ability
            if (m_uiArcanePulseTimer < uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_SURGE_OF_POWER_PULSE) == CAST_OK)
                {
                    DoScriptText(SAY_DEEP_BREATH, m_creature);
                    DoScriptText(SAY_EMOTE_BREATH, m_creature);
                    m_uiArcanePulseTimer = 60000;
                }
            }
            else
                m_uiArcanePulseTimer -= uiDiff;

            if (m_uiArcaneStormTimer < uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_ARCANE_STORM : SPELL_ARCANE_STORM_H) == CAST_OK)
                    m_uiArcaneStormTimer = urand(15000, 17000);
            }
            else
                m_uiArcaneStormTimer -= uiDiff;

            break;
        case PHASE_DRAGONS:

            if (m_uiStaticFieldTimer < uiDiff)
            {
                // Cast Static Field spell on a number of targets, based on difficulty
                for (uint8 i = 0; i < m_uiMaxStaticFieldTargets; ++i)
                {
                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                    {
                        if (DoCastSpellIfCan(pTarget, SPELL_STATIC_FIELD_SUMMON, CAST_TRIGGERED) == CAST_OK)
                        {
                            switch (urand(0, 2))
                            {
                            case 0:
                                DoScriptText(SAY_SPELL_1, m_creature);
                                break;
                            case 1:
                                DoScriptText(SAY_SPELL_2, m_creature);
                                break;
                            case 2:
                                DoScriptText(SAY_SPELL_3, m_creature);
                                break;
                            }
                            m_uiStaticFieldTimer = urand(10000, 17000);
                        }
                    }
                }
            }
            else
                m_uiStaticFieldTimer -= uiDiff;

            if (m_uiSurgeOfPowerTimer < uiDiff)
            {
                if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                {
                    if (DoCastSpellIfCan(pTarget, SPELL_SURGE_OF_POWER) == CAST_OK)
                    {
                        if (!urand(0, 3))
                            DoScriptText(SAY_SURGE, m_creature);

                        m_uiSurgeOfPowerTimer = urand(5000, 15000);
                    }
                }
            }
            else
                m_uiSurgeOfPowerTimer -= uiDiff;

            break;
        case PHASE_TRANSITION_1:
        case PHASE_TRANSITION_2:
            // Nothing here - wait for transition to finish
            break;
        }
    }
    void UpdateAI(const uint32 uiDiff) override
    {
        DialogueUpdate(uiDiff);

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

        // Don't use spells during the epilogue
        if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
            return;

        if (m_bIsFirstPhase)
        {
            // *Heroic mode only:
            if (!m_bIsRegularMode)
            {
                if (m_uiShockBarrierTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_SHOCK_BARRIER) == CAST_OK)
                    {
                        m_uiPyroblastTimer = 1000;
                        m_uiShockBarrierTimer = 60000;
                    }
                }
                else
                    m_uiShockBarrierTimer -= uiDiff;

                if (m_uiPyroblastTimer)
                {
                    if (m_uiPyroblastTimer <= uiDiff)
                    {
                        if (DoCastSpellIfCan(m_creature, SPELL_PYROBLAST) == CAST_OK)
                            m_uiPyroblastTimer = 0;
                    }
                    else
                        m_uiPyroblastTimer -= uiDiff;
                }
            }

            if (m_uiFireballTimer < uiDiff)
            {
                if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                {
                    if (DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_FIREBALL : SPELL_FIREBALL_H) == CAST_OK)
                        m_uiFireballTimer = urand(2000, 4000);
                }
            }
            else
                m_uiFireballTimer -= uiDiff;

            if (m_uiPhoenixTimer < uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_PHOENIX) == CAST_OK)
                {
                    DoScriptText(SAY_PHOENIX, m_creature);
                    m_uiPhoenixTimer = 45000;
                }
            }
            else
                m_uiPhoenixTimer -= uiDiff;

            if (m_uiFlameStrikeTimer < uiDiff)
            {
                if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                {
                    if (DoCastSpellIfCan(pTarget, SPELL_FLAME_STRIKE) == CAST_OK)
                    {
                        DoScriptText(SAY_FLAMESTRIKE, m_creature);
                        m_uiFlameStrikeTimer = urand(15000, 25000);
                    }
                }
            }
            else
                m_uiFlameStrikeTimer -= uiDiff;

            // Below 50%
            if (m_creature->GetHealthPercent() < 50.0f)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_TELEPORT_CENTER, CAST_INTERRUPT_PREVIOUS) == CAST_OK)
                {
                    SetCombatMovement(false);
                    m_creature->GetMotionMaster()->Clear();
                    m_creature->GetMotionMaster()->MoveIdle();

                    m_bIsFirstPhase = false;
                }
            }

            DoMeleeAttackIfReady();
        }
        else
        {
            if (m_uiGravityLapseTimer < uiDiff)
            {
                switch (m_uiGravityLapseStage)
                {
                    case 0:
                        // Cast Gravity Lapse on Players
                        if (DoCastSpellIfCan(m_creature, SPELL_GRAVITY_LAPSE) == CAST_OK)
                        {
                            if (m_bFirstGravityLapse)
                            {
                                DoScriptText(SAY_GRAVITY_LAPSE, m_creature);
                                m_bFirstGravityLapse = false;
                            }
                            else
                                DoScriptText(SAY_RECAST_GRAVITY, m_creature);

                            m_uiGravityLapseTimer = 2000;
                            m_uiGravityIndex = 0;
                            ++m_uiGravityLapseStage;
                        }
                        break;
                    case 1:
                        // Summon spheres and apply the Gravity Lapse visual - upon visual expire, the gravity lapse is removed
                        if (DoCastSpellIfCan(m_creature, SPELL_GRAVITY_LAPSE_VISUAL) == CAST_OK)
                        {
                            for (uint8 i = 0; i < MAX_ARCANE_SPHERES; ++i)
                                DoCastSpellIfCan(m_creature, SPELL_ARCANE_SPHERE_SUMMON, CAST_TRIGGERED);

                            m_uiGravityLapseTimer = 30000;
                            ++m_uiGravityLapseStage;
                        }
                        break;
                    case 2:
                        // Cast Power Feedback and stay stunned for 10 secs - also break the statues if they are not broken
                        if (DoCastSpellIfCan(m_creature, SPELL_POWER_FEEDBACK) == CAST_OK)
                        {
                            DoScriptText(SAY_TIRED, m_creature);
                            RemoveGravityLapse();
                            m_uiGravityLapseTimer = 10000;
                            m_uiGravityLapseStage = 0;
                        }
                        break;
                }
            }
            else
                m_uiGravityLapseTimer -= uiDiff;
        }
    }
    void UpdateAI(const uint32 uiDiff) override
    {
        DialogueUpdate(uiDiff);

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

        if (m_uiBerserkTimer)
        {
            if (m_uiBerserkTimer <= uiDiff)
            {
                // it's unclear wether it casts Berserk or Ascend to Heavens
                if (DoCastSpellIfCan(m_creature, SPELL_ASCEND_HEAVENS, CAST_INTERRUPT_PREVIOUS) == CAST_OK)
                {
                    DoScriptText(SAY_BERSERK, m_creature);
                    m_uiBerserkTimer = 0;
                }
            }
            else
                m_uiBerserkTimer -= uiDiff;
        }

        if (m_uiQuantumStrikeTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_QUANTUM_STRIKE : SPELL_QUANTUM_STRIKE_H) == CAST_OK)
                m_uiQuantumStrikeTimer = 4000;
        }
        else
            m_uiQuantumStrikeTimer -= uiDiff;

        if (m_uiBigBangTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_BIG_BANG : SPELL_BIG_BANG_H) == CAST_OK)
                m_uiBigBangTimer = 90000;
        }
        else
            m_uiBigBangTimer -= uiDiff;

        if (m_uiCosmicSmashTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_COSMIC_SMASH_SUMMON : SPELL_COSMIC_SMASH_SUMMON_H) == CAST_OK)
                m_uiCosmicSmashTimer = urand(40000, 50000);
        }
        else
            m_uiCosmicSmashTimer -= uiDiff;

        if (m_uiPhasePunchTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_PHASE_PUNCH) == CAST_OK)
                m_uiPhasePunchTimer = 15000;
        }
        else
            m_uiPhasePunchTimer -= uiDiff;

        // summons are happening only above 20% hp
        if (!m_bIsLowHealth)
        {
            if (m_uiCollapsingStarTimer < uiDiff)
            {
                // spawn as many stars as it's needed to a max of 4
                uint8 uiMaxStars = MAX_BLACK_HOLES - m_uiActiveStars;
                if (uiMaxStars)
                {
                    for (uint8 i = 0; i < uiMaxStars; ++i)
                        DoSpawnCollapsingStar();

                    DoScriptText(SAY_SUMMON_STAR, m_creature);
                    m_uiCollapsingStarTimer = 60000;
                }
                else
                    m_uiCollapsingStarTimer = 10000;
            }
            else
                m_uiCollapsingStarTimer -= uiDiff;

            if (m_uiConstellationTimer < uiDiff)
            {
                // activate as many constelations as it's needed to a max of 3
                uint8 uiMaxConstellations = MAX_ACTIVE_CONSTELATIONS - m_uiActiveConstelations;
                if (uiMaxConstellations)
                {
                    m_uiConstellationTimer = 50000;

                    for (uint8 i = 0; i < uiMaxConstellations; ++i)
                        ActivateRandomConstellation();
                }
                else
                    m_uiConstellationTimer = 10000;
            }
            else
                m_uiConstellationTimer -= uiDiff;
        }

        // switch to second phase
        if (!m_bIsLowHealth && m_creature->GetHealthPercent() < 20.0f)
        {
            DoScriptText(SAY_PHASE_2, m_creature);
            m_bIsLowHealth = true;

            // despawn all remaining blackholes and collapsing stars
            for (GuidList::const_iterator itr = m_lSummonedGuids.begin(); itr != m_lSummonedGuids.end(); ++itr)
            {
                if (Creature* pBlackHole = m_creature->GetMap()->GetCreature(*itr))
                    pBlackHole->ForcedDespawn();
            }

            // spawn new worm holes
            for (uint8 i = 0; i < MAX_WORM_HOLES; ++i)
                m_creature->SummonCreature(NPC_WORM_HOLE, afWormHoles[i][0], afWormHoles[i][1], afWormHoles[i][2], 0, TEMPSUMMON_DEAD_DESPAWN, 0);
        }

        DoMeleeAttackIfReady();
    }
    void UpdateAI(const uint32 uiDiff) override
    {
        switch (m_uiPhase)
        {
            case PHASE_CHANNEL:

                if (m_uiSummonDefenderTimer < uiDiff)
                {
                    DoSummonAshtongue(SPELL_SUMMON_DEFENDER);
                    m_uiSummonDefenderTimer = 15000;
                }
                else
                    m_uiSummonDefenderTimer -= uiDiff;

                if (m_lSorcerersGUIDList.size() <= m_uiChannelersDead)
                {
                    if (m_uiSummonSorcererTimer < uiDiff)
                    {
                        DoSummonAshtongue(SPELL_SUMMON_SORCERER);
                        m_uiSummonSorcererTimer = urand(20000, 30000);
                    }
                    else
                        m_uiSummonSorcererTimer -= uiDiff;
                }

                if (m_uiSummonPackTimer < uiDiff)
                {
                    DoSummonAshtongue();
                    m_uiSummonPackTimer = 35000;
                }
                else
                    m_uiSummonPackTimer -= uiDiff;

                break;
            case PHASE_COMBAT:

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

                if (!m_bHasYelledOnce && m_creature->GetHealthPercent() < 15.0f)
                {
                    DoScriptText(SAY_LOW_HEALTH, m_creature);
                    m_bHasYelledOnce = true;
                }

                if (m_uiDestructivePoisonTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_DESTRUCTIVE_POISON) == CAST_OK)
                        m_uiDestructivePoisonTimer = 15000;
                }
                else
                    m_uiDestructivePoisonTimer -= uiDiff;

                if (m_uiLightningBoltTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CHAIN_LIGHTNING) == CAST_OK)
                        m_uiLightningBoltTimer = 10000;
                }
                else
                    m_uiLightningBoltTimer -= uiDiff;

                DoMeleeAttackIfReady();

                break;
            case PHASE_EPILOGUE:
                DialogueUpdate(uiDiff);
                break;
        }
    }
 void UpdateAI(const uint32 uiDiff) { DialogueUpdate(uiDiff); }
Beispiel #9
0
    void UpdateEscortAI(const uint32 uiDiff) override
    {
        DialogueUpdate(uiDiff);

        if (m_uiOutroTimer)
        {
            if (m_uiOutroTimer <= uiDiff)
            {
                switch (m_uiOutroPhase)
                {
                    case 0:
                        DoScriptText(SAY_REMULOS_OUTRO_1, m_creature);
                        m_uiOutroTimer = 3000;
                        break;
                    case 1:
                        // Despawn Remulos after the outro is finished - he will respawn automatically at his home position after a few min
                        DoScriptText(SAY_REMULOS_OUTRO_2, m_creature);
                        m_creature->SetRespawnDelay(1 * MINUTE);
                        m_creature->ForcedDespawn(3000);
                        m_uiOutroTimer = 0;
                        break;
                }
                ++m_uiOutroPhase;
            }
            else
                m_uiOutroTimer -= uiDiff;
        }

        // during the battle
        if (m_uiShadesummonTimer)
        {
            if (m_uiShadesummonTimer <= uiDiff)
            {
                // do this yell only first time
                if (m_bIsFirstWave)
                {
                    // summon 3 shades inside the house
                    for (uint8 i = 0; i < MAX_SHADOWS; ++i)
                        m_creature->SummonCreature(NPC_NIGHTMARE_PHANTASM, aShadowsLocations[i].m_fX, aShadowsLocations[i].m_fY, aShadowsLocations[i].m_fZ, 0, TEMPSPAWN_DEAD_DESPAWN, 0);

                    if (Creature* pEranikus = m_creature->GetMap()->GetCreature(m_eranikusGuid))
                        DoScriptText(SAY_ERANIKUS_ATTACK_1, pEranikus);

                    ++m_uiSummonCount;
                    SetEscortPaused(false);
                    m_bIsFirstWave = false;
                }

                // Summon 3 shades per turn until the maximum summon turns are reached
                float fX, fY, fZ;
                // Randomize the summon point
                uint8 uiSummonPoint = roll_chance_i(70) ? uint32(MAX_SHADOWS) : urand(MAX_SHADOWS + 1, MAX_SHADOWS + 2);

                if (m_uiSummonCount < MAX_SUMMON_TURNS)
                {
                    for (uint8 i = 0; i < MAX_SHADOWS; ++i)
                    {
                        m_creature->GetRandomPoint(aShadowsLocations[uiSummonPoint].m_fX, aShadowsLocations[uiSummonPoint].m_fY, aShadowsLocations[uiSummonPoint].m_fZ, 10.0f, fX, fY, fZ);
                        m_creature->SummonCreature(NPC_NIGHTMARE_PHANTASM, fX, fY, fZ, 0.0f, TEMPSPAWN_DEAD_DESPAWN, 0);
                    }

                    ++m_uiSummonCount;
                }

                // If all the shades were summoned then set Eranikus in combat
                // We don't count the dead shades, because the boss is usually set in combat before all shades are dead
                if (m_uiSummonCount == MAX_SUMMON_TURNS)
                {
                    m_uiShadesummonTimer = 0;

                    if (Creature* pEranikus = m_creature->GetMap()->GetCreature(m_eranikusGuid))
                    {
                        pEranikus->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0);
                        pEranikus->SetLevitate(false);
                        pEranikus->GetMotionMaster()->MovePoint(POINT_ID_ERANIKUS_COMBAT, aEranikusLocations[2].m_fX, aEranikusLocations[2].m_fY, aEranikusLocations[2].m_fZ);
                    }
                }
                else
                    m_uiShadesummonTimer = urand(20000, 30000);
            }
            else
                m_uiShadesummonTimer -= uiDiff;
        }

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

        if (m_uiHealTimer < uiDiff)
        {
            if (Unit* pTarget = DoSelectLowestHpFriendly(DEFAULT_VISIBILITY_DISTANCE))
            {
                switch (urand(0, 2))
                {
                    case 0: DoCastSpellIfCan(pTarget, SPELL_HEALING_TOUCH); break;
                    case 1: DoCastSpellIfCan(pTarget, SPELL_REJUVENATION);  break;
                    case 2: DoCastSpellIfCan(pTarget, SPELL_REGROWTH);      break;
                }
            }
            m_uiHealTimer = 10000;
        }
        else
            m_uiHealTimer -= uiDiff;

        if (m_uiStarfireTimer < uiDiff)
        {
            if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
            {
                if (DoCastSpellIfCan(pTarget, SPELL_STARFIRE) == CAST_OK)
                    m_uiStarfireTimer = 20000;
            }
        }
        else
            m_uiStarfireTimer -= uiDiff;

        DoMeleeAttackIfReady();
    }
Beispiel #10
0
    void UpdateAI(const uint32 uiDiff) override
    {
        DialogueUpdate(uiDiff);

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

        if (!m_bHasLowHp && m_creature->GetHealthPercent() < 20.0f)
        {
            DoScriptText(SAY_LOWHP, m_creature);
            m_bHasLowHp = true;
        }

        if (m_uiPyroblastTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_PYROBLAST) == CAST_OK)
            {
                m_uiPyroblastTimer = 40000;
                DoScriptText(SAY_PYRO, m_creature);
            }
        }
        else
            m_uiPyroblastTimer -= uiDiff;

        if (m_uiFireballTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_FIREBALL) == CAST_OK)
                m_uiFireballTimer = 4000;
        }
        else
            m_uiFireballTimer -= uiDiff;

        if (m_uiFrostBoltTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_FROSTBOLT) == CAST_OK)
                m_uiFrostBoltTimer = urand(4000, 6000);
        }
        else
            m_uiFrostBoltTimer -= uiDiff;

        if (m_uiConeColtTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, SPELL_CONE_OF_COLD) == CAST_OK)
                m_uiConeColtTimer = urand(7000, 12000);
        }
        else
            m_uiConeColtTimer -= uiDiff;

        if (m_uiFireBlastTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_FIRE_BLAST) == CAST_OK)
                m_uiFireBlastTimer = urand(5000, 16000);
        }
        else
            m_uiFireBlastTimer -= uiDiff;

        if (m_uiArcaneMissileTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_ARCANE_MISSILES) == CAST_OK)
                m_uiArcaneMissileTimer = urand(5000, 8000);
        }
        else
            m_uiArcaneMissileTimer -= uiDiff;

        DoMeleeAttackIfReady();
    }
    void UpdateAI(const uint32 uiDiff) override
    {
        DialogueUpdate(uiDiff);

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

        if (m_uiFelfireShockTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FELFIRE_SHOCK : SPELL_FELFIRE_SHOCK_H) == CAST_OK)
                m_uiFelfireShockTimer = urand(35000, 45000);
        }
        else
            m_uiFelfireShockTimer -= uiDiff;

        if (m_uiKnockAwayTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, SPELL_KNOCK_AWAY) == CAST_OK)
            {
                m_uiKnockAwayTimer = urand(30000, 35000);
                m_uiFelfireLineupTimer = 2000;
            }
        }
        else
            m_uiKnockAwayTimer -= uiDiff;

        // Prepare the boss for charging
        if (m_uiFelfireLineupTimer)
        {
            if (m_uiFelfireLineupTimer <= uiDiff)
            {
                if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                {
                    if (DoCastSpellIfCan(pTarget, SPELL_CHARGE_TARGETING) == CAST_OK)
                    {
                        // ToDo: the Wrath-Scryer's Felfire npcs should be summoned at this point and aligned to the chosen target!
                        m_creature->CastSpell(m_creature, SPELL_FELFIRE_LINE_UP, TRIGGERED_OLD_TRIGGERED);
                        DoScriptText(urand(0, 1) ? SAY_CHARGE_1 : SAY_CHARGE_2, m_creature, pTarget);

                        m_uiChargeTimer        = 2500;
                        m_uiFelfireLineupTimer = 0;
                    }
                }
            }
            else
                m_uiFelfireLineupTimer -= uiDiff;
        }

        // Charge the target
        if (m_uiChargeTimer)
        {
            if (m_uiChargeTimer <= uiDiff)
            {
                m_creature->RemoveAurasDueToSpell(SPELL_KNOCK_AWAY);
                SetCombatMovement(false); // prevents interrupting charge
                // Note: this spell will also light up the Wrath-Scryer's Felfire npcs
                if (DoCastSpellIfCan(m_creature, SPELL_CHARGE) == CAST_OK)
                    m_uiChargeTimer = 0;
            }
            else
                m_uiChargeTimer -= uiDiff;
        }

        DoMeleeAttackIfReady();
    }
        void UpdateAI(const uint32 uiDiff) override
        {
            if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            {
                return;
            }

            DialogueUpdate(uiDiff);

            switch (m_uiPhase)
            {
            case PHASE_TRANSITION:
                // Transition phase is handled in the dialogue helper; however we don't want the spell timers to be decreased so we use a specific phase
                break;
            case PHASE_SACRIFICE:
                // Final phase - use the same spells
                // no break;
            case PHASE_ARMAGEDDON:

                // In the last phase he uses Armageddon continuously
                if (m_uiArmageddonTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_ARMAGEDDON) == CAST_OK)
                    {
                        m_uiArmageddonTimer = m_uiPhase == PHASE_SACRIFICE ? 20000 : 30000;
                    }
                }
                else
                {
                    m_uiArmageddonTimer -= uiDiff;
                }

                // Go to next phase and start transition dialogue
                if (m_uiPhase == PHASE_ARMAGEDDON && m_creature->GetHealthPercent() < 25.0f)
                {
                    StartNextDialogueText(PHASE_SACRIFICE);
                }

                // no break - use the spells from the phases below;
            case PHASE_DARKNESS:

                // In the last phase he uses this spell more often
                if (m_uiDarknessOfSoulsTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_DARKNESS_OF_SOULS) == CAST_OK)
                    {
                        m_uiDarknessOfSoulsTimer = m_uiPhase == PHASE_SACRIFICE ? 30000 : 45000;
                    }
                }
                else
                {
                    m_uiDarknessOfSoulsTimer -= uiDiff;
                }

                if (m_uiFlameDartTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_FLAME_DART) == CAST_OK)
                    {
                        m_uiFlameDartTimer = urand(25000, 30000);
                    }
                }
                else
                {
                    m_uiFlameDartTimer -= uiDiff;
                }

                // Go to next phase and start transition dialogue
                if (m_uiPhase == PHASE_DARKNESS && m_creature->GetHealthPercent() < 55.0f)
                {
                    StartNextDialogueText(PHASE_ARMAGEDDON);
                }

                // no break - use the spells from the phase below;
            case PHASE_INFERNO:

                if (m_uiKalecSummonTimer)
                {
                    if (m_uiKalecSummonTimer <= uiDiff)
                    {
                        m_creature->SummonCreature(NPC_KALECGOS, aKalegSpawnLoc[0], aKalegSpawnLoc[1], aKalegSpawnLoc[2], aKalegSpawnLoc[3], TEMPSUMMON_CORPSE_DESPAWN, 0);
                        m_uiKalecSummonTimer = 0;
                    }
                    else
                    {
                        m_uiKalecSummonTimer -= uiDiff;
                    }
                }

                if (m_uiLegionLightingTimer < uiDiff)
                {
                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                    {
                        if (DoCastSpellIfCan(pTarget, SPELL_LEGION_LIGHTING) == CAST_OK)
                        {
                            m_uiLegionLightingTimer = urand(10000, 15000);
                        }
                    }
                }
                else
                {
                    m_uiLegionLightingTimer -= uiDiff;
                }

                if (m_uiFireBloomTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_FIRE_BLOOM) == CAST_OK)
                    {
                        m_uiFireBloomTimer = 20000;
                    }
                }
                else
                {
                    m_uiFireBloomTimer -= uiDiff;
                }

                if (m_uiSoulFlyTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_SOUL_FLY) == CAST_OK)
                    {
                        m_uiSoulFlyTimer = urand(3000, 10000);
                    }
                }
                else
                {
                    m_uiSoulFlyTimer -= uiDiff;
                }

                // Only spawn a Shadow orb when necessary
                if (m_uiShieldOrbCount < m_uiMaxShieldOrbs)
                {
                    if (m_uiShieldOrbTimer < uiDiff)
                    {
                        // Get some random coords for the Orb
                        float fX, fY, fZ;
                        m_creature->GetNearPoint2D(fX, fY, 25.0f, frand(0, 2 * M_PI_F));
                        fZ = frand(35.0f, 45.0f);

                        m_creature->SummonCreature(NPC_SHIELD_ORB, fX, fY, fZ, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
                        ++m_uiShieldOrbCount;
                        m_uiShieldOrbTimer = 30000;
                    }
                    else
                    {
                        m_uiShieldOrbTimer -= uiDiff;
                    }
                }

                // Go to next phase and start transition dialogue
                if (m_uiPhase == PHASE_INFERNO && m_creature->GetHealthPercent() < 85.0f)
                {
                    StartNextDialogueText(PHASE_DARKNESS);
                }

                DoMeleeAttackIfReady();

                break;
            }
        }
Beispiel #13
0
    void UpdateAI(const uint32 uiDiff)
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        DialogueUpdate(uiDiff);

        switch (m_uiPhase)
        {
            case PHASE_TRANSITION:
                // Transition phase is handled in the dialogue helper; however we don't want the spell timers to be decreased so we use a specific phase
                break;
            case PHASE_SACRIFICE:
                // Final phase - use the same spells
                // no break;
            case PHASE_ARMAGEDDON:

                // In the last phase he uses Armageddon continuously
                if (m_uiArmageddonTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_ARMAGEDDON) == CAST_OK)
                        m_uiArmageddonTimer = m_uiPhase == PHASE_SACRIFICE ? 20000 : 30000;
                }
                else
                    m_uiArmageddonTimer -= uiDiff;

                // Go to next phase and start transition dialogue
                if (m_uiPhase == PHASE_ARMAGEDDON && m_creature->GetHealthPercent() < 25.0f)
                    StartNextDialogueText(PHASE_SACRIFICE);

                // no break - use the spells from the phases below;
            case PHASE_DARKNESS:

                // In the last phase he uses this spell more often
                /* ToDo: Uncomment this spell when the Blue Dragonfight Orbs are implemented
                if (m_uiDarknessOfSoulsTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_DARKNESS_OF_SOULS) == CAST_OK)
                        m_uiDarknessOfSoulsTimer = m_uiPhase == PHASE_SACRIFICE ? 30000 : 45000;
                }
                else
                    m_uiDarknessOfSoulsTimer -= uiDiff;
                */

                if (m_uiFlameDartTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_FLAME_DART) == CAST_OK)
                        m_uiFlameDartTimer = urand(25000, 30000);
                }
                else
                    m_uiFlameDartTimer -= uiDiff;

                // Go to next phase and start transition dialogue
                if (m_uiPhase == PHASE_DARKNESS && m_creature->GetHealthPercent() < 55.0f)
                    StartNextDialogueText(PHASE_ARMAGEDDON);

                // no break - use the spells from the phase below;
            case PHASE_INFERNO:

                if (m_uiKalecSummonTimer)
                {
                    if (m_uiKalecSummonTimer <= uiDiff)
                    {
                        m_creature->SummonCreature(NPC_KALECGOS, m_creature->GetPositionX(), m_creature->GetPositionY(), 85.0f, 3.80f, TEMPSUMMON_CORPSE_DESPAWN, 0);
                        m_uiKalecSummonTimer = 0;
                    }
                    else
                        m_uiKalecSummonTimer -= uiDiff;
                }

                if (m_uiLegionLightingTimer < uiDiff)
                {
                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                    {
                        if (DoCastSpellIfCan(pTarget, SPELL_LEGION_LIGHTING) == CAST_OK)
                            m_uiLegionLightingTimer = urand(10000, 15000);
                    }
                }
                else
                    m_uiLegionLightingTimer -= uiDiff;

                if (m_uiFireBloomTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_FIRE_BLOOM) == CAST_OK)
                        m_uiFireBloomTimer = 20000;
                }
                else
                    m_uiFireBloomTimer -= uiDiff;

                if (m_uiSoulFlyTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_SOUL_FLY) == CAST_OK)
                        m_uiSoulFlyTimer = urand(3000, 10000);
                }
                else
                    m_uiSoulFlyTimer -= uiDiff;

                // Go to next phase and start transition dialogue
                if (m_uiPhase == PHASE_INFERNO && m_creature->GetHealthPercent() < 85.0f)
                    StartNextDialogueText(PHASE_DARKNESS);

                DoMeleeAttackIfReady();

                break;
        }
    }
 void Update(uint32 uiDiff) { DialogueUpdate(uiDiff); }