void AttackStart(Unit* pWho)
	{
		if (!pWho)
			return;

		if (m_creature->Attack(pWho, true))
		{
			m_creature->AddThreat(pWho, 0.0f);
			m_creature->SetInCombatWith(pWho);
			pWho->SetInCombatWith(m_creature);

			if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
				m_creature->GetMotionMaster()->MovementExpired();

			if (IsCombatMovement())
				m_creature->GetMotionMaster()->MoveChase(pWho);
		}
	}
void FollowerAI::AttackStart(Unit* pWho)
{
    if (!pWho)
        return;

    if (me->Attack(pWho, true))
    {
        me->AddThreat(pWho, 0.0f);
        me->SetInCombatWith(pWho);
        pWho->SetInCombatWith(me);

        if (me->HasUnitState(UNIT_STAT_FOLLOW))
            me->ClearUnitState(UNIT_STAT_FOLLOW);

        if (IsCombatMovement())
            me->GetMotionMaster()->MoveChase(pWho);
    }
}
Beispiel #3
0
    void MoveInLineOfSight(Unit* pWho) override
    {
        if (pWho->GetEntry() == NPC_BRONJAHM)
        {
            if (m_creature->IsWithinDistInMap(pWho, INTERACTION_DISTANCE))
            {
                DoCastSpellIfCan(pWho, SPELL_CONSUME_SOUL_TRIGGER, CAST_TRIGGERED);

                // Inform the instance about a used soul fragment
                if (instance_forge_of_souls* pInstance = (instance_forge_of_souls*)m_creature->GetInstanceData())
                    pInstance->SetGuid(DATA_SOULFRAGMENT_REMOVE, m_creature->GetObjectGuid());

                m_creature->ForcedDespawn();
                return;
            }
            if (IsCombatMovement())
            {
                SetCombatMovement(false);
                m_creature->GetMotionMaster()->MoveFollow(pWho, 0.0f, 0.0f);
            }
        }
    }
    void UpdateAI(const uint32 diff) override
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        // Shoot
        if (m_uiShootTimer < diff)
        {
            if (m_creature->GetDistance2d(m_creature->getVictim()) >= 5.0f && DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHOOT_2) == CAST_OK)
                m_uiShootTimer = urand(2500, 3500);
        }
        else 
            m_uiShootTimer -= diff;

        if (!IsCombatMovement())
        { //Melee
            if (!m_bInMelee && (m_creature->GetDistance2d(m_creature->getVictim()) < 5.0f || m_creature->GetDistance2d(m_creature->getVictim()) > 95.0f || !m_creature->IsWithinLOSInMap(m_creature->getVictim())))
            {
                SetCombatMovement(true);
                DoStartMovement(m_creature->getVictim());
                m_bInMelee = true;
                return;
            }
        }
        else
        { //Range
            if (m_bInMelee && m_creature->GetDistance2d(m_creature->getVictim()) >= 5.0f && m_creature->GetDistance2d(m_creature->getVictim()) <= 95.0f && m_creature->IsWithinLOSInMap(m_creature->getVictim()))
            {
                SetCombatMovement(false);
                m_bInMelee = false;
                DoStartNoMovement(m_creature->getVictim());
                return;
            }
        }
        
        DoMeleeAttackIfReady();
    }
