void UseAbility()
 {
     uint8 random = urand(0, 2);
     Unit* target = NULL;
     switch (PlayerAbility[PlayerClass][random].target)
     {
         case ABILITY_TARGET_SELF:
             target = me;
             break;
         case ABILITY_TARGET_VICTIM:
             target = me->getVictim();
             break;
         case ABILITY_TARGET_ENEMY:
         default:
             target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
             break;
         case ABILITY_TARGET_HEAL:
             target = DoSelectLowestHpFriendly(50, 0);
             break;
         case ABILITY_TARGET_BUFF:
             {
                 std::list<Creature*> templist = DoFindFriendlyMissingBuff(50, PlayerAbility[PlayerClass][random].spell);
                 if (!templist.empty())
                     target = *(templist.begin());
             }
             break;
     }
     if (target)
         DoCast(target, PlayerAbility[PlayerClass][random].spell, false);
 }
Beispiel #2
0
    void UpdateAI(const uint32 uiDiff)
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        if (m_uiBloodlustTimer < uiDiff)
        {
            std::list<Creature*> lTempList = DoFindFriendlyMissingBuff(50.0f, SPELL_BLOODLUST);

            if (!lTempList.empty())
            {
                Unit* pTarget = *(lTempList.begin());
                DoCastSpellIfCan(pTarget, SPELL_BLOODLUST);
            }

            m_uiBloodlustTimer = 12000;
        }
        else
            m_uiBloodlustTimer -= uiDiff;

        if (m_uiCleaveTimer < uiDiff)
        {
            DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE);
            m_uiCleaveTimer = 12000;
        }
        else
            m_uiCleaveTimer -= uiDiff;

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

        //DemoralizingShout_Timer
        if (DemoralizingShout_Timer <= diff)
        {
            DoCast(me->getVictim(), SPELL_DEMORALIZINGSHOUT);
            DemoralizingShout_Timer = 15000 + rand()%5000;
        } else DemoralizingShout_Timer -= diff;

        //Inspire_Timer
        if (Inspire_Timer <= diff)
        {
            Creature *pTarget = NULL;
            std::list<Creature*> pList = DoFindFriendlyMissingBuff(45.0f,SPELL_INSPIRE);
            if (!pList.empty())
            {
                std::list<Creature*>::const_iterator i = pList.begin();
                advance(i, (rand()%pList.size()));
                pTarget = (*i);
            }

            if (pTarget)
                DoCast(pTarget, SPELL_INSPIRE);

            DoCast(me, SPELL_INSPIRE);

            Inspire_Timer = 20000 + rand()%6000;
        } else Inspire_Timer -= diff;

        //Knockdown_Timer
        if (Knockdown_Timer <= diff)
        {
            DoCast(me->getVictim(), SPELL_KNOCKDOWN);
            Knockdown_Timer = 12000 + rand()%3000;
        } else Knockdown_Timer -= diff;

        //Flamespear_Timer
        if (Flamespear_Timer <= diff)
        {
            Unit *pTarget = NULL;
            pTarget = SelectUnit(SELECT_TARGET_RANDOM,0);
            if (pTarget) DoCast(pTarget, SPELL_FLAMESPEAR);

            Flamespear_Timer = 12000 + rand()%4000;
        } else Flamespear_Timer -= diff;

        //DarkStrike_Timer
        if (Darkstrike_Timer <= diff)
        {
            DoCast(me, SPELL_DARKSTRIKE);
            Darkstrike_Timer = 15000 + rand()%3000;
        } else Darkstrike_Timer -= diff;

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

        //DemoralizingShout_Timer
        if (DemoralizingShout_Timer < diff)
        {
            DoCastSpellIfCan(m_creature->getVictim(),SPELL_DEMORALIZINGSHOUT);
            DemoralizingShout_Timer = urand(15000, 20000);
        }else DemoralizingShout_Timer -= diff;

        //Inspire_Timer
        if (Inspire_Timer < diff)
        {
            Creature* target = NULL;
            std::list<Creature*> pList = DoFindFriendlyMissingBuff(45.0f,SPELL_INSPIRE);
            if (!pList.empty())
            {
                std::list<Creature*>::iterator i = pList.begin();
                advance(i, (rand()%pList.size()));
                target = (*i);
            }

            if (target)
                DoCastSpellIfCan(target,SPELL_INSPIRE);

            DoCastSpellIfCan(m_creature,SPELL_INSPIRE);

            Inspire_Timer = urand(20000, 26000);
        }else Inspire_Timer -= diff;

        //Knockdown_Timer
        if (Knockdown_Timer < diff)
        {
            DoCastSpellIfCan(m_creature->getVictim(),SPELL_KNOCKDOWN);
            Knockdown_Timer = urand(12000, 15000);
        }else Knockdown_Timer -= diff;

        //Flamespear_Timer
        if (Flamespear_Timer < diff)
        {
            Unit* target = NULL;
            target = SelectUnit(SELECT_TARGET_RANDOM,0);
            if (target) DoCastSpellIfCan(target,SPELL_FLAMESPEAR);

            Flamespear_Timer = urand(12000, 16000);
        }else Flamespear_Timer -= diff;

        //DarkStrike_Timer
        if (Darkstrike_Timer < diff)
        {
            DoCastSpellIfCan(m_creature, SPELL_DARKSTRIKE);
            Darkstrike_Timer = urand(15000, 18000);
        }else Darkstrike_Timer -= diff;

        DoMeleeAttackIfReady();
    }
