コード例 #1
0
        void SpellHit(Unit* caster, const SpellInfo* spell) override
        {
            if (withhead)
                return;

            if (spell->Id == SPELL_FLYING_HEAD)
            {
                if (Phase < 3)
                    ++Phase;
                else
                    Phase = 3;
                withhead = true;
                me->RemoveAllAuras();
                me->SetName("Headless Horseman");
                me->SetFullHealth();
                SaySound(SAY_REJOINED);
                DoCast(me, SPELL_HEAD);
                caster->GetMotionMaster()->Clear(false);
                caster->GetMotionMaster()->MoveFollow(me, 6, float(urand(0, 5)));
                //DoResetThreat();//not sure if need
                ThreatContainer::StorageType threatlist = caster->getThreatManager().getThreatList();
                for (ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
                {
                    Unit* unit = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid());
                    if (unit && unit->IsAlive() && unit != caster)
                        me->AddThreat(unit, caster->getThreatManager().getThreat(unit));
                }
            }
        }
コード例 #2
0
void BossAI::TeleportCheaters()
{
    float x, y, z;
    me->GetPosition(x, y, z);

    ThreatContainer::StorageType threatList = me->getThreatManager().getThreatList();
    for (ThreatContainer::StorageType::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr)
        if (Unit* target = (*itr)->getTarget())
            if (target->GetTypeId() == TYPEID_PLAYER && !CheckBoundary(target))
                target->NearTeleportTo(x, y, z, 0);
}
コード例 #3
0
ファイル: GuardAI.cpp プロジェクト: MistyWorld/MistyWorld_6xx
bool GuardAI::CanSeeAlways(WorldObject const* obj)
{
    if (!obj->isType(TYPEMASK_UNIT))
        return false;

    ThreatContainer::StorageType threatList = me->getThreatManager().getThreatList();
    for (ThreatContainer::StorageType::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr)
        if ((*itr)->getUnitGuid() == obj->GetGUID())
            return true;

    return false;
}
コード例 #4
0
 void CastGravityLapseKnockUp()
 {
     ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
     ThreatContainer::StorageType::const_iterator i = threatlist.begin();
     for (i = threatlist.begin(); i != threatlist.end(); ++i)
     {
         Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid());
         if (unit && (unit->GetTypeId() == TYPEID_PLAYER))
             // Knockback into the air
             unit->CastSpell(unit, SPELL_GRAVITY_LAPSE_DOT, true, 0, 0, me->GetGUID());
     }
 }
コード例 #5
0
            void SetBloodvenomTarget()
            {
                ThreatContainer::StorageType threatList = me->getThreatManager().getThreatList();
                ThreatContainer::StorageType::const_iterator hostileReference = threatList.begin();
                SummonList::const_iterator bloodvenomGUID = BloodVenoms.begin();

                while (bloodvenomGUID != BloodVenoms.end() && hostileReference != threatList.end())
                {
                    if (Creature* bloodvenom = ObjectAccessor::GetCreature(*me, *bloodvenomGUID))
                        bloodvenom->AI()->SetGUID((*hostileReference)->getUnitGuid());

                    ++hostileReference;
                    ++bloodvenomGUID;
                }
            }
コード例 #6
0
 void RemoveGravityLapse()
 {
     ThreatContainer::StorageType threatlist = me->GetThreatManager().getThreatList();
     ThreatContainer::StorageType::const_iterator i = threatlist.begin();
     for (i = threatlist.begin(); i != threatlist.end(); ++i)
     {
         Unit* unit = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid());
         if (unit && (unit->GetTypeId() == TYPEID_PLAYER))
         {
             unit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_FLY);
             unit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_DOT);
             unit->SetCanFly(false);
         }
     }
 }
コード例 #7
0
 void CastGravityLapseFly()                              // Use Fly Packet hack for now as players can't cast "fly" spells unless in map 530. Has to be done a while after they get knocked into the air...
 {
     ThreatContainer::StorageType threatlist = me->GetThreatManager().getThreatList();
     ThreatContainer::StorageType::const_iterator i = threatlist.begin();
     for (i = threatlist.begin(); i != threatlist.end(); ++i)
     {
         Unit* unit = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid());
         if (unit && (unit->GetTypeId() == TYPEID_PLAYER))
         {
             // Also needs an exception in spell system.
             unit->CastSpell(unit, SPELL_GRAVITY_LAPSE_FLY, true, 0, 0, me->GetGUID());
             unit->SetCanFly(true);
         }
     }
 }
コード例 #8
0
 void TeleportPlayersToSelf()
 {
     float x = KaelLocations[0][0];
     float y = KaelLocations[0][1];
     me->SetPosition(x, y, LOCATION_Z, 0.0f);
     ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
     ThreatContainer::StorageType::const_iterator i = threatlist.begin();
     for (i = threatlist.begin(); i != threatlist.end(); ++i)
     {
         Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid());
         if (unit && (unit->GetTypeId() == TYPEID_PLAYER))
             unit->CastSpell(unit, SPELL_TELEPORT_CENTER, true);
     }
     DoCast(me, SPELL_TELEPORT_CENTER, true);
 }