Beispiel #5
0
/// This function shows if combat movement is enabled, overwrite for more info
void ScriptedAI::GetAIInformation(ChatHandler& reader)
{
    reader.PSendSysMessage("ScriptedAI, combat movement is %s", reader.GetOnOffStr(IsCombatMovement()));
}
Beispiel #6
0
    void UpdateAI(const uint32 uiDiff)
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        if (m_uiPhase == 0)                                 // Phase 1
        {
            // Switching Phase, Soulstorm is cast in SpellHitTarget
            if (m_creature->GetHealthPercent() < 30.0f)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_TELEPORT) == CAST_OK)
                    m_uiPhase = 1;
            }

            // Corrupt Soul
            if (m_uiCorruptSoulTimer < uiDiff)
            {
                if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                {
                    if (DoCastSpellIfCan(pTarget, SPELL_CORRUPT_SOUL) == CAST_OK)
                    {
                        DoScriptText(SAY_CORRUPT_SOUL, m_creature);
                        m_uiCorruptSoulTimer = urand(20000, 30000);
                    }
                }
            }
            else
                m_uiCorruptSoulTimer -= uiDiff;

            // Magic's Bane
            if (m_uiMagicsBaneTimer < uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_MAGICS_BANE) == CAST_OK)
                    m_uiMagicsBaneTimer = urand(7000, 15000);
            }
            else
                m_uiMagicsBaneTimer -= uiDiff;

            // Used to prevent Shadowbolt-Casting on Aggro for a few seconds
            if (m_uiShadowboltTimer <= uiDiff)
                m_uiShadowboltTimer = 0;
            else
                m_uiShadowboltTimer -= uiDiff;

            // Use ShadowBolt as default attack if victim is not in range
            // TODO - not entirely clear how this works in case the tank is out of shadow-bolt range
            if (!m_uiShadowboltTimer && !m_creature->CanReachWithMeleeAttack(m_creature->getVictim()) && m_creature->GetCombatDistance(m_creature->getVictim()) < 20.0f)
            {
                if (IsCombatMovement())
                {
                    SetCombatMovement(false);
                    m_creature->GetMotionMaster()->MoveIdle();
                    m_creature->StopMoving();
                }
                DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHADOW_BOLT);
            }
            else
            {
                if (!IsCombatMovement())
                {
                    SetCombatMovement(true);
                    m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
                    m_uiShadowboltTimer = 2000;             // Give some time to chase
                }

                DoMeleeAttackIfReady();
            }
        }
        else                                                // Soulstorm Phase
        {
            if (m_uiFearTimer < uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_FEAR) == CAST_OK)
                    m_uiFearTimer = urand(10000, 15000);
            }
            else
                m_uiFearTimer -= uiDiff;

            // Default attack
            if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                DoCastSpellIfCan(pTarget, SPELL_SHADOW_BOLT);
        }
    }
