示例#1
0
void ImpAI::UpdateAI(const uint32 diff)
{
    if (!me->isAlive())
        return;

    m_owner = me->GetCharmerOrOwner();

    updateAlliesTimer.Update(diff);
    if (updateAlliesTimer.Passed())
        UpdateAllies();

    if (m_forceTimer)
    {
        if (m_forceTimer < diff)
            m_forceTimer = 0;
        else
            m_forceTimer -= diff;
    }

   // me->getVictim() can't be used for check in case stop fighting, me->getVictim() clear at Unit death etc.
    if (Unit *target = me->getVictim())
    {
        if (_needToStop())
        {
            DEBUG_LOG("Pet AI stoped attacking [guid=%u]", me->GetGUIDLow());
            _stopAttack();
            return;
        }
        float dist = me->GetDistance2d(target);
        if (dist < 30 && m_chasing)
        {
            me->clearUnitState(UNIT_STAT_FOLLOW);
            me->GetMotionMaster()->MoveIdle();
            m_chasing = false;
        }
        if (dist > 30 && !m_chasing)
        {
            me->GetMotionMaster()->MoveChase(target);
            m_chasing = true;
        }
    }
    else
    {
        if (me->isInCombat())
        {
            if (!m_owner|| !m_owner->GetObjectGuid().IsPlayer())
                _stopAttack();
        }
        else if (m_owner && me->GetCharmInfo()) //no victim
        {
            if (m_owner->isInCombat() && !(me->HasReactState(REACT_PASSIVE) || me->GetCharmInfo()->HasCommandState(COMMAND_STAY)))
                AttackStart(m_owner->getAttackerForHelper());
            else if (me->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW) && !me->hasUnitState(UNIT_STAT_FOLLOW))
                me->GetMotionMaster()->MoveFollow(m_owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
        }
    }

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

    if (!me->hasUnitState(UNIT_STAT_CASTING))
    {
        //Autocast
        for (uint8 i = 0; i < me->GetPetAutoSpellSize(); i++)
            PrepareSpellForAutocast(me->GetPetAutoSpellOnPos(i));

        AutocastPreparedSpells();
    }
}
示例#2
0
文件: PetAI.cpp 项目: ejt/vanilla
void PetAI::UpdateAI(const uint32 diff)
{
    if (!m_creature->IsAlive())
        { return; }

    Unit* owner = m_creature->GetCharmerOrOwner();

    if (m_updateAlliesTimer <= diff)
        // UpdateAllies self set update timer
        { UpdateAllies(); }
    else
        { m_updateAlliesTimer -= diff; }

    if (inCombat && (!m_creature->getVictim() || (m_creature->IsPet() && ((Pet*)m_creature)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS)))
        { _stopAttack(); }

    // i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
    if (m_creature->getVictim())
    {
        if (_needToStop())
        {
            DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "PetAI (guid = %u) is stopping attack.", m_creature->GetGUIDLow());
            _stopAttack();
            return;
        }

        bool meleeReach = m_creature->CanReachWithMeleeAttack(m_creature->getVictim());

        if (m_creature->IsStopped() || meleeReach)
        {
            // required to be stopped cases
            if (m_creature->IsStopped() && m_creature->IsNonMeleeSpellCasted(false))
            {
                if (m_creature->hasUnitState(UNIT_STAT_FOLLOW_MOVE))
                    { m_creature->InterruptNonMeleeSpells(false); }
                else
                    { return; }
            }
            // not required to be stopped case
            else if (DoMeleeAttackIfReady())
            {
                if (!m_creature->getVictim())
                    { return; }

                // if pet misses its target, it will also be the first in threat list
                m_creature->getVictim()->AddThreat(m_creature);

                if (_needToStop())
                    { _stopAttack(); }
            }
        }
    }
    else if (owner && m_creature->GetCharmInfo())
    {
        if (owner->IsInCombat() && !(m_creature->GetCharmInfo()->HasReactState(REACT_PASSIVE) || m_creature->GetCharmInfo()->HasCommandState(COMMAND_STAY)))
        {
            AttackStart(owner->getAttackerForHelper());
        }
        else if (m_creature->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
        {
            if (!m_creature->hasUnitState(UNIT_STAT_FOLLOW))
            {
                m_creature->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
            }
        }
    }

    // Autocast (casted only in combat or persistent spells in any state)
    if (!m_creature->IsNonMeleeSpellCasted(false))
    {
        typedef std::vector<std::pair<Unit*, Spell*> > TargetSpellList;
        TargetSpellList targetSpellStore;

        for (uint8 i = 0; i < m_creature->GetPetAutoSpellSize(); ++i)
        {
            uint32 spellID = m_creature->GetPetAutoSpellOnPos(i);
            if (!spellID)
                { continue; }

            SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellID);
            if (!spellInfo)
                { continue; }

            if (m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
                { continue; }

            // ignore some combinations of combat state and combat/noncombat spells
            if (!inCombat)
            {
                // ignore attacking spells, and allow only self/around spells
                if (!IsPositiveSpell(spellInfo->Id))
                    { continue; }

                // non combat spells allowed
                // only pet spells have IsNonCombatSpell and not fit this reqs:
                // Consume Shadows, Lesser Invisibility, so ignore checks for its
                if (!IsNonCombatSpell(spellInfo))
                {
                    // allow only spell without spell cost or with spell cost but not duration limit
                    int32 duration = GetSpellDuration(spellInfo);
                    if ((spellInfo->manaCost || spellInfo->ManaCostPercentage || spellInfo->manaPerSecond) && duration > 0)
                        { continue; }

                    // allow only spell without cooldown > duration
                    int32 cooldown = GetSpellRecoveryTime(spellInfo);
                    if (cooldown >= 0 && duration >= 0 && cooldown > duration)
                        { continue; }

                    // not allow instant kill autocasts as full health cost
                    if (IsSpellHaveEffect(spellInfo, SPELL_EFFECT_INSTAKILL))
                        { continue; }
                }
            }
            else
            {
                // just ignore non-combat spells
                if (IsNonCombatSpell(spellInfo))
                    { continue; }
            }

            Spell* spell = new Spell(m_creature, spellInfo, false);

            if (inCombat && !m_creature->hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(m_creature->getVictim()))
            {
                targetSpellStore.push_back(TargetSpellList::value_type(m_creature->getVictim(), spell));
                continue;
            }
            else
            {
                bool spellUsed = false;
                for (GuidSet::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
                {
                    Unit* Target = m_creature->GetMap()->GetUnit(*tar);

                    // only buff targets that are in combat, unless the spell can only be cast while out of combat
                    if (!Target)
                        { continue; }

                    if (spell->CanAutoCast(Target))
                    {
                        targetSpellStore.push_back(TargetSpellList::value_type(Target, spell));
                        spellUsed = true;
                        break;
                    }
                }
                if (!spellUsed)
                    { delete spell; }
            }
        }

        // found units to cast on to
        if (!targetSpellStore.empty())
        {
            uint32 index = urand(0, targetSpellStore.size() - 1);

            Spell* spell  = targetSpellStore[index].second;
            Unit*  target = targetSpellStore[index].first;

            targetSpellStore.erase(targetSpellStore.begin() + index);

            SpellCastTargets targets;
            targets.setUnitTarget(target);

            if (!m_creature->HasInArc(M_PI_F, target))
            {
                m_creature->SetInFront(target);
                if (target->GetTypeId() == TYPEID_PLAYER)
                    { m_creature->SendCreateUpdateToPlayer((Player*)target); }

                if (owner && owner->GetTypeId() == TYPEID_PLAYER)
                    { m_creature->SendCreateUpdateToPlayer((Player*)owner); }
            }

            m_creature->AddCreatureSpellCooldown(spell->m_spellInfo->Id);
            if (m_creature->IsPet())
                { ((Pet*)m_creature)->CheckLearning(spell->m_spellInfo->Id); }

            spell->prepare(&targets);
        }

        // deleted cached Spell objects
        for (TargetSpellList::const_iterator itr = targetSpellStore.begin(); itr != targetSpellStore.end(); ++itr)
            { delete itr->second; }
    }
}
        void UpdateAI(const uint32 diff)
        {
            if (questPhase == 1)
            {
                if (timer <= diff)
                {
                    me->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND);
                    me->setFaction(FACTION_HOSTILE);
                    questPhase = 0;

                    if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                    {
                        me->AddThreat(pTarget, 5000000.0f);
                        AttackStart(pTarget);
                    }
                }
                else
                    timer -= diff;
            }

            if (!UpdateVictim())
              return;

            // healer
            if (spellFlashLight && HealthBelowPct(70))
            {
                if (timerFlashLight <= diff)
                {
                    DoCast(me, SPELL_FLASH_OF_LIGHT);
                    timerFlashLight = 3225 +  rand()%3225;
                }
                else
                    timerFlashLight -= diff;
            }

            if (spellJustice)
            {
                if (timerJustice <= diff)
                {
                    DoCast(me, SPELL_SEAL_OF_JUSTICE);
                    timerJustice = 10000 + rand()%10000;
                }
                else
                    timerJustice -= diff;
            }

            if (spellJudLight)
            {
                if (timerJudLight <= diff)
                {
                    DoCast(me, SPELL_JUDGEMENT_OF_LIGHT);
                    timerJudLight = 10000 + rand()%10000;
                }
                else
                    timerJudLight -= diff;
            }

            if (spellCommand)
            {
                  if (timerCommand <= diff)
                  {
                      DoCast(me, SPELL_SEAL_OF_COMMAND);
                      timerCommand = 20000 + rand()%20000;
                  }
                  else
                      timerCommand -= diff;
            }

            DoMeleeAttackIfReady();
        }
        void HandleFlightSequence()
        {
            switch (uiFlightCount)
            {
            case 0:
                //me->AttackStop();
                me->GetMotionMaster()->Clear(false);
                me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
                me->StopMoving();
                DoScriptText(YELL_TAKEOFF, me);
                events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 2000);
                break;
            case 1:
                me->GetMotionMaster()->MovePoint(0, me->GetPositionX()+1, me->GetPositionY(), me->GetPositionZ()+10);
                break;
            case 2:
            {
                Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150, true);
                if (!target)
                    target = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_PLAYER_GUID) : 0);

                if (!target)
                {
                    EnterEvadeMode();
                    return;
                }

                Creature* Vapor = me->SummonCreature(MOB_VAPOR, target->GetPositionX()-5+rand()%10, target->GetPositionY()-5+rand()%10, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 9000);
                if (Vapor)
                {
                    Vapor->AI()->AttackStart(target);
                    me->InterruptNonMeleeSpells(false);
                    DoCast(Vapor, SPELL_VAPOR_CHANNEL, false); // core bug
                    Vapor->CastSpell(Vapor, SPELL_VAPOR_TRIGGER, true);
                }

                events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 10000);
                break;
            }
            case 3:
            {
                DespawnSummons(MOB_VAPOR_TRAIL);
                //DoCast(me, SPELL_VAPOR_SELECT); need core support

                Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150, true);
                if (!target)
                    target = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_PLAYER_GUID) : 0);

                if (!target)
                {
                    EnterEvadeMode();
                    return;
                }

                //target->CastSpell(target, SPELL_VAPOR_SUMMON, true); need core support
                Creature* pVapor = me->SummonCreature(MOB_VAPOR, target->GetPositionX()-5+rand()%10, target->GetPositionY()-5+rand()%10, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 9000);
                if (pVapor)
                {
                    if (pVapor->AI())
                        pVapor->AI()->AttackStart(target);
                    me->InterruptNonMeleeSpells(false);
                    DoCast(pVapor, SPELL_VAPOR_CHANNEL, false); // core bug
                    pVapor->CastSpell(pVapor, SPELL_VAPOR_TRIGGER, true);
                }

                events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 10000);
                break;
            }
            case 4:
                DespawnSummons(MOB_VAPOR_TRAIL);
                events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 1);
                break;
            case 5:
            {
                Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150, true);
                if (!target)
                    target = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_PLAYER_GUID) : 0);

                if (!target)
                {
                    EnterEvadeMode();
                    return;
                }

                breathX = target->GetPositionX();
                breathY = target->GetPositionY();
                float x, y, z;
                target->GetContactPoint(me, x, y, z, 70);
                me->GetMotionMaster()->MovePoint(0, x, y, z+10);
                break;
            }
            case 6:
                me->SetOrientation(me->GetAngle(breathX, breathY));
                me->StopMoving();
                //DoTextEmote("takes a deep breath.", NULL);
                events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 10000);
                break;
            case 7:
            {
                DoCast(me, SPELL_FOG_BREATH, true);
                float x, y, z;
                me->GetPosition(x, y, z);
                x = 2 * breathX - x;
                y = 2 * breathY - y;
                me->GetMotionMaster()->MovePoint(0, x, y, z);
                events.ScheduleEvent(EVENT_SUMMON_FOG, 1);
                break;
            }
            case 8:
                me->CastStop(SPELL_FOG_BREATH);
                me->RemoveAurasDueToSpell(SPELL_FOG_BREATH);
                ++uiBreathCount;
                events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 1);
                if (uiBreathCount < 3)
                    uiFlightCount = 4;
                break;
            case 9:
                if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO))
                    DoStartMovement(target);
                else
                {
                    EnterEvadeMode();
                    return;
                }
                break;
            case 10:
                me->SetDisableGravity(false);
                me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
                EnterPhase(PHASE_GROUND);
                AttackStart(SelectTarget(SELECT_TARGET_TOPAGGRO));
                break;
            }
            ++uiFlightCount;
        }