コード例 #9
0
ファイル: pet_mage.cpp プロジェクト: Jildor/TrinityCore
            bool IsInThreatList(Unit* target)
            {
                Unit* owner = me->GetCharmerOrOwner();

                std::list<Unit*> targets;
                Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(me, me, 30.0f);
                Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(me, targets, u_check);
                me->VisitNearbyObject(40.0f, searcher);

                for (std::list<Unit*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
                {
                    if ((*iter) == target)
                    {
                        // Consider only units without CC
                        if (!(*iter)->HasBreakableByDamageCrowdControlAura((*iter)))
                        {
                            ThreatContainer::StorageType triggers = (*iter)->getThreatManager().getThreatList();
                            for (ThreatContainer::StorageType::const_iterator trig_citr = triggers.begin(); trig_citr != triggers.end(); ++trig_citr)
                            {
                                // Try to find threat referenced to owner
                                if ((*trig_citr)->getTarget() == owner)
                                    return true;
                            }
                        }
                    }
                }
                return false;
            }
コード例 #10
0
        void MergeThreatList(Creature* target)
        {
            if (!target)
                return;

            ThreatContainer::StorageType threatlist = target->getThreatManager().getThreatList();
            for (ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
            {
                Unit* unit = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid());
                if (unit)
                {
                    DoModifyThreatPercent(unit, -100);
                    float threat = target->getThreatManager().getThreat(unit);
                    me->AddThreat(unit, threat);       // This makes it so that the unit has the same amount of threat in Reliquary's threatlist as in the target creature's (One of the Essences).
                }
            }
        }
コード例 #11
0
void ScriptedAI::DoResetThreat()
{
    if (!me->CanHaveThreatList() || me->getThreatManager().isThreatListEmpty())
    {
        sLog->outError(LOG_FILTER_TSCR, "DoResetThreat called for creature that either cannot have threat list or has empty threat list (me entry = %d)", me->GetEntry());
        return;
    }

    ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();

    for (ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
    {
        Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid());
        if (unit && DoGetThreat(unit))
            DoModifyThreatPercent(unit, -100);
    }
}
コード例 #12
0
 void CastGravityLapseFly()                              // Use Fly Packet hack for now as players can't cast "fly" spells unless in map 530. Has to be done a while after they get knocked into the air...
 {
     ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
     ThreatContainer::StorageType::const_iterator i = threatlist.begin();
     for (i = threatlist.begin(); i != threatlist.end(); ++i)
     {
         Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid());
         if (unit && (unit->GetTypeId() == TYPEID_PLAYER))
         {
             // Also needs an exception in spell system.
             unit->CastSpell(unit, SPELL_GRAVITY_LAPSE_FLY, true, 0, 0, me->GetGUID());
             // Use packet hack
             WorldPacket data(SMSG_MOVE_SET_CAN_FLY, 12);
             data.append(unit->GetPackGUID());
             data << uint32(0);
             unit->SendMessageToSet(&data, true);
         }
     }
 }
コード例 #13
0
        void RemoveGravityLapse()
        {
            ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
            ThreatContainer::StorageType::const_iterator i = threatlist.begin();
            for (i = threatlist.begin(); i != threatlist.end(); ++i)
            {
                Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid());
                if (unit && (unit->GetTypeId() == TYPEID_PLAYER))
                {
                    unit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_FLY);
                    unit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_DOT);

                    WorldPacket data(SMSG_MOVE_UNSET_CAN_FLY, 12);
                    data.append(unit->GetPackGUID());
                    data << uint32(0);
                    unit->SendMessageToSet(&data, true);
                }
            }
        }
コード例 #14
0
        Unit* CalculateHatefulStrikeTarget()
        {
            uint32 health = 0;
            Unit* target = nullptr;

            ThreatContainer::StorageType threatList = me->getThreatManager().getThreatList();
            for (ThreatContainer::StorageType::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr)
            {
                Unit* unit = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid());
                if (unit && me->IsWithinMeleeRange(unit))
                {
                    if (unit->GetHealth() > health)
                    {
                        health = unit->GetHealth();
                        target = unit;
                    }
                }
            }

            return target;
        }
コード例 #15
0
Unit* ScriptedAI::SelectUnit(SelectAggroTarget pTarget, uint32 uiPosition)
{
    ThreatContainer::StorageType threatList = me->getThreatManager().getThreatList();
    ThreatContainer::StorageType::const_iterator itr = threatList.begin();
    ThreatContainer::StorageType::reverse_iterator ritr = threatList.rbegin();

    if (uiPosition >= threatList.size() || !threatList.size())
        return NULL;

    switch (pTarget)
    {
    case SELECT_TARGET_RANDOM:
        advance (itr , uiPosition +  (rand() % (threatList.size() - uiPosition)));
        return Unit::GetUnit((*me), (*itr)->getUnitGuid());
        break;

    case SELECT_TARGET_TOPAGGRO:
        advance (itr , uiPosition);
        return Unit::GetUnit((*me), (*itr)->getUnitGuid());
        break;

    case SELECT_TARGET_BOTTOMAGGRO:
        advance (ritr , uiPosition);
        return Unit::GetUnit((*me), (*ritr)->getUnitGuid());
        break;

    default:
        return UnitAI::SelectTarget(pTarget, uiPosition);
    }
}
コード例 #16
0
ファイル: boss_murmur.cpp プロジェクト: Keader/Sunwell
        void UpdateAI(uint32 diff)
        {
            if (!UpdateVictim() || me->HasUnitState(UNIT_STATE_CASTING))
                return;

            events.Update(diff);
            switch (events.GetEvent())
            {
                case EVENT_SPELL_SONIC_BOOM:
                    Talk(EMOTE_SONIC_BOOM);
                    me->CastSpell(me, DUNGEON_MODE(SPELL_SONIC_BOOM_CAST_N, SPELL_SONIC_BOOM_CAST_H), false);
                    events.RepeatEvent(28500);
                    events.DelayEvents(1500);
                    events.ScheduleEvent(EVENT_SPELL_SONIC_BOOM_EFFECT, 0);
                    return;
                case EVENT_SPELL_SONIC_BOOM_EFFECT:
                    me->CastSpell(me, DUNGEON_MODE(SPELL_SONIC_BOOM_EFFECT_N, SPELL_SONIC_BOOM_EFFECT_H), true);
                    events.PopEvent();
                    break;
                case EVENT_SPELL_MURMURS_TOUCH:
                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 80.0f, true))
                        me->CastSpell(target, DUNGEON_MODE(SPELL_MURMURS_TOUCH_N, SPELL_MURMURS_TOUCH_H), false);
                    events.RepeatEvent(urand(25000, 35000));
                    break;
                case EVENT_SPELL_RESONANCE:
                    if (!me->IsWithinMeleeRange(me->GetVictim()))
                        me->CastSpell(me, SPELL_RESONANCE, false);
                    events.RepeatEvent(5000);
                    break;
                case EVENT_SPELL_MAGNETIC:
                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 80.0f, true))
                    {
                        me->CastSpell(target, SPELL_MAGNETIC_PULL, false);
                        events.RepeatEvent(urand(15000, 30000));
                        return;
                    }
                    events.RepeatEvent(500);
                    break;
                case EVENT_SPELL_THUNDERING:
                    me->CastSpell(me, SPELL_THUNDERING_STORM, true);
                    events.RepeatEvent(15000);
                    break;
                case EVENT_SPELL_SONIC_SHOCK:
                    me->CastSpell(me->GetVictim(), SPELL_SONIC_SHOCK, false);
                    events.RepeatEvent(urand(10000, 20000));
                    break;
            }

            if (!me->isAttackReady())
                return;

            if (!me->IsWithinMeleeRange(me->GetVictim()))
            {
                ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
                for (ThreatContainer::StorageType::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i)
                    if (Unit* target = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid()))
                        if (target->IsAlive() && me->IsWithinMeleeRange(target))
                        {
                            me->TauntApply(target);
                            break;
                        }
            }

            DoMeleeAttackIfReady();
        }
