void CheckSpellSteal(uint32 diff)
 {
     if (!SPELLSTEAL || GC_Timer > diff || Rand() > 25 || IsCasting()) return;
     Unit* target = FindHostileDispelTarget(40, true);
     if (target && doCast(target, SPELLSTEAL))
         GC_Timer = 800;
 }
Example #2
0
 void CheckBlink(uint32 diff)
 {
     if (GetBotCommandState() == COMMAND_STAY || me->IsMounted()) return;
     if (Blink_cd > diff || me->getLevel() < 20 || IsCasting()) return;
     if (me->GetExactDist(master) > std::max(float(master->GetBotFollowDist()), 25.f)/* && me->IsWithinLOSInMap(master)*/)
     {
         me->SetFacingTo(me->GetAngle(master));
         if (doCast(me, BLINK))
         {
             Blink_cd = 15000 - me->getLevel()/4 * 100; //13 sec with improved
             GC_Timer = 500;
         }
         return;
     }
     if (!me->getAttackers().empty() && me->GetExactDist(master) > 15)
     {
         if (Unit* op = me->SelectNearestTarget(10))
         {
             if (op->GetVictim() == me)
             {
                 me->SetFacingTo(me->GetAngle(master));
                 if (doCast(me, BLINK))
                 {
                     Blink_cd = 15000 - me->getLevel()/4 * 100; //13 sec with improved
                     GC_Timer = 500;
                 }
             }
         }
     }
 }
Example #3
0
        void DoNormalAttack(uint32 diff)
        {
            opponent = me->GetVictim();
            if (opponent)
            {
                if (!IsCasting())
                    StartAttack(opponent, true);
            }
            else
                return;
            if (MoveBehind(*opponent))
                wait = 5;

            //float dist = me->GetExactDist(opponent);
            float meleedist = me->GetDistance(opponent);

            //TORMENT
            if (TORMENT && Torment_cd <= diff && meleedist < 5 && (!tank || tank == me || opponent->GetVictim() == m_creatureOwner))
            {
                temptimer = GC_Timer;
                if (doCast(opponent, TORMENT))
                {
                    Torment_cd = 5000;
                    GC_Timer = temptimer;
                    return;
                }
            }
        }
Example #4
0
	void AIUpdate()
	{
		if (!IsCasting())
		{
			if (mBlastWaveTimer == -1 || IsTimerFinished(mBlastWaveTimer))
			{
				Unit* unit = GetBestUnitTarget(TargetFilter_Closest);
				if (unit && GetRangeToUnit(unit) < 15.0f)
				{
					CastSpellNowNoScheduling(mBlastWave);
					if (mBlastWaveTimer == -1)
						mBlastWaveTimer = AddTimer(6000);
					else
						ResetTimer(mBlastWaveTimer, 6000);
					ParentClass::AIUpdate();
					return;
				}
			}

			if (IsTimerFinished(mEventTimer))
			{
				ResetTimer(mEventTimer, 30000);
				CastSpellNowNoScheduling(mSpellShield);
			}
		}

		ParentClass::AIUpdate();
	}
        void DoNormalAttack(uint32 diff)
        {
            opponent = me->GetVictim();
            if (opponent)
            {
                if (!IsCasting())
                    StartAttack(opponent, true);
            }
            else
                return;
            if (MoveBehind(*opponent))
                wait = 5;

            //float dist = me->GetExactDist(opponent);
            float meleedist = me->GetDistance(opponent);

            //TORMENT
            if (IsSpellReady(TORMENT_1, diff, false) && meleedist < 5 && !IsTank(opponent->GetVictim()))
            {
                temptimer = GC_Timer;
                if (doCast(opponent, GetSpell(TORMENT_1)))
                {
                    GC_Timer = temptimer;
                    return;
                }
            }
        }
        void CheckPots(uint32 diff)
        {
            if (me->IsMounted() || IsCasting()) return;

            if (GetHealthPCT(me) < 67 && Potion_cd <= diff)
            {
                temptimer = GC_Timer;
                if (doCast(me, HEALINGPOTION))
                {
                    Potion_cd = POTION_CD;
                    GC_Timer = temptimer;
                }
            }
            if (GetManaPCT(me) < 35 && Rand() < 35)
            {
                if (EVOCATION && Evocation_cd <= diff && !me->isMoving() &&
                    me->getAttackers().empty() && doCast(me, EVOCATION))
                    Evocation_cd = 60000;
                else if (Potion_cd <= diff)
                {
                    temptimer = GC_Timer;
                    if (doCast(me, MANAPOTION))
                    {
                        Potion_cd = POTION_CD;
                        GC_Timer = temptimer;
                    }
                }
            }
        }
 void CheckBlink(uint32 diff)
 {
     if (GetBotCommandState() == COMMAND_STAY || me->IsMounted()) return;
     if (!BLINK || Blink_cd > diff || me->getLevel() < 20 || IsCasting()) return;
     if (!me->IsInCombat() && me->GetExactDist(master) > std::max(float(master->GetBotFollowDist()), 35.f) &&
         me->HasInArc(M_PI*0.75f, master))
     {
         temptimer = GC_Timer;
         if (doCast(me, BLINK))
         {
             Blink_cd = 13000;
             GC_Timer = temptimer;
         }
         return;
     }
     if (!me->getAttackers().empty() && me->GetExactDist(master) > 15)
     {
         if (Unit* op = me->SelectNearestTarget(7))
         {
             if (op->GetVictim() == me)
             {
                 me->SetFacingTo(me->GetAngle(master));
                 temptimer = GC_Timer;
                 if (doCast(me, BLINK))
                 {
                     Blink_cd = 13000;
                     GC_Timer = temptimer;
                 }
             }
         }
     }
 }