示例#5
0
 void MoveInLineOfSight(Unit* who)
 {
     if (me->IsWithinDist(who, 50) && !me->isInCombat() && me->IsValidAttackTarget(who))
         AttackStart(who);
 }
示例#6
0
        void UpdateAI(const uint32 diff)
        {
            if (SayTimer <= diff)
            {
                if (Event)
                    SayTimer = NextStep(++Step);
            } else SayTimer -= diff;

            if (Attack)
            {
                Player* pPlayer = Unit::GetPlayer(*me, PlayerGUID);
                me->setFaction(14);
                me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                if (pPlayer)
                {
                Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20);
                if (Creepjack)
                {
                    Creepjack->Attack(pPlayer, true);
                    Creepjack->setFaction(14);
                    Creepjack->GetMotionMaster()->MoveChase(pPlayer);
                    Creepjack->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                }
                Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20);
                if (Malone)
                {
                    Malone->Attack(pPlayer, true);
                    Malone->setFaction(14);
                    Malone->GetMotionMaster()->MoveChase(pPlayer);
                    Malone->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                }
                    DoStartMovement(pPlayer);
                    AttackStart(pPlayer);
                }
                Attack = false;
            }

            if (HealthBelowPct(5) && !Done)
            {
                me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                me->RemoveAllAuras();

                Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20);
                if (Creepjack)
                {
                    CAST_CRE(Creepjack)->AI()->EnterEvadeMode();
                    Creepjack->setFaction(1194);
                    Creepjack->GetMotionMaster()->MoveTargetedHome();
                    Creepjack->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                }
                Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20);
                if (Malone)
                {
                    CAST_CRE(Malone)->AI()->EnterEvadeMode();
                    Malone->setFaction(1194);
                    Malone->GetMotionMaster()->MoveTargetedHome();
                    Malone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                }
                me->setFaction(1194);
                Done = true;
                DoScriptText(SAY_GIVEUP, me, NULL);
                me->DeleteThreatList();
                me->CombatStop();
                me->GetMotionMaster()->MoveTargetedHome();
                Player* pPlayer = Unit::GetPlayer(*me, PlayerGUID);
                if (pPlayer)
                    CAST_PLR(pPlayer)->GroupEventHappens(QUEST_WBI, me);
            }
            DoMeleeAttackIfReady();
        }
示例#7
0
        void UpdateAI(const uint32 diff)
        {
            npc_escortAI::UpdateAI(diff);

            if (!PlayerGUID)
            {
                me->setDeathState(JUST_DIED);
                return;
            }

            if (!me->isInCombat() && !Event_onWait)
            {
                if (checkPlayer_Timer <= diff)
                {
                    Player* player = Unit::GetPlayer(*me, PlayerGUID);
                    if (player && player->isInCombat() && player->getAttackerForHelper())
                        AttackStart(player->getAttackerForHelper());
                    checkPlayer_Timer = 1000;
                } else checkPlayer_Timer -= diff;
            }

            if (Event_onWait && Event_Timer <= diff)
            {
                Player* player = Unit::GetPlayer(*me, PlayerGUID);
                if (!player || (player && player->GetQuestStatus(10965) == QUEST_STATUS_NONE))
                {
                    me->setDeathState(JUST_DIED);
                    return;
                }

                switch (CurrWP)
                {
                    case 0:
                        switch (Step)
                        {
                            case 0:
                                me->Say(CLINTAR_SPIRIT_SAY_START, 0, PlayerGUID);
                                Event_Timer = 8000;
                                Step = 1;
                                break;
                            case 1:
                                Event_onWait = false;
                                break;
                        }
                        break;
                    case 6:
                        switch (Step)
                        {
                            case 0:
                                me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133);
                                Event_Timer = 5000;
                                Step = 1;
                                break;
                            case 1:
                                me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
                                DoScriptText(CLINTAR_SPIRIT_SAY_GET_ONE, me, player);
                                Event_onWait = false;
                                break;
                        }
                        break;
                    case 15:
                        switch (Step)
                        {
                            case 0:
                                me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133);
                                Event_Timer = 5000;
                                Step = 1;
                                break;
                            case 1:
                                me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
                                Event_onWait = false;
                                break;
                        }
                        break;
                    case 16:
                        switch (Step)
                        {
                            case 0:
                                DoScriptText(CLINTAR_SPIRIT_SAY_GET_TWO, me, player);
                                Event_Timer = 15000;
                                Step = 1;
                                break;
                            case 1:
                                Event_onWait = false;
                                break;
                        }
                        break;
                    case 20:
                        switch (Step)
                        {
                            case 0:
                                {
                                Creature* mob = me->SummonCreature(ASPECT_RAVEN, ASPECT_RAVEN_SUMMON_X, ASPECT_RAVEN_SUMMON_Y, ASPECT_RAVEN_SUMMON_Z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000);
                                if (mob)
                                {
                                    mob->AddThreat(me, 10000.0f);
                                    mob->AI()->AttackStart(me);
                                }
                                Event_Timer = 2000;
                                Step = 1;
                                break;
                                }
                            case 1:
                                Event_onWait = false;
                                break;
                        }
                        break;
                    case 24:
                        switch (Step)
                        {
                            case 0:
                                me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133);
                                Event_Timer = 5000;
                                Step = 1;
                                break;
                            case 1:
                                me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
                                Event_onWait = false;
                                break;
                        }
                        break;
                    case 25:
                        switch (Step)
                        {
                            case 0:
                                DoScriptText(CLINTAR_SPIRIT_SAY_GET_THREE, me, player);
                                Event_Timer = 4000;
                                Step = 1;
                                break;
                            case 1:
                                Event_onWait = false;
                                break;
                        }
                        break;
                    case 40:
                        switch (Step)
                        {
                            case 0:
                                me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 2);
                                DoScriptText(CLINTAR_SPIRIT_SAY_GET_FINAL, me, player);
                                player->CompleteQuest(10965);
                                Event_Timer = 1500;
                                Step = 1;
                                break;
                            case 1:
                                me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
                                Event_Timer = 3000;
                                Step = 2;
                                break;
                            case 2:
                                player->TalkedToCreature(me->GetEntry(), me->GetGUID());
                                PlayerGUID = 0;
                                Reset();
                                me->setDeathState(JUST_DIED);
                                break;
                        }
                        break;
                    default:
                        Event_onWait = false;
                        break;
                }
            } else if (Event_onWait) Event_Timer -= diff;
        }
示例#8
0
		void MoveInLineOfSight(Unit *who) {
			if (me->IsWithinDist(who, 50) && !me->isInCombat()
					&& me->IsHostileTo(who))
				AttackStart(who);
		}
    void UpdateAI(const uint32 diff)
    {
        if (Intro && !Done)
        {
            if (AggroTimer <= diff)
            {
                me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                DoScriptText(SAY_AGGRO, me);
                me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
                Done = true;
                if (AggroTargetGUID)
                {
                    Unit* pUnit = Unit::GetUnit((*me), AggroTargetGUID);
                    if (pUnit)
                        AttackStart(pUnit);

                    DoZoneInCombat();
                }
                else
                {
                    EnterEvadeMode();
                    return;
                }
            } else AggroTimer -= diff;
        }

        if (!UpdateVictim() || !Done)
            return;

        if (SummonShadowsTimer <= diff)
        {
            //MindControlGhost();

            for (uint8 i = 0; i < 2; ++i)
            {
                Creature* Shadow = NULL;
                float X = CalculateRandomLocation(me->GetPositionX(), 10);
                Shadow = me->SummonCreature(CREATURE_SHADOWY_CONSTRUCT, X, me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 0);
                if (Shadow)
                {
                    Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
                    if (!pTarget)
                        pTarget = me->getVictim();

                    if (pTarget)
                        Shadow->AI()->AttackStart(pTarget);
                }
            }
            SummonShadowsTimer = 60000;
        } else SummonShadowsTimer -= diff;

        if (SummonDoomBlossomTimer <= diff)
        {
            if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
            {
                float X = CalculateRandomLocation(pTarget->GetPositionX(), 20);
                float Y = CalculateRandomLocation(pTarget->GetPositionY(), 20);
                float Z = pTarget->GetPositionZ();
                Z = me->GetMap()->GetVmapHeight(X, Y, Z);
                Creature* DoomBlossom = me->SummonCreature(CREATURE_DOOM_BLOSSOM, X, Y, Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000);
                if (DoomBlossom)
                {
                    DoomBlossom->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                    DoomBlossom->setFaction(me->getFaction());
                    DoomBlossom->AddThreat(pTarget, 1.0f);
                    CAST_AI(mob_doom_blossomAI, DoomBlossom->AI())->SetTeronGUID(me->GetGUID());
                    pTarget->CombatStart(DoomBlossom);
                    SetThreatList(DoomBlossom);
                    SummonDoomBlossomTimer = 35000;
                }
            }
        } else SummonDoomBlossomTimer -= diff;

        if (IncinerateTimer <= diff)
        {
            Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
            if (!pTarget)
                pTarget = me->getVictim();

            if (pTarget)
            {
                DoScriptText(RAND(SAY_SPECIAL1,SAY_SPECIAL2), me);
                DoCast(pTarget, SPELL_INCINERATE);
                IncinerateTimer = 20000 + rand()%31 * 1000;
            }
        } else IncinerateTimer -= diff;

        if (CrushingShadowsTimer <= diff)
        {
            Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
            if (pTarget && pTarget->isAlive())
                DoCast(pTarget, SPELL_CRUSHING_SHADOWS);
            CrushingShadowsTimer = 10000 + rand()%16 * 1000;
        } else CrushingShadowsTimer -= diff;

        /*** NOTE FOR FUTURE DEV: UNCOMMENT BELOW ONLY IF MIND CONTROL IS FULLY IMPLEMENTED **/
        /*if (ShadowOfDeathTimer <= diff)
        {
            Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);

            if (!pTarget)
               pTarget = me->getVictim();

            if (pTarget && pTarget->isAlive() && pTarget->GetTypeId() == TYPEID_PLAYER)
            {
                DoCast(pTarget, SPELL_SHADOW_OF_DEATH);
                GhostGUID = pTarget->GetGUID();
                ShadowOfDeathTimer = 30000;
                SummonShadowsTimer = 53000; // Make it VERY close but slightly less so that we can check if the aura is still on the player
            }
        } else ShadowOfDeathTimer -= diff;*/

        if (RandomYellTimer <= diff)
        {
            DoScriptText(RAND(SAY_SPELL1,SAY_SPELL2), me);
            RandomYellTimer = 50000 + rand()%51 * 1000;
        } else RandomYellTimer -= diff;

        if (!me->HasAura(SPELL_BERSERK))
        {
            if (EnrageTimer <= diff)
        {
            DoCast(me, SPELL_BERSERK);
            DoScriptText(SAY_ENRAGE, me);
        } else EnrageTimer -= diff;
        }

        DoMeleeAttackIfReady();
    }