コード例 #17
0
ファイル: pet_mage.cpp プロジェクト: Jildor/TrinityCore
            void Init()
            {
                Unit* owner = me->GetCharmerOrOwner();

                std::list<Unit*> targets;
                Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(me, me, 30.0f);
                Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(me, targets, u_check);
                me->VisitNearbyObject(40.0f, searcher);

                Unit* highestThreatUnit = nullptr;
                float highestThreat = 0.0f;
                Unit* nearestPlayer = nullptr;
                for (std::list<Unit*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
                {
                    // Consider only units without CC
                    if (!(*iter)->HasBreakableByDamageCrowdControlAura((*iter)))
                    {
                        // Take first found unit
                        if (!highestThreatUnit && (*iter)->GetTypeId() != TYPEID_PLAYER)
                        {
                            highestThreatUnit = (*iter);
                            continue;
                        }
                        if (!nearestPlayer && ((*iter)->GetTypeId() == TYPEID_PLAYER))
                        {
                            nearestPlayer = (*iter);
                            continue;
                        }
                        // else compare best fit unit with current unit
                        ThreatContainer::StorageType triggers = (*iter)->getThreatManager().getThreatList();
                        for (ThreatContainer::StorageType::const_iterator trig_citr = triggers.begin(); trig_citr != triggers.end(); ++trig_citr)
                        {
                            // Try to find threat referenced to owner
                            if ((*trig_citr)->getTarget() == owner)
                            {
                                // Check if best fit hostile unit hs lower threat than this current unit
                                if (highestThreat < (*trig_citr)->getThreat())
                                {
                                    // If so, update best fit unit
                                    highestThreat = (*trig_citr)->getThreat();
                                    highestThreatUnit = (*iter);
                                    break;
                                }
                            }
                        }
                        // In case no unit with threat was found so far, always check for nearest unit (only for players)
                        if ((*iter)->GetTypeId() == TYPEID_PLAYER)
                        {
                            // If this player is closer than the previous one, update it
                            if (me->GetDistance((*iter)->GetPosition()) < me->GetDistance(nearestPlayer->GetPosition()))
                                nearestPlayer = (*iter);
                        }
                    }
                }
                // Prioritize units with threat referenced to owner
                if (highestThreat > 0.0f && highestThreatUnit)
                        me->Attack(highestThreatUnit, false);
                // If there is no such target, try to attack nearest hostile unit if such exists
                else if (nearestPlayer)
                        me->Attack(nearestPlayer, false);
            }
コード例 #18
0
ファイル: boss_murmur.cpp プロジェクト: Asandru/Script-Land
        void UpdateAI(uint32 diff)
        {
            //Return since we have no target or casting
            if (!UpdateVictim() || me->IsNonMeleeSpellCasted(false))
                return;

            // Sonic Boom
            if (SonicBoom)
            {
                DoCast(me, SPELL_SONIC_BOOM_EFFECT, true);
                SonicBoomEffect();

                SonicBoom = false;
                Resonance_Timer = 1500;
            }
            if (SonicBoom_Timer <= diff)
            {
                Talk(EMOTE_SONIC_BOOM);
                DoCast(me, SPELL_SONIC_BOOM_CAST);
                SonicBoom_Timer = 30000;
                SonicBoom = true;
                return;
            } else SonicBoom_Timer -= diff;

            // Murmur's Touch
            if (MurmursTouch_Timer <= diff)
            {
                if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 80, true))
                    DoCast(target, SPELL_MURMURS_TOUCH);
                MurmursTouch_Timer = urand(25000, 35000);
            } else MurmursTouch_Timer -= diff;

            // Resonance
            if (!SonicBoom && !(me->IsWithinMeleeRange(me->GetVictim())))
            {
                if (Resonance_Timer <= diff)
                {
                    DoCast(me, SPELL_RESONANCE);
                    Resonance_Timer = 5000;
                } else Resonance_Timer -= diff;
            }

            // Magnetic Pull
            if (MagneticPull_Timer <= diff)
            {
                if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                    if (target->GetTypeId() == TYPEID_PLAYER && target->IsAlive())
                    {
                        DoCast(target, SPELL_MAGNETIC_PULL);
                        MagneticPull_Timer = 15000+rand()%15000;
                        return;
                    }
                MagneticPull_Timer = 500;
            } else MagneticPull_Timer -= diff;

            if (IsHeroic())
            {
                // Thundering Storm
                if (ThunderingStorm_Timer <= diff)
                {
                    ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
                    for (ThreatContainer::StorageType::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i)
                        if (Unit* target = Unit::GetUnit(*me, (*i)->getUnitGuid()))
                            if (target->IsAlive() && !me->IsWithinDist(target, 35, false))
                                DoCast(target, SPELL_THUNDERING_STORM, true);
                    ThunderingStorm_Timer = 15000;
                } else ThunderingStorm_Timer -= diff;

                // Sonic Shock
                if (SonicShock_Timer <= diff)
                {
                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 20, false))
                        if (target->IsAlive())
                            DoCast(target, SPELL_SONIC_SHOCK);
                    SonicShock_Timer = 10000+rand()%10000;
                } else SonicShock_Timer -= diff;
            }

            // Select nearest most aggro target if top aggro too far
            if (!me->isAttackReady())
                return;
            if (!me->IsWithinMeleeRange(me->GetVictim()))
            {
                ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
                for (ThreatContainer::StorageType::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i)
                    if (Unit* target = Unit::GetUnit(*me, (*i)->getUnitGuid()))
                        if (target->IsAlive() && me->IsWithinMeleeRange(target))
                        {
                            me->TauntApply(target);
                            break;
                        }
            }

            DoMeleeAttackIfReady();
        }