Example #8
0
	void AIUpdate()
	{
		if (!IsCasting())
		{
			if (IsTimerFinished(mGrowthTimer))
			{
				if (mGrowthStacks == 30)
				{
					RemoveAura(GRUUL_THE_DRAGONKILLER_GROWTH);
					mGrowthStacks = 0;
				}
				if (mGrowthStacks != 29)
				{
					ResetTimer(mGrowthTimer, 30000);
				}
				else if (mGrowthStacks == 29)
				{
					ResetTimer(mGrowthTimer, 300000);
				}

				ApplyAura(GRUUL_THE_DRAGONKILLER_GROWTH);
				++mGrowthStacks;
			}
			else if (IsTimerFinished(mHurtfulTimer))
			{
				Unit* pCurrentTarget = _unit->GetAIInterface()->GetNextTarget();
				if (pCurrentTarget != NULL)
				{
					Unit* pTarget = pCurrentTarget;
					for (unordered_set<Player*>::iterator itr = _unit->GetInRangePlayerSetBegin(); itr != _unit->GetInRangePlayerSetEnd(); itr++) 
					{
						Player* pPlayer = TO_PLAYER(*itr);
						if (!pPlayer->isAlive())
							continue;
//						if (pPlayer->m_auracount[SPELL_AURA_MOD_INVISIBILITY])
//							continue;
						if (pPlayer->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FEIGN_DEATH))
							continue;
						if (GetRangeToUnit(pPlayer) > 8.0f)
							continue;
						if (_unit->GetAIInterface()->getThreatByPtr(pPlayer) >= _unit->GetAIInterface()->getThreatByPtr(pCurrentTarget))
							continue;

						pTarget = TO_UNIT(pPlayer);
					}
					
					if (pTarget == pCurrentTarget)
						CastSpellNowNoScheduling(mHurtfulStrike);
					else
						_unit->CastSpell(pTarget, GRUUL_THE_DRAGONKILLER_HURTFUL_STRIKE, true);
				}

				ResetTimer(mHurtfulTimer, 8000);
			}
		}

		ParentClass::AIUpdate();
	}
	/*
		During the AIUpdate() Selin will spam FelExplosion until hes out of mana
		He will then attempt to gain mana from a FelCrystal thats in the room by running to them
	*/
	void AIUpdate()
	{
		// 10% of his mana according to wowhead is 3231 which is whats needed to cast FelExplosion
		if(GetManaPercent() < 10 || FelExplosion->mEnabled == false)
			Mana();
		else if(!IsCasting())// Mana is greater than 10%
			CastFelExplosion();

		ParentClass::AIUpdate();
	}
Example #10
0
bool MoonScriptCreatureAI::CastSpellInternal(SpellDesc* pSpell, uint32 pCurrentTime)
{
	if( pSpell == NULL) return false;
	//Do not cast if we are already casting
	if( IsCasting() ) return false;

	//We do not cast in special states such as : stunned, feared, silenced, charmed, asleep, confused and if they are not ignored
	if ( ( ~pSpell->mTargetType.mTargetFilter & TargetFilter_IgnoreSpecialStates ) && _unit->m_special_state & ( UNIT_STATE_STUN | UNIT_STATE_FEAR | UNIT_STATE_SLEEP | UNIT_STATE_SILENCE | UNIT_STATE_CHARM | UNIT_STATE_CONFUSE ) )
		return false;

	//Do not cast if we are in cooldown
	uint32 CurrentTime = ( pCurrentTime == 0 ) ? (uint32)time(NULL) : pCurrentTime;
	if( pSpell->mLastCastTime + pSpell->mCooldown > CurrentTime ) return false;

	//Check range before casting
	Unit *Target = GetTargetForSpell( pSpell );
	if( Target )
	{
		RangeStatusPair Status;
		if( pSpell->mTargetType.mTargetFilter & TargetFilter_InRangeOnly || ( Status = GetSpellRangeStatusToUnit( Target, pSpell ) ).first == RangeStatus_Ok )
		{
			//Safe-delay if we got special state flag before
			DelayNextAttack( CalcSpellAttackTime( pSpell ) );

			//If we were running to a target, stop because we're in range now
			PopRunToTargetCache();

			//Do emote associated with this spell
			RandomEmote(pSpell->mEmotes);

			//Cast spell now
			if( pSpell->mInfo ) CastSpellOnTarget(Target, pSpell->mTargetType, pSpell->mInfo, ( pSpell->mCastTime == 0 ) ? true : false);
			else if( pSpell->mSpellFunc ) pSpell->mSpellFunc(pSpell, this, Target, pSpell->mTargetType);
			else sLog.outDebug("MoonScriptCreatureAI::CastSpellInternal() : Invalid spell!\n");

			//Store cast time for cooldown
			pSpell->mLastCastTime = CurrentTime;
			return true;
		}
		else if( !pSpell->mStrictRange ) //Target is out of range, run to it
		{
			PushRunToTargetCache( Target, pSpell, Status );
			return false;
		}
	}

	//If we get here, its because the RunToTarget changed type, so its no longer valid, clear it
	PopRunToTargetCache();
	DelayNextAttack(0);		//Cancel attack delay
	return true;			//No targets possible? Consider spell casted nonetheless
}
Example #11
0
bool CMagicState::TryHitInterrupt(CBattleEntity* PAttacker)
{

    if (!IsCasting() || IsInterrupted() || m_PSpell->getSpellGroup() == SPELLGROUP_SONG)
    {
    	return false;
    }

    if(battleutils::TryInterruptSpell(PAttacker, m_PEntity))
    {
        ForceInterrupt();
        return true;
    }

    return false;
}
		void AIUpdate()
		{
			if(!IsCasting())
			{
				if(mBurningNovaTimer == INVALIDATE_TIMER || IsTimerFinished(mBurningNovaTimer))
				{
					if(IsHeroic())
						CastSpell(mVortex);
					CastSpell(mBurningNova);

					ResetTimer(mBurningNovaTimer, 30000);

					ParentClass::AIUpdate();
				};
			};

			ParentClass::AIUpdate();
		}