示例#10
0
        void UpdateAI(const uint32 diff)
        {
            //Speech
            if (DoingSpeech)
            {
                if (SpeechTimer <= diff)
                {
                    switch (SpeechNum)
                    {
                        case 0:
                            //16 seconds till next line
                            DoScriptText(SAY_LINE2, me);
                            SpeechTimer = 16000;
                            ++SpeechNum;
                            break;
                        case 1:
                            //This one is actually 16 seconds but we only go to 10 seconds because he starts attacking after he says "I must fight this!"
                            DoScriptText(SAY_LINE3, me);
                            SpeechTimer = 10000;
                            ++SpeechNum;
                            break;
                        case 2:
                            me->setFaction(103);
                            if (PlayerGUID && Unit::GetUnit(*me, PlayerGUID))
                            {
                                AttackStart(Unit::GetUnit(*me, PlayerGUID));
                                DoCast(me, SPELL_ESSENCEOFTHERED);
                            }
                            SpeechTimer = 0;
                            DoingSpeech = false;
                            break;
                    }
                } else SpeechTimer -= diff;
            }

            //Return since we have no target
            if (!UpdateVictim())
                return;

            // Yell if hp lower than 15%
            if (HealthBelowPct(15) && !HasYelled)
            {
                DoScriptText(SAY_HALFLIFE, me);
                HasYelled = true;
            }

            //Cleave_Timer
            if (Cleave_Timer <= diff)
            {
                DoCast(me->getVictim(), SPELL_CLEAVE);
                Cleave_Timer = 15000;
            } else Cleave_Timer -= diff;

            //FlameBreath_Timer
            if (FlameBreath_Timer <= diff)
            {
                DoCast(me->getVictim(), SPELL_FLAMEBREATH);
                FlameBreath_Timer = urand(4000, 8000);
            } else FlameBreath_Timer -= diff;

            //BurningAdrenalineCaster_Timer
            if (BurningAdrenalineCaster_Timer <= diff)
            {
                Unit* target = NULL;

                uint8 i = 0;
                while (i < 3)   // max 3 tries to get a random target with power_mana
                {
                    ++i;
                    target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true); //not aggro leader
                    if (target && target->getPowerType() == POWER_MANA)
                            i = 3;
                }
                if (target)                                     // cast on self (see below)
                    target->CastSpell(target, SPELL_BURNINGADRENALINE, 1);

                BurningAdrenalineCaster_Timer = 15000;
            } else BurningAdrenalineCaster_Timer -= diff;

            //BurningAdrenalineTank_Timer
            if (BurningAdrenalineTank_Timer <= diff)
            {
                // have the victim cast the spell on himself otherwise the third effect aura will be applied
                // to Vael instead of the player
                me->getVictim()->CastSpell(me->getVictim(), SPELL_BURNINGADRENALINE, 1);

                BurningAdrenalineTank_Timer = 45000;
            } else BurningAdrenalineTank_Timer -= diff;

            //FireNova_Timer
            if (FireNova_Timer <= diff)
            {
                DoCast(me->getVictim(), SPELL_FIRENOVA);
                FireNova_Timer = 5000;
            } else FireNova_Timer -= diff;

            //TailSwipe_Timer
            if (TailSwipe_Timer <= diff)
            {
                //Only cast if we are behind
                /*if (!me->HasInArc(M_PI, me->getVictim()))
                {
                DoCast(me->getVictim(), SPELL_TAILSWIPE);
                }*/

                TailSwipe_Timer = 20000;
            } else TailSwipe_Timer -= diff;

            DoMeleeAttackIfReady();
        }
