void UpdateAI(uint32 diff) { ReduceCD(diff); if (IAmDead()) return; if (!me->GetVictim()) Evade(); if (clearcast && !me->IsNonMeleeSpellCast(false)) { if (Aura* potency = me->GetAura(ARCANE_POTENCY_BUFF)) { if (potency->GetCharges() == 1) clearcast = false; potency->DropCharge(AURA_REMOVE_BY_EXPIRE); if (me->HasAura(CLEARCASTBUFF)) { me->ModifyPower(POWER_MANA, cost); me->RemoveAurasDueToSpell(CLEARCASTBUFF, me->GetGUID(), 0, AURA_REMOVE_BY_EXPIRE); } } } CheckAuras(); if (wait == 0) wait = GetWait(); else return; BreakCC(diff); if (CCed(me) && (!ICEBLOCK || !me->HasAura(ICEBLOCK))) return;//TODO CheckBlink(diff); CheckPoly(diff); CheckPots(diff); //CureTarget(master, REMOVE_CURSE, diff); //CureTarget(me, REMOVE_CURSE, diff); CureGroup(master, REMOVE_CURSE, diff); FocusMagic(diff); BuffAndHealGroup(master, diff); if (!me->IsInCombat()) DoNonCombatActions(diff); if (!CheckAttackTarget(CLASS_MAGE)) return; CheckPoly2();//this should go AFTER getting opponent Counter(); CheckSpellSteal(diff); DoNormalAttack(diff); }
void UpdateAI(uint32 diff) { ReduceCD(diff); if (!GlobalUpdate(diff)) return; CheckAttackState(); CheckAuras(); if (wait == 0) wait = GetWait(); else return; BreakCC(diff); if (CCed(me)) return; ////if pet is dead or unreachable //Creature* m_botsPet = me->GetBotsPet(); //if (!m_botsPet || m_botsPet->FindMap() != master->GetMap() || (me->GetDistance2d(m_botsPet) > sWorld->GetMaxVisibleDistanceOnContinents() - 20.f)) // if (master->getLevel() >= 10 && !me->IsInCombat() && !IsCasting() && !me->IsMounted()) // SummonBotsPet(PET_VOIDWALKER); //TODO: implement healthstone if (Potion_cd <= diff && GetHealthPCT(me) < 67) { temptimer = GC_Timer; if (doCast(me, HEALINGPOTION)) { Potion_cd = POTION_CD; GC_Timer = temptimer; } } if (Potion_cd <= diff && GetManaPCT(me) < 50) { temptimer = GC_Timer; if (doCast(me, MANAPOTION)) { Potion_cd = POTION_CD; GC_Timer = temptimer; } } if (!me->IsInCombat()) DoNonCombatActions(); if (!CheckAttackTarget(BOT_CLASS_WARLOCK)) return; DoNormalAttack(diff); }
void UpdateAI(uint32 diff) { ReduceCD(diff); if (IAmDead()) return; CheckAttackState(); CheckAuras(); if (wait == 0) wait = GetWait(); else return; if (CCed(me)) return; //TODO: add checks to help owner if (!me->IsInCombat()) DoNonCombatActions(); if (!CheckAttackTarget(PET_TYPE_VOIDWALKER)) return; DoNormalAttack(diff); }
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; }
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; }