Example #13
0
 void AIUpdate()
 {
     ParentClass::AIUpdate();
     if (IsTimerFinished(mElizaCombatTimer))
     {
         SetCanEnterCombat(true);
         AggroNearestUnit();
         RemoveTimer(mElizaCombatTimer);
     }
     if ( GetHealthPercent()>=10 && GetHealthPercent()<=98 && !IsCasting())
     {
         // Correct me if I'm wrong but I saw only 1 guard spawning
         mElizaGuard = _unit->GetMapMgr()->GetInterface()->GetCreatureNearestCoords(_unit->GetPositionX(), _unit->GetPositionY(), _unit->GetPositionZ(), 1871);
         if ( mElizaGuard == NULL )
         {
             CastSpellNowNoScheduling(mSummonGuard);
         }
     }
 }
Example #14
0
bool ArcScriptCreatureAI::CastSpellInternal(SpellDesc* pSpell, uint32 pCurrentTime)
{
	//Do not cast if we are already casting
	if( IsCasting() ) return false;

	//Do not cast if we are in cooldown
	uint32 CurrentTime = ( pCurrentTime == 0 ) ? (uint32)time(NULL) : pCurrentTime;
	if( pSpell->mLastCastTime + pSpell->mCooldown > CurrentTime ) return false;

	//Check range before casting
	Unit* Target = GetTargetForSpell(pSpell);
	if( Target )
	{
		if( IsUnitInRange(Target, pSpell) )
		{
			//If we were running to a target, stop because we're in range now
			PopRunToTargetCache();

			//Do emote associated with this spell
			RandomEmote(pSpell->mEmotes);

			//Cast spell now
			if( pSpell->mInfo ) CastSpellOnTarget(Target, pSpell->mTargetType, pSpell->mInfo, ( pSpell->mCastTime == 0 ) ? true : false);
			else if( pSpell->mSpellFunc ) pSpell->mSpellFunc(pSpell, this, Target, pSpell->mTargetType);
			else sLog.outDebug("ArcScriptCreatureAI::CastSpellInternal() : Invalid spell!\n");

			//Store cast time for cooldown
			pSpell->mLastCastTime = CurrentTime;
			return true;
		}
		else if( !pSpell->mStrictRange ) //Target is out of range, run to it
		{
			PushRunToTargetCache(Target, pSpell);
			return false;
		}
	}

	//If we get here, its because the RunToTarget changed type, so its no longer valid, clear it
	PopRunToTargetCache();
	DelayNextAttack(0);		//Cancel attack delay
	return true;			//No targets possible? Consider spell casted nonetheless
}
Example #15
0
        void DoNormalAttack(uint32 diff)
        {
            opponent = me->GetVictim();
            if (opponent)
            {
                if (!IsCasting())
                    StartAttack(opponent);
            }
            else
                return;
            AttackerSet m_attackers = master->getAttackers();
            AttackerSet b_attackers = me->getAttackers();

            Unit* u = me->SelectNearestTarget(20);
            //ICE_BARRIER
            if (ICE_BARRIER && Ice_Barrier_cd <= diff && u && u->GetVictim() == me && 
                u->GetDistance(me) < 8 && !me->HasAura(ICE_BARRIER))
            {
                if (me->IsNonMeleeSpellCasted(true))
                    me->InterruptNonMeleeSpells(true);
                if (doCast(me, ICE_BARRIER))
                {
                    Ice_Barrier_cd = 41000 - me->getLevel()*200;//down to 25 sec on 80
                    GC_Timer = 800;
                    return;
                }
            }
            if ((!ICE_BARRIER || Ice_Barrier_cd > diff) && 
                BLINK && Blink_cd < 3000 && u && u->GetVictim() == me && 
                !me->HasAura(ICE_BARRIER) && u->GetDistance(me) < 6)
            {
                if (me->IsNonMeleeSpellCasted(true))
                    me->InterruptNonMeleeSpells(true);
                if (doCast(me, BLINK))
                {
                    Blink_cd = 15000 - me->getLevel()/4 * 100;
                    GC_Timer = 800;
                    return;
                }
            }

            if (me->HasAura(ICEBLOCK))
                if (((GetManaPCT(me) > 45 && GetHealthPCT(me) > 80) || b_attackers.empty()) && Iceblock_cd <= 57000 && tank)
                    me->RemoveAurasDueToSpell(ICEBLOCK);
            //ICEBLOCK
            if (ICEBLOCK && Rand() < 50 && !b_attackers.empty() && tank && Iceblock_cd <= diff && 
                (GetManaPCT(me) < 15 || GetHealthPCT(me) < 45 || b_attackers.size() > 4) && 
                !me->HasAura(ICEBLOCK))
            {
                if (me->IsNonMeleeSpellCasted(true))
                    me->InterruptNonMeleeSpells(true);
                if (doCast(me, ICEBLOCK))
                {
                    Iceblock_cd = 60000;
                    return;
                }
            }

            if (IsCasting()) return;

            BOLT = (CCed(opponent, true) || (opponent->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED) && me->HasAura(COMBUSTION))) ? FIREBALL : FROSTBOLT;
            NOVA = BOLT == FIREBALL && BLASTWAVE ? BLASTWAVE : FROSTNOVA ? FROSTNOVA : 0;

            float dist = me->GetExactDist(opponent);
            if (dist > 30)
                return;

            if (COMBUSTION && Rand() < 15 && 
                (opponent->GetMaxHealth() > master->GetMaxHealth()*10 || 
                m_attackers.size() > 1 || b_attackers.size() > 2))
            {
                if (!HasAuraName(me, "Combustion") && Combustion_cd <= diff)
                {
                    temptimer = GC_Timer;
                    if (doCast(me, COMBUSTION))
                    {
                        Combustion_cd = 60000;
                        //Reset timers for fun
                        Nova_cd = 0; FireBlast_cd = 0; DragonBreath_cd = 0;
                    }
                    GC_Timer = temptimer;
                }
            }
            //DAMAGE
            //PYROBLAST
            if (PYROBLAST && Rand() < 75 && Pyroblast_cd <= diff && GC_Timer <= diff && 
                b_attackers.size() < 2 && dist < 30 && opponent->IsPolymorphed() && 
                doCast(opponent, PYROBLAST))
                Pyroblast_cd = 50;
            //nova //TODO: SEPARATE
            u = me->SelectNearestTarget(7);
            if (u && NOVA && Nova_cd <= diff && !CCed(u, true) && IsInBotParty(u->GetVictim()))
            {
                Unit* tar = u->GetVictim();
                if (tar && IsInBotParty(tar) && doCast(me, NOVA))
                {
                    Nova_cd = 15000;
                    return;
                }
            }
            //living bomb
            if (LIVINGBOMB && Rand() < 25 && Living_Bomb_cd <= diff && GC_Timer <= diff && 
                dist < 30 && opponent->GetHealth() > me->GetHealth()/2 && 
                !opponent->HasAura(LIVINGBOMB, me->GetGUID()) && 
                doCast(opponent, LIVINGBOMB))
            {
                Living_Bomb_cd = 6000;
                GC_Timer = 500;
                return;
            }
            //cone of cold
            if (CONEOFCOLD && ConeofCold_cd <= diff && GC_Timer <= diff && dist < 7 && 
                me->HasInArc(M_PI, opponent) && 
                doCast(opponent, CONEOFCOLD))
            {
                ConeofCold_cd = 14000;
                GC_Timer = 500;
                return;
            }
            //dragon's breath
            u = me->SelectNearestTarget(7);
            if (DRAGONBREATH && u && DragonBreath_cd <= diff && GC_Timer <= diff && 
                me->HasInArc(M_PI, opponent) && !HasAuraName(u, FROSTNOVA) && 
                doCast(opponent, DRAGONBREATH))
            {
                DragonBreath_cd = 25000;
                GC_Timer = 800;
                return;
            }
            /*//blast wave //TODO Separate again
            u = me->SelectNearestTarget(8);
            if (BLASTWAVE != 0 && u && isTimerReady(BlastWave_cd) && 
                !HasAuraName(u, FROSTNOVA) && !HasAuraName(u, DRAGONBREATH) && 
                doCast(me, BLASTWAVE))
            {
                BlastWave_cd = BLASTWAVE_CD;
                GC_Timer = 800;
            }*/
            //fire blast
            if (FireBlast_cd <= diff && GC_Timer <= diff && dist < 20 && 
                Rand() < 20 + 80*(!opponent->HasAuraType(SPELL_AURA_MOD_STUN) && me->HasAura(IMPACT_BUFF)) && 
                doCast(opponent, FIREBLAST))
            {
                FireBlast_cd = 6000;
                GC_Timer = 500;
                return;
            }
            //flamestrike
            if (GC_Timer <= diff && Rand() < 60 && me->HasAura(FIRESTARTERBUFF))
            {
                Unit* FStarget = FindAOETarget(30, true, false);
                if (FStarget && doCast(FStarget, FLAMESTRIKE, true))
                {
                    me->RemoveAurasDueToSpell(FIRESTARTERBUFF);
                    GC_Timer = 0;
                    return;
                }
            }
            //blizzard
            if (BLIZZARD && Rand() < 80 && Blizzard_cd <= diff)
            {
                Unit* blizztarget = FindAOETarget(30, true);
                if (blizztarget && doCast(blizztarget, BLIZZARD))
                {
                    Blizzard_cd = 5000;
                    return;
                }
                Blizzard_cd = 2000;//fail
            }
            //Frost of Fire Bolt
            if (Rand() < 75 && Bolt_cd <= diff && dist < 30 && 
                doCast(opponent, BOLT))
            {
                Bolt_cd = uint32(float(sSpellMgr->GetSpellInfo(BOLT)->CalcCastTime()/100) * me->GetFloatValue(UNIT_MOD_CAST_SPEED) + 200);
                return;
            }
            //Arcane Missiles
            if (Rand() < 10 && GC_Timer <= diff && !me->isMoving() && dist < 20 && 
                doCast(opponent, ARCANEMISSILES))
                return;
        }