示例#11
0
文件: PetAI.cpp 项目: dsstest/ArkCORE
void PetAI::UpdateAI(const uint32 diff) {
	if (!me->isAlive())
		return;

	Unit* owner = me->GetCharmerOrOwner();

	if (m_updateAlliesTimer <= diff)
		// UpdateAllies self set update timer
		UpdateAllies();
	else
		m_updateAlliesTimer -= diff;

	// me->getVictim() can't be used for check in case stop fighting, me->getVictim() clear at Unit death etc.
	if (me->getVictim()) {
		if (_needToStop()) {
			sLog->outStaticDebug("Pet AI stopped attacking [guid=%u]",
					me->GetGUIDLow());
			_stopAttack();
			return;
		}
		targetHasCC = _CheckTargetCC(me->getVictim());

		DoMeleeAttackIfReady();
	} else if (owner && me->GetCharmInfo()) //no victim
			{
		Unit *nextTarget = SelectNextTarget();

		if (me->HasReactState(REACT_PASSIVE))
			_stopAttack();
		else if (nextTarget)
			AttackStart(nextTarget);
		else
			HandleReturnMovement();
	} else if (owner && !me->HasUnitState(UNIT_STAT_FOLLOW)) // no charm info and no victim
		me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST,
				me->GetFollowAngle());

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

	// Autocast (casted only in combat or persistent spells in any state)
	if (me->GetGlobalCooldown() == 0 && !me->HasUnitState(UNIT_STAT_CASTING)) {
		typedef std::vector<std::pair<Unit*, Spell*> > TargetSpellList;
		TargetSpellList targetSpellStore;

		for (uint8 i = 0; i < me->GetPetAutoSpellSize(); ++i) {
			uint32 spellID = me->GetPetAutoSpellOnPos(i);
			if (!spellID)
				continue;

			SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellID);
			if (!spellInfo)
				continue;

			// ignore some combinations of combat state and combat/noncombat spells
			if (!me->getVictim()) {
				// ignore attacking spells, and allow only self/around spells
				if (!IsPositiveSpell(spellInfo->Id))
					continue;

				// non combat spells allowed
				// only pet spells have IsNonCombatSpell and not fit this reqs:
				// Consume Shadows, Lesser Invisibility, so ignore checks for its
				if (!IsNonCombatSpell(spellInfo)) {
					// allow only spell without spell cost or with spell cost but not duration limit
					int32 duration = GetSpellDuration(spellInfo);
					if ((spellInfo->manaCost || spellInfo->ManaCostPercentage
							|| spellInfo->manaPerSecond) && duration > 0)
						continue;

					// allow only spell without cooldown > duration
					int32 cooldown = GetSpellRecoveryTime(spellInfo);
					if (cooldown >= 0 && duration >= 0 && cooldown > duration)
						continue;
				}
			} else {
				// just ignore non-combat spells
				if (IsNonCombatSpell(spellInfo))
					continue;
			}

			Spell *spell = new Spell(me, spellInfo, false, 0);

			// Fix to allow pets on STAY to autocast
			if (me->getVictim() && _CanAttack(me->getVictim())
					&& spell->CanAutoCast(me->getVictim())) {
				targetSpellStore.push_back(
						std::make_pair<Unit*, Spell*>(me->getVictim(), spell));
				continue;
			} else {
				bool spellUsed = false;
				for (std::set<uint64>::const_iterator tar = m_AllySet.begin();
						tar != m_AllySet.end(); ++tar) {
					Unit* Target = ObjectAccessor::GetUnit(*me, *tar);

					//only buff targets that are in combat, unless the spell can only be cast while out of combat
					if (!Target)
						continue;

					if (spell->CanAutoCast(Target)) {
						targetSpellStore.push_back(
								std::make_pair<Unit*, Spell*>(Target, spell));
						spellUsed = true;
						break;
					}
				}
				if (!spellUsed)
					delete spell;
			}
		}

		//found units to cast on to
		if (!targetSpellStore.empty()) {
			uint32 index = urand(0, targetSpellStore.size() - 1);

			Spell* spell = targetSpellStore[index].second;
			Unit* target = targetSpellStore[index].first;

			targetSpellStore.erase(targetSpellStore.begin() + index);

			SpellCastTargets targets;
			targets.setUnitTarget(target);

			if (!me->HasInArc(M_PI, target)) {
				me->SetInFront(target);
				if (target && target->GetTypeId() == TYPEID_PLAYER)
					me->SendUpdateToPlayer(target->ToPlayer());

				if (owner && owner->GetTypeId() == TYPEID_PLAYER)
					me->SendUpdateToPlayer(owner->ToPlayer());
			}

			me->AddCreatureSpellCooldown(spell->m_spellInfo->Id);

			spell->prepare(&targets);
		}

		// deleted cached Spell objects
		for (TargetSpellList::const_iterator itr = targetSpellStore.begin();
				itr != targetSpellStore.end(); ++itr)
			delete itr->second;
	}
}
示例#12
0
        void UpdateAI(const uint32 uiDiff) override
        {
            if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            {
                return;
            }

            // Summon panters every 5 seconds
            if (m_uiSummonTimer < uiDiff)
            {
                if (m_pInstance)
                {
                    if (Creature* pTrigger = m_pInstance->instance->GetCreature(ObjectGuid(m_pInstance->GetData64(TYPE_SIGNAL_2))))
                    {
                        m_creature->SummonCreature(NPC_ZULIAN_PROWLER, pTrigger->GetPositionX(), pTrigger->GetPositionY(), pTrigger->GetPositionZ(), 0, TEMPSUMMON_TIMED_OOC_DESPAWN, 30000);
                    }
                    if (Creature* pTrigger = m_pInstance->instance->GetCreature(ObjectGuid(m_pInstance->GetData64(TYPE_SIGNAL_3))))
                    {
                        m_creature->SummonCreature(NPC_ZULIAN_PROWLER, pTrigger->GetPositionX(), pTrigger->GetPositionY(), pTrigger->GetPositionZ(), 0, TEMPSUMMON_TIMED_OOC_DESPAWN, 30000);
                    }
                }

                m_uiSummonTimer = 5000;
            }
            else
            {
                m_uiSummonTimer -= uiDiff;
            }

            if (m_uiVisibleTimer)
            {
                if (m_uiVisibleTimer <= uiDiff)
                {
                    // Restore visibility
                    m_creature->SetVisibility(VISIBILITY_ON);

                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                    {
                        AttackStart(pTarget);
                    }

                    m_uiVisibleTimer = 0;
                }
                else
                {
                    m_uiVisibleTimer -= uiDiff;
                }

                // Do nothing while vanished
                return;
            }

            // Troll phase
            if (!m_bIsPhaseTwo)
            {
                if (m_uiShadowWordPainTimer < uiDiff)
                {
                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                    {
                        if (DoCastSpellIfCan(pTarget, SPELL_SHADOW_WORD_PAIN) == CAST_OK)
                        {
                            m_uiShadowWordPainTimer = 15000;
                        }
                    }
                }
                else
                {
                    m_uiShadowWordPainTimer -= uiDiff;
                }

                if (m_uiMarkTimer < uiDiff)
                {
                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_MARK_ARLOKK, SELECT_FLAG_PLAYER))
                    {
                        if (DoCastSpellIfCan(pTarget, SPELL_MARK_ARLOKK) == CAST_OK)
                        {
                            DoScriptText(SAY_FEAST_PANTHER, m_creature, pTarget);
                            m_uiMarkTimer = 30000;
                        }
                    }
                }
                else
                {
                    m_uiMarkTimer -= uiDiff;
                }

                if (m_uiGougeTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_GOUGE) == CAST_OK)
                    {
                        if (m_creature->GetThreatManager().getThreat(m_creature->getVictim()))
                        {
                            m_creature->GetThreatManager().modifyThreatPercent(m_creature->getVictim(), -80);
                        }

                        m_uiGougeTimer = urand(17000, 27000);
                    }
                }
                else
                {
                    m_uiGougeTimer -= uiDiff;
                }

                // Transform to Panther
                if (m_uiTransformTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_PANTHER_TRANSFORM) == CAST_OK)
                    {
                        m_uiTransformTimer = 80000;
                        m_bIsPhaseTwo = true;
                    }
                }
                else
                {
                    m_uiTransformTimer -= uiDiff;
                }
            }
            // Panther phase
            else
            {
                if (m_uiRavageTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_RAVAGE) == CAST_OK)
                    {
                        m_uiRavageTimer = urand(10000, 15000);
                    }
                }
                else
                {
                    m_uiRavageTimer -= uiDiff;
                }

                if (m_uiTrashTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_TRASH) == CAST_OK)
                    {
                        m_uiTrashTimer = urand(13000, 15000);
                    }
                }
                else
                {
                    m_uiTrashTimer -= uiDiff;
                }

                if (m_uiWhirlwindTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_WHIRLWIND) == CAST_OK)
                    {
                        m_uiWhirlwindTimer = 15000;
                    }
                }
                else
                {
                    m_uiWhirlwindTimer -= uiDiff;
                }

                if (m_uiVanishTimer < uiDiff)
                {
                    // Note: this is a workaround because we do not know the real vanish spell
                    m_creature->SetVisibility(VISIBILITY_OFF);
                    DoResetThreat();

                    m_uiVanishTimer = 85000;
                    m_uiVisibleTimer = 45000;
                }
                else
                {
                    m_uiVanishTimer -= uiDiff;
                }

                // Transform back
                if (m_uiTransformTimer < uiDiff)
                {
                    m_creature->RemoveAurasDueToSpell(SPELL_PANTHER_TRANSFORM);
                    m_uiTransformTimer = 30000;
                    m_bIsPhaseTwo = false;
                }
                else
                {
                    m_uiTransformTimer -= uiDiff;
                }
            }

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

			events.Update(diff);

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

			switch( events.GetEvent() )
			{
				case 0:
					break;
				case EVENT_YELL_DEAD_1:
					Talk(YELL_DEAD_1);
					events.PopEvent();
					break;
				case EVENT_START_RESURRECTION:
					me->CastSpell(me, SPELL_SUMMON_VALKYR, true);
					events.PopEvent();
					events.RescheduleEvent(EVENT_VALKYR_BEAM, 7000);
					events.RescheduleEvent(EVENT_VALKYR_MOVE, 1);
					events.RescheduleEvent(EVENT_ANNHYLDE_YELL, 3000);
					break;
				case EVENT_VALKYR_MOVE:
					if( Creature* s = ObjectAccessor::GetCreature(*me, ValkyrGUID) )
						s->GetMotionMaster()->MovePoint(1, s->GetPositionX(), s->GetPositionY(), s->GetPositionZ()-15.0f);
					events.PopEvent();
					break;
				case EVENT_ANNHYLDE_YELL:
					if( Creature* s = ObjectAccessor::GetCreature(*me, ValkyrGUID) )
						s->AI()->Talk(YELL_ANHYLDE_2);
					events.PopEvent();
					break;
				case EVENT_VALKYR_BEAM:
					me->RemoveAura(SPELL_SUMMON_VALKYR);
					if( Creature* c = ObjectAccessor::GetCreature(*me, ValkyrGUID) )
						c->CastSpell(me, SPELL_RESURRECTION_BEAM, false);
					events.PopEvent();
					events.RescheduleEvent(EVENT_RESURRECTION_BALL, 4000);
					break;
				case EVENT_RESURRECTION_BALL:
					me->CastSpell(me, SPELL_RESURRECTION_BALL, true);
					events.PopEvent();
					events.RescheduleEvent(EVENT_RESURRECTION_HEAL, 4000);
					break;
				case EVENT_RESURRECTION_HEAL:
					me->RemoveAura(SPELL_RESURRECTION_BALL);
					me->CastSpell(me, SPELL_RESURRECTION_HEAL, true);
					FeignDeath(false);
					events.PopEvent();
					events.RescheduleEvent(EVENT_MORPH_TO_UNDEAD, 3000);
					break;
				case EVENT_MORPH_TO_UNDEAD:
					me->CastSpell(me, SPELL_INGVAR_TRANSFORM, true);
					events.PopEvent();
					events.RescheduleEvent(EVENT_START_PHASE_2, 1000);
					break;
				case EVENT_START_PHASE_2:
					if( Creature* c = ObjectAccessor::GetCreature(*me, ValkyrGUID) )
					{
						c->DespawnOrUnsummon();
						summons.DespawnAll();
					}
					events.PopEvent();
					me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
					AttackStart(me->GetVictim());
					me->GetMotionMaster()->MoveChase(me->GetVictim());
					Talk(YELL_AGGRO_2);

					// schedule Phase 2 abilities
					events.RescheduleEvent(EVENT_SPELL_ROAR, 15000);
					events.RescheduleEvent(EVENT_SPELL_CLEAVE_OR_WOE_STRIKE, 2000);
					events.RescheduleEvent(EVENT_SPELL_SMASH, 5000);
					events.RescheduleEvent(EVENT_SPELL_ENRAGE_OR_SHADOW_AXE, 10000);

					break;

				// ABILITIES HERE:
				case EVENT_UNROOT:
					me->SetControlled(false, UNIT_STATE_ROOT);
					me->DisableRotate(false);
					events.PopEvent();
					break;
				case EVENT_SPELL_ROAR:
					Talk(EMOTE_ROAR);

					me->_AddCreatureSpellCooldown(SPELL_STAGGERING_ROAR, 0);
					me->_AddCreatureSpellCooldown(SPELL_DREADFUL_ROAR, 0);

					if (me->GetDisplayId() == DISPLAYID_DEFAULT)
						me->CastSpell((Unit*)NULL, SPELL_STAGGERING_ROAR, false);
					else
						me->CastSpell((Unit*)NULL, SPELL_DREADFUL_ROAR, false);
					events.RepeatEvent(urand(15000,20000));
					break;
				case EVENT_SPELL_CLEAVE_OR_WOE_STRIKE:
					if( me->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) == 0 )
					{
						events.RepeatEvent(3000);
						break;
					}
					if (me->GetDisplayId() == DISPLAYID_DEFAULT)
						me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
					else
						me->CastSpell(me->GetVictim(), SPELL_WOE_STRIKE, false);
					events.RepeatEvent(urand(0,4000)+3000);
					break;
				case EVENT_SPELL_SMASH:
					if( me->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) == 0 )
					{
						events.RepeatEvent(3000);
						break;
					}
					me->SetControlled(true, UNIT_STATE_ROOT);
					me->DisableRotate(true);
					me->SendMovementFlagUpdate();
					if (me->GetDisplayId() == DISPLAYID_DEFAULT)
						me->CastSpell((Unit*)NULL, SPELL_SMASH, false);
					else
						me->CastSpell((Unit*)NULL, SPELL_DARK_SMASH, false);
					events.RepeatEvent(urand(9000,11000));
					events.RescheduleEvent(EVENT_UNROOT, 3750);
					break;
				case EVENT_SPELL_ENRAGE_OR_SHADOW_AXE:
					if (me->GetDisplayId() == DISPLAYID_DEFAULT)
					{
						me->CastSpell(me, SPELL_ENRAGE, false);
						events.RepeatEvent(10000);
					}
					else
					{
						me->CastSpell((Unit*)NULL, SPELL_SHADOW_AXE, true);
						SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
						events.RepeatEvent(35000);
						events.RescheduleEvent(EVENT_AXE_RETURN, 10000);
					}
					break;
				case EVENT_AXE_RETURN:
					if (Creature* c = ObjectAccessor::GetCreature(*me, ThrowGUID))
						c->GetMotionMaster()->MoveCharge(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+0.5f);
					events.PopEvent();
					events.RescheduleEvent(EVENT_AXE_PICKUP, 1500);
					break;
				case EVENT_AXE_PICKUP:
					if (Creature* c = ObjectAccessor::GetCreature(*me, ThrowGUID))
					{
						c->DestroyForNearbyPlayers();
						c->DespawnOrUnsummon();
						summons.DespawnAll();
					}
					ThrowGUID = 0;
					SetEquipmentSlots(true);
					events.PopEvent();
					break;
			}

			if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
				DoMeleeAttackIfReady();
		}
        void UpdateAI(const uint32 diff)
        {
            if (instance)
            {
                if (!leotherasGUID)
                    leotherasGUID = instance->GetData64(DATA_LEOTHERAS);

                if (!me->isInCombat() && instance->GetData64(DATA_LEOTHERAS_EVENT_STARTER))
                {
                    Unit* victim = NULL;
                    victim = Unit::GetUnit(*me, instance->GetData64(DATA_LEOTHERAS_EVENT_STARTER));
                    if (victim)
                        AttackStart(victim);
                }
            }

            if (!UpdateVictim())
            {
                CastChanneling();
                return;
            }

            if (instance && !instance->GetData64(DATA_LEOTHERAS_EVENT_STARTER))
            {
                EnterEvadeMode();
                return;
            }

            if (Mindblast_Timer <= diff)
            {
                Unit* target = NULL;
                target = SelectTarget(SELECT_TARGET_RANDOM, 0);

                if (target)DoCast(target, SPELL_MINDBLAST);

                Mindblast_Timer = urand(10000, 15000);
            } else Mindblast_Timer -= diff;

            if (Earthshock_Timer <= diff)
            {
                Map* map = me->GetMap();
                Map::PlayerList const &PlayerList = map->GetPlayers();
                for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr)
                {
                    if (Player* i_pl = itr->getSource())
                    {
                        bool isCasting = false;
                        for (uint8 i = 0; i < CURRENT_MAX_SPELL; ++i)
                            if (i_pl->GetCurrentSpell(i))
                                isCasting = true;

                        if (isCasting)
                        {
                            DoCast(i_pl, SPELL_EARTHSHOCK);
                            break;
                        }
                    }
                }
                Earthshock_Timer = urand(8000, 15000);
            } else Earthshock_Timer -= diff;
            DoMeleeAttackIfReady();
        }