コード例 #19
0
            void UpdateAI(uint32 diff) override
            {
                if (!UpdateVictim())
                    return;

                events.Update(diff);

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

                while (uint32 eventId = events.ExecuteEvent())
                {
                    switch (eventId)
                    {
                        case EVENT_SONIC_BOOM:
                            Talk(EMOTE_SONIC_BOOM);
                            DoCast(me, SPELL_SONIC_BOOM_CAST);
                            events.ScheduleEvent(EVENT_SONIC_BOOM, 30000);
                            events.ScheduleEvent(EVENT_RESONANCE, 1500);
                            break;
                        case EVENT_MURMURS_TOUCH:
                            if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 80.0f, true))
                                DoCast(target, SPELL_MURMURS_TOUCH);
                            events.ScheduleEvent(EVENT_MURMURS_TOUCH, urand(25000, 35000));
                            break;
                        case EVENT_RESONANCE:
                            if (!(me->IsWithinMeleeRange(me->GetVictim())))
                            {
                                DoCast(me, SPELL_RESONANCE);
                                events.ScheduleEvent(EVENT_RESONANCE, 5000);
                            }
                            break;
                        case EVENT_MAGNETIC_PULL:
                            if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
                            {
                                DoCast(target, SPELL_MAGNETIC_PULL);
                                events.ScheduleEvent(EVENT_MAGNETIC_PULL, urand(15000, 30000));
                                break;
                            }
                            events.ScheduleEvent(EVENT_MAGNETIC_PULL, 500);
                            break;
                        case EVENT_THUNDERING_STORM:
                            DoCastAOE(SPELL_THUNDERING_STORM, true);
                            events.ScheduleEvent(EVENT_THUNDERING_STORM, 15000);
                            break;
                        case EVENT_SONIC_SHOCK:
                            if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 20.0f, false))
                                DoCast(target, SPELL_SONIC_SHOCK);
                            events.ScheduleEvent(EVENT_SONIC_SHOCK, urand(10000, 20000));
                            break;
                    }

                    if (me->HasUnitState(UNIT_STATE_CASTING))
                        return;
                }

                // Select nearest most aggro target if top aggro too far
                if (!me->isAttackReady())
                    return;

                if (!me->IsWithinMeleeRange(me->GetVictim()))
                {
                    ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
                    for (ThreatContainer::StorageType::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i)
                        if (Unit* target = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid()))
                            if (me->IsWithinMeleeRange(target))
                            {
                                me->TauntApply(target);
                                break;
                            }
                }

                DoMeleeAttackIfReady();
            }
コード例 #20
0
        void UpdateAI(uint32 diff)
        {
            if (!UpdateVictim())
                return;

            //Shimmer_Timer Timer
            if (Shimmer_Timer <= diff)
            {
                //Remove old vulnerabilty spell
                if (CurrentVurln_Spell)
                    me->RemoveAurasDueToSpell(CurrentVurln_Spell);

                //Cast new random vulnerabilty on self
                uint32 spell = RAND(SPELL_FIRE_VULNERABILITY, SPELL_FROST_VULNERABILITY,
                    SPELL_SHADOW_VULNERABILITY, SPELL_NATURE_VULNERABILITY, SPELL_ARCANE_VULNERABILITY);

                DoCast(me, spell);
                CurrentVurln_Spell = spell;

                Talk(EMOTE_SHIMMER);
                Shimmer_Timer = 45000;
            } else Shimmer_Timer -= diff;

            //Breath1_Timer
            if (Breath1_Timer <= diff)
            {
                DoCastVictim(Breath1_Spell);
                Breath1_Timer = 60000;
            } else Breath1_Timer -= diff;

            //Breath2_Timer
            if (Breath2_Timer <= diff)
            {
                DoCastVictim(Breath2_Spell);
                Breath2_Timer = 60000;
            } else Breath2_Timer -= diff;

            //Affliction_Timer
            if (Affliction_Timer <= diff)
            {
                ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
                for (ThreatContainer::StorageType::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i)
                {
                    if ((*i) && (*i)->GetSource())
                    {
                        if (Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid()))
                        {
                            //Cast affliction
                            DoCast(unit, RAND(SPELL_BROODAF_BLUE, SPELL_BROODAF_BLACK,
                                               SPELL_BROODAF_RED, SPELL_BROODAF_BRONZE, SPELL_BROODAF_GREEN), true);

                            //Chromatic mutation if target is effected by all afflictions
                            if (unit->HasAura(SPELL_BROODAF_BLUE)
                                && unit->HasAura(SPELL_BROODAF_BLACK)
                                && unit->HasAura(SPELL_BROODAF_RED)
                                && unit->HasAura(SPELL_BROODAF_BRONZE)
                                && unit->HasAura(SPELL_BROODAF_GREEN))
                            {
                                //target->RemoveAllAuras();
                                //DoCast(target, SPELL_CHROMATIC_MUT_1);

                                //Chromatic mutation is causing issues
                                //Assuming it is caused by a lack of core support for Charm
                                //So instead we instant kill our target

                                //WORKAROUND
                                if (unit->GetTypeId() == TYPEID_PLAYER)
                                    unit->CastSpell(unit, 5, false);
                            }
                        }
                    }
                }

                Affliction_Timer = 10000;
            } else Affliction_Timer -= diff;

            //Frenzy_Timer
            if (Frenzy_Timer <= diff)
            {
                DoCast(me, SPELL_FRENZY);
                Talk(EMOTE_FRENZY);
                Frenzy_Timer = urand(10000, 15000);
            } else Frenzy_Timer -= diff;

            //Enrage if not already enraged and below 20%
            if (!Enraged && HealthBelowPct(20))
            {
                DoCast(me, SPELL_ENRAGE);
                Enraged = true;
            }

            DoMeleeAttackIfReady();
        }
