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; }
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; } } } } }
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; } } }
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; } } } } }
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(); }
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 }
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(); }
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); } } }
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 }
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; }
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; }
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; }