示例#15
0
void PetAI::UpdateAI(const uint32 diff)
{
    if (!m_creature->isAlive())
        return;

    m_updateAlliesTimer.Update(diff);
    if (m_updateAlliesTimer.Passed())
    {
        UpdateAllies();
        m_updateAlliesTimer.Reset();
    }

    Unit* owner = m_creature->GetCharmerOrOwner();

    if (owner && !m_creature->IsWithinDistInMap(owner, m_fMaxRadiusToOwner) && !m_creature->IsInUnitState(UNIT_ACTION_HOME))
    {
        if (owner->GetTypeId() == TYPEID_PLAYER && (m_creature->IsPet() || m_creature->isCharmed()))
        {
            owner->CallForAllControlledUnits(DoPetActionWithHelper((Player*)owner, ACT_REACTION, REACT_PASSIVE, m_creature->GetObjectGuid(), ObjectGuid()), CONTROLLED_PET | CONTROLLED_GUARDIANS | CONTROLLED_CHARM);
            owner->CallForAllControlledUnits(DoPetActionWithHelper((Player*)owner, ACT_COMMAND, COMMAND_FOLLOW, m_creature->GetObjectGuid(), ObjectGuid()), CONTROLLED_PET | CONTROLLED_GUARDIANS | CONTROLLED_CHARM);
            return;
        }
    }

    if (!inCombat && m_savedTargetGuid)
    {
        if (Unit* savedTarget = m_creature->GetMap()->GetUnit(m_savedTargetGuid))
        {
            if (!savedTarget->isAlive())
                m_savedTargetGuid.Clear();
            else if (!savedTarget->IsCrowdControlled())
                AttackStart(savedTarget);
        }
        else
            m_savedTargetGuid.Clear();
    }

    Unit* pVictim = m_creature->getVictim();

    if (inCombat &&
            (!pVictim || !pVictim->isAlive() ||
             (m_creature->IsPet() && m_creature->GetCharmInfo()->HasState(CHARM_STATE_ACTION, ACTIONS_DISABLE))))
        _stopAttack();

    if (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT) || m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED))
    {
        UpdateAIType();
        return;
    }

    // i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
    if (pVictim)
    {
        bool meleeReach = m_creature->CanReachWithMeleeAttack(pVictim);

        if (_needToStop())
        {
            DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "PetAI (guid = %u) is stopping attack.", m_creature->GetGUIDLow());
            _stopAttack();
            return;
        }
        else if (!pVictim->isAlive())                        // Stop attack if target dead
        {
            m_creature->InterruptNonMeleeSpells(false);
            _stopAttack();
            return;
        }
        // Stop attack if target under CC effect
        else if (sWorld.getConfig(CONFIG_BOOL_PET_ADVANCED_AI) && IsInCombat() &&
                 pVictim->IsCrowdControlled() &&
                 !m_creature->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
        {
            m_savedTargetGuid = pVictim->GetObjectGuid();
            m_creature->InterruptSpell(CURRENT_GENERIC_SPELL, true);
            if (!m_creature->IsNonMeleeSpellCasted(false, false, true))
                _stopAttack();
            return;
        }
        else if (m_creature->IsStopped() || meleeReach)
        {
            // required to be stopped cases
            if (m_creature->IsStopped() && m_creature->IsNonMeleeSpellCasted(false))
            {
                if (m_creature->hasUnitState(UNIT_STAT_FOLLOW_MOVE))
                    m_creature->InterruptNonMeleeSpells(false);
                else
                    return;
            }
            // not required to be stopped case
            else if (DoMeleeAttackIfReady())
            {
                pVictim = m_creature->getVictim();
                if (!pVictim)
                    return;

                // if pet misses its target, it will also be the first in threat list
                pVictim->AddThreat(m_creature);

                if (_needToStop())
                    _stopAttack();
            }
        }

        if (!m_creature->IsNonMeleeSpellCasted(true))
        {
            m_attackDistanceRecheckTimer.Update(diff);
            if (m_attackDistanceRecheckTimer.Passed())
            {
                m_attackDistanceRecheckTimer.Reset();
                if (sWorld.getConfig(CONFIG_BOOL_PET_ADVANCED_AI) && m_AIType == PET_AI_RANGED && pVictim)
                {
                    float dist = m_creature->GetDistance(pVictim);
                    if ((m_creature->CanReachWithMeleeAttack(pVictim) &&
                            m_creature->IsWithinDist(owner, m_creature->GetMap()->GetVisibilityDistance() / 2.0f)) ||
                            dist > (m_attackDistance + 2.0f))
                    {
                        MoveToVictim(pVictim);
                        return;
                    }
                }

                if (sWorld.getConfig(CONFIG_BOOL_PET_ADVANCED_AI))
                {
                    // FIXME: AOE check
                }
            }
        }
    }
    else if (Unit* target = GetPrimaryTarget())
    {
        AttackStart(target);
    }
    else if (owner)
    {
        switch (m_creature->GetCharmState(CHARM_STATE_REACT))
        {
        case REACT_DEFENSIVE:
        {
            if (!m_primaryTargetGuid)
            {
                Unit* ownerVictim = owner->getVictim();
                if (ownerVictim && ownerVictim->isAlive())
                    AttackStart(ownerVictim);
            }
            break;
        }
        case REACT_AGGRESSIVE:
        {
            if (Unit* pTarget = owner->getAttackerForHelper())
                AttackStart(pTarget);
            break;
        }
        // case REACT_PASSIVE:
        default:
            break;
        }
    }

    UpdateAIType();

    if (m_creature->IsNonMeleeSpellCasted(true))
        return;

    // Autocast (casted only in combat or persistent spells in any state)
    if (!sWorld.getConfig(CONFIG_BOOL_PET_ADVANCED_AI) && m_AIType != PET_AI_PASSIVE)
    {
        typedef std::vector<std::pair<ObjectGuid, uint32> > TargetSpellList;
        TargetSpellList targetSpellStore;

        for (uint8 i = 0; i < m_creature->GetPetAutoSpellSize(); ++i)
        {
            uint32 spellID = m_creature->GetPetAutoSpellOnPos(i);
            if (!spellID)
                continue;

            SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellID);
            if (!spellInfo)
                continue;

            if (m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
                continue;

            if (m_creature->HasSpellCooldown(spellInfo))
                continue;

            // ignore some combinations of combat state and combat/noncombat spells
            if (!inCombat)
            {
                // ignore attacking spells, and allow only self/around spells
                if (!IsPositiveSpell(spellInfo->Id))
                    continue;

                // non combat spells allowed
                // only pet spells have IsNonCombatSpell and not fit this reqs:
                // Consume Shadows, Lesser Invisibility, so ignore checks for its
                if (!IsNonCombatSpell(spellInfo))
                {
                    // allow only spell without spell cost or with spell cost but not duration limit
                    int32 duration = GetSpellDuration(spellInfo);
                    if ((spellInfo->manaCost || spellInfo->ManaCostPercentage || spellInfo->manaPerSecond) && duration > 0)
                        continue;

                    // allow only spell without cooldown > duration
                    int32 cooldown = GetSpellRecoveryTime(spellInfo);
                    if (cooldown >= 0 && duration >= 0 && cooldown > duration)
                        continue;
                }
            }
            else
            {
                // just ignore non-combat spells
                if (IsNonCombatSpell(spellInfo))
                    continue;
            }

            Unit* autoCastTarget = NULL;

            if (inCombat)
            {
                Unit* pVictim = m_creature->getVictim();
                if (pVictim && !m_creature->hasUnitState(UNIT_STAT_FOLLOW))
                {
                    SpellCastResult result = CanAutoCast(pVictim, spellInfo);
                    if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
                        autoCastTarget = pVictim;
                }
            }

            if (!autoCastTarget)
            {
                for (GuidSet::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
                {
                    Unit* target = m_creature->GetMap()->GetUnit(*tar);

                    // Only buff targets that are in combat, unless the spell can only be cast while out of combat
                    if (!target)
                        continue;

                    SpellCastResult result = CanAutoCast(target, spellInfo);
                    if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
                    {
                        autoCastTarget = target;
                        break;
                    }
                }
            }

            if (autoCastTarget)
                targetSpellStore.push_back(TargetSpellList::value_type(autoCastTarget->GetObjectGuid(), spellInfo->Id));
        }

        // found units to cast on to
        if (!targetSpellStore.empty())
        {
            uint32 index = urand(0, targetSpellStore.size() - 1);
            if (Unit* target = m_creature->GetMap()->GetUnit(targetSpellStore[index].first))
                m_creature->DoPetCastSpell(target, targetSpellStore[index].second);
        }
    }
    else
    {
        AutoSpellList currentSpells;
        switch (m_AIType)
        {
        case PET_AI_PASSIVE:
        {
            currentSpells.push_back(GetSpellType(PET_SPELL_BUFF));
            break;
        }
        case PET_AI_SLACKER:
        {
            if (!IsInCombat())
                break;

            if (m_creature->IsCrowdControlled() || (owner && owner->IsCrowdControlled()))
                currentSpells.push_back(GetSpellType(PET_SPELL_FREEACTION));
            currentSpells.push_back(GetSpellType(PET_SPELL_DEFENCE));
            currentSpells.push_back(GetSpellType(PET_SPELL_BUFF));
            currentSpells.push_back(GetSpellType(PET_SPELL_DEBUFF));
            currentSpells.push_back(GetSpellType(PET_SPELL_RANGED));
            break;
        }
        case PET_AI_HEALER:
        {
            if (!IsInCombat())
                break;

            if (m_creature->IsCrowdControlled() || (owner && owner->IsCrowdControlled()))
                currentSpells.push_back(GetSpellType(PET_SPELL_FREEACTION));
            if (m_creature->GetHealth() < m_creature->GetMaxHealth() ||
                    (owner && (owner->GetHealth() < owner->GetMaxHealth())))
                currentSpells.push_back(GetSpellType(PET_SPELL_HEAL));
            currentSpells.push_back(GetSpellType(PET_SPELL_BUFF));
            currentSpells.push_back(GetSpellType(PET_SPELL_RANGED));
            break;
        }
        case PET_AI_RANGED:
        {
            if (!IsInCombat())
                break;

            if (m_creature->IsCrowdControlled() || (owner && owner->IsCrowdControlled()))
                currentSpells.push_back(GetSpellType(PET_SPELL_FREEACTION));
            currentSpells.push_back(GetSpellType(PET_SPELL_RANGED));
            currentSpells.push_back(GetSpellType(PET_SPELL_DEBUFF));
            currentSpells.push_back(GetSpellType(PET_SPELL_BUFF));
            break;
        }
        case PET_AI_MELEE:
        case PET_AI_RANGED_NOAMMO:
        {
            if (!IsInCombat())
                break;

            if (Unit* victim = m_creature->getVictim())
            {
                Unit* victimVictim = victim->getVictim();
                if (!victimVictim || (victimVictim->GetObjectGuid() != m_creature->GetObjectGuid()))
                {
                    currentSpells.push_back(GetSpellType(PET_SPELL_ATTACKSTART));
                    currentSpells.push_back(GetSpellType(PET_SPELL_THREAT));
                }
            }

            if (m_creature->IsCrowdControlled() || (owner && owner->IsCrowdControlled()))
                currentSpells.push_back(GetSpellType(PET_SPELL_FREEACTION));
        }
        /* no break here!*/
        default:
        {
            if (!IsInCombat())
                break;

            currentSpells.push_back(GetSpellType(PET_SPELL_MELEE));
            currentSpells.push_back(GetSpellType(PET_SPELL_DEBUFF));
            currentSpells.push_back(GetSpellType(PET_SPELL_RANGED));
            currentSpells.push_back(GetSpellType(PET_SPELL_BUFF));
            break;
        }
        }

        if (!IsInCombat())
        {
            currentSpells.push_back(GetSpellType(PET_SPELL_NONCOMBAT));
            if (m_creature->GetHealthPercent() < 95.0f)
                currentSpells.push_back(GetSpellType(PET_SPELL_HEAL));
        }
        else
            currentSpells.push_back(GetSpellType(PET_SPELL_SPECIAL));

        for (AutoSpellList::const_iterator itr = currentSpells.begin(); itr != currentSpells.end(); ++itr)
        {
            uint32 spellID = *itr;
            if (!spellID)
                continue;

            SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellID);
            if (!spellInfo)
                continue;

            if (m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
                continue;

            Unit* pTarget = m_creature->IsPet()
                            ? ((Pet*)m_creature)->SelectPreferredTargetForSpell(spellInfo)
                            : ((Creature*)m_creature)->SelectPreferredTargetForSpell(spellInfo);

            bool b_castOk = false;

            if (pTarget)
            {
                SpellCastResult result = CanAutoCast(pTarget, spellInfo);
                DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS,"PetAI::Update %s, AI %u try cast %u Target %s",
                                 m_creature->GetGuidStr().c_str(),
                                 m_AIType,
                                 spellID,
                                 pTarget ? pTarget->GetGuidStr().c_str() : "<none>");

                switch (result)
                {
                case SPELL_FAILED_TOO_CLOSE:
                case SPELL_FAILED_OUT_OF_RANGE:
                    break; // ignore
                case SPELL_FAILED_UNIT_NOT_INFRONT:
                {
                    if (DoCastSpellIfCan(pTarget, spellID) == CAST_OK)
                    {
                        b_castOk = true;
                        m_creature->SetInFront(pTarget);
                        if (pTarget->GetTypeId() == TYPEID_PLAYER)
                            m_creature->SendCreateUpdateToPlayer((Player*)pTarget);
                    }
                    break;
                }
                case SPELL_CAST_OK:
                {
                    if (DoCastSpellIfCan(pTarget, spellID) == CAST_OK)
                        b_castOk = true;

                    break;
                }
                default:
                {
                    Player* owner = (Player*)m_creature->GetOwner();
                    if (owner)
                        Spell::SendCastResult(owner, spellInfo, 0, result, true);

                    DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "PetAI::Update cast %s, AI %u Target %s spell %u result %u",
                                     m_creature->GetGuidStr().c_str(),
                                     m_AIType,
                                     pTarget ? pTarget->GetGuidStr().c_str() : "<none>",
                                     spellID,
                                     result);
                    break;
                }
                }
            }
            else
                continue;

            if (b_castOk)
            {
                if (m_creature->IsPet())
                {
                    if (((Pet*)m_creature)->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
                        m_creature->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
                    else
                        m_creature->SendPetAIReaction();
                }
                break;
            }
        }
    }
}
示例#16
0
        void UpdateAI(const uint32 diff)
        {
            if (!UpdateVictim())
                return;

            if (me->getVictim() && me->isAlive())
            {
                if (HealthAbovePct(50))
                {
                    if (Charge_Timer <= diff)
                    {
                        if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                        {
                            DoCast(target, SPELL_CHARGE);
                            AttackStart(target);
                        }

                        Charge_Timer = urand(15000, 30000);
                    } else Charge_Timer -= diff;

                    if (SonicBurst_Timer <= diff)
                    {
                        DoCast(me->getVictim(), SPELL_SONICBURST);
                        SonicBurst_Timer = urand(8000, 13000);
                    } else SonicBurst_Timer -= diff;

                    if (Screech_Timer <= diff)
                    {
                        DoCast(me->getVictim(), SPELL_SCREECH);
                        Screech_Timer = urand(18000, 26000);
                    } else Screech_Timer -= diff;

                    if (SpawnBats_Timer <= diff)
                    {
                        Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0);

                        Creature* Bat = NULL;
                        Bat = me->SummonCreature(11368, -12291.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (target && Bat) Bat ->AI()->AttackStart(target);

                        Bat = me->SummonCreature(11368, -12289.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (target && Bat) Bat ->AI()->AttackStart(target);

                        Bat = me->SummonCreature(11368, -12293.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (target && Bat) Bat ->AI()->AttackStart(target);

                        Bat = me->SummonCreature(11368, -12291.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (target && Bat) Bat ->AI()->AttackStart(target);

                        Bat = me->SummonCreature(11368, -12289.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (target && Bat) Bat ->AI()->AttackStart(target);
                        Bat = me->SummonCreature(11368, -12293.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (target && Bat) Bat ->AI()->AttackStart(target);

                        SpawnBats_Timer = 60000;
                    } else SpawnBats_Timer -= diff;
                }
                else
                {
                    if (PhaseTwo)
                    {
                        if (PhaseTwo && ShadowWordPain_Timer <= diff)
                        {
                            if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                            {
                                DoCast(target, SPELL_SHADOW_WORD_PAIN);
                                ShadowWordPain_Timer = urand(12000, 18000);
                            }
                        }
                        ShadowWordPain_Timer -=diff;

                        if (MindFlay_Timer <= diff)
                        {
                            DoCast(me->getVictim(), SPELL_MIND_FLAY);
                            MindFlay_Timer = 16000;
                        }
                        MindFlay_Timer -=diff;

                        if (ChainMindFlay_Timer <= diff)
                        {
                            me->InterruptNonMeleeSpells(false);
                            DoCast(me->getVictim(), SPELL_CHAIN_MIND_FLAY);
                            ChainMindFlay_Timer = urand(15000, 30000);
                        }
                        ChainMindFlay_Timer -=diff;

                        if (GreaterHeal_Timer <= diff)
                        {
                            me->InterruptNonMeleeSpells(false);
                            DoCast(me, SPELL_GREATERHEAL);
                            GreaterHeal_Timer = urand(25000, 35000);
                        }
                        GreaterHeal_Timer -=diff;

                        if (SpawnFlyingBats_Timer <= diff)
                        {
                            Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0);
                            if (!target)
                                return;

                            Creature* FlyingBat = me->SummonCreature(14965, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()+15, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                            if (FlyingBat)
                                FlyingBat->AI()->AttackStart(target);

                            SpawnFlyingBats_Timer = urand(10000, 15000);
                        } else SpawnFlyingBats_Timer -=diff;
                    }
                    else
                    {
                        me->SetDisplayId(15219);
                        DoResetThreat();
                        PhaseTwo = true;
                    }
                }

                DoMeleeAttackIfReady();
            }
        }
示例#17
0
    void UpdateAI(const uint32 diff)
    {
        if (!UpdateVictim())
            return;
	Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM,0);
	if (!pTarget)
	return;

        if(me->GetPositionY() > -60 || me->GetPositionX() < 450) // Not Blizzlike, anti-exploit to prevent players from pulling bosses to vehicles.
        {
            me->RemoveAllAuras();
            me->DeleteThreatList();
            me->CombatStop(false);
            me->GetMotionMaster()->MoveTargetedHome();
        }

        if (me->getVictim() && !me->getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself())
            me->Kill(me->getVictim());
	    
	if ((me->GetHealth()*100 / me->GetMaxHealth()) < 90 && Phase == 0)
        {
	Phase = 1;
	bFly = true;
	}

        if ((me->GetHealth()*100 / me->GetMaxHealth()) < 50 && Phase == 1)
        {
	    me->RemoveAllAuras();
	    Phase = 2;
	    InitialSpawn = false;
	    if (IsFlying)
		{
		    me->SetFlying(false);
                    me->GetMotionMaster()->MoveTargetedHome();
		    IsFlying = false;
		    me->SetReactState(REACT_AGGRESSIVE);
		    me->SendMovementFlagUpdate();
		}
            DoScriptText(SAY_PHASE_2_TRANS, me); 
        }

        if ((me->GetHealth()*100 / me->GetMaxHealth()) < 33 && Phase == 2)
        {
            Phase = 3;
            DoScriptText(SAY_PHASE_3_TRANS, me);
        }

        if (Phase >= 2)
        {
            if (FuseArmorTimer <= diff)
            {
                DoCastVictim(SPELL_FUSEARMOR);
                FuseArmorTimer = 10000;
            } else FuseArmorTimer -= diff;

            if (WingBuffetTimer <= diff)
            {
                DoCast(SPELL_WINGBUFFET);
                WingBuffetTimer = urand(27000,34000);
            } else WingBuffetTimer -= diff;

            if (FireballTimer <= diff)
            {
                if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true))
                {
                    me->SetInFront(pTarget);
                    DoCast(pTarget, SPELL_FIREBALL);
                }
                FireballTimer = 18000;
            } else FireballTimer -= diff;

            if (Phase == 3)
            {
                if (FlameBuffetTimer <= diff)
                {
                    DoScriptText(EMOTE_BREATH, me);
                    std::list<Unit*> pTargets;
                    SelectTargetList(pTargets, RAID_MODE(3,9), SELECT_TARGET_RANDOM, 100, true);
                    uint8 i = 0;
                    for (std::list<Unit*>::const_iterator itr = pTargets.begin(); itr != pTargets.end();)
                    {
                        if (me->HasInArc(M_PI, *itr))
                        {
                            DoCast(*itr, SPELL_FLAMEBUFFET, true);
                            ++i;
                        }
                        if (++itr == pTargets.end() || i == RAID_MODE(3,9))
                        {
                            AttackStart(*--itr);
                            break;
                        }
			if (!i)
			return;
                    }
                    FlameBuffetTimer = 25000;
                } else FlameBuffetTimer -= diff;
		
		if (FlameBreathTimer <= diff)
		{
                DoScriptText(EMOTE_BREATH, me);
                DoCastVictim(SPELL_FLAMEBREATH);
                FlameBreathTimer = 15000;
		} else FlameBreathTimer -= diff;
	  }
	  DoMeleeAttackIfReady();
        }
        else if (Phase == 1)
        {
	     if (bFly)
	     {
		FlyPhase(Phase, diff);
		SummonAddsTimer = 8000;
		bFly = false;
	     }
	     
	     Creature* pSpellHitt;
		pSpellHitt = NULL;
    
	     if (pSpellHitt = me->FindNearestCreature(NPC_VISUAL_HITT, 5.0f, true))
	     {
	            me->GetMotionMaster()->MoveTargetedHome();
		    me->SetFlying(false);
		    me->SendMovementFlagUpdate();
		    IsFlying = false;
		    bFlyPhase1 = true;
		    bFlyPhaseTimer = 35000;
		    bFly = false;
		    InitialSpawn = false;
		    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
		    StunTimer = 2000;
		}
		 if (!bFly && bFlyPhase1 && !IsFlying && StunTimer <= diff)
		    {
		    DoCast(me,SPELL_STUN);
		    StunTimer = 2000;
		    } else StunTimer -= diff;
	     
	     if (bFlyPhase1 && bFlyPhaseTimer <= diff)
		    {
		    me->RemoveAllAuras();
		    me->SetReactState(REACT_AGGRESSIVE);
		    me->SendMovementFlagUpdate();
		    DoScriptText(EMOTE_BREATH, me);
		    DoCastVictim(SPELL_FLAMEBREATH);
		    DoCast(SPELL_WINGBUFFET);
		    bFlyPhaseTimer = 40000;
		    SpawnHarpoonTimer = 60000;
		    bFly = true;
		    bFlyPhase1 = false;
		    } else bFlyPhaseTimer -= diff;

            if (FireballTimer <= diff)
            {
                if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true))
                {
                    me->SetInFront(pTarget);
                    DoCast(pTarget, SPELL_FIREBALL);
                }
                FireballTimer = 12000;
            } else FireballTimer -= diff;

            if (DevouringFlameTimer <= diff)
            {
                if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true))
                {
                    me->SetInFront(pTarget);
                    DoCast(pTarget, DEVOURING_FLAME_VISUAL);
                }
                DevouringFlameTimer = 6000;
            } else DevouringFlameTimer -= diff;
	    
	    if (InitialSpawn)
	    {
              if (SummonAddsTimer <= diff)
	      {
                SummonAdds();
		InitialSpawn = true;
	      } else SummonAddsTimer -= diff;
	    }
	    
	    if (InitialSpawn && SpawnHarpoonTimer <= diff)
	    {
	    if (pInstance)
	    pInstance->SetData(DATA_HARPOON, pInstance->GetData(DATA_HARPOON)+1);
	    //if(!GetClosestGameObjectWithEntry(me, GO_BROKEN_HARPOON, 200.0f))
	      //if (GameObject* pGo = me->SummonGameObject(GO_BROKEN_HARPOON, 607.613, -134.207, 391.297, 4.10138, 0, 0, 0, 0,0))
		 
	    SpawnHarpoonTimer = 60000;
	    } else SpawnHarpoonTimer -= diff;
	    
	    //EnterEvadeIfOutOfCombatArea(diff);
        }
    }
        void UpdateAI(uint32 diff) override
        {
            //Only if not incombat check if the event is started
            if (!me->IsInCombat() && instance->GetData(DATA_KARATHRESSEVENT))
            {
                if (Unit* target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_KARATHRESSEVENT_STARTER)))
                {
                    AttackStart(target);
                    GetAdvisors();
                }
            }

            //Return since we have no target
            if (!UpdateVictim())
                return;

            //someone evaded!
            if (!instance->GetData(DATA_KARATHRESSEVENT))
            {
                EnterEvadeMode();
                return;
            }

            //CataclysmicBolt_Timer
            if (CataclysmicBolt_Timer <= diff)
            {
                //select a random unit other than the main tank
                Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);

                //if there aren't other units, cast on the tank
                if (!target)
                    target = me->GetVictim();

                if (target)
                    DoCast(target, SPELL_CATACLYSMIC_BOLT);
                CataclysmicBolt_Timer = 10000;
            } else CataclysmicBolt_Timer -= diff;

            //SearNova_Timer
            if (SearNova_Timer <= diff)
            {
                DoCastVictim(SPELL_SEAR_NOVA);
                SearNova_Timer = 20000 + rand32() % 40000;
            } else SearNova_Timer -= diff;

            //Enrage_Timer
            if (Enrage_Timer <= diff)
            {
                DoCast(me, SPELL_ENRAGE);
                Enrage_Timer = 90000;
            } else Enrage_Timer -= diff;

            //Blessing of Tides Trigger
            if (!HealthAbovePct(75) && !BlessingOfTides)
            {
                BlessingOfTides = true;
                bool continueTriggering = false;
                for (uint8 i = 0; i < MAX_ADVISORS; ++i)
                {
                    if (!Advisors[i].IsEmpty())
                    {
                        Creature* advisor = ObjectAccessor::GetCreature(*me, Advisors[i]);
                        if (advisor && advisor->IsAlive())
                        {
                            continueTriggering = true;
                            break;
                        }
                    }
                }

                if (continueTriggering)
                {
                    DoCast(me, SPELL_BLESSING_OF_THE_TIDES);
                    me->Yell(SAY_GAIN_BLESSING_OF_TIDES, LANG_UNIVERSAL);
                    DoPlaySoundToSet(me, SOUND_GAIN_BLESSING_OF_TIDES);
                }
            }

            DoMeleeAttackIfReady();
        }