コード例 #21
0
ファイル: boss_kalecgos.cpp プロジェクト: 125125/TrinityCore
        void UpdateAI(uint32 diff) override
        {
            if (!me->HasAura(AURA_SPECTRAL_INVISIBILITY))
                me->CastSpell(me, AURA_SPECTRAL_INVISIBILITY, true);

            if (!UpdateVictim())
                return;

            if (CheckTimer <= diff)
            {
                Creature* Kalec = ObjectAccessor::GetCreature(*me, KalecGUID);
                if (!Kalec || !Kalec->IsAlive())
                {
                    if (Creature* Kalecgos = ObjectAccessor::GetCreature(*me, KalecgosGUID))
                        Kalecgos->AI()->EnterEvadeMode();
                    return;
                }

                if (HealthBelowPct(10) && !isEnraged)
                {
                    if (Creature* Kalecgos = ObjectAccessor::GetCreature(*me, KalecgosGUID))
                        Kalecgos->AI()->DoAction(DO_ENRAGE);
                    DoAction(DO_ENRAGE);
                }

                Creature* Kalecgos = ObjectAccessor::GetCreature(*me, KalecgosGUID);
                if (Kalecgos && !Kalecgos->IsInCombat())
                {
                    EnterEvadeMode();
                    return;
                }

                if (!isBanished && HealthBelowPct(1))
                {
                    if (Kalecgos)
                    {
                        if (Kalecgos->HasAura(SPELL_BANISH))
                        {
                            me->DealDamage(me, me->GetHealth());
                            return;
                        }
                        DoAction(DO_BANISH);
                    }
                    else
                    {
                        me->MonsterTextEmote(EMOTE_UNABLE_TO_FIND, NULL);
                        EnterEvadeMode();
                        return;
                    }
                }
                CheckTimer = 1000;
            } else CheckTimer -= diff;

            if (ResetThreat <= diff)
            {
                ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
                for (ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
                {
                    if (Unit* unit = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid()))
                        if (unit->GetPositionZ() > me->GetPositionZ() + 5)
                            me->getThreatManager().modifyThreatPercent(unit, -100);
                }
                ResetThreat = 1000;
            } else ResetThreat -= diff;

            if (ShadowBoltTimer <= diff)
            {
                if (!(rand32() % 5))
                    Talk(SAY_SATH_SPELL1);
                DoCast(me, SPELL_SHADOW_BOLT);
                ShadowBoltTimer = 7000 + (rand32() % 3000);
            } else ShadowBoltTimer -= diff;

            if (AgonyCurseTimer <= diff)
            {
                Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
                if (!target)
                    target = me->GetVictim();
                DoCast(target, SPELL_AGONY_CURSE);
                AgonyCurseTimer = 20000;
            } else AgonyCurseTimer -= diff;

            if (CorruptionStrikeTimer <= diff)
            {
                if (!(rand32() % 5))Talk(SAY_SATH_SPELL2);
                DoCastVictim(SPELL_CORRUPTION_STRIKE);
                CorruptionStrikeTimer = 13000;
            } else CorruptionStrikeTimer -= diff;

            DoMeleeAttackIfReady();
        }