Beispiel #7
0
    void UpdateAI(const uint32 uiDiff)
    {
        if (m_bIntro && m_uiIntroTimer <= uiDiff)
        {
            switch (m_uiStage)
            {
            case 0:
                DoScriptText(SAY_INTRO_01, m_creature);
                m_uiStage = 1;
                m_uiIntroTimer = 5*IN_MILLISECONDS;
                break;
            case 1:
                DoScriptText(SAY_INTRO_02, m_creature);
                m_uiStage = 2;
                m_uiIntroTimer = 5*IN_MILLISECONDS;
                break;
            case 2:
                DoScriptText(SAY_INTRO_03, m_creature);
                m_uiStage = 3;
                m_bIntro = false;
                break;
            default:
                break;
            }
        }
        else
            m_uiIntroTimer -= uiDiff;

        if (m_creature->HasAura(SPELL_MANA_BARRIER))
        {
            if (m_creature->GetHealth() <= m_creature->GetMaxHealth())
            {
                if (m_creature->GetPower(POWER_MANA) > (m_creature->GetMaxHealth() - m_creature->GetHealth()))
                {
                    m_creature->SetPower(POWER_MANA, m_creature->GetPower(POWER_MANA) - (m_creature->GetMaxHealth() - m_creature->GetHealth()));
                    m_creature->SetHealth(m_creature->GetMaxHealth());
                }
                else
                    m_creature->SetPower(POWER_MANA, 0);
            }
        }

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

        if (m_bMovementStarted)
            return;

        DoControlObsessedPlayers();

        switch (m_uiStage)
        {
        case 3:
            if (IsCombatMovement())
                SetCombatMovement(false);

            if (m_uiShadowBoltTimer <= uiDiff)
            {
                if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                {
                    switch (m_uiMode)
                    {
                    case RAID_DIFFICULTY_10MAN_NORMAL:
                    case RAID_DIFFICULTY_10MAN_HEROIC:
                        DoCast(pTarget, SPELL_SHADOW_BOLT_N);
                        break;
                    case RAID_DIFFICULTY_25MAN_NORMAL:
                    case RAID_DIFFICULTY_25MAN_HEROIC:
                        DoCast(pTarget, SPELL_SHADOW_BOLT_H);
                        break;
                    }
                    m_uiShadowBoltTimer = urand(5*IN_MILLISECONDS, 8*IN_MILLISECONDS);
                }
            }
            else
                m_uiShadowBoltTimer -= uiDiff;

            if (m_uiSummonGuardsTimer <= uiDiff)
            {
                switch (m_uiMode)
                {
                case RAID_DIFFICULTY_10MAN_NORMAL:
                    CallGuards();
                    m_uiSummonGuardsTimer = MINUTE*IN_MILLISECONDS;
                    break;
                case RAID_DIFFICULTY_25MAN_NORMAL:
                    CallGuards();
                    m_uiSummonGuardsTimer = 40*IN_MILLISECONDS;
                    break;
                case RAID_DIFFICULTY_10MAN_HEROIC:
                    CallGuards();
                    m_uiSummonGuardsTimer = MINUTE*IN_MILLISECONDS;
                    break;
                case RAID_DIFFICULTY_25MAN_HEROIC:
                    CallGuards();
                    m_uiSummonGuardsTimer = 40*IN_MILLISECONDS;
                    break;
                default:
                    m_uiSummonGuardsTimer = MINUTE*IN_MILLISECONDS;
                    break;
                }
            }
            else
                m_uiSummonGuardsTimer -= uiDiff;

            break;
        case 4:
            if (m_uiFrostboltTimer <= uiDiff)
            {
                switch (m_uiMode)
                {
                case RAID_DIFFICULTY_10MAN_NORMAL:
                    DoCast(m_creature->getVictim(), SPELL_FROSTBOLT_10_N);
                    break;
                case RAID_DIFFICULTY_25MAN_NORMAL:
                case RAID_DIFFICULTY_10MAN_HEROIC:
                case RAID_DIFFICULTY_25MAN_HEROIC:
                    DoCast(m_creature->getVictim(), SPELL_FROSTBOLT_25);
                    break;
                default:
                    break;
                }
                m_uiFrostboltTimer = urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS);
            }
            else
                m_uiFrostboltTimer -= uiDiff;

            if (m_uiFrostboltVolleyTimer <= uiDiff)
            {
                switch (m_uiMode)
                {
                case RAID_DIFFICULTY_10MAN_NORMAL:
                    DoCast(m_creature->getVictim(), SPELL_FROSTBOLT_VOLLEY_10_N);
                    break;
                case RAID_DIFFICULTY_25MAN_NORMAL:
                    DoCast(m_creature->getVictim(), SPELL_FROSTBOLT_VOLLEY_25_N);
                    break;
                case RAID_DIFFICULTY_10MAN_HEROIC:
                case RAID_DIFFICULTY_25MAN_HEROIC:
                    DoCast(m_creature->getVictim(), SPELL_FROSTBOLT_VOLLEY_H);
                    break;
                default:
                    break;
                }
                m_uiFrostboltVolleyTimer = urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS);
            }
            else
                m_uiFrostboltVolleyTimer -= uiDiff;

            if (m_uiTouchOfInsignificanceTimer <= uiDiff)
            {
                DoCast(m_creature->getVictim(), SPELL_TOUCH_OF_INSIGNIFICANCE);
                m_uiTouchOfInsignificanceTimer = urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS);
            }
            else
                m_uiTouchOfInsignificanceTimer -= uiDiff;

            if (m_uiSummonSpiritTimer <= uiDiff)
            {
                CallSpirit();
                m_uiSummonSpiritTimer = urand(8*IN_MILLISECONDS, 15*IN_MILLISECONDS);
            }
            else
                m_uiSummonSpiritTimer -= uiDiff;

            if (m_uiSummonGuardsTimer <= uiDiff)
            {
                switch (m_uiMode)
                {
                case RAID_DIFFICULTY_10MAN_NORMAL:
                    break;
                case RAID_DIFFICULTY_25MAN_NORMAL:
                    break;
                case RAID_DIFFICULTY_10MAN_HEROIC:
                    CallGuard();
                    m_uiSummonGuardsTimer = 45*IN_MILLISECONDS;
                    break;
                case RAID_DIFFICULTY_25MAN_HEROIC:
                    CallGuards();
                    m_uiSummonGuardsTimer = 60*IN_MILLISECONDS;
                    break;
                default:
                    break;
                }
            }
            else
                m_uiSummonGuardsTimer -= uiDiff;

            break;
        }

        if (m_uiMode != RAID_DIFFICULTY_10MAN_NORMAL)
        {
            if (m_uiDominateMindTimer <= uiDiff)
            {
                DominateMind();

                switch (m_uiMode)
                {
                case RAID_DIFFICULTY_10MAN_HEROIC:
                case RAID_DIFFICULTY_25MAN_NORMAL:
                    m_uiDominateMindTimer = urand(12*IN_MILLISECONDS, 15*IN_MILLISECONDS);
                    break;
                case RAID_DIFFICULTY_25MAN_HEROIC:
                    m_uiDominateMindTimer = urand(4*IN_MILLISECONDS, 6*IN_MILLISECONDS);
                    break;
                default:
                    m_uiDominateMindTimer = 0;
                    break;
                }
            }
            else
                m_uiDominateMindTimer -= uiDiff;
        }

        if (m_uiDeathAndDecayTimer <= uiDiff)
        {
            if(Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
            {
                if(pTarget)
                {
                    switch (m_uiMode)
                    {
                    case RAID_DIFFICULTY_10MAN_NORMAL:
                    case RAID_DIFFICULTY_10MAN_HEROIC:
                        DoCast(pTarget, SPELL_DEATH_AND_DECAY_10);
                        break;
                    case RAID_DIFFICULTY_25MAN_NORMAL:
                        DoCast(pTarget, SPELL_DEATH_AND_DECAY_25_N);
                        break;
                    case RAID_DIFFICULTY_25MAN_HEROIC:
                        DoCast(pTarget, SPELL_DEATH_AND_DECAY_25_H);
                        break;
                    default:
                        break;
                    }
                }
            }
            m_uiDeathAndDecayTimer = urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS);
        }
        else
            m_uiDeathAndDecayTimer -= uiDiff;

        if(!m_creature->HasAura(SPELL_MANA_BARRIER) && m_uiStage == 3)
        {
            m_uiStage = 4;
            DoScriptText(SAY_PHASE2_01, m_creature);
            SetCombatMovement(false);
            m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
        }

        if(m_uiBerserkTimer <= uiDiff)
        {
            DoCast(m_creature, SPELL_BERSERK);
            DoScriptText(SAY_BERSERK_01, m_creature);
        };

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

        // When Solarian reaches 20% she will transform into a huge void walker.
        if (m_Phase != PHASE_VOID && m_creature->GetHealthPercent() < 20.0f)
        {
            m_Phase = PHASE_VOID;

            // To make sure she behaves like expected
            m_bIsAppearDelay = false;
            if (!IsCombatMovement())
            {
                SetCombatMovement(true);
                m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
            }
            m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
            m_creature->SetVisibility(VISIBILITY_ON);

            DoScriptText(SAY_VOIDA, m_creature);
            DoScriptText(SAY_VOIDB, m_creature);

            m_creature->SetArmor(WV_ARMOR);
            m_creature->SetDisplayId(MODEL_VOIDWALKER);
            m_creature->SetFloatValue(OBJECT_FIELD_SCALE_X, m_fDefaultSize*2.5f);
        }

        if (m_bIsAppearDelay)
        {
            if (m_uiAppearDelayTimer < uiDiff)
            {
                m_bIsAppearDelay = false;

                if (m_Phase == PHASE_SUMMON_AGENTS)
                {
                    m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                    m_creature->SetVisibility(VISIBILITY_OFF);
                }
                // Let move and attack again
                else if (!IsCombatMovement())
                {
                    SetCombatMovement(true);
                    m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
                }

                m_uiAppearDelayTimer = 2000;
            }
            else
                m_uiAppearDelayTimer -= uiDiff;

            // Combat is still on hold
            return;
        }

        switch (m_Phase)
        {
            case PHASE_NORMAL:
                // Wrath of the Astromancer targets a random player which will explode after 6 secondes
                if (m_uiWrathOfTheAstromancerTimer < uiDiff)
                {
                    // Target the tank ?
                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1, SPELL_WRATH_OF_THE_ASTROMANCER, SELECT_FLAG_PLAYER))
                    {
                        if (DoCastSpellIfCan(pTarget, SPELL_WRATH_OF_THE_ASTROMANCER, CAST_INTERRUPT_PREVIOUS) == CAST_OK)
                            m_uiWrathOfTheAstromancerTimer = 25000;
                    }
                    else
                        m_uiWrathOfTheAstromancerTimer = 10000;
                }
                else
                    m_uiWrathOfTheAstromancerTimer -= uiDiff;

                // Blinding Light Timer
                if (m_uiBlindingLightTimer < uiDiff)
                {
                    // She casts this spell every 45 seconds. It is a kind of Moonfire spell, which she strikes down on the whole raid simultaneously. It hits everyone in the raid for 2280 to 2520 arcane damage.
                    if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_BLINDING_LIGHT) == CAST_OK)
                        m_uiBlindingLightTimer = 45000;
                }
                else
                    m_uiBlindingLightTimer -= uiDiff;

                // Arcane Missiles Timer - TODO - check timer, if this spell is cast always, CombatMovement should be disabled here
                if (m_uiArcaneMissilesTimer < uiDiff)
                {
                    // Solarian casts Arcane Missiles on on random targets in the raid.
                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                    {
                        if (!m_creature->HasInArc(2.5f, pTarget))
                            pTarget = m_creature->getVictim();

                        if (pTarget)
                            DoCastSpellIfCan(pTarget, SPELL_ARCANE_MISSILES);
                    }

                    m_uiArcaneMissilesTimer = 5000;
                }
                else
                    m_uiArcaneMissilesTimer -= uiDiff;

                // Phase 1 Timer
                if (m_uiPhaseOneTimer < uiDiff)
                {
                    m_Phase = PHASE_SUMMON_AGENTS;

                    // After these 50 seconds she portals to the middle of the room and disappears, leaving 3 light portals behind.
                    m_creature->GetMotionMaster()->Clear();
                    m_creature->StopMoving();
                    m_creature->AttackStop();

                    SetCombatMovement(false);

                    m_creature->NearTeleportTo(CENTER_X, CENTER_Y, CENTER_Z, CENTER_O, true);

                    for(int i = 0; i <= 2; ++i)
                    {
                        if (!i)
                        {
                            m_aPortals[i][0] = Portal_X(SMALL_PORTAL_RADIUS);
                            m_aPortals[i][1] = Portal_Y(m_aPortals[i][0], SMALL_PORTAL_RADIUS);
                            m_aPortals[i][2] = CENTER_Z;
                        }
                        else
                        {
                            m_aPortals[i][0] = Portal_X(LARGE_PORTAL_RADIUS);
                            m_aPortals[i][1] = Portal_Y(m_aPortals[i][0], LARGE_PORTAL_RADIUS);
                            m_aPortals[i][2] = PORTAL_Z;
                        }
                    }

                    if ((abs(int(m_aPortals[2][0]) - int(m_aPortals[1][0])) < 7) && (abs(int(m_aPortals[2][1]) - int(m_aPortals[1][1])) < 7))
                    {
                        int i = 1;
                        if (abs(int(CENTER_X) + int(26.0f) - int(m_aPortals[2][0])) < 7)
                            i = -1;

                        m_aPortals[2][0] = m_aPortals[2][0]+7*i;
                        m_aPortals[2][1] = Portal_Y(m_aPortals[2][0], LARGE_PORTAL_RADIUS);
                    }

                    for (int i = 0; i <= 2; ++i)
                        m_creature->SummonCreature(NPC_ASTROMANCER_SOLARIAN_SPOTLIGHT, m_aPortals[i][0], m_aPortals[i][1], m_aPortals[i][2], CENTER_O, TEMPSUMMON_TIMED_DESPAWN, m_uiPhaseTwoTimer+m_uiPhaseThreeTimer+m_uiAppearDelayTimer+1700);

                    m_bIsAppearDelay = true;
                    m_uiPhaseOneTimer = 48000;            //  2s for appearDelay

                    // Do nothing more, if phase switched
                    return;
                }
                else
                    m_uiPhaseOneTimer -= uiDiff;

                DoMeleeAttackIfReady();
                break;

            case PHASE_SUMMON_AGENTS:
                // Check Phase 2 Timer
                if (m_uiPhaseTwoTimer < uiDiff)
                {
                    //10 seconds after Solarian disappears, 12 mobs spawn out of the three portals.
                    m_Phase = PHASE_SUMMON_PRIESTS;
                    for (int i = 0; i <= 2; ++i)
                    {
                        for (int j = 1; j <= 4; ++j)
                            m_creature->SummonCreature(NPC_SOLARIUM_AGENT, m_aPortals[i][0], m_aPortals[i][1], m_aPortals[i][2], 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                    }

                    DoScriptText(SAY_SUMMON1, m_creature);

                    m_uiPhaseTwoTimer = 8000;               //  2s for appearDelay
                }
                else
                    m_uiPhaseTwoTimer -= uiDiff;

                break;

            case PHASE_SUMMON_PRIESTS:
                // Check Phase 3 Timer
                if (m_uiPhaseThreeTimer < uiDiff)
                {
                    m_Phase = PHASE_NORMAL;

                    // 15 seconds later Solarian reappears out of one of the 3 portals. Simultaneously, 2 healers appear in the two other portals.
                    int i = irand(0, 2);
                    m_creature->GetMotionMaster()->Clear();
                    m_creature->GetMap()->CreatureRelocation(m_creature, m_aPortals[i][0], m_aPortals[i][1], m_aPortals[i][2], CENTER_O);

                    for (int j = 0; j <= 2; ++j)
                        if (j != i)
                            m_creature->SummonCreature(NPC_SOLARIUM_PRIEST, m_aPortals[j][0], m_aPortals[j][1], m_aPortals[j][2], 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);

                    m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                    m_creature->SetVisibility(VISIBILITY_ON);

                    DoScriptText(SAY_SUMMON2, m_creature);

                    m_bIsAppearDelay = true;
                    m_uiPhaseThreeTimer = 15000;
                }
                else
                    m_uiPhaseThreeTimer -= uiDiff;

                break;

            case PHASE_VOID:
                // Fear Timer
                if (m_uiFearTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_FEAR) == CAST_OK)
                        m_uiFearTimer = 20000;
                }
                else
                    m_uiFearTimer -= uiDiff;

                // Void Bolt Timer
                if (m_uiVoidBoltTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_VOID_BOLT) == CAST_OK)
                        m_uiVoidBoltTimer = 10000;
                }
                else
                    m_uiVoidBoltTimer -= uiDiff;

                DoMeleeAttackIfReady();
                break;
        }
    }
    void UpdateAI(const uint32 diff) override
    {
        //Return since we have no target
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        // Pummel
        if (m_uiPummelTimer < diff)
        {
            if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_PUMMEL) == CAST_OK)
                m_uiPummelTimer = 12000;
        }
        else 
            m_uiPummelTimer -= diff;

        // Knock Away
        if (m_uiKnockAwayTimer < diff)
        {
            if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_KNOCK_AWAY) == CAST_OK)
                m_uiKnockAwayTimer = urand(15000, 20000);
        }
        else 
            m_uiKnockAwayTimer -= diff;

        // Summon Rifleman
        if (m_uiSummonRiflemanTimer < diff)
        {
            //Cast
            switch (urand(0, 8))
            {
                case 0:
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_1X,ADD_1Y,ADD_1Z,ADD_1O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_2X,ADD_2Y,ADD_2Z,ADD_2O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_4X,ADD_4Y,ADD_4Z,ADD_4O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    break;
                case 1:
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_2X,ADD_2Y,ADD_2Z,ADD_2O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_3X,ADD_3Y,ADD_3Z,ADD_3O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_5X,ADD_5Y,ADD_5Z,ADD_5O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    break;
                case 2:
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_3X,ADD_3Y,ADD_3Z,ADD_3O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_4X,ADD_4Y,ADD_4Z,ADD_4O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_6X,ADD_6Y,ADD_6Z,ADD_6O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    break;
                case 3:
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_4X,ADD_4Y,ADD_4Z,ADD_4O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_5X,ADD_5Y,ADD_5Z,ADD_5O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_7X,ADD_7Y,ADD_7Z,ADD_7O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    break;
                case 4:
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_5X,ADD_5Y,ADD_5Z,ADD_5O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_6X,ADD_6Y,ADD_6Z,ADD_6O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_8X,ADD_8Y,ADD_8Z,ADD_8O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    break;
                case 5:
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_6X,ADD_6Y,ADD_6Z,ADD_6O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_7X,ADD_7Y,ADD_7Z,ADD_7O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_9X,ADD_9Y,ADD_9Z,ADD_9O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    break;
                case 6:
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_7X,ADD_7Y,ADD_7Z,ADD_7O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_8X,ADD_8Y,ADD_8Z,ADD_8O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_1X,ADD_1Y,ADD_1Z,ADD_1O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    break;
                case 7:
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_8X,ADD_8Y,ADD_8Z,ADD_8O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_9X,ADD_9Y,ADD_9Z,ADD_9O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_2X,ADD_2Y,ADD_2Z,ADD_2O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    break;
                case 8:
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_9X,ADD_9Y,ADD_9Z,ADD_9O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_1X,ADD_1Y,ADD_1Z,ADD_1O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    m_creature->SummonCreature(NPC_CRIMSON_RIFLEMAN, ADD_3X,ADD_3Y,ADD_3Z,ADD_3O, TEMPSUMMON_TIMED_DESPAWN, 240000);
                    break;
            }            
            m_uiSummonRiflemanTimer = 10000;
        }
        else 
            m_uiSummonRiflemanTimer -= diff;

        // Shoot
        if (m_uiShootTimer < diff)
        {
            if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHOOT) == CAST_OK)
                m_uiShootTimer = urand(2500, 3500);
        }
        else 
            m_uiShootTimer -= diff;

        if (!IsCombatMovement())
        { //Melee
            if (!m_bInMelee && (m_creature->GetDistance2d(m_creature->getVictim()) < 8.0f || m_creature->GetDistance2d(m_creature->getVictim()) > 27.0f || !m_creature->IsWithinLOSInMap(m_creature->getVictim())))
            {
                SetCombatMovement(true);
                DoStartMovement(m_creature->getVictim());
                m_bInMelee = true;
                return;
            }
        }
        else
        { //Range
            if (m_bInMelee && m_creature->GetDistance2d(m_creature->getVictim()) >= 8.0f && m_creature->GetDistance2d(m_creature->getVictim()) <= 27.0f && m_creature->IsWithinLOSInMap(m_creature->getVictim()))
            {
                SetCombatMovement(false);
                m_bInMelee = false;
                DoStartNoMovement(m_creature->getVictim());
                return;
            }
        }

        DoMeleeAttackIfReady();
    }