示例#19
0
        void UpdateAI(uint32 diff)
        {
            if (!isActive)
            {
                IntroTimer += diff;
                if (IntroTimer > 5000 && IntroTimer < 10000)
                {
                    if (SelectTargetFromPlayerList(60))
                    {
                        Talk(SAY_INTRO_1);
                        IntroTimer = 10000;
                    }
                    else
                        IntroTimer = 0;
                }

                if (IntroTimer >= 30000 && IntroTimer < 40000)
                {
                    Talk(SAY_INTRO_2);
                    IntroTimer = 40000;
                }
                if (IntroTimer >= 60000)
                {
                    isActive = true;
                    if (m_pInstance)
                        m_pInstance->SetData(TYPE_LOKEN_INTRO, 1);

                    me->SetControlled(false, UNIT_STATE_STUNNED);
                    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);

                    if (Player* target = SelectTargetFromPlayerList(80))
                        AttackStart(target);
                }

                return;
            }

            //Return since we have no target
            if (!UpdateVictim())
                return;

            events.Update(diff);

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

            switch (events.GetEvent())
            {
                case EVENT_CHECK_HEALTH:
                    if (HealthBelowPct(HealthCheck))
                    {
                        LokenSpeach(true);
                        HealthCheck -= 25;
                    }

                    events.RepeatEvent(1000);
                    break;
                case EVENT_LIGHTNING_NOVA:
                    events.RepeatEvent(15000);
                    me->CastSpell(me, SPELL_LIGHTNING_NOVA_VISUAL, true);
                    me->CastSpell(me, SPELL_LIGHTNING_NOVA_THUNDERS, true);

                    events.DelayEvents(5001);
                    events.ScheduleEvent(EVENT_AURA_REMOVE, me->GetMap()->IsHeroic() ? 4000 : 5000);

                    me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_LIGHTNING_NOVA_H : SPELL_LIGHTNING_NOVA_N, false);
                    break;
                case EVENT_SHOCKWAVE:
                    me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_PULSING_SHOCKWAVE_H : SPELL_PULSING_SHOCKWAVE_N, false);
                    events.PopEvent();
                    break;
                case EVENT_ARC_LIGHTNING:
                    if (Unit* target = SelectTargetFromPlayerList(100, SPELL_ARC_LIGHTNING))
                        me->CastSpell(target, SPELL_ARC_LIGHTNING, false);

                    events.RepeatEvent(12000);
                    break;
                case EVENT_AURA_REMOVE:
                    me->RemoveAura(SPELL_LIGHTNING_NOVA_THUNDERS);
                    events.PopEvent();
                    break;
            }

            DoMeleeAttackIfReady();
        }
        void UpdateAI(uint32 diff) override
        {
            //Only if not incombat check if the event is started
            if (!me->IsInCombat() && instance->GetData(DATA_KARATHRESSEVENT))
            {
                if (Unit* target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_KARATHRESSEVENT_STARTER)))
                    AttackStart(target);
            }

            //Return since we have no target
            if (!UpdateVictim())
                return;

            //someone evaded!
            if (!instance->GetData(DATA_KARATHRESSEVENT))
            {
                EnterEvadeMode();
                return;
            }

            //LeechingThrow_Timer
            if (LeechingThrow_Timer <= diff)
            {
                DoCastVictim(SPELL_LEECHING_THROW);
                LeechingThrow_Timer = 20000;
            } else LeechingThrow_Timer -= diff;

            //Multishot_Timer
            if (Multishot_Timer <= diff)
            {
                DoCastVictim(SPELL_MULTISHOT);
                Multishot_Timer = 20000;
            } else Multishot_Timer -= diff;

            //TheBeastWithin_Timer
            if (TheBeastWithin_Timer <= diff)
            {
                DoCast(me, SPELL_THE_BEAST_WITHIN);

                Creature* Pet = ObjectAccessor::GetCreature(*me, SummonedPet);
                if (Pet && Pet->IsAlive())
                    Pet->CastSpell(Pet, SPELL_PET_ENRAGE, true);

                TheBeastWithin_Timer = 30000;
            } else TheBeastWithin_Timer -= diff;

            //Pet_Timer
            if (Pet_Timer < diff && pet == false)
            {
                pet = true;
                //uint32 spell_id;
                uint32 pet_id;
                if (!urand(0, 1))
                {
                    //spell_id = SPELL_SUMMON_FATHOM_LURKER;
                    pet_id = CREATURE_FATHOM_LURKER;
                }
                else
                {
                    //spell_id = SPELL_SUMMON_FATHOM_SPOREBAT;
                    pet_id = CREATURE_FATHOM_SPOREBAT;
                }
                //DoCast(me, spell_id, true);
                if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                {
                    if (Creature* Pet = DoSpawnCreature(pet_id, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
                    {
                        Pet->AI()->AttackStart(target);
                        SummonedPet = Pet->GetGUID();
                    }
                }
            } else Pet_Timer -= diff;

            DoMeleeAttackIfReady();
        }
示例#21
0
void WorldBossAI::_EnterCombat()
{
    Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true);
    if (target)
        AttackStart(target);
}
        void UpdateAI(uint32 diff) override
        {
            //Only if not incombat check if the event is started
            if (!me->IsInCombat() && instance->GetData(DATA_KARATHRESSEVENT))
            {
                if (Unit* target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_KARATHRESSEVENT_STARTER)))
                    AttackStart(target);
            }

            //Return since we have no target
            if (!UpdateVictim())
                return;

            //someone evaded!
            if (!instance->GetData(DATA_KARATHRESSEVENT))
            {
                EnterEvadeMode();
                return;
            }

            if (!me->HasAura(SPELL_WINDFURY_WEAPON))
            {
                DoCast(me, SPELL_WINDFURY_WEAPON);
            }

            //FrostShock_Timer
            if (FrostShock_Timer <= diff)
            {
                DoCastVictim(SPELL_FROST_SHOCK);
                FrostShock_Timer = 25000 + rand32() % 5000;
            } else FrostShock_Timer -= diff;

            //Spitfire_Timer
            if (Spitfire_Timer <= diff)
            {
                DoCast(me, SPELL_SPITFIRE_TOTEM);
                if (Unit* SpitfireTotem = me->FindNearestCreature(CREATURE_SPITFIRE_TOTEM, 100.0f))
                    SpitfireTotem->ToCreature()->AI()->AttackStart(me->GetVictim());

                Spitfire_Timer = 60000;
            }
            else
                Spitfire_Timer -= diff;

            //PoisonCleansing_Timer
            if (PoisonCleansing_Timer <= diff)
            {
                DoCast(me, SPELL_POISON_CLEANSING_TOTEM);
                PoisonCleansing_Timer = 30000;
            }
            else
                PoisonCleansing_Timer -= diff;

            //Earthbind_Timer
            if (Earthbind_Timer <= diff)
            {
                DoCast(me, SPELL_EARTHBIND_TOTEM);
                Earthbind_Timer = 45000;
            }
            else
                Earthbind_Timer -= diff;

            DoMeleeAttackIfReady();
        }