コード例 #22
0
ファイル: boss_kaelthas.cpp プロジェクト: Aminxhm/OregonCore
    void UpdateAI(const uint32 diff)
    {
        //Phase 1
        switch (Phase)
        {
        case 1:
            {
                Unit* pTarget = NULL;
                Creature* Advisor = NULL;

                //Subphase switch
                switch (PhaseSubphase)
                {
                //Subphase 1 - Start
                case 0:
                    if (Phase_Timer <= diff)
                    {
                        DoScriptText(SAY_INTRO_THALADRED, me);

                        //start advisor within 7 seconds
                        Phase_Timer = 7000;

                        PhaseSubphase++;
                    }
                    else Phase_Timer -= diff;
                    break;

                //Subphase 1 - Unlock advisor
                case 1:
                    if (Phase_Timer <= diff)
                    {
                        Advisor = (Creature*)(Unit::GetUnit((*me), m_auiAdvisorGuid[0]));

                        if (Advisor)
                        {
                            Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                            Advisor->setFaction(me->getFaction());

                            pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
                            if (pTarget)
                                Advisor->AI()->AttackStart(pTarget);
                        }

                        PhaseSubphase++;
                    }
                    else Phase_Timer -= diff;
                    break;

                //Subphase 2 - Start
                case 2:
                    Advisor = (Creature*)(Unit::GetUnit((*me), m_auiAdvisorGuid[0]));

                    if (Advisor && (Advisor->getStandState() == UNIT_STAND_STATE_DEAD))
                    {
                        DoScriptText(SAY_INTRO_SANGUINAR, me);

                        //start advisor within 12.5 seconds
                        Phase_Timer = 12500;

                        PhaseSubphase++;
                    }
                    break;

                //Subphase 2 - Unlock advisor
                case 3:
                    if (Phase_Timer <= diff)
                    {
                        Advisor = (Creature*)(Unit::GetUnit((*me), m_auiAdvisorGuid[1]));

                        if (Advisor)
                        {
                            Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                            Advisor->setFaction(me->getFaction());

                            pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
                            if (pTarget)
                                Advisor->AI()->AttackStart(pTarget);
                        }

                        PhaseSubphase++;
                    }
                    else Phase_Timer -= diff;
                    break;

                //Subphase 3 - Start
                case 4:
                    Advisor = (Creature*)(Unit::GetUnit((*me), m_auiAdvisorGuid[1]));

                    if (Advisor && (Advisor->getStandState() == UNIT_STAND_STATE_DEAD))
                    {
                        DoScriptText(SAY_INTRO_CAPERNIAN, me);

                        //start advisor within 7 seconds
                        Phase_Timer = 7000;

                        PhaseSubphase++;
                    }
                    break;

                //Subphase 3 - Unlock advisor
                case 5:
                    if (Phase_Timer <= diff)
                    {
                        Advisor = (Creature*)(Unit::GetUnit((*me), m_auiAdvisorGuid[2]));

                        if (Advisor)
                        {
                            Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                            Advisor->setFaction(me->getFaction());

                            pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
                            if (pTarget)
                                Advisor->AI()->AttackStart(pTarget);
                        }

                        PhaseSubphase++;
                    }
                    else Phase_Timer -= diff;
                    break;

                //Subphase 4 - Start
                case 6:
                    Advisor = (Creature*)(Unit::GetUnit((*me), m_auiAdvisorGuid[2]));

                    if (Advisor && (Advisor->getStandState() == UNIT_STAND_STATE_DEAD))
                    {
                        DoScriptText(SAY_INTRO_TELONICUS, me);

                        //start advisor within 8.4 seconds
                        Phase_Timer = 8400;

                        PhaseSubphase++;
                    }
                    break;

                //Subphase 4 - Unlock advisor
                case 7:
                    if (Phase_Timer <= diff)
                    {
                        Advisor = (Creature*)(Unit::GetUnit((*me), m_auiAdvisorGuid[3]));

                        if (Advisor)
                        {
                            Advisor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                            Advisor->setFaction(me->getFaction());

                            pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
                            if (pTarget)
                                Advisor->AI()->AttackStart(pTarget);
                        }

                        Phase_Timer = 3000;

                        PhaseSubphase++;
                    }
                    else Phase_Timer -= diff;
                    break;

                //End of phase 1
                case 8:
                    Advisor = (Creature*)(Unit::GetUnit((*me), m_auiAdvisorGuid[3]));

                    if (Advisor && (Advisor->getStandState() == UNIT_STAND_STATE_DEAD))
                    {
                        Phase = 2;
                        m_pInstance->SetData(DATA_KAELTHASEVENT, 2);

                        DoScriptText(SAY_PHASE2_WEAPON, me);
                        PhaseSubphase = 0;
                        Phase_Timer = 3500;
                        DoCast(me, SPELL_SUMMON_WEAPONS);
                    }
                    break;
                }
            }
            break;

        case 2:
            {
                if (PhaseSubphase == 0)
                {
                    if (Phase_Timer <= diff)
                        PhaseSubphase = 1;
                    else Phase_Timer -= diff;
                }

                //Spawn weapons
                if (PhaseSubphase == 1)
                {
                    me->CastSpell(me, SPELL_SUMMON_WEAPONS, false);

                    uint8 uiMaxWeapon = sizeof(m_auiSpellSummonWeapon) / sizeof(uint32);

                    for (uint32 i = 0; i < uiMaxWeapon; ++i)
                        me->CastSpell(me, m_auiSpellSummonWeapon[i], true);

                    PhaseSubphase = 2;
                    Phase_Timer = TIME_PHASE_2_3;
                }

                if (PhaseSubphase == 2)
                {
                    if (Phase_Timer < diff)
                    {
                        DoScriptText(SAY_PHASE3_ADVANCE, me);
                        m_pInstance->SetData(DATA_KAELTHASEVENT, 3);
                        Phase = 3;
                        PhaseSubphase = 0;
                    }
                    else Phase_Timer -= diff;
                }
            }
            break;

        case 3:
            {
                if (PhaseSubphase == 0)
                {
                    //Respawn advisors
                    Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);

                    Creature* Advisor;
                    for (uint32 i = 0; i < MAX_ADVISORS; i++)
                    {
                        Advisor = (Creature*)(Unit::GetUnit((*me), m_auiAdvisorGuid[i]));
                        if (!Advisor)
                            error_log("OSCR: Kael'Thas Advisor %u does not exist. Possibly despawned? Incorrectly Killed?", i);
                        else if (pTarget)
                            ((advisorbase_ai*)Advisor->AI())->Revive(pTarget);
                    }

                    PhaseSubphase = 1;
                    Phase_Timer = TIME_PHASE_3_4;
                }

                if (Phase_Timer <= diff)
                {
                    DoScriptText(SAY_PHASE4_INTRO2, me);
                    Phase = 4;

                    m_pInstance->SetData(DATA_KAELTHASEVENT, 4);

                    // Sometimes people can collect Aggro in Phase 1-3. Reset threat before releasing Kael.
                    DoResetThreat();

                    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);

                    if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
                        AttackStart(pTarget);

                    Phase_Timer = 30000;
                }
                else Phase_Timer -= diff;
            }
            break;

        case 4:
        case 5:
        case 6:
            {
                //Return since we have no target
                if (!UpdateVictim())
                    return;

                //Fireball_Timer
                if (!InGravityLapse && !ChainPyros && Phase != 5)
                {
                    if (Fireball_Timer <= diff)
                    {
                        if (!IsCastingFireball)
                        {
                            if (!me->IsNonMeleeSpellCast(false))
                            {
                                //interruptable
                                me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false);
                                int32 dmg = 20000 + rand() % 5000;
                                me->CastCustomSpell(me->getVictim(), SPELL_FIREBALL, &dmg, 0, 0, false);
                                IsCastingFireball = true;
                                Fireball_Timer = 2500;
                            }
                        }
                        else
                        {
                            //apply resistance
                            me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true);
                            IsCastingFireball = false;
                            Fireball_Timer = 5000 + rand() % 10000;
                        }
                    }
                    else Fireball_Timer -= diff;

                    //ArcaneDisruption_Timer
                    if (ArcaneDisruption_Timer <= diff)
                    {
                        DoCastVictim( SPELL_ARCANE_DISRUPTION, true);

                        ArcaneDisruption_Timer = 60000;
                    }
                    else ArcaneDisruption_Timer -= diff;

                    if (FlameStrike_Timer <= diff)
                    {
                        if (Unit* pUnit = SelectUnit(SELECT_TARGET_RANDOM, 0))
                            DoCast(pUnit, SPELL_FLAME_STRIKE);

                        FlameStrike_Timer = 30000;
                    }
                    FlameStrike_Timer -= diff;

                    if (MindControl_Timer <= diff)
                    {
                        if (me->getThreatManager().getThreatList().size() >= 2)
                            for (uint32 i = 0; i < 3; i++)
                            {
                                debug_log("OSCR: Kael'Thas mind control not supported.");
                                //DoCast(pTarget, SPELL_MIND_CONTROL);
                            }

                        MindControl_Timer = 60000;
                    }
                    MindControl_Timer -= diff;
                }

                //Phoenix_Timer
                if (Phoenix_Timer <= diff)
                {
                    DoCast(me, SPELL_PHOENIX_ANIMATION);

                    if (Creature* pPhoenix = me->SummonCreature(NPC_PHOENIX, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000))
                    {
                        if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
                            pPhoenix->AI()->AttackStart(pTarget);
                    }
                    else
                        error_log("OSCR: Kael'Thas Phoenix could not be spawned");

                    switch (rand() % 2)
                    {
                    case 0:
                        DoScriptText(SAY_SUMMON_PHOENIX1, me);
                        break;
                    case 1:
                        DoScriptText(SAY_SUMMON_PHOENIX2, me);
                        break;
                    }

                    Phoenix_Timer = 60000;
                }
                else Phoenix_Timer -= diff;

                //Phase 4 specific spells
                if (Phase == 4)
                {
                    if (me->GetHealth() * 100 / me->GetMaxHealth() < 50)
                    {
                        m_pInstance->SetData(DATA_KAELTHASEVENT, 4);
                        Phase = 5;
                        Phase_Timer = 10000;

                        DoScriptText(SAY_PHASE5_NUTS, me);

                        me->StopMoving();
                        me->GetMotionMaster()->Clear();
                        me->GetMotionMaster()->MoveIdle();
                        me->Relocate(afGravityPos[0], afGravityPos[1], afGravityPos[2], 0);
                        Movement::MoveSplineInit init(*me);
                        init.MoveTo(afGravityPos[0], afGravityPos[1], afGravityPos[2], true);
                        init.Launch();

                        me->InterruptNonMeleeSpells(false);
                        DoCast(me, SPELL_FULLPOWER);
                        me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                    }

                    //ShockBarrier_Timer
                    if (ShockBarrier_Timer <= diff)
                    {
                        DoCast(me, SPELL_SHOCK_BARRIER);
                        ChainPyros = true;
                        PyrosCasted = 0;

                        ShockBarrier_Timer = 60000;
                    }
                    else ShockBarrier_Timer -= diff;

                    //Chain Pyros (3 of them max)
                    if (ChainPyros && !me->IsNonMeleeSpellCast(false))
                    {
                        if (PyrosCasted < 3)
                        {
                            DoCastVictim( SPELL_PYROBLAST);
                            PyrosCasted++;
                        }
                        else
                        {
                            ChainPyros = false;
                            Fireball_Timer = 2500;
                            ArcaneDisruption_Timer = 60000;
                        }
                    }
                }

                if (Phase == 5)
                {
                    if (Phase_Timer <= diff)
                    {
                        me->InterruptNonMeleeSpells(false);
                        me->RemoveAurasDueToSpell(SPELL_FULLPOWER);
                        DoCast(me, SPELL_EXPLODE);
                        me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                        Phase = 6;
                        AttackStart(me->getVictim());
                    }
                    else Phase_Timer -= diff;
                }

                //Phase 5
                if (Phase == 6)
                {

                    //GravityLapse_Timer
                    if (GravityLapse_Timer <= diff)
                    {
                        ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
                        ThreatContainer::StorageType::const_iterator i = threatlist.begin();

                        Movement::MoveSplineInit init(*me);
                        switch (GravityLapse_Phase)
                        {
                        case 0:
                            me->StopMoving();
                            me->GetMotionMaster()->Clear();
                            me->GetMotionMaster()->MoveIdle();
                            me->Relocate(afGravityPos[0], afGravityPos[1], afGravityPos[2], 0);
                            init.MoveTo(afGravityPos[0], afGravityPos[1], afGravityPos[2], true);
                            init.Launch();

                            // 1) Kael'thas will portal the whole raid right into his body
                            for (i = threatlist.begin(); i != threatlist.end(); ++i)
                            {
                                Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid());
                                if (pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER))
                                {
                                    //Use work around packet to prevent player from being dropped from combat
                                    DoTeleportPlayer(pUnit, afGravityPos[0], afGravityPos[1], afGravityPos[2], pUnit->GetOrientation());
                                }
                            }
                            GravityLapse_Timer = 500;
                            ++GravityLapse_Phase;
                            InGravityLapse = true;
                            ShockBarrier_Timer = 1000;
                            NetherBeam_Timer = 5000;
                            break;

                        case 1:
                            switch (rand() % 2)
                            {
                            case 0:
                                DoScriptText(SAY_GRAVITYLAPSE1, me);
                                break;
                            case 1:
                                DoScriptText(SAY_GRAVITYLAPSE2, me);
                                break;
                            }

                            // 2) At that point he will put a Gravity Lapse debuff on everyone
                            for (i = threatlist.begin(); i != threatlist.end(); ++i)
                            {
                                if (Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()))
                                {
                                    me->CastSpell(pUnit, SPELL_KNOCKBACK, true);
                                    //Gravity lapse - needs an exception in Spell system to work

                                    pUnit->CastSpell(pUnit, SPELL_GRAVITY_LAPSE, true, 0, 0, me->GetGUID());
                                    pUnit->CastSpell(pUnit, SPELL_GRAVITY_LAPSE_AURA, true, 0, 0, me->GetGUID());

                                    //Using packet workaround
                                    WorldPacket data(12);
                                    data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
                                    data << pUnit->GetPackGUID();
                                    data << uint32(0);
                                    pUnit->SendMessageToSet(&data, true);
                                }
                            }
                            GravityLapse_Timer = 10000;
                            GravityLapse_Phase++;
                            break;

                        case 2:
                            //Cast nether vapor aura on self
                            me->InterruptNonMeleeSpells(false);
                            DoCast(me, SPELL_NETHER_VAPOR);

                            GravityLapse_Timer = 20000;
                            GravityLapse_Phase++;
                            break;

                        case 3:
                            //Remove flight
                            for (i = threatlist.begin(); i != threatlist.end(); ++i)
                            {
                                if (Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()))
                                {
                                    //Using packet workaround
                                    WorldPacket data(12);
                                    data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
                                    data << pUnit->GetPackGUID();
                                    data << uint32(0);
                                    pUnit->SendMessageToSet(&data, true);
                                }
                            }
                            me->RemoveAurasDueToSpell(SPELL_NETHER_VAPOR);
                            InGravityLapse = false;
                            GravityLapse_Timer = 60000;
                            GravityLapse_Phase = 0;
                            AttackStart(me->getVictim());
                            break;
                        }
                    }
                    else GravityLapse_Timer -= diff;

                    if (InGravityLapse)
                    {
                        //ShockBarrier_Timer
                        if (ShockBarrier_Timer <= diff)
                        {
                            DoCast(me, SPELL_SHOCK_BARRIER);
                            ShockBarrier_Timer = 20000;
                        }
                        else ShockBarrier_Timer -= diff;

                        //NetherBeam_Timer
                        if (NetherBeam_Timer <= diff)
                        {
                            if (Unit* pUnit = SelectUnit(SELECT_TARGET_RANDOM, 0))
                                DoCast(pUnit, SPELL_NETHER_BEAM);

                            NetherBeam_Timer = 4000;
                        }
                        else NetherBeam_Timer -= diff;
                    }
                }

                if (!InGravityLapse)
                    DoMeleeAttackIfReady();
            }
        }
    }