Example #16
0
void ArcScriptCreatureAI::AIUpdate()
{
	SpellDesc*	Spell;
	uint32		CurrentTime = (uint32)time(NULL);

	//Elapse timers
	for( TimerArray::iterator TimerIter = mTimers.begin(); TimerIter != mTimers.end(); ++TimerIter )
	{
		TimerIter->second -= mAIUpdateFrequency;
	}

	//Check if we have a spell scheduled to be cast
	for( SpellDescList::iterator SpellIter = mScheduledSpells.begin(); SpellIter != mScheduledSpells.end(); ++SpellIter )
	{
		Spell = (*SpellIter);
		if( CastSpellInternal(Spell, CurrentTime) )	//Can fail if we are already casting a spell, or if the spell is on cooldown
		{
			mScheduledSpells.erase(SpellIter);
			break;
		}
	}

	//Do not schedule spell if we are *currently* casting a non-instant cast spell
	if( !IsCasting() && !mRunToTargetCache )
	{
		//Check if have queued spells that needs to be scheduled before we go back to random casting
		for( SpellDescList::iterator SpellIter = mQueuedSpells.begin(); SpellIter != mQueuedSpells.end(); ++SpellIter )
		{
			Spell = (*SpellIter);
			mScheduledSpells.push_back(Spell);
			mQueuedSpells.erase(SpellIter);

			//Stop melee attack for a short while for scheduled spell cast
			if( Spell->mCastTime >= 0 )
			{
				DelayNextAttack(mAIUpdateFrequency + CalcSpellAttackTime(Spell));
				if( Spell->mCastTime > 0 )
				{
					SetCanMove(false);
					SetBehavior(Behavior_Spell);
				}
			}
			return;	//Scheduling one spell at a time, exit now
		}

		//Try our chance at casting a spell (Will actually be cast on next ai update, so we just
		//schedule it. This is needed to avoid next dealt melee damage while we cast the spell.)
		float ChanceRoll = RandomFloat(100), ChanceTotal = 0;
		for( SpellDescArray::iterator SpellIter = mSpells.begin(); SpellIter != mSpells.end(); ++SpellIter )
		{
			Spell = (*SpellIter);
			if( Spell->mEnabled == false ) continue;
			if( Spell->mChance == 0 ) continue;

			//Check if spell won the roll
			if( (Spell->mChance == 100 || (ChanceRoll >= ChanceTotal && ChanceRoll < ChanceTotal + Spell->mChance)) &&
				(Spell->mLastCastTime + Spell->mCooldown <= CurrentTime) &&
				!IsSpellScheduled(Spell) )
			{
				mScheduledSpells.push_back(Spell);

				//Stop melee attack for a short while for scheduled spell cast
				if( Spell->mCastTime >= 0 )
				{
					DelayNextAttack(mAIUpdateFrequency + CalcSpellAttackTime(Spell));
					if( Spell->mCastTime > 0 )
					{
						SetCanMove(false);
						SetBehavior(Behavior_Spell);
					}
				}
				return;	//Scheduling one spell at a time, exit now
			}
			else if( Spell->mChance != 100 ) ChanceTotal += Spell->mChance;	//Only add spells that aren't 100% chance of casting
		}

		//Go back to default behavior since we didn't decide anything
		SetCanMove(true);
		SetBehavior(Behavior_Melee);

		//Random taunts
		if( ChanceRoll >= 95 ) RandomEmote(mOnTauntEmotes);
	}
}
        void DoNormalAttack(uint32 diff)
        {
            opponent = me->GetVictim();
            if (opponent)
            {
                if (!IsCasting())
                    StartAttack(opponent);
            }
            else
                return;

            //TODO: add more damage spells

            if (feartimer <= diff && GC_Timer <= diff)
            { CheckFear(); feartimer = 2000; }

            if (IsSpellReady(RAIN_OF_FIRE_1, diff) && !me->isMoving() && HasRole(BOT_ROLE_DPS) && Rand() < 25)
            {
                Unit* blizztarget = FindAOETarget(30, true);
                if (blizztarget && doCast(blizztarget, GetSpell(RAIN_OF_FIRE_1)))
                    return;
                SetSpellCooldown(RAIN_OF_FIRE_1, 2000);//fail
            }

            float dist = me->GetExactDist(opponent);

            if (IsSpellReady(CURSE_OF_THE_ELEMENTS_1, diff) && dist < 30 && Rand() < 15 &&
                !HasAuraName(opponent, CURSE_OF_THE_ELEMENTS_1) &&
                doCast(opponent, GetSpell(CURSE_OF_THE_ELEMENTS_1)))
            {
                GC_Timer = 800;
                return;
            }

            if (IsSpellReady(CORRUPTION_1, diff) && HasRole(BOT_ROLE_DPS) && dist < 30 && Rand() < 25 &&
                !opponent->HasAura(GetSpell(CORRUPTION_1), me->GetGUID()) &&
                doCast(opponent, GetSpell(CORRUPTION_1)))
                return;

            if (IsSpellReady(HAUNT_1, diff) && HasRole(BOT_ROLE_DPS) && dist < 30 && Rand() < 25 &&
                !opponent->HasAura(GetSpell(HAUNT_1), me->GetGUID()) &&
                doCast(opponent, GetSpell(HAUNT_1)))
                return;

            if (GC_Timer <= diff && HasRole(BOT_ROLE_DPS) && dist < 30 && Rand() < 15 && !Afflicted(opponent))
            {
                if (GetSpellCooldown(CONFLAGRATE_1) <= 8000 && doCast(opponent, GetSpell(IMMOLATE_1)))
                    return;
                else if (doCast(opponent, GetSpell(UNSTABLE_AFFLICTION_1)))
                    return;
            }

            if (IsSpellReady(CONFLAGRATE_1, diff) && HasRole(BOT_ROLE_DPS) && dist < 30 && Rand() < 35 &&
                HasAuraName(opponent, IMMOLATE_1) &&
                doCast(opponent, GetSpell(CONFLAGRATE_1)))
                return;

            if (IsSpellReady(CHAOS_BOLT_1, diff) && HasRole(BOT_ROLE_DPS) && dist < 30 && Rand() < 50 &&
                doCast(opponent, GetSpell(CHAOS_BOLT_1)))
                return;

            if (IsSpellReady(SHADOW_BOLT_1, diff) && HasRole(BOT_ROLE_DPS) && dist < 30 &&
                doCast(opponent, GetSpell(SHADOW_BOLT_1)))
                return;
        }
        void FocusMagic(uint32 diff)
        {
            if (!FOCUSMAGIC || fmCheckTimer > diff || GC_Timer > diff ||
                me->getLevel() < 20 || Rand() < 50 || IsCasting())
                return;

            if (Unit* target = FindAffectedTarget(FOCUSMAGIC, me->GetGUID(), 70, 2))
            {
                fmCheckTimer = 15000;
                return;
            }
            else
            {
                Group* pGroup = master->GetGroup();
                if (!pGroup)
                {
                    if (master->getPowerType() == POWER_MANA && me->GetExactDist(master) < 30 &&
                        !master->HasAura(FOCUSMAGIC))
                    target = master;
                }
                else
                {
                    for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
                    {
                        Player* pPlayer = itr->GetSource();
                        if (!pPlayer || pPlayer->IsInWorld() || pPlayer->IsDead()) continue;
                        if (me->GetMapId() != pPlayer->GetMapId()) continue;
                        if (pPlayer->getPowerType() == POWER_MANA && me->GetExactDist(pPlayer) < 30 &&
                            !pPlayer->HasAura(FOCUSMAGIC))
                        {
                            target = pPlayer;
                            break;
                        }
                    }
                    if (!target)
                    {
                        for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
                        {
                            Player* pPlayer = itr->GetSource();
                            if (!pPlayer || !pPlayer->IsInWorld() || !pPlayer->HaveBot()) continue;
                            if (me->GetMapId() != pPlayer->GetMapId()) continue;
                            for (uint8 i = 0; i != pPlayer->GetMaxNpcBots(); ++i)
                            {
                                Creature* cre = pPlayer->GetBotMap(i)->_Cre();
                                if (!cre || !cre->IsInWorld() || cre == me || cre->IsDead()) continue;
                                if (cre->getPowerType() == POWER_MANA && me->GetExactDist(cre) < 30 &&
                                    !cre->HasAura(FOCUSMAGIC))
                                {
                                    target = cre;
                                    break;
                                }
                            }
                        }
                    }
                }

                if (target && doCast(target, FOCUSMAGIC))
                {
                    GC_Timer = 500;
                    fmCheckTimer = 30000;
                    return;
                }
            }

            fmCheckTimer = 5000;
        }