示例#23
0
 void UpdateAI(const uint32 /*diff*/)
 {
     if (!me->getVictim())
         if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
             AttackStart(target);
 }
        void UpdateAI(uint32 diff) override
        {
            //Only if not incombat check if the event is started
            if (!me->IsInCombat() && instance->GetData(DATA_KARATHRESSEVENT))
            {
                if (Unit* target = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_KARATHRESSEVENT_STARTER)))
                    AttackStart(target);
            }

            //Return since we have no target
            if (!UpdateVictim())
                return;

            //someone evaded!
            if (!instance->GetData(DATA_KARATHRESSEVENT))
            {
                EnterEvadeMode();
                return;
            }

            //WaterBoltVolley_Timer
            if (WaterBoltVolley_Timer <= diff)
            {
                DoCastVictim(SPELL_WATER_BOLT_VOLLEY);
                WaterBoltVolley_Timer = 30000;
            } else WaterBoltVolley_Timer -= diff;

            //TidalSurge_Timer
            if (TidalSurge_Timer <= diff)
            {
                DoCastVictim(SPELL_TIDAL_SURGE);
                // Hacky way to do it - won't trigger elseways
                if (me->GetVictim())
                    me->EnsureVictim()->CastSpell(me->GetVictim(), SPELL_TIDAL_SURGE_FREEZE, true);
                TidalSurge_Timer = 15000 + rand32() % 5000;
            } else TidalSurge_Timer -= diff;

            //Cyclone_Timer
            if (Cyclone_Timer <= diff)
            {
                //DoCast(me, SPELL_SUMMON_CYCLONE); // Doesn't work
                Cyclone_Timer = 30000 + rand32() % 10000;

                if (Creature* Cyclone = me->SummonCreature(CREATURE_CYCLONE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), float(rand32() % 5), TEMPSUMMON_TIMED_DESPAWN, 15000))
                {
                    Cyclone->SetObjectScale(3.0f);
                    Cyclone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                    Cyclone->setFaction(me->getFaction());
                    Cyclone->CastSpell(Cyclone, SPELL_CYCLONE_CYCLONE, true);
                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                        Cyclone->AI()->AttackStart(target);
                }
            }
            else
                Cyclone_Timer -= diff;

            //Heal_Timer
            if (Heal_Timer <= diff)
            {
                // It can be cast on any of the mobs
                Unit* unit = NULL;

                while (unit == NULL || !unit->IsAlive())
                    unit = selectAdvisorUnit();

                if (unit && unit->IsAlive())
                    DoCast(unit, SPELL_HEAL);
                Heal_Timer = 60000;
            }
            else
                Heal_Timer -= diff;

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

        switch (m_uiPhase)
        {
            case PHASE_FAKE_DEATH:
                if (m_uiResurrectTimer < uiDiff)
                {
                    // resurrect him in any case
                    DoCastSpellIfCan(m_creature, SPELL_RESURRECT);

                    m_uiPhase = PHASE_WAITING;
                    if (m_pInstance)
                    {
                        CanPreventAddsResurrect();
                        m_pInstance->SetData(TYPE_THEKAL, IN_PROGRESS);
                    }
                }
                else
                    m_uiResurrectTimer -= uiDiff;

            // No break needed here
            case PHASE_WAITING:
                return;

            case PHASE_NORMAL:
                if (m_uiMortalCleaveTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_MORTAL_CLEAVE) == CAST_OK)
                        m_uiMortalCleaveTimer = urand(15000, 20000);
                }
                else
                    m_uiMortalCleaveTimer -= uiDiff;

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

                break;
            case PHASE_TIGER:
                if (m_uiChargeTimer < uiDiff)
                {
                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                    {
                        if (DoCastSpellIfCan(pTarget, SPELL_CHARGE) == CAST_OK)
                        {
                            DoResetThreat();
                            AttackStart(pTarget);
                            m_uiChargeTimer = urand(15000, 22000);
                        }
                    }
                }
                else
                    m_uiChargeTimer -= uiDiff;

                if (m_uiFrenzyTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_FRENZY) == CAST_OK)
                        m_uiFrenzyTimer = 30000;
                }
                else
                    m_uiFrenzyTimer -= uiDiff;

                if (m_uiForcePunchTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_FORCE_PUNCH) == CAST_OK)
                        m_uiForcePunchTimer = urand(16000, 21000);
                }
                else
                    m_uiForcePunchTimer -= uiDiff;

                if (m_uiSummonTigersTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_TIGERS) == CAST_OK)
                        m_uiSummonTigersTimer = 50000;
                }
                else
                    m_uiSummonTigersTimer -= uiDiff;

                if (!m_bEnraged && m_creature->GetHealthPercent() < 11.0f)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_ENRAGE) == CAST_OK)
                        m_bEnraged = true;
                }

                break;
        }

        DoMeleeAttackIfReady();
    }