コード例 #23
0
        void UpdateAI(uint32 diff)
        {
            if(!UpdateVictim())
                return;

            ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
            ThreatContainer::StorageType::const_iterator i = threatlist.begin();

            events.Update(diff);

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

            while(uint32 eventId = events.ExecuteEvent())
            {
                switch(eventId)
                {    
                    case EVENT_DISTANCE:
                        distanceMelee = true;
                        for (i = threatlist.begin(); i != threatlist.end(); ++i)
                        {
                            if (Unit* player = Unit::GetUnit(*me, (*i)->getUnitGuid()))
                                if (player && (player->GetTypeId() == TYPEID_PLAYER) && me->IsWithinMeleeRange(player, 5.0f))
                                {
                                    distanceMelee = false;
                                    break;
                                }
                        }

                        if (distanceMelee)
                            events.ScheduleEvent(EVENT_SEETHE, 2*IN_MILLISECONDS);

                        events.ScheduleEvent(EVENT_DISTANCE, 200);
                        break;

                    case EVENT_SEETHE:
                        me->CastSpell(me->getVictim(), SPELL_SEETHE);
                        distanceMelee = false;
                        break;

                    case EVENT_ENDLESS_RAGE:
                        me->CastSpell(me->getVictim(), SPELL_ENDLESS_RAGE);
                        Talk(SAY_ENDLESS_RAGE);
                        break;

                    case EVENT_GROWING_ANGER:
                        me->CastSpell(me, SPELL_GROWING_ANGER);
                        Talk(SAY_GROWING_ANGER);
                        break;

                    case EVENT_PHASE_GROWING_ANGER:
                        events.SetPhase(PHASE_GROWING_ANGER);
                        events.ScheduleEvent(EVENT_ENDLESS_RAGE, 20*IN_MILLISECONDS);
                        events.ScheduleEvent(EVENT_GROWING_ANGER, urand(30*IN_MILLISECONDS, 35*IN_MILLISECONDS));
                        events.ScheduleEvent(EVENT_UNLEASHED_WRATH, 50*IN_MILLISECONDS);
                        break;

                    case EVENT_UNLEASHED_WRATH:
                        DoCast(SPELL_UNLEASHED_WRATH);
                        events.SetPhase(PHASE_UNLEASHED_WRATH);
                        events.ScheduleEvent(EVENT_PHASE_GROWING_ANGER, 25*IN_MILLISECONDS, 0, PHASE_GROWING_ANGER);
                        events.ScheduleEvent(EVENT_ENDLESS_RAGE, 15*IN_MILLISECONDS);
                        break;

                    case EVENT_BERSERK:
                        DoCast(SPELL_BERSERK);
                        break;

                    default:
                        break;
                }
            }
            DoMeleeAttackIfReady();
        }