Beispiel #5
0
 Creature* SelectRandomFriendlyMissingBuff(uint32 spell)
 {
     std::list<Creature *> lst = DoFindFriendlyMissingBuff(40.0f, spell);
     std::list<Creature *>::const_iterator itr = lst.begin();
     if (lst.empty())
         return NULL;
     advance(itr, rand()%lst.size());
     return (*itr);
 }
            void UpdateAI(const uint32 diff)
            {
                if (!UpdateVictim())
                    return;

                events.Update(diff);

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

                while (uint32 eventId = events.ExecuteEvent())
                {
                    switch (eventId)
                    {
                        case EVENT_DARK_STRIKE:
                            DoCast(me, SPELL_DARK_STRIKE);
                            events.ScheduleEvent(EVENT_DARK_STRIKE, urand(15000, 18000));
                            break;
                        case EVENT_DEMORALIZING_SHOUT:
                            DoCastVictim(SPELL_DEMORALIZING_SHOUT);
                            events.ScheduleEvent(EVENT_DEMORALIZING_SHOUT, urand(15000, 20000));
                            break;
                        case EVENT_INSPIRE:
                        {
                            Creature* target = NULL;
                            std::list<Creature*> healers = DoFindFriendlyMissingBuff(45.0f, SPELL_INSPIRE);
                            if (!healers.empty())
                            {
                                std::list<Creature*>::const_iterator itr = healers.begin();
                                std::advance(itr, urand(0, healers.size()-1));
                                target = *itr;
                            }

                            if (target)
                                DoCast(target, SPELL_INSPIRE);

                            DoCast(me, SPELL_INSPIRE);
                            events.ScheduleEvent(EVENT_INSPIRE, urand(20000, 26000));
                            break;
                        }
                        case EVENT_KNOCKDOWN:
                            DoCastVictim(SPELL_KNOCKDOWN);
                            events.ScheduleEvent(EVENT_KNOCKDOWN, urand(12000, 15000));
                            break;
                        case EVENT_FLAMESPEAR:
                            if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
                                DoCast(target, SPELL_FLAMESPEAR);
                            events.ScheduleEvent(EVENT_FLAMESPEAR, urand(12000, 16000));
                            break;
                        default:
                            break;
                    }
                }

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

                events.Update(diff);

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

                while (uint32 eventId = events.ExecuteEvent())
                {
                    switch (eventId)
                    {
                        case EVENT_DARK_STRIKE:
                            DoCast(me, SPELL_DARK_STRIKE);
                            events.ScheduleEvent(EVENT_DARK_STRIKE, urand(15000, 18000));
                            break;
                        case EVENT_DEMORALIZING_SHOUT:
                            DoCastVictim(SPELL_DEMORALIZING_SHOUT);
                            events.ScheduleEvent(EVENT_DEMORALIZING_SHOUT, urand(15000, 20000));
                            break;
                        case EVENT_INSPIRE:
                        {
                            std::list<Creature*> healers = DoFindFriendlyMissingBuff(45.0f, SPELL_INSPIRE);
                            if (!healers.empty())
                                DoCast(Trinity::Containers::SelectRandomContainerElement(healers), SPELL_INSPIRE);

                            DoCast(me, SPELL_INSPIRE);
                            events.ScheduleEvent(EVENT_INSPIRE, urand(20000, 26000));
                            break;
                        }
                        case EVENT_KNOCKDOWN:
                            DoCastVictim(SPELL_KNOCKDOWN);
                            events.ScheduleEvent(EVENT_KNOCKDOWN, urand(12000, 15000));
                            break;
                        case EVENT_FLAMESPEAR:
                            if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
                                DoCast(target, SPELL_FLAMESPEAR);
                            events.ScheduleEvent(EVENT_FLAMESPEAR, urand(12000, 16000));
                            break;
                        default:
                            break;
                    }
                }

                DoMeleeAttackIfReady();
            }