示例#26
0
        void UpdateAI(const uint32 diff)
        {
            //Only if not incombat check if the event is started
            if (!me->isInCombat() && instance && instance->GetData(DATA_MAULGAREVENT))
            {
                Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_MAULGAREVENT_TANK));

                if (target)
                {
                    AttackStart(target);
                    GetCouncil();
                }
            }

            //Return since we have no target
            if (!UpdateVictim())
                return;

            //someone evaded!
            if (instance && !instance->GetData(DATA_MAULGAREVENT))
            {
                EnterEvadeMode();
                return;
            }

            //ArcingSmash_Timer
            if (ArcingSmash_Timer <= diff)
            {
                DoCast(me->getVictim(), SPELL_ARCING_SMASH);
                ArcingSmash_Timer = 10000;
            } else ArcingSmash_Timer -= diff;

            //Whirlwind_Timer
                   if (Whirlwind_Timer <= diff)
                   {
                        DoCast(me->getVictim(), SPELL_WHIRLWIND);
                        Whirlwind_Timer = 55000;
                   } else Whirlwind_Timer -= diff;

            //MightyBlow_Timer
            if (MightyBlow_Timer <= diff)
            {
                DoCast(me->getVictim(), SPELL_MIGHTY_BLOW);
                MightyBlow_Timer = 30000+rand()%10000;
            } else MightyBlow_Timer -= diff;

            //Entering Phase 2
            if (!Phase2 && HealthBelowPct(50))
            {
                Phase2 = true;
                Talk(SAY_ENRAGE);

                DoCast(me, SPELL_DUAL_WIELD, true);
                me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
                me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
            }

            if (Phase2)
            {
                //Charging_Timer
                if (Charging_Timer <= diff)
                {
                    Unit* target = NULL;
                    target = SelectTarget(SELECT_TARGET_RANDOM, 0);
                    if (target)
                    {
                        AttackStart(target);
                        DoCast(target, SPELL_BERSERKER_C);
                    }
                    Charging_Timer = 20000;
                } else Charging_Timer -= diff;

                //Intimidating Roar
                if (Roar_Timer <= diff)
                {
                    DoCast(me, SPELL_ROAR);
                    Roar_Timer = 40000+(rand()%10000);
                } else Roar_Timer -= diff;
            }

            DoMeleeAttackIfReady();
        }
示例#27
0
            void UpdateAI(const uint32 diff)
            {
                if (!UpdateVictim())
                    return;

                if (me->getVictim() && me->isAlive())
                {
                    if (PoisonVolley_Timer <= diff)
                    {
                        DoCast(me->getVictim(), SPELL_POISONVOLLEY);
                        PoisonVolley_Timer = urand(10000, 20000);
                    } else PoisonVolley_Timer -= diff;

                    if (!PhaseTwo && Aspect_Timer <= diff)
                    {
                        DoCast(me->getVictim(), SPELL_ASPECT_OF_MARLI);
                        Aspect_Timer = urand(13000, 18000);
                    } else Aspect_Timer -= diff;

                    if (!Spawned && SpawnStartSpiders_Timer <= diff)
                    {
                        Talk(SAY_SPIDER_SPAWN);

                        Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0);
                        if (!target)
                            return;

                        Creature* Spider = NULL;

                        Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (Spider)
                            Spider->AI()->AttackStart(target);
                        Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (Spider)
                            Spider->AI()->AttackStart(target);
                        Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (Spider)
                            Spider->AI()->AttackStart(target);
                        Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (Spider)
                            Spider->AI()->AttackStart(target);

                        Spawned = true;
                    } else SpawnStartSpiders_Timer -= diff;

                    if (SpawnSpider_Timer <= diff)
                    {
                        Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0);
                        if (!target)
                            return;

                        Creature* Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (Spider)
                            Spider->AI()->AttackStart(target);
                        SpawnSpider_Timer = urand(12000, 17000);
                    } else SpawnSpider_Timer -= diff;

                    if (!PhaseTwo && Transform_Timer <= diff)
                    {
                        Talk(SAY_TRANSFORM);
                        DoCast(me, SPELL_SPIDER_FORM);
                        const CreatureTemplate* cinfo = me->GetCreatureTemplate();
                        me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 35)));
                        me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 35)));
                        me->UpdateDamagePhysical(BASE_ATTACK);
                        DoCast(me->getVictim(), SPELL_ENVOLWINGWEB);

                        if (DoGetThreat(me->getVictim()))
                            DoModifyThreatPercent(me->getVictim(), -100);

                        PhaseTwo = true;
                        Transform_Timer = urand(35000, 60000);
                    } else Transform_Timer -= diff;

                    if (PhaseTwo)
                    {
                        if (Charge_Timer <= diff)
                        {
                            Unit* target = NULL;
                            int i = 0;
                            while (i < 3)                           // max 3 tries to get a random target with power_mana
                            {
                                ++i;
                                target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true);  // not aggro leader
                                if (target && target->getPowerType() == POWER_MANA)
                                        i = 3;
                            }
                            if (target)
                            {
                                DoCast(target, SPELL_CHARGE);
                                //me->SetPosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0);
                                //me->SendMonsterMove(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, true, 1);
                                AttackStart(target);
                            }

                            Charge_Timer = 8000;
                        } else Charge_Timer -= diff;

                        if (TransformBack_Timer <= diff)
                        {
                            me->SetDisplayId(15220);
                            const CreatureTemplate* cinfo = me->GetCreatureTemplate();
                            me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 1)));
                            me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 1)));
                            me->UpdateDamagePhysical(BASE_ATTACK);

                            PhaseTwo = false;
                            TransformBack_Timer = urand(25000, 40000);
                        } else TransformBack_Timer -= diff;

                    }

                    DoMeleeAttackIfReady();
                }
            }
示例#28
0
        void UpdateAI(const uint32 diff)
        {
            //Only if not incombat check if the event is started
            if (!me->isInCombat() && instance && instance->GetData(DATA_MAULGAREVENT))
            {
                Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_MAULGAREVENT_TANK));

                if (target)
                {
                    AttackStart(target);
                }
            }

            //Return since we have no target
            if (!UpdateVictim())
                return;

            //someone evaded!
            if (instance && !instance->GetData(DATA_MAULGAREVENT))
            {
                EnterEvadeMode();
                return;
            }

            //GreaterFireball_Timer
            if (GreaterFireball_Timer < diff || me->IsWithinDist(me->getVictim(), 30))
            {
                DoCast(me->getVictim(), SPELL_GREATER_FIREBALL);
                GreaterFireball_Timer = 2000;
            } else GreaterFireball_Timer -= diff;

            //SpellShield_Timer
            if (SpellShield_Timer <= diff)
            {
                me->InterruptNonMeleeSpells(false);
                DoCast(me->getVictim(), SPELL_SPELLSHIELD);
                SpellShield_Timer = 30000;
            } else SpellShield_Timer -= diff;

            //BlastWave_Timer
            if (BlastWave_Timer <= diff)
            {
                Unit* target = NULL;
                std::list<HostileReference*> t_list = me->getThreatManager().getThreatList();
                std::vector<Unit*> target_list;
                for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
                {
                    target = Unit::GetUnit(*me, (*itr)->getUnitGuid());
                                                                //15 yard radius minimum
                    if (target && target->IsWithinDist(me, 15, false))
                        target_list.push_back(target);
                    target = NULL;
                }
                if (!target_list.empty())
                    target = *(target_list.begin()+rand()%target_list.size());

                me->InterruptNonMeleeSpells(false);
                DoCast(target, SPELL_BLAST_WAVE);
                BlastWave_Timer = 60000;
            } else BlastWave_Timer -= diff;
        }
示例#29
0
    void UpdateAI(const uint32 diff)
    {
        if (!UpdateVictim())
            return;

        //Invisible_Timer
        if (Invisible_Timer <= diff)
        {
            me->InterruptSpell(CURRENT_GENERIC_SPELL);

            SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
            me->SetDisplayId(11686);

            me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
            Invisible = true;

            Invisible_Timer = 15000 + rand()%15000;
        } else Invisible_Timer -= diff;

        if (Invisible)
        {
            if (Ambush_Timer <= diff)
            {
                Unit *pTarget = NULL;
                pTarget = SelectUnit(SELECT_TARGET_RANDOM,0);
                if (pTarget)
                {
                    DoTeleportTo(pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ());
                    DoCast(pTarget, SPELL_AMBUSH);
                }

                Ambushed = true;
                Ambush_Timer = 3000;
            } else Ambush_Timer -= diff;
        }

        if (Ambushed)
        {
            if (Visible_Timer <= diff)
            {
                me->InterruptSpell(CURRENT_GENERIC_SPELL);

                me->SetDisplayId(15268);
                SetEquipmentSlots(false, EQUIP_ID_MAIN_HAND, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);

                me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                Invisible = false;

                Visible_Timer = 4000;
            } else Visible_Timer -= diff;
        }

        //Resetting some aggro so he attacks other gamers
        if (!Invisible)
            if (Aggro_Timer <= diff)
            {
                Unit *pTarget = NULL;
                pTarget = SelectUnit(SELECT_TARGET_RANDOM,1);

                if (DoGetThreat(me->getVictim()))
                    DoModifyThreatPercent(me->getVictim(),-50);

                if (pTarget)
                    AttackStart(pTarget);

                Aggro_Timer = 7000 + rand()%13000;
            } else Aggro_Timer -= diff;

        if (!Invisible)
            if (ThousandBlades_Timer <= diff)
            {
                DoCast(me->getVictim(), SPELL_THOUSANDBLADES);
                ThousandBlades_Timer = 7000 + rand()%5000;
            } else ThousandBlades_Timer -= diff;

        DoMeleeAttackIfReady();
    }
示例#30
0
void PetAI::UpdateAI(const uint32 diff)
{
    m_owner = me->GetCharmerOrOwner();

    // quest support - Razorthorn Ravager, switch to CreatureAI when charmed and not in combat
    if (me->GetEntry() == 24922 && me->isCharmed() && !me->isInCombat())
        me->NeedChangeAI = true;

    updateAlliesTimer.Update(diff);
    if (updateAlliesTimer.Passed())
        UpdateAllies();

    if (m_forceTimer)
    {
        if (m_forceTimer < diff)
            m_forceTimer = 0;
        else
            m_forceTimer -= diff;
    }

    if (me->getVictim())
    {
        if (_needToStop())
        {
            _stopAttack();
            return;
        }

        DoMeleeAttackIfReady();
    }
    else
    {
        if (me->isInCombat())
        {
            if (!me->GetOwner() || !me->GetOwner()->GetObjectGuid().IsPlayer())
                _stopAttack();
        }
        else if (Unit* owner = me->GetOwner())
        {
            if (!me->HasReactState(REACT_PASSIVE) && !me->GetCharmInfo()->HasCommandState(COMMAND_STAY))
            {
                Unit* target = NULL;
                if (owner->isInCombat())
                    target = owner->getAttackerForHelper();
                else
                    target = me->getAttackerForHelper();

                if (target)
                    AttackStart(target);
            }

            // we still do NOT have target, if follow command were appliend and we are NOT followin, reapply movegen :P
            if (!me->getVictim() && me->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW) && !me->hasUnitState(UNIT_STAT_FOLLOW))
                me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
        }
    }

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

    if (!me->hasUnitState(UNIT_STAT_CASTING))
    {
        //Autocast
        for (uint8 i = 0; i < me->GetPetAutoSpellSize(); i++)
            PrepareSpellForAutocast(me->GetPetAutoSpellOnPos(i));

        AutocastPreparedSpells();
    }
}