Example #19
0
        void DoNormalAttack(uint32 diff)
        {
            opponent = me->GetVictim();
            if (opponent)
            {
                if (!IsCasting())
                    StartAttack(opponent);
            }
            else
                return;

            //TODO: add more damage spells

            if (fear_cd <= diff && GC_Timer <= diff)
            { CheckFear(); fear_cd = 2000; }

            if (RAIN_OF_FIRE && Rain_of_fire_cd <= diff && GC_Timer <= diff && !me->isMoving() && Rand() < 25)
            {
                Unit* blizztarget = FindAOETarget(35, true);
                if (blizztarget && doCast(blizztarget, RAIN_OF_FIRE))
                {
                    Rain_of_fire_cd = 5000;
                    return;
                }
                Rain_of_fire_cd = 2000;//fail
            }

            float dist = me->GetExactDist(opponent);

            if (CURSE_OF_THE_ELEMENTS && GC_Timer <= diff && dist < 40 && Rand() < 15 &&
                !HasAuraName(opponent, CURSE_OF_THE_ELEMENTS) &&
                doCast(opponent, CURSE_OF_THE_ELEMENTS))
            {
                GC_Timer = 800;
                return;
            }

            if (CORRUPTION && GC_Timer <= diff && dist < 40 && Rand() < 25 &&
                !opponent->HasAura(CORRUPTION, me->GetGUID()) &&
                doCast(opponent, CORRUPTION))
                return;

            if (HAUNT && Haunt_cd <= diff && GC_Timer <= diff && dist < 40 && Rand() < 25 &&
                !opponent->HasAura(HAUNT, me->GetGUID()) &&
                doCast(opponent, HAUNT))
            {
                Haunt_cd = 8000;
                return;
            }

            if (GC_Timer <= diff && dist < 40 && Rand() < 15 && !Afflicted(opponent))
            {
                if (IMMOLATE && (!CONFLAGRATE || conflagarate_cd <= 8000) && doCast(opponent, IMMOLATE))
                    return;
                else if (UNSTABLE_AFFLICTION && doCast(opponent, UNSTABLE_AFFLICTION))
                    return;
            }

            if (CONFLAGRATE && conflagarate_cd <= diff && GC_Timer <= diff && dist < 40 && Rand() < 35 &&
                HasAuraName(opponent, IMMOLATE) &&
                doCast(opponent, CONFLAGRATE))
            {
                conflagarate_cd = 8000;
                return;
            }

            if (CHAOS_BOLT && chaos_bolt_cd <= diff && GC_Timer <= diff && dist < 40 && Rand() < 50 &&
                doCast(opponent, CHAOS_BOLT))
            {
                chaos_bolt_cd = me->getLevel() < 80 ? 10000 : 8000;
                return;
            }

            if (SHADOW_BOLT && GC_Timer <= diff && dist < 40 &&
                doCast(opponent, SHADOW_BOLT))
                return;
        }
        void DoNormalAttack(uint32 diff)
        {
            opponent = me->GetVictim();
            if (opponent)
            {
                if (!IsCasting())
                    StartAttack(opponent);
            }
            else
                return;

            AttackerSet m_attackers = master->getAttackers();
            AttackerSet b_attackers = me->getAttackers();

            Unit* u = me->SelectNearestTarget(20);
            //ICE_BARRIER
            if (ICE_BARRIER && Ice_Barrier_cd <= diff && u && u->GetVictim() == me &&
                u->GetDistance(me) < 8 && !me->HasAura(ICE_BARRIER))
            {
                if (me->IsNonMeleeSpellCast(true))
                    me->InterruptNonMeleeSpells(true);
                if (doCast(me, ICE_BARRIER))
                {
                    Ice_Barrier_cd = 25000;
                    GC_Timer = 800;
                    return;
                }
            }
            if ((!ICE_BARRIER || Ice_Barrier_cd > diff) &&
                BLINK && Blink_cd < 3000 && u && u->GetVictim() == me &&
                u->GetDistance(me) < 6 && !me->HasAura(ICE_BARRIER))
            {
                if (me->IsNonMeleeSpellCast(true))
                    me->InterruptNonMeleeSpells(true);
                if (doCast(me, BLINK))
                {
                    Blink_cd = 13000;
                    GC_Timer = 800;
                    return;
                }
            }

            if (me->HasAura(ICEBLOCK))
                if (((GetManaPCT(me) > 45 && GetHealthPCT(me) > 80) || b_attackers.empty()) && Iceblock_cd <= 57000 && tank)
                    me->RemoveAurasDueToSpell(ICEBLOCK);
            //ICEBLOCK
            if (ICEBLOCK && Rand() < 50 && !b_attackers.empty() && tank && Iceblock_cd <= diff &&
                (GetManaPCT(me) < 15 || GetHealthPCT(me) < 45 || b_attackers.size() > 4) &&
                !me->HasAura(ICEBLOCK))
            {
                if (me->IsNonMeleeSpellCast(true))
                    me->InterruptNonMeleeSpells(true);
                if (doCast(me, ICEBLOCK))
                {
                    Iceblock_cd = 60000;
                    Nova_cd = 0; //Glyph of Iceblock
                    return;
                }
            }

            if (IsCasting()) return;

            float dist = me->GetExactDist(opponent);

            BOLT = (CCed(opponent, true) || !FROSTBOLT) ? FIREBALL : FROSTBOLT;
            NOVA = BOLT == FROSTBOLT && BLASTWAVE && dist > 5 ? BLASTWAVE : FROSTNOVA ? FROSTNOVA : 0;

            ////Combustion doesn't work properly on 434 (14.08.13)
            //if (COMBUSTION && Combustion_cd <= diff && Rand() < 15 && dist < 40)
            //{
            //    if (opponent->HasAuraTypeWithCaster(SPELL_AURA_PERIODIC_DAMAGE, me->GetGUID()))
            //    {
            //        temptimer = GC_Timer;
            //        if (doCast(me, COMBUSTION))
            //        {
            //            Combustion_cd = 60000;
            //            Nova_cd = 0; FireBlast_cd = 0; DragonBreath_cd = 0;
            //        }
            //        GC_Timer = temptimer;
            //    }
            //}
            //DAMAGE
            //PYROBLAST
            if (PYROBLAST && Pyroblast_cd <= diff && GC_Timer <= diff && Rand() < 95 &&
                (b_attackers.size() < 2 || (*b_attackers.begin()) == opponent) &&
                dist < 40 && opponent->IsPolymorphed() &&
                doCast(opponent, PYROBLAST))
            {
                Pyroblast_cd = 7500;
                //debug
                DragonBreath_cd = std::max<uint32>(DragonBreath_cd, 450);
                Nova_cd = std::max<uint32>(Nova_cd, 450);
                return;
            }
            //nova //TODO: SEPARATE
            u = me->SelectNearestTarget(6.3f);
            if (NOVA && Nova_cd <= diff && u && Rand() < 75 && !CCed(u, true) && IsInBotParty(u->GetVictim()))
            {
                if (doCast(me, NOVA))
                {
                    Nova_cd = 15000;
                    GetInPosition(true);
                    return;
                }
            }
            //living bomb
            if (LIVINGBOMB && Living_Bomb_cd <= diff && GC_Timer <= diff && Rand() < 45 && dist < 40 &&
                opponent->GetHealth() > me->GetHealth()/2 &&
                !opponent->HasAura(LIVINGBOMB, me->GetGUID()) &&
                doCast(opponent, LIVINGBOMB))
            {
                Living_Bomb_cd = 6000;
                GC_Timer = 500;
                return;
            }
            //cone of cold
            if (CONEOFCOLD && ConeofCold_cd <= diff && GC_Timer <= diff && Rand() < 50 && dist < 7 &&
                me->HasInArc(M_PI*0.75f, opponent) &&
                doCast(opponent, CONEOFCOLD))
            {
                ConeofCold_cd = 8000;
                GC_Timer = 500;
                GetInPosition(true);
                return;
            }
            //dragon's breath
            if (DRAGONBREATH && DragonBreath_cd <= diff && GC_Timer <= diff && !CCed(opponent, true) &&
                ((me->HasInArc(M_PI*0.75f, opponent) && dist < 7) ||
                (u && u != opponent && me->HasInArc(M_PI*0.75f, u) && IsInBotParty(u->GetVictim()))) &&
                doCast(/*opponent*/me, DRAGONBREATH))
            {
                DragonBreath_cd = 15000;
                GC_Timer = 800;
                return;
            }
            /*//blast wave //TODO Separate again
            u = me->SelectNearestTarget(8);
            if (BLASTWAVE != 0 && u && isTimerReady(BlastWave_cd) &&
                !HasAuraName(u, FROSTNOVA) && !HasAuraName(u, DRAGONBREATH) &&
                doCast(me, BLASTWAVE))
            {
                BlastWave_cd = BLASTWAVE_CD;
                GC_Timer = 800;
            }*/
            //fire blast
            if (FIREBLAST && FireBlast_cd <= diff && GC_Timer <= diff && dist < 40)
            {
                if (Rand() < 20 + 80*(!opponent->isFrozen() && !opponent->HasAuraType(SPELL_AURA_MOD_STUN) && me->HasAura(IMPACT_BUFF)))
                {
                    if (doCast(opponent, FIREBLAST))
                    {

                        FireBlast_cd = 6000;
                        GC_Timer = 500;
                        return;
                    }
                }
            }
            //flamestrike - use Improved Flamestrike for instant cast
            if (FLAMESTRIKE && GC_Timer <= diff && me->getLevel() >= 50 && Rand() < 25)
            {
                Unit* FStarget = FindAOETarget(40, true, false);
                if (FStarget && doCast(FStarget, FLAMESTRIKE, true))
                    return;
            }
            //blizzard
            if (BLIZZARD && Blizzard_cd <= diff && !me->isMoving() && Rand() < 40)
            {
                Unit* blizztarget = FindAOETarget(35, true);
                if (blizztarget && doCast(blizztarget, BLIZZARD))
                {
                    Blizzard_cd = 5000;
                    return;
                }
                Blizzard_cd = 1500; //fail
            }
            //Frost of Fire Bolt
            if (BOLT && Bolt_cd <= diff && Rand() < 75 && dist < 35 &&
                doCast(opponent, BOLT))
            {
                Bolt_cd = uint32(float(sSpellMgr->GetSpellInfo(BOLT)->CalcCastTime()/100) * me->GetFloatValue(UNIT_MOD_CAST_SPEED) + 200);
                //debug
                DragonBreath_cd = std::max<uint32>(DragonBreath_cd, 450);
                Nova_cd = std::max<uint32>(Nova_cd, 450);
                return;
            }
            ////Arcane Missiles
            //if (Rand() < 15 && GC_Timer <= diff && !me->isMoving() && dist < 40 &&
            //    doCast(opponent, ARCANEMISSILES))
            //    return;
        }