Beispiel #8
0
        void _UpdateAI(uint32 diff)
        {
            if (diff < _frenzyTimer)
                _frenzyTimer -= diff;
            else if (me->HasUnitState(UNIT_STATE_CASTING))
                _frenzyTimer = 0;
            else
            { // target priority: knight > other rider > horse > gothik
                std::list<Creature*> potentialTargets = DoFindFriendlyMissingBuff(30.0, SPELLHELPER_UNHOLY_FRENZY);
                Creature *knightTarget = nullptr, *riderTarget = nullptr, *horseTarget = nullptr, *gothikTarget = nullptr;
                for (Creature* pTarget : potentialTargets)
                {
                    switch (pTarget->GetEntry())
                    {
                        case NPC_DEAD_KNIGHT:
                            knightTarget = pTarget;
                            break;
                        case NPC_DEAD_RIDER:
                            riderTarget = pTarget;
                            break;
                        case NPC_DEAD_HORSE:
                            horseTarget = pTarget;
                            break;
                        case NPC_GOTHIK:
                            gothikTarget = pTarget;
                            break;
                    }
                    if (knightTarget)
                        break;
                }
                Creature* target = knightTarget ? knightTarget : riderTarget ? riderTarget : horseTarget ? horseTarget : gothikTarget ? gothikTarget : nullptr;
                if (target)
                    DoCast(target, SPELL_UNHOLY_FRENZY);
                _frenzyTimer = 20 * IN_MILLISECONDS;
            }

            if (diff < _drainTimer)
                _drainTimer -= diff;
            else
            {
                DoCastVictim(SPELL_DRAIN_LIFE);
                _drainTimer = urandms(10,15);
            }

            if (!me->HasUnitState(UNIT_STATE_CASTING))
                DoMeleeAttackIfReady();
        }
Beispiel #9
0
		void UpdateAI(const uint32 diff) {
			if (!UpdateVictim())
				return;

			if (bloodlust_timer <= diff) {
				std::list<Creature*> templist = DoFindFriendlyMissingBuff(50,
						SPELL_BLOODLUST);
				if (!templist.empty()) {
					if (Unit *pTarget = *(templist.begin()))
						DoCast(pTarget, SPELL_BLOODLUST, false);
				}
				bloodlust_timer = 12000;
			} else
				bloodlust_timer -= diff;

			if (cleave_timer <= diff) {
				DoCast(me->getVictim(), SPELL_CLEAVE, false);
				cleave_timer = 12000; //3 sec cast
			} else
				cleave_timer -= diff;

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

        // Demoralizing Shout Timer
        if (m_uiDemoralizingShoutTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, SPELL_DEMORALIZING_SHOUT) == CAST_OK)
                m_uiDemoralizingShoutTimer = urand(15000, 20000);
        }
        else
            m_uiDemoralizingShoutTimer -= uiDiff;

        // Inspire Timer
        if (m_uiInspireTimer < uiDiff)
        {
            Creature* pTarget = NULL;
            std::list<Creature*> pList = DoFindFriendlyMissingBuff(45.0f, SPELL_INSPIRE);
            if (!pList.empty())
            {
                std::list<Creature*>::iterator i = pList.begin();
                advance(i, (rand() % pList.size()));
                pTarget = (*i);
            }

            if (!pTarget)
                pTarget = m_creature;

            if (DoCastSpellIfCan(pTarget, SPELL_INSPIRE) == CAST_OK)
                m_uiInspireTimer = 10000;
        }
        else
            m_uiInspireTimer -= uiDiff;

        // Hand of Ragnaros Timer
        if (m_uiKnockdownTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, SPELL_HAND_OF_RAGNAROS) == CAST_OK)
                m_uiKnockdownTimer = urand(12000, 15000);
        }
        else
            m_uiKnockdownTimer -= uiDiff;

        // Flamespear Timer
        if (m_uiFlamespearTimer < uiDiff)
        {
            if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
            {
                if (DoCastSpellIfCan(pTarget, SPELL_FLAMESPEAR) == CAST_OK)
                    m_uiFlamespearTimer = urand(12000, 16000);
            }
        }
        else
            m_uiFlamespearTimer -= uiDiff;

        // Dark Strike Timer
        if (m_uiDarkstrikeTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_DARK_STRIKE) == CAST_OK)
                m_uiDarkstrikeTimer = urand(15000, 18000);
        }
        else
            m_uiDarkstrikeTimer -= uiDiff;

        DoMeleeAttackIfReady();
    }
Beispiel #11
0
bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& holder, Unit* actionInvoker /*=NULL*/)
{
    if (!holder.Enabled || holder.Time)
        return false;

    //Check the inverse phase mask (event doesn't trigger if current phase bit is set in mask)
    if (holder.Event.event_inverse_phase_mask & (1 << m_Phase))
        return false;

    CreatureEventAI_Event const& event = holder.Event;

    //Check event conditions based on the event type, also reset events
    switch (event.event_type)
    {
    case EVENT_T_TIMER:
        if (!me->isInCombat())
            return false;

        //Repeat Timers
        holder.UpdateRepeatTimer(me, event.timer.repeatMin, event.timer.repeatMax);
        break;
    case EVENT_T_TIMER_OOC:
        if (me->isInCombat())
            return false;

        //Repeat Timers
        holder.UpdateRepeatTimer(me, event.timer.repeatMin, event.timer.repeatMax);
        break;
    case EVENT_T_HP:
    {
        if (!me->isInCombat() || !me->GetMaxHealth())
            return false;

        uint32 perc = uint32(me->GetHealthPct());

        if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin)
            return false;

        //Repeat Timers
        holder.UpdateRepeatTimer(me, event.percent_range.repeatMin, event.percent_range.repeatMax);
        break;
    }
    case EVENT_T_MANA:
    {
        if (!me->isInCombat() || !me->GetMaxPower(POWER_MANA))
            return false;

        uint32 perc = (me->GetPower(POWER_MANA)*100) / me->GetMaxPower(POWER_MANA);

        if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin)
            return false;

        //Repeat Timers
        holder.UpdateRepeatTimer(me, event.percent_range.repeatMin, event.percent_range.repeatMax);
        break;
    }
    case EVENT_T_AGGRO:
        break;
    case EVENT_T_KILL:
        //Repeat Timers
        holder.UpdateRepeatTimer(me, event.kill.repeatMin, event.kill.repeatMax);
        break;
    case EVENT_T_DEATH:
    case EVENT_T_EVADE:
        break;
    case EVENT_T_SPELLHIT:
        //Spell hit is special case, param1 and param2 handled within CreatureEventAI::SpellHit

        //Repeat Timers
        holder.UpdateRepeatTimer(me, event.spell_hit.repeatMin, event.spell_hit.repeatMax);
        break;
    case EVENT_T_RANGE:
        //Repeat Timers
        holder.UpdateRepeatTimer(me, event.range.repeatMin, event.range.repeatMax);
        break;
    case EVENT_T_OOC_LOS:
        //Repeat Timers
        holder.UpdateRepeatTimer(me, event.ooc_los.repeatMin, event.ooc_los.repeatMax);
        break;
    case EVENT_T_RESET:
    case EVENT_T_SPAWNED:
        break;
    case EVENT_T_TARGET_HP:
    {
        if (!me->isInCombat() || !me->getVictim() || !me->getVictim()->GetMaxHealth())
            return false;

        uint32 perc = uint32(me->getVictim()->GetHealthPct());

        if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin)
            return false;

        //Repeat Timers
        holder.UpdateRepeatTimer(me, event.percent_range.repeatMin, event.percent_range.repeatMax);
        break;
    }
    case EVENT_T_TARGET_CASTING:
        if (!me->isInCombat() || !me->getVictim() || !me->getVictim()->IsNonMeleeSpellCasted(false, false, true))
            return false;

        //Repeat Timers
        holder.UpdateRepeatTimer(me, event.target_casting.repeatMin, event.target_casting.repeatMax);
        break;
    case EVENT_T_FRIENDLY_HP:
    {
        if (!me->isInCombat())
            return false;

        Unit* unit = DoSelectLowestHpFriendly((float)event.friendly_hp.radius, event.friendly_hp.hpDeficit);
        if (!unit)
            return false;

        actionInvoker = unit;

        //Repeat Timers
        holder.UpdateRepeatTimer(me, event.friendly_hp.repeatMin, event.friendly_hp.repeatMax);
        break;
    }
    case EVENT_T_FRIENDLY_IS_CC:
    {
        if (!me->isInCombat())
            return false;

        std::list<Creature*> pList;
        DoFindFriendlyCC(pList, (float)event.friendly_is_cc.radius);

        //List is empty
        if (pList.empty())
            return false;

        //We don't really care about the whole list, just return first available
        actionInvoker = *(pList.begin());

        //Repeat Timers
        holder.UpdateRepeatTimer(me, event.friendly_is_cc.repeatMin, event.friendly_is_cc.repeatMax);
        break;
    }
    case EVENT_T_FRIENDLY_MISSING_BUFF:
    {
        std::list<Creature*> pList;
        DoFindFriendlyMissingBuff(pList, (float)event.friendly_buff.radius, event.friendly_buff.spellId);

        //List is empty
        if (pList.empty())
            return false;

        //We don't really care about the whole list, just return first available
        actionInvoker = *(pList.begin());

        //Repeat Timers
        holder.UpdateRepeatTimer(me, event.friendly_buff.repeatMin, event.friendly_buff.repeatMax);
        break;
    }
    case EVENT_T_SUMMONED_UNIT:
    {
        //Prevent event from occuring on no unit or non creatures
        if (!actionInvoker || actionInvoker->GetTypeId() != TYPEID_UNIT)
            return false;

        //Creature id doesn't match up
        if (actionInvoker->ToCreature()->GetEntry() != event.summon_unit.creatureId)
            return false;

        //Repeat Timers
        holder.UpdateRepeatTimer(me, event.summon_unit.repeatMin, event.summon_unit.repeatMax);
        break;
    }
    case EVENT_T_TARGET_MANA:
    {
        if (!me->isInCombat() || !me->getVictim() || !me->getVictim()->GetMaxPower(POWER_MANA))
            return false;

        uint32 perc = (me->getVictim()->GetPower(POWER_MANA)*100) / me->getVictim()->GetMaxPower(POWER_MANA);

        if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin)
            return false;

        //Repeat Timers
        holder.UpdateRepeatTimer(me, event.percent_range.repeatMin, event.percent_range.repeatMax);
        break;
    }
    case EVENT_T_REACHED_HOME:
    case EVENT_T_RECEIVE_EMOTE:
        break;
    case EVENT_T_BUFFED:
    {
        //Note: checked only aura for effect 0, if need check aura for effect 1/2 then
        // possible way: pack in event.buffed.amount 2 uint16 (ammount+effectIdx)
        Aura const* aura = me->GetAura(event.buffed.spellId);
        if (!aura || aura->GetStackAmount() < event.buffed.amount)
            return false;

        //Repeat Timers
        holder.UpdateRepeatTimer(me, event.buffed.repeatMin, event.buffed.repeatMax);
        break;
    }
    case EVENT_T_TARGET_BUFFED:
    {
        //Prevent event from occuring on no unit
        if (!actionInvoker)
            return false;

        //Note: checked only aura for effect 0, if need check aura for effect 1/2 then
        // possible way: pack in event.buffed.amount 2 uint16 (ammount+effectIdx)
        Aura const* aura = actionInvoker->GetAura(event.buffed.spellId);
        if (!aura || aura->GetStackAmount() < event.buffed.amount)
            return false;

        //Repeat Timers
        holder.UpdateRepeatTimer(me, event.buffed.repeatMin, event.buffed.repeatMax);
        break;
    }
    default:
        sLog->outErrorDb("CreatureEventAI: Creature %u using Event %u has invalid Event Type(%u), missing from ProcessEvent() Switch.", me->GetEntry(), holder.Event.event_id, holder.Event.event_type);
        break;
    }

    //Disable non-repeatable events
    if (!(holder.Event.event_flags & EFLAG_REPEATABLE))
        holder.Enabled = false;

    //Store random here so that all random actions match up
    uint32 rnd = rand();

    //Return if chance for event is not met
    if (holder.Event.event_chance <= rnd % 100)
        return false;

    //Process actions
    for (uint8 j = 0; j < MAX_ACTIONS; ++j)
        ProcessAction(holder.Event.action[j], rnd, holder.Event.event_id, actionInvoker);

    return true;
}