bool PlayerbotDruidAI::RezTarget (Unit *target) { if(!target || target->isAlive()) return false; Player *m_bot = GetPlayerBot(); if (target->IsNonMeleeSpellCasted(true)) { return false; } //Already resurrected if (m_bot->isInCombat()) { if (!CanCast(REBIRTH,target)) return false; Unit *m_tank = FindMainTankInRaid(m_bot); if (!m_tank) m_tank = m_bot; if (target->GetGUID() != m_tank->GetGUID() && (target->getClass() != (uint8) CLASS_PRIEST || target->getClass() != (uint8) CLASS_DRUID || target->getClass() != (uint8) CLASS_PALADIN) ) return false; std::string msg = "Rezzing "; msg += target->GetName(); // msg += " with "; // msg += *REZZSpell->SpellName; GetPlayerBot()->Say(msg, LANG_UNIVERSAL); return CastSpell(REBIRTH, target); } else { if (!CanCast(REVIVE,target)) return false; std::string msg = "Rezzing "; msg += target->GetName(); // msg += " with "; // msg += *REZZSpell->SpellName; GetPlayerBot()->Say(msg, LANG_UNIVERSAL); return CastSpell(REVIVE, target); } return false; }
bool PlayerbotDruidAI::HealTarget(Unit *target, uint8 hp) { PlayerbotAI *ai = GetAI(); Player *m_bot = GetPlayerBot(); if (!m_bot || !ai || m_bot->isDead()) { return false; } if (!target || target->isDead()) { return false; } // Decide if it is worth to change form if (ai->GetForm() == FORM_MOONKIN || ai->GetForm() == FORM_CAT || ai->GetForm() == FORM_DIREBEAR || ai->GetForm() == FORM_BEAR) { if (hp < 75 && GetAI()->GetManaPercent() >= 70 ) { ChangeForm(1); } else if (hp < 40 && GetAI()->GetManaPercent() >= 50) { ChangeForm(1); } else if (hp < 25 && GetAI()->GetManaPercent() >= 30) { ChangeForm(1); } else return false; } // if(m_bot->HasAura(TRAVEL_FORM)) ChangeForm(1); if(hp < 60 && m_bot->HasAura(NATURES_SWIFTNESS) && CastSpell(HEALING_TOUCH, target)) { return true; } if(hp < 90 && CastSpell(LIFEBLOOM, target)) { return true; } if(hp < 80 && CastSpell(REJUVENATION, target)) { return true; } if(hp < 60 && CastSpell(REGROWTH, target)) { return true; } if(hp < 70 && CanCast(NOURISH,target) && (HasAuraName(target,REJUVENATION,m_bot->GetGUID()) || HasAuraName(target,LIFEBLOOM,m_bot->GetGUID()) || HasAuraName(target,REGROWTH,m_bot->GetGUID())) ) { return CastSpell(NOURISH, target, false); } if(hp < 50 && CanCast(SWIFTMEND,target) && (HasAuraName(target,REJUVENATION,m_bot->GetGUID()) || HasAuraName(target,REGROWTH,m_bot->GetGUID())) ) { return CastSpell(SWIFTMEND, target, false); } if(hp < 40 && m_bot->isInCombat() && CastSpell(NATURES_SWIFTNESS, m_bot)) { } // NO gcd if(hp < 40 && CastSpell(HEALING_TOUCH, target)) { return true; } return false; } //end HealTarget
bool PlayerbotDruidAI::HealGroup(Unit *target, uint8 hp, uint8 &countNeedHeal) { PlayerbotAI *ai = GetAI(); Player *m_bot = GetPlayerBot(); if (!m_bot || !ai || m_bot->isDead()) { return false; } if (!target || target->isDead()) { return false; } if (countNeedHeal < 2) { return false; } // Decide if it is worth to change form if (ai->GetForm() == FORM_MOONKIN || ai->GetForm() == FORM_CAT || ai->GetForm() == FORM_DIREBEAR || ai->GetForm() == FORM_BEAR) { if (hp > 70) { return false; } if (!CanCast(TRANQUILITY,target,0,0,1) && !WILD_GROWTH) { return false; } if (!WILD_GROWTH && hp > 35) { return false; } if (hp < 65 && GetAI()->GetManaPercent() >= 70 ) { ChangeForm(1); } else if (hp < 40 && GetAI()->GetManaPercent() >= 50) { ChangeForm(1); } else if (hp < 25 && GetAI()->GetManaPercent() >= 30) { ChangeForm(1); } else return false; } if (hp < 36 && m_bot->isInCombat() && CanCast(TRANQUILITY,target)) { bool sc = CastSpell(TRANQUILITY, target, false); if (sc) GetAI()->SetIgnoreUpdateTime(10); return sc; } if (hp < 75 && CastSpell(WILD_GROWTH,target)) { return true; } return false; }
bool PlayerbotShamanAI::HealTarget(Unit *target, uint8 hp) { if(!target || target->isDead()) return false; Player *m_bot = GetPlayerBot(); if(hp < 30 && m_bot->isInCombat() && CastSpell(NATURES_SWIFTNESS, m_bot)) {} // NO gcd if(hp < 60 && CanCast(HEAL,target,true) && m_bot->HasAura(NATURES_SWIFTNESS) && CastSpell(HEAL, target, false)) { return true; } if(hp < 30 && CastSpell(LESSER_HEAL,target,true,true)) { return true; } if(hp < 40 && m_bot->getRace() == (uint8) RACE_DRAENEI && CastSpell(R_GIFT_OF_NAARU,target)) {} // no GCD if(hp < 65 && CanCast(EARTH_SHIELD,target) && !m_bot->HasAura(EARTH_SHIELD,m_bot->GetGUID()) && CastSpell(EARTH_SHIELD,target,false)) { return true; } if(hp < 65 && CastSpell(HEAL,target,true,true)) { return true; } if(hp < 85 && CastSpell(LESSER_HEAL,target,true,true)) { return true; } return false; } //end HealTarget
bool PlayerbotDruidAI::BuffPlayer(Unit *target) { PlayerbotAI *ai = GetAI(); Player *m_bot = GetPlayerBot(); if (!m_bot || !ai || m_bot->isDead()) { return false; } if(!target || target->isDead()) { return false; } if (CanCast(THORNS,target,0,0,1) && !HasAuraName(target, THORNS)) { // Decide if it is worth to change form if( /*m_bot->HasAura(MOONKIN_FORM) ||*/ m_bot->HasAura(CAT_FORM) || m_bot->HasAura(BEAR_FORM)) { if(GetAI()->GetManaPercent() >= 80 ) { ChangeForm(1); } else { return false; } } return CastSpell(THORNS, target, false); } if (CanCast(MARK_OF_THE_WILD,target,0,0,1) && !HasAuraName(target, GIFT_OF_THE_WILD) && !HasAuraName(target, MARK_OF_THE_WILD)) { // Decide if it is worth to change form if(/*m_bot->HasAura(MOONKIN_FORM) ||*/ m_bot->HasAura(CAT_FORM) || m_bot->HasAura(BEAR_FORM)) { if(GetAI()->GetManaPercent() >= 70 ) { ChangeForm(1); } else return false; } return CastSpell(MARK_OF_THE_WILD, target, false); } return false; }
void ToggleVisibility() { mAddsSpawned = !mAddsSpawned; if(mAddsSpawned) { if(CanCast(m_creature, GetSpellStore()->LookupEntry(17651)) == false) //CC check { mAddsSpawned = !mAddsSpawned; return; } float x, y, z; m_creature->GetPosition(x, y, z); m_creature->SummonCreature(11263, x + 0, y + 0, z, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN_FORCED, 10000); m_creature->SummonCreature(11263, x + 5, y + 0, z, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN_FORCED, 10000); m_creature->SummonCreature(11263, x + 0, y + 5, z, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN_FORCED, 10000); m_creature->SummonCreature(11263, x - 5, y + 0, z, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN_FORCED, 10000); m_creature->SummonCreature(11263, x + 0, y - 5, z, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN_FORCED, 10000); m_creature->SetVisibility(UnitVisibility::VISIBILITY_OFF); m_creature->RemoveAllAuras(); mImageProjectionTimer = 10000; } else { mImageProjectionTimer = 12000; m_creature->SetVisibility(UnitVisibility::VISIBILITY_ON); } }
bool PlayerbotDruidAI::ChangeForm(uint32 form) { PlayerbotAI *ai = GetAI(); Player *m_bot = GetPlayerBot(); if (!m_bot || !ai || m_bot->isDead()) { return false; } if (!form) return false; if (form == 1 && ai->GetForm() == FORM_NONE) return false; if (form != 1) { if (!CanCast(form,m_bot,0,0,1)) return false; if (m_bot->HasAura(form)) { return false; } } if (ai->GetForm() == FORM_TREE) m_bot->RemoveAurasDueToSpell(TREE_OF_LIFE_FORM); else if (ai->GetForm() == FORM_CAT) m_bot->RemoveAurasDueToSpell(CAT_FORM); else if (ai->GetForm() == FORM_MOONKIN) m_bot->RemoveAurasDueToSpell(MOONKIN_FORM); else if (ai->GetForm() == FORM_DIREBEAR || ai->GetForm() == FORM_BEAR) m_bot->RemoveAurasDueToSpell(BEAR_FORM); else if (ai->GetForm() == FORM_TRAVEL) m_bot->RemoveAurasDueToSpell(TRAVEL_FORM); else if (ai->GetForm() == FORM_FLIGHT || ai->GetForm() == FORM_FLIGHT_EPIC) m_bot->RemoveAurasDueToSpell(FLIGHT_FORM); else if (ai->GetForm() == FORM_AQUA) m_bot->RemoveAurasDueToSpell(AQUATIC_FORM); if (form == 1) { return true; } return CastSpell(form,m_bot,false); }
bool PlayerbotPaladinAI::HealTarget(Unit *target, uint8 hp) { if(!target || target->isDead()) return false; Player *m_bot = GetPlayerBot(); if(hp < 10 && m_bot->isInCombat() && CastSpell(LOH, target)) { return true; } if(hp < 10 && m_bot->isInCombat() && CastSpell(SACRED_SHIELD,target)) { return true; } if(hp < 15 && m_bot->isInCombat() && CastSpell(HOP,target)) { return true; } if(hp < 20 && m_bot->isInCombat() && CastSpell(BEACON_OF_LIGHT,target)) { return true; } if(hp < 30 && CastSpell(HOLY_SHOCK,target,true,true,true)) { return true; } if(hp < 30 && m_bot->isInCombat() && CanCast(DIVINE_FAVOR,m_bot,true) && CanCast(HOLY_LIGHT,target,true) ) { CastSpell(DIVINE_FAVOR, m_bot,false); return CastSpell(HOLY_LIGHT,target,false); } //No gcd if(hp < 30 && CastSpell(FLASH_OF_LIGHT,target,true,true)) { return true; } if(hp < 40 && m_bot->getRace() == (uint8) RACE_DRAENEI && CastSpell(R_GIFT_OF_NAARU,target)) { return true; } // no GCD but has cast if(hp < 65 && CastSpell(HOLY_LIGHT,target,true,true)) { return true; } if(hp < 85 && CastSpell(FLASH_OF_LIGHT,target,true,true)) { return true; } if(hp < 95 && m_bot->isInCombat() && CastSpell(BEACON_OF_LIGHT,target)) { return true; } return false; } //end HealTarget
bool PlayerbotShamanAI::ChangeTotems(uint32 mode) { uint32 earth=0, fire=0, water=0, air=0; PlayerbotAI *ai = GetAI(); if(!ai) return false; Player *m_bot = GetPlayerBot(); if(!m_bot || m_bot->isDead()) return false; Unit *pTarget = m_bot->GetSelectedUnit(); Unit *pVictim = NULL; if (m_bot->GetSelectedUnit()->IsFriendlyTo(m_bot)) pTarget = NULL; if (pTarget) pVictim = pTarget->getVictim(); //Defaults if (!HasAuraName(m_bot,"Horn of Winter") )earth = STRENGTH_OF_EARTH_TOTEM; if (!earth) earth = STONESKIN_TOTEM; if (!earth) earth = EARTHBIND_TOTEM; fire = TOTEM_OF_WRATH; if (!fire) fire = FLAMETONGUE_TOTEM; if (!fire) fire = SEARING_TOTEM; water = MANA_SPRING_TOTEM; if (!water) water = HEALING_STREAM_TOTEM; if (TALENT_ELEMENTAL || TALENT_RESTO) air = WRATH_OF_AIR_TOTEM; else air = WINDFURY_TOTEM; //Target reactive stuff if (pTarget) { if (GROUNDING_TOTEM && pTarget->IsNonMeleeSpellCasted(true)) air = GROUNDING_TOTEM; } if (STONESKIN_TOTEM && isUnderAttack()) earth = STONESKIN_TOTEM; uint32 totz[4] = {earth, fire, water, air}; for (int i = 0; i < 4; i++) { if (!totz[i]) continue; SpellInfo const *tSpell = GetSpellInfo(totz[i]); SpellEntry *tmp = 0; tmp->Id = tSpell->Id; if (!tSpell) continue; uint32 tEntry = (uint32) tSpell->Effects->MiscValue; if (!tEntry) continue; //CreatureTemplate const *totemEntry = ObjectMgr::GetCreatureTemplateStore(tEntry); if (!tEntry) continue; if (CanCast(totz[i], m_bot) && !m_bot->FindNearestCreature(tEntry,30)) { return CastSpell(totz[i],m_bot,false); } } return false; }
bool PlayerbotPaladinAI::RezTarget (Unit *target) { if(!target || target->isAlive()) return false; Player *m_bot = GetPlayerBot(); if (target->IsNonMeleeSpellCasted(true)) { return false; } //Already resurrected if (m_bot->isInCombat()) { return false; } if (!CanCast(REDEMPTION,target)) return false; std::string msg = "Rezzing "; msg += target->GetName(); GetPlayerBot()->Say(msg, LANGUAGE_UNIVERSAL); return CastSpell(REDEMPTION, target, false); }
bool PlayerbotPaladinAI::ChangeAura(uint32 aura) { Player *m_bot = GetPlayerBot(); if(!aura) return false; if(!CanCast(aura,m_bot)) return false; if(m_bot->HasAura(aura)) { if (aura == DEVOTION_AURA) { if (ChangeAura(FIRE_AURA)) return true; if (ChangeAura(FROST_AURA)) return true; if (ChangeAura(SHADOW_AURA)) return true; return true; } else return ChangeAura(DEVOTION_AURA); } return CastSpell(aura,m_bot,false); }
_THyPhyReturnObject* _THyPhy::CastResult (const void* theObject, const int requestedType) { _THyPhyReturnObject * convertedObject = nil; if (CanCast(theObject,requestedType)) { int hyphyObjClass = ((_PMathObj)theObject)->ObjectClass(); switch (hyphyObjClass) { case NUMBER: { if (hyphyObjClass == NUMBER) { return new _THyPhyNumber (((_PMathObj)theObject)->Compute()->Value()); } if (hyphyObjClass == STRING) { _String sV ((_String*)((_FString*)theObject)->toStr()); return new _THyPhyNumber (sV.toNum()); } } case STRING: { _String sV ((_String*)((_PMathObj)theObject)->toStr()); return new _THyPhyString (sV.sData,sV.sLength); } case MATRIX: { if (hyphyObjClass == NUMBER) { double evaluate = ((_PMathObj)theObject)->Compute()->Value(); return new _THyPhyMatrix (1,1,&evaluate); } if (hyphyObjClass == MATRIX) { _Matrix * evalutedNumeric = (_Matrix*)((_Matrix*)(((_PMathObj)theObject)->Compute())) ->ComputeNumeric(); return new _THyPhyMatrix (evalutedNumeric->GetHDim(),evalutedNumeric->GetVDim(),evalutedNumeric->theData); } } } } return convertedObject; }
void DoNonCombatActions() { Feast(); if(isTimerReady(GC_Timer) && !m_creature->HasAura(SPELL_LIGHTNING_SHIELD, 0)) doCast(m_creature, SPELL_LIGHTNING_SHIELD); //Casts buffs // if(!m_creature->isInCombat()) // { //if(!m_creature->HasAura(SPELL_WINDFURY_WEAPON, 0)) doCast(m_creature, SPELL_WINDFURY_WEAPON); // if(isTimerReady(GC_Timer) && !m_creature->HasAura(SPELL_LIGHTNING_SHIELD, 0)) // doCast(m_creature, SPELL_LIGHTNING_SHIELD); // } //Heal/rez others // //check group members, this doesn't check bots/pets. They will be done later. Preference //goes to real players first. // //buff and heal group if(master->GetGroup()) { RezGroup(SPELL_SHAMAN_REZZ, master); BuffAndHealGroup(master); // CureGroup(master); } /* TESTING */ Group::MemberSlotList const &a =((Player*)master)->GetGroup()->GetMemberSlots(); for(Group::member_citerator itr = a.begin(); itr != a.end(); itr++) { Player *tPlayer = ((Player *)master)->GetObjPlayer(itr->guid); if(tPlayer == NULL) continue; //healing others if(tPlayer->isAlive() && isTimerReady(Others_Heal_Timer) && tPlayer->GetGUID() != master->GetGUID() && tPlayer->GetHealth()*100 / tPlayer->GetMaxHealth() < 75 && CanCast(tPlayer, GetSpellStore()->LookupEntry (SPELL_CHAIN_HEAL))) { doCast(tPlayer, SPELL_CHAIN_HEAL, false); Others_Heal_Timer = 100; } //rezzes if(tPlayer->isDead() && !m_creature->isInCombat() && //CanCast(tPlayer, GetSpellStore()->LookupEntry (SPELL_SHAMAN_REZZ)) && m_creature->GetDistance(tPlayer) < 40 && isTimerReady(Rez_Timer)) { char *str = (char *)malloc(32); sprintf(str, "Rezzing %s", tPlayer->GetName()); m_creature->MonsterSay(str, LANG_UNIVERSAL, NULL); free(str); doCast(tPlayer, SPELL_SHAMAN_REZZ, false); Rez_Timer = 160; } } /* TESTING */ /* TESTING */ if((master->GetHealth()*100 / master->GetMaxHealth() < 90) && Lesser_Healing_Timer <= 0) { doCast(master, SPELL_LESSER_HEALING); Lesser_Healing_Timer = 90; Heal_Timer = Heal_Timer + 5; //wait 5 seconds before casting a real heal //if(master->isInCombat()) && master->getVictim() == NULL) return; return; } else if(Lesser_Healing_Timer >= 0) --Lesser_Healing_Timer; if((master->GetHealth()*100 / master->GetMaxHealth() < 75) && isTimerReady(Heal_Timer)) { doCast(master, SPELL_CHAIN_HEAL); Heal_Timer = 10; } if(m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 90) { if(Self_Lesser_Healing_Timer <= 0) { doCast(m_creature, SPELL_LESSER_HEALING); Self_Lesser_Healing_Timer = 90; return; } else if(Self_Lesser_Healing_Timer >= 0) --Self_Lesser_Healing_Timer; } /* TESTING */ }
void PlayerbotHunterAI::DoNextCombatManeuver(Unit *pTarget) { if (!pTarget || pTarget->isDead()) return; PlayerbotAI *ai = GetAI(); if (!ai) return; Player *m_bot = GetPlayerBot(); if (!m_bot || m_bot->isDead()) return; Unit *pVictim = pTarget->getVictim(); Unit *m_tank = FindMainTankInRaid(GetMaster()); if (!m_tank && m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup()) { FindMainTankInRaid(m_bot); } if (!m_tank) { m_tank = m_bot; } uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth(); float pDist = m_bot->GetDistance(pTarget); uint8 pThreat = GetThreatPercent(pTarget); Pet *pet = m_bot->GetPet(); if (m_tank->GetGUID() == m_bot->GetGUID() && pet && pet->isAlive() && pet->isInCombat()) { m_tank = pet; } uint8 petThreat = 0; if (pet) { GetThreatPercent(pTarget,pet); } // switch (ai->GetScenarioType()) // { // case PlayerbotAI::SCENARIO_DUEL: // ai->CastSpell(RAPTOR_STRIKE); // return; // } // ------- Non Duel combat ---------- #pragma region Choose Target // Choose Target if (isUnderAttack()) // I am under attack { if (pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist <= 2) { } // My target is almost up to me, no need to search else //Have to select nearest target { Unit *curAtt = GetNearestAttackerOf(m_bot); if (curAtt && curAtt->GetGUID() != pTarget->GetGUID()) { m_bot->SetSelection(curAtt->GetGUID()); //ai->AddLootGUID(curAtt->GetGUID()); DoNextCombatManeuver(curAtt); //Restart new update to get variables fixed.. return; } } //my target is attacking me } #pragma endregion #pragma region Pet Actions // Pet's own Actions if( pet && pet->isAlive() ) { // Setup pet if (pet->GetCharmInfo()->IsAtStay()) {pet->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW); } //Heal pet if ( ( ((float)pet->GetHealth()/(float)pet->GetMaxHealth()) < 0.5f ) && ( PET_MEND>0 && !pet->getDeathState() != ALIVE && pVictim != m_bot && CastSpell(PET_MEND,m_bot) )) { return; } // Set pet to attack hunter's attacker > its own attackers > hunter's target if (!pet->getVictim()) { pet->AI()->AttackStart(pTarget); } else if (isUnderAttack(m_bot)) { pet->AI()->AttackStart(pTarget); } //Always help hunter if she's under attack else if (pet->getVictim()->GetGUID() != pTarget->GetGUID() && !isUnderAttack(pet)) { pet->AI()->AttackStart(pTarget); } else if (isUnderAttack(pet)) // Pet is under attack and hunter has no attackers { if ( pet->getVictim()->getVictim() && pet->getVictim()->getVictim()->GetGUID() == pet->GetGUID() && pDist <= 2) { } // My target is almost up to me, no need to search else //Have to select nearest target { Unit *curAtt = GetNearestAttackerOf(pet,true); if (curAtt && (!pet->getVictim() || curAtt->GetGUID() != pet->getVictim()->GetGUID())) { pet->AI()->AttackStart(curAtt); //Attack nearest attacker } } //Actions to do under attack (Always tank it, and try to kill it, until someone (!= hunter) takes aggro back) //Hunter should help her pet whether main tank or not, unless she's being attacked (BEWARE Targeting Loop possibility) if (pet->getVictim() && !isUnderAttack(m_bot) && pet->getVictim()->GetGUID() != pTarget->GetGUID()) { m_bot->SetSelection(pet->getVictim()->GetGUID()); DoNextCombatManeuver(pet->getVictim()); //Restart new update to get variables fixed.. return; } } // Pet tanking behaviour if (pet->GetGUID() == m_tank->GetGUID() || isUnderAttack(m_bot) || isUnderAttack(pet)) { if (GROWL) pet->GetCharmInfo()->SetSpellAutocast(GROWL,true); //Autocast growl if (BAD_ATTITUDE) pet->GetCharmInfo()->SetSpellAutocast(BAD_ATTITUDE,true); if (COWER) pet->GetCharmInfo()->SetSpellAutocast(COWER,false); if (CastSpell(INTIMIDATION,m_bot)) { return; } } else { if (GROWL) pet->GetCharmInfo()->SetSpellAutocast(GROWL,false); //Do not try to get aggro if (BAD_ATTITUDE) pet->GetCharmInfo()->SetSpellAutocast(BAD_ATTITUDE,false); if (COWER) pet->GetCharmInfo()->SetSpellAutocast(COWER,true); //Autocast cower } // NORMAL PET dps attacks if (petThreat < threatThreshold || pet->GetGUID() == m_tank->GetGUID() || isUnderAttack(m_bot)) { if (CastSpell(KILL_COMMAND,m_bot)) { } else if (CastSpell(BESTIAL_WRATH,m_bot)) { } } // NETHERSHOCK DEMORALIZINGSCREECH } #pragma endregion // If there's a cast stop if(m_bot->HasUnitState(UNIT_STAT_CASTING)) return; // Cast CC breakers if any match found (does not work yet) // uint32 ccSpells[4] = { R_ESCAPE_ARTIST, R_EVERY_MAN_FOR_HIMSELF, R_WILL_OF_FORSAKEN, R_STONEFORM }; // if (castSelfCCBreakers(ccSpells)) { } //most of them dont have gcd #pragma region Evasive manuevers // Do evasive manuevers if under attack if (isUnderAttack()) { if (m_tank->GetGUID() == m_bot->GetGUID()) { } // i am tank and my pet is probably dead, so i have to face the attackers else if (CastSpell(FEIGN_DEATH,m_bot)) { return; } //avoid attack //else if (m_bot->getRace() == (uint8) RACE_NIGHTELF && CastSpell(R_SHADOWMELD,m_bot) ) { return; } else if (CastSpell(CONCUSSIVE_SHOT,pTarget)) { return; } else if (CastSpell(WYVERN_STING,pTarget)) { return; } else if (CastSpell(SCATTER_SHOT,pTarget)) { return; } else if (CastSpell(FREEZING_ARROW,pTarget)) { return; } else if (CastSpell(MISDIRECTION,m_tank)) { return; } else if (m_bot->getRace() == (uint8) RACE_TAUREN && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget) ) { return; } //no gcd but is cast else if (pTarget->GetCreatureType() == (uint32) CREATURE_TYPE_BEAST && CastSpell(SCARE_BEAST,pTarget)) { return; } else if (pDist <= 2 && CastSpell(FREEZING_TRAP,pTarget)) { return; } } #pragma endregion //Select combat mode m_role = BOT_ROLE_DPS_RANGED; if ((isUnderAttack() && pDist <= ATTACK_DISTANCE) || !m_bot->GetUInt32Value(PLAYER_AMMO_ID) ) { m_role = BOT_ROLE_DPS_MELEE; } TakePosition(pTarget); #pragma region Buff / Protect //Buff UP if (m_bot->getRace() == (uint8) RACE_TROLL && CastSpell(R_BERSERKING,m_bot) ) { } //no GCD if (m_bot->getRace() == (uint8) RACE_ORC && CastSpell(R_BLOOD_FURY,m_bot) ) { } //no GCD if (CastSpell(TRUESHOT_AURA, m_bot)) { return; } if (CastSpell(RAPID_FIRE,m_bot)) { return; } if (CastSpell(HUNTERS_MARK,pTarget)) { return; } if ((ai->GetHealthPercent() < 80 || ai->GetManaPercent() < 60 ) && CastSpell(READINESS,m_bot)) { } //no gcd //Protect yourself if needed if (m_bot->getRace() == (uint8) RACE_DWARF && ai->GetHealthPercent() < 75 && CastSpell(R_STONEFORM,m_bot) ) { } //no gcd if (ai->GetHealthPercent() < 20 && CastSpell(DETERRENCE,m_bot)) {} //No GCD if (m_bot->getRace() == (uint8) RACE_DRAENEI && ai->GetHealthPercent() < 55 && CastSpell(R_GIFT_OF_NAARU,m_bot)) { return; } //Break Spells if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && ( pTarget->IsNonMeleeSpellCasted(true) || ai->GetManaPercent() < 20 ) && CastSpell(R_ARCANE_TORRENT, pTarget) ) { } //no gcd if (pTarget->IsNonMeleeSpellCasted(true) && CastSpell(SILENCING_SHOT, pTarget) ) { return; } if (pTarget->IsNonMeleeSpellCasted(true) && CastSpell(SCATTER_SHOT, pTarget) ) { return; } //Catch if (pTarget->HasUnitMovementFlag(UNIT_FLAG_FLEEING)) { if (CastSpell(WING_CLIP,pTarget)) return; if (CastSpell(CONCUSSIVE_SHOT,pTarget)) return; if (CastSpell(SCATTER_SHOT, pTarget) ) { return; } } #pragma endregion //Do combat switch (m_role) { #pragma region BOT_ROLE_DPS_MELEE case BOT_ROLE_DPS_MELEE: if (AUTO_SHOT) { m_bot->InterruptNonMeleeSpells( true, AUTO_SHOT ); } //Stop autoshot if (CastSpell(ASPECT_OF_THE_MONKEY,m_bot)) { return; } //Get Monkey aspect if (m_bot->getRace() == (uint8) RACE_TAUREN && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) { return; } //no gcd but is cast // Threat control if (pThreat < threatThreshold || m_tank->GetGUID() == m_bot->GetGUID() || m_bot->HasAura(MISDIRECTION) ) { } //Continue attack else { if (pet && isUnderAttack(pet) && pet->getVictim() && pet->getVictim()->GetGUID() != pTarget->GetGUID()) //Should be helping pet { m_bot->SetSelection(pet->getVictim()->GetGUID()); return; } else if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) // I am attacking wrong target!! { m_bot->SetSelection(m_tank->getVictim()->GetGUID()); return; } else if (CastSpell(FEIGN_DEATH,m_bot)) { return; } else { return; } // No more threat reducing spells, just slow down } if (CastSpell(RAPTOR_STRIKE,pTarget,true,true)) {} //No gcd if (CastSpell(MONGOOSE_BITE,pTarget,true,true)) { return; } // Cannot be sure if casted or not else if (CastSpell(COUNTERATTACK,pTarget,true,true)) { return; } // Cannot be sure if casted or not if (CastSpell(WING_CLIP,pTarget)) { return; } if (isUnderAttack(m_tank,6) && CastSpell(SNAKE_TRAP,m_bot)) { return; } if (isUnderAttack(m_tank,4) && CastSpell(EXPLOSIVE_TRAP,m_bot)) { return; } if (CastSpell(IMMOLATION_TRAP,m_bot)) { return; } break; #pragma endregion #pragma region BOT_ROLE_DPS_RANGED case BOT_ROLE_DPS_RANGED: if (m_pulling) { if (GetAI()->CastSpell(CONCUSSIVE_SHOT,pTarget) || GetAI()->CastSpell(AUTO_SHOT,pTarget)) { m_pulling = false; GetAI()->SetCombatOrder(ORDERS_NONE); GetAI()->Follow(*GetMaster()); GetAI()->SetIgnoreUpdateTime(2); if(HasPet(GetPlayerBot())) m_bot->GetPet()->SetReactState(REACT_DEFENSIVE); } return; } if (AUTO_SHOT && !m_bot->FindCurrentSpellBySpellId(AUTO_SHOT)) { ai->CastSpell(AUTO_SHOT,pTarget); } //Start autoshot if (!(ai->GetManaPercent() < 85 && m_bot->HasAura(ASPECT_OF_THE_VIPER)) && CastSpell(ASPECT_OF_THE_HAWK,m_bot)) { return; } //Get Hawk aspect if ((ai->GetManaPercent() < 25) && CastSpell(ASPECT_OF_THE_VIPER,m_bot,true,false,true)) { return; } //Build up mana // if i am main tank, protect master by taunt if(m_tank->GetGUID() == m_bot->GetGUID()) { // Taunt if needed (Only for master) Unit *curAtt = GetAttackerOf(GetMaster()); if (curAtt && CastSpell(DISTRACTING_SHOT, curAtt)) { return; } // My target is not attacking me, taunt.. if (pVictim && pVictim->GetGUID() != m_bot->GetGUID() && CastSpell(DISTRACTING_SHOT, pTarget) ) { return; } } // If i am not tank, transfer threat to tank or pet.. else { if (CastSpell(MISDIRECTION,m_tank)) { return; } if (pet && pet->isAlive() && CastSpell(MISDIRECTION,pet)) { return; } // Threat control if (pThreat < threatThreshold || m_bot->HasAura(MISDIRECTION) ) { } //Continue attack else { if (pet && isUnderAttack(pet) && pet->getVictim() && pet->getVictim()->GetGUID() != pTarget->GetGUID()) //Should be helping pet { m_bot->SetSelection(pet->getVictim()->GetGUID()); return; } else if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) // I am attacking wrong target!! { m_bot->SetSelection(m_tank->getVictim()->GetGUID()); return; } else if (CastSpell(FEIGN_DEATH,m_bot)) { return; } else { return; } // No more threat reducing spells, just slow down } } // DO dps if (ai->GetHealthPercent(*pTarget) < 20 && CastSpell(KILL_SHOT,pTarget)) { return; } if (isUnderAttack(m_tank,4) && CastSpell(MULTI_SHOT,pTarget)) { return; } if (isUnderAttack(m_tank,4) && CastSpell(VOLLEY,pTarget)) { GetAI()->SetIgnoreUpdateTime(7); return; } if (CanCast(CHIMERA_SHOT,pTarget) && (pTarget->HasAura(VIPER_STING,m_bot->GetGUID()) || pTarget->HasAura(SERPENT_STING,m_bot->GetGUID()) ) && CastSpell(CHIMERA_SHOT,pTarget,false) ) { return; } if (ai->GetManaPercent() < 60 && ai->GetManaPercent(*pTarget) > 4 && CastSpell(VIPER_STING,pTarget)) { return; } if (!pTarget->HasAura(VIPER_STING,m_bot->GetGUID()) && CastSpell(SERPENT_STING,pTarget)) { return; } if (CastSpell(ARCANE_SHOT,pTarget)) { return; } if (CastSpell(BLACK_ARROW,pTarget)) { return; } if (CastSpell(EXPLOSIVE_SHOT,pTarget)) { return; } if (CastSpell(STEADY_SHOT,pTarget)) { return; } break; #pragma endregion } /*// drink potion if support / healer (Other builds simply overuse mana and waste mana pots) if(ai->GetManaPercent() < 5 && (m_role == BOT_ROLE_SUPPORT || m_role == BOT_ROLE_HEALER) ) { Item *pItem = ai->FindPotion(); if(pItem != NULL) { if (pItem->GetSpell() && m_bot->HasSpellCooldown(pItem->GetSpell()) ) { return; } //pot is in cooldown ai->UseItem(*pItem); } }*/ } // end DoNextCombatManeuver
void PlayerbotPaladinAI::DoNextCombatManeuver(Unit *pTarget) { if (!pTarget || pTarget->isDead()) return; PlayerbotAI *ai = GetAI(); if (!ai) return; Player *m_bot = GetPlayerBot(); if (!m_bot || m_bot->isDead()) return; Unit *pVictim = pTarget->getVictim(); Unit *m_tank = FindMainTankInRaid(GetMaster()); if (!m_tank && m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup()) { FindMainTankInRaid(m_bot); } if (!m_tank) { m_tank = m_bot; } uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth(); float pDist = m_bot->GetDistance(pTarget); uint8 pThreat = GetThreatPercent(pTarget); uint8 reqHeal = 0; uint8 OwnPartyHP = GetHealthPercentRaid(m_bot, reqHeal); // Fill mana if needed if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && ai->GetManaPercent() < 20 && CastSpell(R_ARCANE_TORRENT, pTarget)) { } //no gcd if (ai->GetManaPercent() < 30 && CastSpell (DIVINE_PLEA, m_bot)) { return; } // If hp is too low divine shield if (ai->GetHealthPercent() < 20 && (!m_bot->HasAura(DIVINE_SHIELD) || !m_bot->HasAura(HOP) || !m_bot->HasAura(SACRED_SHIELD))) { if (!m_bot->HasAura(FORBEARANCE)) { if (CastSpell(DIVINE_SHIELD,m_bot)) { return; } if (CastSpell(HOP,m_bot)) { return; } } else if (CastSpell(SACRED_SHIELD,m_bot)) { return; } } // if i am under attack and if i am not tank or offtank: change target if needed if (m_tank->GetGUID() != m_bot->GetGUID() && !TALENT_PROT && isUnderAttack() ) { // Keep hitting but reduce threat if (CastSpell(HOS,m_bot,true,true)) { } //else if (m_bot->getRace() == (uint8) RACE_NIGHTELF && CastSpell(R_SHADOWMELD,m_bot)) { return; } else //I cannot reduce threat so { if (pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist <= 2) { } // My target is almost up to me, no need to search else //Have to select nearest target { Unit *curAtt = GetNearestAttackerOf(m_bot); if (curAtt && curAtt->GetGUID() != pTarget->GetGUID()) { m_bot->SetSelection(curAtt->GetGUID()); //ai->AddLootGUID(curAtt->GetGUID()); DoNextCombatManeuver(curAtt); //Restart new update to get variables fixed.. return; } } //my target is attacking me } } #pragma region Choose Actions // Choose actions accoring to talents if (m_tank->GetGUID() == m_bot->GetGUID()) // Hey! I am Main Tank { if (TALENT_PROT) { m_role=BOT_ROLE_TANK; } //Just Keep Tanking else { if (TALENT_RETRI) { if ((ai->GetHealthPercent() <= 40 || masterHP <40 ) && (ai->GetManaPercent() >= 40)) { m_role = BOT_ROLE_SUPPORT; } else if (OwnPartyHP < 40 && ai->GetManaPercent() >= 30) { m_role = BOT_ROLE_SUPPORT; } else { m_role = BOT_ROLE_TANK; } //have no shield but can tank if you think so } else if (TALENT_HOLY) //I am both healer and tank?? Hmm { if ((ai->GetHealthPercent() <= 70 || masterHP <70 ) && (ai->GetManaPercent() >= 50))m_role = BOT_ROLE_SUPPORT; else if (OwnPartyHP < 20 && ai->GetManaPercent() >= 30) { m_role = BOT_ROLE_SUPPORT; } else m_role = BOT_ROLE_TANK; } else { m_role = BOT_ROLE_TANK; } //Unknown build or low level } } else if (TALENT_RETRI) { if ((ai->GetHealthPercent() <= 40 || masterHP <40 ) && (ai->GetManaPercent() >= 40)) { m_role = BOT_ROLE_SUPPORT; } else if (OwnPartyHP < 40 && ai->GetManaPercent() >= 30) {m_role = BOT_ROLE_SUPPORT;} else { m_role = BOT_ROLE_DPS_MELEE; } } else if (TALENT_PROT) { if ((ai->GetHealthPercent() <= 30 || masterHP <40 ) && (ai->GetManaPercent() >= 20)) { m_role = BOT_ROLE_SUPPORT; } else if (OwnPartyHP < 40 && ai->GetManaPercent() >= 40) { m_role = BOT_ROLE_SUPPORT; } else { m_role = BOT_ROLE_OFFTANK; } } else if (TALENT_HOLY) { m_role = BOT_ROLE_SUPPORT; } else { m_role = BOT_ROLE_DPS_MELEE; } //Unknown build or low level.. Mainly attack //takepos if (m_role == BOT_ROLE_SUPPORT || m_role == BOT_ROLE_HEALER) TakePosition(pTarget,BOT_ROLE_DPS_MELEE,0.5f); else TakePosition(pTarget,m_role); // If there's a cast stop if(m_bot->HasUnitState(UNIT_STATE_CASTING)) return; Unit *target = DoSelectLowestHpFriendly(40, 1000); switch(m_role) { #pragma region BOT_ROLE_SUPPORT case BOT_ROLE_SUPPORT: ChangeAura(CONCENTRATION_AURA); if (!TALENT_PROT && m_tank->GetGUID() != m_bot->GetGUID()) m_bot->RemoveAurasDueToSpell(RIGHTEOUS_FURY); // Choose Seal if (SOW && ai->GetManaPercent() <= 30) { if (CastSpell(SOW,m_bot)) { return; } } else if (m_bot->HasAura(SOW) && ai->GetManaPercent() < 85) { } // Paladin was striving for mana, keep until he got most of his mana back else if(SOL && ai->GetHealthPercent() < 40) { if(CastSpell(SOL,m_bot)) { return; } } else if(CastSpell(SOR, m_bot)) { return; } if (!m_bot->HasAura(FORBEARANCE) && CastSpell(AVENGING_WRATH,m_bot)) { } // no gcd if (DoSupportRaid(m_bot)) { return; } //heal pets and bots if(target && target->isAlive() && HealTarget(target, target->GetHealth()*100 / target->GetMaxHealth()) ) { return; } if (ai->GetManaPercent() <= 80 && CastSpell(JOW,pTarget,true,true)) { return; } // Use Spells only if mana is sufficient.. if(ai->GetManaPercent() < offensiveSpellThreshold ) return; break; #pragma endregion #pragma region BOT_ROLE_TANK / BOT_ROLE_OFFTANK case BOT_ROLE_TANK: case BOT_ROLE_OFFTANK: ChangeAura(DEVOTION_AURA); if (CastSpell(RIGHTEOUS_FURY,m_bot)) { return; } // Choose Seal if (SOW && ai->GetManaPercent() <= 30) { if (CastSpell(SOW,m_bot)) { return; } } else if (m_bot->HasAura(SOW) && ai->GetManaPercent() < 85) { } // Paladin was striving for mana, keep until he got most of his mana back else if (SOL && ai->GetHealthPercent() < 40) { if (CastSpell(SOL,m_bot)) { return; } } else if (CastSpell(SOR,m_bot)) { return; } // We are tank/offtank threat is not an issiue; // Use taunts only if helping target is not main tank.. // Taunt if needed (Only for master) if(GetMaster()->GetGUID() != m_tank->GetGUID()) { // Taunt if needed (Only for master) Unit *curAtt = GetAttackerOf(GetMaster()); if (curAtt) { if (isUnderAttack(GetMaster(),2) && CastSpell(RIGHTEOUS_DEFENSE, GetMaster())) { return; } if (CastSpell(HOR, curAtt,true,true)) { } //No GCD } } // My target is not attacking me, taunt.. if ( m_tank->GetGUID() == m_bot->GetGUID() && pVictim && pVictim->GetGUID() != m_bot->GetGUID() && CastSpell(HOR, pTarget,true,true) ) { } //NO GCD // Tank specials if (TALENT_PROT && ai->GetManaPercent() < 90 && CastSpell (DIVINE_PLEA, m_bot)) { return; } //Prot paladin always uses this.. if (pVictim && pVictim->GetGUID() == m_bot->GetGUID() && CastSpell(HOLY_SHIELD,m_bot)) { return; } if (CastSpell(AVENGERS_SHIELD,pTarget,true,true)) { return; } if (CastSpell(HOTR,pTarget,true,true)) { return; } if (CastSpell(HOLY_WRATH,pTarget,true,true)){ return; } if (CastSpell(CONSECRATION,pTarget)) { return; } if (m_bot->getRace() == (uint8) RACE_DWARF && CastSpell(R_STONEFORM,m_bot)) { return; } if (DoSupportRaid(m_bot)) { return; } //heal pets and bots if(target && target->isAlive() && HealTarget(target, target->GetHealth()*100 / target->GetMaxHealth()) ) { return; } break; #pragma endregion #pragma region BOT_ROLE_DPS_MELEE case BOT_ROLE_DPS_MELEE: ChangeAura(RETRIBUTION_AURA); if (!TALENT_PROT && m_tank->GetGUID() != m_bot->GetGUID()) m_bot->RemoveAurasDueToSpell(RIGHTEOUS_FURY); if (CastSpell(SOV,m_bot)) { return; } if (CastSpell (HAMMER_OF_JUSTICE, pTarget)) { return; } if (!m_bot->HasAura(FORBEARANCE) && CastSpell(AVENGING_WRATH,m_bot)) {} //no gcd if (CastSpell(JOW,pTarget)) { return; } if (CastSpell(DIVINE_STORM, pTarget)) { return; } if (CastSpell(CRUSADER_STRIKE, pTarget)) { return; } if (GetAI()->GetHealthPercent(*pTarget)<20 && CastSpell(HAMMER_OF_WRATH, pTarget)) { return; } if (CastSpell(CONSECRATION,pTarget)) { return; } if (m_bot->HasAura(AOW) && CastSpell(EXORCISM,pTarget)) { return; } if (CastSpell(HOLY_WRATH,pTarget)) { return; } break; #pragma endregion } #pragma region PaladinCommon // Shared dps spells if (pTarget->GetCreatureType() == (uint32) CREATURE_TYPE_HUMANOID && pTarget->IsNonMeleeSpellCasted(true) && CastSpell (REPENTANCE, pTarget)) { return; } if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && pTarget->IsNonMeleeSpellCasted(true) && CastSpell(R_ARCANE_TORRENT, pTarget)) { } //no gcd if (m_bot->getRace() == (uint8) RACE_TROLL && CastSpell(R_BERSERKING,m_bot)) {} // no GCD if (m_bot->getRace() == (uint8) RACE_ORC && CastSpell(R_BLOOD_FURY,m_bot)) {} // no GCD // If at threat limit, stop if(pThreat > threatThreshold && !TALENT_PROT && m_tank->GetGUID() != m_bot->GetGUID() && !isUnderAttack()) { if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) // I am attacking wrong target!! { m_bot->SetSelection(m_tank->getVictim()->GetGUID()); return; } else { if (CastSpell(HOS,m_bot)) { return; } //Lets see if we can manage with HOS else { return; } //use no spells and wait threat to be reduced } } // Continue attacking if theres excess mana (for healers) if (m_role == BOT_ROLE_SUPPORT && ai->GetManaPercent() < offensiveSpellThreshold) { return; } if (GetAI()->GetHealthPercent(*pTarget)<20 && CastSpell(HAMMER_OF_WRATH, pTarget,true,true)) { return; } //no gcd but cast if (CastSpell (HAMMER_OF_JUSTICE, pTarget)) { return; } if (CanCast(JOW,pTarget,true) && ( ( ai->GetManaPercent() <= 70 && ai->GetHealthPercent() > 90) || ( ai->GetManaPercent() <= 50 && ai->GetHealthPercent() > 75) || ( ai->GetManaPercent() <= 20 && ai->GetHealthPercent() > 20) ) && CastSpell(JOW,pTarget,false)) { return; } else if (CastSpell(JOL,pTarget),true,true) { return; } if (CastSpell(SHIELD_OF_RIGHTEOUSNESS,pTarget,true,true)) { return; } if (CastSpell (DIVINE_STORM, pTarget,true,true)) { return; } if (CastSpell (CRUSADER_STRIKE, pTarget,true,true)) { return; } if (m_bot->getRace() == (uint8) RACE_TAUREN && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) { return; } //no GCD but cast if (isUnderAttack(m_tank,4) && CastSpell(HOLY_WRATH,pTarget,true,true)) { return; } if (isUnderAttack(m_tank,4) && CastSpell(CONSECRATION,pTarget)) { return; } if (CastSpell(HOLY_SHOCK,pTarget,true,true)) { return; } if (m_role != BOT_ROLE_SUPPORT && ai->GetManaPercent() > 60 && OwnPartyHP < 65 && DoSupportRaid(m_bot)) { return; } //if there is spare time and mana, do healz and other stuff.. else if (m_role != BOT_ROLE_SUPPORT && ai->GetManaPercent() > 30 && DoSupportRaid(m_bot,30,false,false,false,true,false)) { return; } if (CastSpell(EXORCISM,pTarget,true,true)) { return; } // drink potion if support / healer (Other builds simply overuse mana and waste mana pots) if(ai->GetManaPercent() < 5 && (m_role == BOT_ROLE_SUPPORT || m_role == BOT_ROLE_HEALER) ) { Item *pItem = ai->FindPotion(); if(pItem != NULL) { if (pItem->GetSpell() && m_bot->HasSpellCooldown(pItem->GetSpell()) ) { return; } //pot is in cooldown ai->UseItem(*pItem); } } #pragma endregion } //end DoNextCombatManeuver
bool PlayerbotPaladinAI::BuffPlayer(Unit *target) { if(!target || target->isDead()) return false; Player *m_bot = GetPlayerBot(); // Check if target already has a blessing by me.. if (HasAuraName(target,BOW,m_bot->GetGUID()) || HasAuraName(target,BOK,m_bot->GetGUID()) || HasAuraName(target,BOM,m_bot->GetGUID()) || HasAuraName(target,BOS,m_bot->GetGUID()) || HasAuraName(target,GBOW,m_bot->GetGUID()) || HasAuraName(target,GBOK,m_bot->GetGUID()) || HasAuraName(target,GBOM,m_bot->GetGUID()) || HasAuraName(target,GBOS,m_bot->GetGUID()) ) return false; #pragma region Choose Buff > Class switch(target->getClass()) { case CLASS_MAGE: case CLASS_WARLOCK: if (CanCast(GBOW,target) && !HasAuraName(target,BOW) && !HasAuraName(target,GBOW) ) return CastSpell(GBOW,target,false); else if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false); else if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false); break; case CLASS_PRIEST: if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false); else if (CanCast(GBOW,target) && !HasAuraName(target,BOW) && !HasAuraName(target,GBOW) ) return CastSpell(GBOW,target,false); else if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false); break; case CLASS_HUNTER: if (CanCast(GBOM,target) && !HasAuraName(target,BOM) && !HasAuraName(target,GBOM) ) return CastSpell(GBOM,target,false); else if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false); else if (CanCast(GBOW,target) && !HasAuraName(target,BOW) && !HasAuraName(target,GBOW) ) return CastSpell(GBOW,target,false); else if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false); break; case CLASS_ROGUE: if (CanCast(GBOM,target) && !HasAuraName(target,BOM) && !HasAuraName(target,GBOM) ) return CastSpell(GBOM,target,false); else if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false); else if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false); break; case CLASS_WARRIOR: case CLASS_DEATH_KNIGHT: if (target->GetUnitDodgeChance() + target->GetUnitParryChance() > 40) { if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false); else if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false); else if (CanCast(GBOM,target) && !HasAuraName(target,BOM) && !HasAuraName(target,GBOM) ) return CastSpell(GBOM,target,false); } else { if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false); else if (CanCast(GBOM,target) && !HasAuraName(target,BOM) && !HasAuraName(target,GBOM) ) return CastSpell(GBOM,target,false); else if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false); } break; case CLASS_DRUID: case CLASS_SHAMAN: case CLASS_PALADIN: if (target->GetMaxPower(target->getPowerType()) > target->GetMaxHealth()) { if (CanCast(GBOW,target) && !HasAuraName(target,BOW) && !HasAuraName(target,GBOW) ) return CastSpell(GBOW,target,false); else if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false); else if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false); else if (CanCast(GBOM,target) && !HasAuraName(target,BOM) && !HasAuraName(target,GBOM) ) return CastSpell(GBOM,target,false); } else if (target->GetUnitDodgeChance() + target->GetUnitParryChance() > 40) { if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false); else if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false); else if (CanCast(GBOM,target) && !HasAuraName(target,BOM) && !HasAuraName(target,GBOM) ) return CastSpell(GBOM,target,false); else if (CanCast(GBOW,target) && !HasAuraName(target,BOW) && !HasAuraName(target,GBOW) ) return CastSpell(GBOW,target,false); } else { if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false); else if (CanCast(GBOM,target) && !HasAuraName(target,BOM) && !HasAuraName(target,GBOM) ) return CastSpell(GBOM,target,false); else if (CanCast(GBOW,target) && !HasAuraName(target,BOW) && !HasAuraName(target,GBOW) ) return CastSpell(GBOW,target,false); else if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false); } break; default: if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false); else if (CanCast(GBOM,target) && !HasAuraName(target,BOM) && !HasAuraName(target,GBOM) ) return CastSpell(GBOM,target,false); else if (CanCast(GBOW,target) && !HasAuraName(target,BOW) && !HasAuraName(target,GBOW) ) return CastSpell(GBOW,target,false); else if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false); break; } #pragma endregion return false; }
void PlayerbotShamanAI::DoNextCombatManeuver(Unit *pTarget) { if (!pTarget || pTarget->isDead()) return; PlayerbotAI *ai = GetAI(); if (!ai) return; Player *m_bot = GetPlayerBot(); if (!m_bot || m_bot->isDead()) return; Unit *pVictim = pTarget->getVictim(); Unit *m_tank = FindMainTankInRaid(GetMaster()); if (!m_tank && m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup()) { FindMainTankInRaid(m_bot); } if (!m_tank) { m_tank = m_bot; } uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth(); float pDist = m_bot->GetDistance(pTarget); uint8 pThreat = GetThreatPercent(pTarget); uint8 reqHeal = 0; uint8 OwnPartyHP = GetHealthPercentRaid(m_bot, reqHeal); switch(ai->GetScenarioType()) { case SCENARIO_DUEL: ((ai->GetHealthPercent() < 80 && CastSpell(LESSER_HEAL)) || CastSpell(LIGHTNING_BOLT, pTarget)); return; } // Cast CC breakers if any match found (include any dispels first) does not work yet //uint32 ccSpells[4] = { R_ESCAPE_ARTIST, R_EVERY_MAN_FOR_HIMSELF, R_WILL_OF_FORSAKEN, R_STONEFORM }; //if (ai->GetManaPercent() < 35) { ccSpells[0] = 0; ccSpells[1] = 0; } //We dont have any mana to waste... //if (castSelfCCBreakers(ccSpells)) { } // Most of them don't trigger gcd #pragma region Choose Actions // Choose actions accoring to talents if (m_tank->GetGUID() == m_bot->GetGUID()) { m_role=BOT_ROLE_TANK; } // Hey! I am Main Tank else if (TALENT_ENHANCEMENT) { m_role = BOT_ROLE_DPS_MELEE; } else if (TALENT_ELEMENTAL) { m_role = BOT_ROLE_DPS_RANGED; } else if (TALENT_RESTO) { m_role = BOT_ROLE_SUPPORT; } else { m_role = BOT_ROLE_DPS_MELEE; } //Unknown build or low level.. Mainly attack // if i am under attack and if i am not tank or offtank: change target if needed if (m_tank->GetGUID() != m_bot->GetGUID() && isUnderAttack() ) { if (pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist <= 2) { } // My target is almost up to me, no need to search else //Have to select nearest target { Unit *curAtt = GetNearestAttackerOf(m_bot); if (curAtt && curAtt->GetGUID() != pTarget->GetGUID()) { m_bot->SetSelection(curAtt->GetGUID()); //ai->AddLootGUID(curAtt->GetGUID()); DoNextCombatManeuver(curAtt); //Restart new update to get variables fixed.. return; } } //my target is attacking me } #pragma endregion // Choose Weapon Enchant if (ChangeWeaponEnchants()) return; if (TALENT_ELEMENTAL){ if (!m_bot->HasAura(WATER_SHIELD) && CastSpell(WATER_SHIELD,m_bot)) { return; }} if (TALENT_ENHANCEMENT){ if (!m_bot->HasAura(LIGHTNING_SHIELD) && CastSpell(LIGHTNING_SHIELD,m_bot)) { return; }} if (TALENT_RESTO){ if (!m_bot->HasAura(WATER_SHIELD) && CastSpell(WATER_SHIELD,m_bot)) { return; }} // Choose shield /* if (EARTH_SHIELD && ai->GetHealthPercent() < 80 && isUnderAttack()) { if (CastSpell(EARTH_SHIELD,m_bot)) { return; } } else if (WATER_SHIELD && ai->GetManaPercent() < 40) { if (CastSpell(WATER_SHIELD,m_bot)) { return; } } else if (LIGHTNING_SHIELD && ( isUnderAttack() || m_tank->GetGUID() == m_bot->GetGUID() ) && !(m_bot->HasAura(WATER_SHIELD) && ai->GetManaPercent() < 80) ) { if (CastSpell(LIGHTNING_SHIELD,m_bot)) { return; } } else if (CastSpell(WATER_SHIELD,m_bot)) { return; } */ // If there's a cast stop if(m_bot->HasUnitState(UNIT_STAT_CASTING)) return; switch(m_role) { #pragma region BOT_ROLE_TANK / BOT_ROLE_OFFTANK case BOT_ROLE_TANK: case BOT_ROLE_OFFTANK: if (!TALENT_ELEMENTAL && !TALENT_RESTO) { TakePosition(pTarget); } else { TakePosition(pTarget,BOT_ROLE_DPS_RANGED); } // mob will come to you sooner or later no need to hurry // Do support stuff if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; } if (ai->GetManaPercent() > 70 && DoSupportRaid(m_bot)) { return; } break; #pragma endregion #pragma region BOT_ROLE_DPS_MELEE case BOT_ROLE_DPS_MELEE: TakePosition(pTarget); // Do support stuff if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; } if (ai->GetManaPercent() > 40 && DoSupportRaid(m_bot)) { return; } break; #pragma endregion #pragma region BOT_ROLE_DPS_RANGED case BOT_ROLE_DPS_RANGED: TakePosition(pTarget); // Do support stuff if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; } if (ai->GetManaPercent() > 40 && DoSupportRaid(m_bot)) { return; } break; #pragma endregion #pragma region BOT_ROLE_SUPPORT case BOT_ROLE_SUPPORT: TakePosition(pTarget); // Do support stuff if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; } if (DoSupportRaid(m_bot)) { return; } //heal pets and bots Unit *target = DoSelectLowestHpFriendly(40, 1000); if(target && target->isAlive() && HealTarget(target, target->GetHealth()*100 / target->GetMaxHealth()) ) { return; } break; #pragma endregion } #pragma region ShamanCommon //Defensive Stuff if (m_tank->GetGUID() != m_bot->GetGUID() && pVictim && pVictim->GetGUID() == m_bot->GetGUID() ) { if (pDist > 5 && CastSpell(FROST_SHOCK, pTarget)) { return; } if ((pTarget->GetCreatureType() == (uint32) CREATURE_TYPE_BEAST || pTarget->GetCreatureType() == (uint32) CREATURE_TYPE_HUMANOID) && CastSpell(HEX, pTarget)) { return; } // no gcd if (CastSpell(WIND_SHEAR, pTarget)) { } // no gcd } if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && pTarget->IsNonMeleeSpellCasted(true) && CastSpell(R_ARCANE_TORRENT, pTarget)) { } //no gcd if (pTarget->IsNonMeleeSpellCasted(true) && CastSpell(WIND_SHEAR, pTarget)) { } //no gcd if (m_bot->getRace() == (uint8) RACE_TAUREN && pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) { return; } //Catch if (pTarget->HasUnitMovementFlag(UNIT_FLAG_FLEEING)) { if (CastSpell(FROST_SHOCK,pTarget)) return; } //Buff and restores if ( ( (ai->GetHealthPercent() < 60 && isUnderAttack()) || (ai->GetManaPercent() < 30) ) && CastSpell(SHAMANISTIC_RAGE, m_bot)) { return; } if (m_bot->getRace() == (uint8) RACE_TROLL && CastSpell(R_BERSERKING,m_bot)) {} // no GCD if (m_bot->getRace() == (uint8) RACE_ORC && CastSpell(R_BLOOD_FURY,m_bot)) {} // no GCD if (!m_bot->HasAura(HEROISM) && !m_bot->HasAura(EXHAUSTION) && !m_bot->HasAura(SATED) && CastSpell(HEROISM,m_bot)) { return; } if (m_role != BOT_ROLE_SUPPORT && CastSpell(NATURES_SWIFTNESS, m_bot)) { } //healers keep it for healing no gcd else if (CastSpell(ELEMENTAL_MASTERY, m_bot)) { } //no gcd // If at threat limit, use WIND_SHEAR to reduce threat if (pThreat > threatThreshold && m_tank->GetGUID() != m_bot->GetGUID() && !isUnderAttack()) { if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) // I am attacking wrong target!! { m_bot->SetSelection(m_tank->getVictim()->GetGUID()); return; } else { if (CastSpell(WIND_SHEAR,pTarget)) { return; } //Lets see if we can manage else { return; } //use no spells and wait threat to be reduced } } if (TALENT_ELEMENTAL) { if (CastSpell(ELEMENTAL_MASTERY, m_bot)) { } //no gcd if (!pTarget->HasAura(FLAME_SHOCK,m_bot->GetGUID()) && CastSpell(FLAME_SHOCK,pTarget)) { return; } if (CastSpell(LAVA_BURST,pTarget)) { return; } if (CastSpell(CHAIN_LIGHTNING,pTarget)) { return; } if (CastSpell(LIGHTNING_BOLT,pTarget)) { return; } } //dps if (MAELSTROM_WEAPON) { Aura *maelaura = m_bot->GetAura(MAELSTROM_WEAPON); if (maelaura && maelaura->GetStackAmount() == 5) { if ((isUnderAttack(m_tank,3) || m_tank->GetGUID() == m_bot->GetGUID()) && CastSpell(CHAIN_LIGHTNING,pTarget,true,true)) { return; } if (CastSpell(LIGHTNING_BOLT,pTarget,true,true)) { return; } } } if (CastSpell(FLAME_SHOCK,pTarget)) { return; } if (CastSpell(STORMSTRIKE,pTarget,true,true)) { return; } //if (!TALENT_ENHANCEMENT && CanCast(LAVA_BURST,pTarget,true) && pTarget->HasAura(FLAME_SHOCK,m_bot->GetGUID()) && CastSpell(LAVA_BURST,pTarget,false)) { return; } if (CastSpell(FERAL_SPIRIT,m_bot)) { return; } if (CanCast(EARTH_SHOCK,pTarget,true) && (pTarget->HasAura(STORMSTRIKE,m_bot->GetGUID()) || pTarget->HasAura(FLAME_SHOCK,m_bot->GetGUID()) ) && CastSpell(EARTH_SHOCK,pTarget)) { return; } //if (CanCast(FLAME_SHOCK,pTarget) && CastSpell(FLAME_SHOCK,pTarget)) { return; } if (CastSpell(LAVA_LASH,pTarget,true,true)) { return; } if (CastSpell(FIRE_NOVA,pTarget)) { return; } //if ((isUnderAttack(m_tank,4) || m_tank->GetGUID() == m_bot->GetGUID()) && CastSpell(FIRE_NOVA,pTarget)) { return; } if (ai->GetManaPercent() > 60 && castDispel(PURGE,pTarget)) { return; } //PURGE but dont overpurge #pragma endregion // drink potion if support / healer (Other builds simply overuse mana and waste mana pots) if(ai->GetManaPercent() < 5 && (m_role == BOT_ROLE_SUPPORT || m_role == BOT_ROLE_HEALER) ) { Item *pItem = ai->FindPotion(); if(pItem != NULL) { if (pItem->GetSpell() && m_bot->HasSpellCooldown(pItem->GetSpell()) ) { return; } //pot is in cooldown ai->UseItem(*pItem); } } } //end DoNextCombatManeuver
void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 rnd, uint32 eventId, Unit* actionInvoker) { switch (action.type) { case ACTION_T_TEXT: { if (!action.text.TextId1) return; int32 temp = action.text.TextId1; if (action.text.TextId2 && action.text.TextId3) temp = RAND(action.text.TextId1, action.text.TextId2, action.text.TextId3); else if (action.text.TextId2 && urand(0, 1)) temp = action.text.TextId2; if (temp) { Unit* target = NULL; if (actionInvoker) { if (actionInvoker->GetTypeId() == TYPEID_PLAYER) target = actionInvoker; else if (Unit* owner = actionInvoker->GetOwner()) { if (owner->GetTypeId() == TYPEID_PLAYER) target = owner; } } else { target = me->getVictim(); if (target && target->GetTypeId() != TYPEID_PLAYER) if (Unit* owner = target->GetOwner()) if (owner->GetTypeId() == TYPEID_PLAYER) target = owner; } DoScriptText(temp, me, target); } break; } case ACTION_T_SET_FACTION: { if (action.set_faction.factionId) me->setFaction(action.set_faction.factionId); else { if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(me->GetEntry())) { //if no id provided, assume reset and then use default if (me->getFaction() != ci->faction_A) me->setFaction(ci->faction_A); } } break; } case ACTION_T_MORPH_TO_ENTRY_OR_MODEL: { if (action.morph.creatureId || action.morph.modelId) { //set model based on entry from creature_template if (action.morph.creatureId) { if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(action.morph.creatureId)) { uint32 display_id = sObjectMgr->ChooseDisplayId(0, ci); me->SetDisplayId(display_id); } } //if no param1, then use value from param2 (modelId) else me->SetDisplayId(action.morph.modelId); } else me->DeMorph(); break; } case ACTION_T_SOUND: me->PlayDirectSound(action.sound.soundId); break; case ACTION_T_EMOTE: me->HandleEmoteCommand(action.emote.emoteId); break; case ACTION_T_RANDOM_SOUND: { int32 temp = GetRandActionParam(rnd, action.random_sound.soundId1, action.random_sound.soundId2, action.random_sound.soundId3); if (temp >= 0) me->PlayDirectSound(temp); break; } case ACTION_T_RANDOM_EMOTE: { int32 temp = GetRandActionParam(rnd, action.random_emote.emoteId1, action.random_emote.emoteId2, action.random_emote.emoteId3); if (temp >= 0) me->HandleEmoteCommand(temp); break; } case ACTION_T_CAST: { Unit* target = GetTargetByType(action.cast.target, actionInvoker); Unit* caster = me; if (!target) return; if (action.cast.castFlags & CAST_FORCE_TARGET_SELF) caster = target; //Allowed to cast only if not casting (unless we interrupt ourself) or if spell is triggered bool canCast = !caster->IsNonMeleeSpellCasted(false) || (action.cast.castFlags & (CAST_TRIGGERED | CAST_INTERRUPT_PREVIOUS)); // If cast flag CAST_AURA_NOT_PRESENT is active, check if target already has aura on them if (action.cast.castFlags & CAST_AURA_NOT_PRESENT) { if (target->HasAura(action.cast.spellId)) return; } if (canCast) { const SpellInfo* tSpell = sSpellMgr->GetSpellInfo(action.cast.spellId); //Verify that spell exists if (tSpell) { //Check if cannot cast spell if (!(action.cast.castFlags & (CAST_FORCE_TARGET_SELF | CAST_FORCE_CAST)) && !CanCast(target, tSpell, (action.cast.castFlags & CAST_TRIGGERED))) { //Melee current victim if flag not set if (!(action.cast.castFlags & CAST_NO_MELEE_IF_OOM)) { if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE) { m_AttackDistance = 0.0f; m_AttackAngle = 0.0f; me->GetMotionMaster()->MoveChase(me->getVictim(), m_AttackDistance, m_AttackAngle); } } } else { //Interrupt any previous spell if (caster->IsNonMeleeSpellCasted(false) && action.cast.castFlags & CAST_INTERRUPT_PREVIOUS) caster->InterruptNonMeleeSpells(false); caster->CastSpell(target, action.cast.spellId, (action.cast.castFlags & CAST_TRIGGERED)); } } else sLog->outErrorDb("CreatureEventAI: event %d creature %d attempt to cast spell that doesn't exist %d", eventId, me->GetEntry(), action.cast.spellId); } break; } case ACTION_T_SUMMON: { Unit* target = GetTargetByType(action.summon.target, actionInvoker); Creature* creature = NULL; if (action.summon.duration) creature = me->SummonCreature(action.summon.creatureId, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, action.summon.duration); else creature = me->SummonCreature(action.summon.creatureId, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0); if (!creature) sLog->outErrorDb("CreatureEventAI: failed to spawn creature %u. Spawn event %d is on creature %d", action.summon.creatureId, eventId, me->GetEntry()); else if (action.summon.target != TARGET_T_SELF && target) creature->AI()->AttackStart(target); break; } case ACTION_T_THREAT_SINGLE_PCT: if (Unit* target = GetTargetByType(action.threat_single_pct.target, actionInvoker)) me->getThreatManager().modifyThreatPercent(target, action.threat_single_pct.percent); break; case ACTION_T_THREAT_ALL_PCT: { std::list<HostileReference*>& threatList = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::iterator i = threatList.begin(); i != threatList.end(); ++i) if (Unit* Temp = Unit::GetUnit(*me, (*i)->getUnitGuid())) me->getThreatManager().modifyThreatPercent(Temp, action.threat_all_pct.percent); break; } case ACTION_T_QUEST_EVENT: if (Unit* target = GetTargetByType(action.quest_event.target, actionInvoker)) if (target->GetTypeId() == TYPEID_PLAYER) target->ToPlayer()->AreaExploredOrEventHappens(action.quest_event.questId); break; case ACTION_T_CAST_EVENT: if (Unit* target = GetTargetByType(action.cast_event.target, actionInvoker)) if (target->GetTypeId() == TYPEID_PLAYER) target->ToPlayer()->CastedCreatureOrGO(action.cast_event.creatureId, me->GetGUID(), action.cast_event.spellId); break; case ACTION_T_SET_UNIT_FIELD: { Unit* target = GetTargetByType(action.set_unit_field.target, actionInvoker); // not allow modify important for integrity object fields if (action.set_unit_field.field < OBJECT_END || action.set_unit_field.field >= UNIT_END) return; if (target) target->SetUInt32Value(action.set_unit_field.field, action.set_unit_field.value); break; } case ACTION_T_SET_UNIT_FLAG: if (Unit* target = GetTargetByType(action.unit_flag.target, actionInvoker)) target->SetFlag(UNIT_FIELD_FLAGS, action.unit_flag.value); break; case ACTION_T_REMOVE_UNIT_FLAG: if (Unit* target = GetTargetByType(action.unit_flag.target, actionInvoker)) target->RemoveFlag(UNIT_FIELD_FLAGS, action.unit_flag.value); break; case ACTION_T_AUTO_ATTACK: m_MeleeEnabled = action.auto_attack.state != 0; break; case ACTION_T_COMBAT_MOVEMENT: // ignore no affect case if (m_CombatMovementEnabled == (action.combat_movement.state != 0)) return; m_CombatMovementEnabled = action.combat_movement.state != 0; //Allow movement (create new targeted movement gen only if idle) if (m_CombatMovementEnabled) { Unit* victim = me->getVictim(); if (me->isInCombat() && victim) { if (action.combat_movement.melee) { me->AddUnitState(UNIT_STATE_MELEE_ATTACKING); me->SendMeleeAttackStart(victim); } if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == IDLE_MOTION_TYPE) me->GetMotionMaster()->MoveChase(victim, m_AttackDistance, m_AttackAngle); // Targeted movement generator will start melee automatically, no need to send it explicitly } } else { if (me->isInCombat()) { Unit* victim = me->getVictim(); if (action.combat_movement.melee && victim) { me->ClearUnitState(UNIT_STATE_MELEE_ATTACKING); me->SendMeleeAttackStop(victim); } if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE) me->GetMotionMaster()->MoveIdle(); } } break; case ACTION_T_SET_PHASE: m_Phase = action.set_phase.phase; break; case ACTION_T_INC_PHASE: { int32 new_phase = int32(m_Phase)+action.set_inc_phase.step; if (new_phase < 0) { sLog->outErrorDb("CreatureEventAI: Event %d decrease m_Phase under 0. CreatureEntry = %d", eventId, me->GetEntry()); m_Phase = 0; } else if (new_phase >= MAX_PHASE) { sLog->outErrorDb("CreatureEventAI: Event %d incremented m_Phase above %u. m_Phase mask cannot be used with phases past %u. CreatureEntry = %d", eventId, MAX_PHASE-1, MAX_PHASE-1, me->GetEntry()); m_Phase = MAX_PHASE-1; } else m_Phase = new_phase; break; } case ACTION_T_EVADE: EnterEvadeMode(); break; case ACTION_T_FLEE_FOR_ASSIST: me->DoFleeToGetAssistance(); break; case ACTION_T_QUEST_EVENT_ALL: if (actionInvoker && actionInvoker->GetTypeId() == TYPEID_PLAYER) { if (Unit* Temp = Unit::GetUnit(*me, actionInvoker->GetGUID())) if (Temp->GetTypeId() == TYPEID_PLAYER) Temp->ToPlayer()->GroupEventHappens(action.quest_event_all.questId, me); } break; case ACTION_T_CAST_EVENT_ALL: { std::list<HostileReference*>& threatList = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::iterator i = threatList.begin(); i != threatList.end(); ++i) if (Unit* Temp = Unit::GetUnit(*me, (*i)->getUnitGuid())) if (Temp->GetTypeId() == TYPEID_PLAYER) Temp->ToPlayer()->CastedCreatureOrGO(action.cast_event_all.creatureId, me->GetGUID(), action.cast_event_all.spellId); break; } case ACTION_T_REMOVEAURASFROMSPELL: if (Unit* target = GetTargetByType(action.remove_aura.target, actionInvoker)) target->RemoveAurasDueToSpell(action.remove_aura.spellId); break; case ACTION_T_RANGED_MOVEMENT: m_AttackDistance = (float)action.ranged_movement.distance; m_AttackAngle = action.ranged_movement.angle/180.0f*M_PI; if (m_CombatMovementEnabled) { me->GetMotionMaster()->MoveChase(me->getVictim(), m_AttackDistance, m_AttackAngle); } break; case ACTION_T_RANDOM_PHASE: m_Phase = GetRandActionParam(rnd, action.random_phase.phase1, action.random_phase.phase2, action.random_phase.phase3); break; case ACTION_T_RANDOM_PHASE_RANGE: if (action.random_phase_range.phaseMin <= action.random_phase_range.phaseMax) m_Phase = urand(action.random_phase_range.phaseMin, action.random_phase_range.phaseMax); else sLog->outErrorDb("CreatureEventAI: ACTION_T_RANDOM_PHASE_RANGE cannot have Param2 < Param1. Event = %d. CreatureEntry = %d", eventId, me->GetEntry()); break; case ACTION_T_SUMMON_ID: { Unit* target = GetTargetByType(action.summon_id.target, actionInvoker); CreatureEventAI_Summon_Map::const_iterator i = sEventAIMgr->GetCreatureEventAISummonMap().find(action.summon_id.spawnId); if (i == sEventAIMgr->GetCreatureEventAISummonMap().end()) { sLog->outErrorDb("CreatureEventAI: failed to spawn creature %u. Summon map index %u does not exist. EventID %d. CreatureID %d", action.summon_id.creatureId, action.summon_id.spawnId, eventId, me->GetEntry()); return; } Creature* creature = NULL; if ((*i).second.SpawnTimeSecs) creature = me->SummonCreature(action.summon_id.creatureId, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, (*i).second.SpawnTimeSecs); else creature = me->SummonCreature(action.summon_id.creatureId, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0); if (!creature) sLog->outErrorDb("CreatureEventAI: failed to spawn creature %u. EventId %d.Creature %d", action.summon_id.creatureId, eventId, me->GetEntry()); else if (action.summon_id.target != TARGET_T_SELF && target) creature->AI()->AttackStart(target); break; } case ACTION_T_KILLED_MONSTER: //first attempt player who tapped creature if (Player* player = me->GetLootRecipient()) player->RewardPlayerAndGroupAtEvent(action.killed_monster.creatureId, player); // player as param is a hacky solution not to use GUID else { //if not available, use actionInvoker if (Unit* target = GetTargetByType(action.killed_monster.target, actionInvoker)) if (Player* player2 = target->GetCharmerOrOwnerPlayerOrPlayerItself()) player2->RewardPlayerAndGroupAtEvent(action.killed_monster.creatureId, player2); } break; case ACTION_T_SET_INST_DATA: { InstanceScript* instance = (InstanceScript*)me->GetInstanceScript(); if (!instance) { sLog->outErrorDb("CreatureEventAI: Event %d attempt to set instance data without instance script. Creature %d", eventId, me->GetEntry()); return; } instance->SetData(action.set_inst_data.field, action.set_inst_data.value); break; } case ACTION_T_SET_INST_DATA64: { Unit* target = GetTargetByType(action.set_inst_data64.target, actionInvoker); if (!target) { sLog->outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 but Target == NULL. Creature %d", eventId, me->GetEntry()); return; } InstanceScript* instance = (InstanceScript*)me->GetInstanceScript(); if (!instance) { sLog->outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 without instance script. Creature %d", eventId, me->GetEntry()); return; } instance->SetData64(action.set_inst_data64.field, target->GetGUID()); break; } case ACTION_T_UPDATE_TEMPLATE: if (me->GetEntry() == action.update_template.creatureId) { sLog->outErrorDb("CreatureEventAI: Event %d ACTION_T_UPDATE_TEMPLATE call with param1 == current entry. Creature %d", eventId, me->GetEntry()); return; } me->UpdateEntry(action.update_template.creatureId, action.update_template.team ? HORDE : ALLIANCE); break; case ACTION_T_DIE: if (me->isDead()) { sLog->outErrorDb("CreatureEventAI: Event %d ACTION_T_DIE on dead creature. Creature %d", eventId, me->GetEntry()); return; } me->Kill(me); break; case ACTION_T_ZONE_COMBAT_PULSE: { me->SetInCombatWithZone(); break; } case ACTION_T_CALL_FOR_HELP: { me->CallForHelp((float)action.call_for_help.radius); break; } break; // TRINITY ONLY case ACTION_T_MOVE_RANDOM_POINT: //dosen't work in combat { float x, y, z; me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, (float)action.raw.param1); me->GetMotionMaster()->MovePoint(0, x, y, z); break; } case ACTION_T_SET_STAND_STATE: me->SetStandState(UnitStandStateType(action.raw.param1)); break; case ACTION_T_SET_PHASE_MASK: me->SetPhaseMask(action.raw.param1, true); break; case ACTION_T_SET_VISIBILITY: me->SetVisible(bool(action.raw.param1)); break; case ACTION_T_SET_ACTIVE: me->setActive(action.raw.param1 ? true : false); break; case ACTION_T_SET_AGGRESSIVE: me->SetReactState(ReactStates(action.raw.param1)); break; case ACTION_T_ATTACK_START_PULSE: AttackStart(me->SelectNearestTarget((float)action.raw.param1)); break; case ACTION_T_SUMMON_GO: { GameObject* object = NULL; float x, y, z; me->GetPosition(x, y, z); object = me->SummonGameObject(action.raw.param1, x, y, z, 0, 0, 0, 0, 0, action.raw.param2); if (!object) { sLog->outErrorDb("TSCR: EventAI failed to spawn object %u. Spawn event %d is on creature %d", action.raw.param1, eventId, me->GetEntry()); } break; } case ACTION_T_SET_SHEATH: { me->SetSheath(SheathState(action.set_sheath.sheath)); break; } case ACTION_T_FORCE_DESPAWN: { me->DespawnOrUnsummon(action.forced_despawn.msDelay); break; } case ACTION_T_SET_INVINCIBILITY_HP_LEVEL: { if (action.invincibility_hp_level.is_percent) m_InvincibilityHpLevel = me->CountPctFromMaxHealth(action.invincibility_hp_level.hp_level); else m_InvincibilityHpLevel = action.invincibility_hp_level.hp_level; break; } case ACTION_T_MOUNT_TO_ENTRY_OR_MODEL: { if (action.mount.creatureId || action.mount.modelId) { // set model based on entry from creature_template if (action.mount.creatureId) { if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(action.mount.creatureId)) { uint32 display_id = sObjectMgr->ChooseDisplayId(0, cInfo); me->Mount(display_id); } } //if no param1, then use value from param2 (modelId) else me->Mount(action.mount.modelId); } else me->Dismount(); break; } } }
void DoNonCombatActions() { Feast(); if (isTimerReady(uiGc_Timer) && !me->HasAura(SPELL_LIGHTNING_SHIELD, 0)) doCast(me, SPELL_LIGHTNING_SHIELD); if (master->GetGroup()) { RezGroup(SPELL_ANCESTRAL_SPIRIT, master); BuffAndHealGroup(master); } /* TESTING */ Group::MemberSlotList const &a =((Player*)master)->GetGroup()->GetMemberSlots(); for (Group::member_citerator itr = a.begin(); itr != a.end(); itr++) { Player* tPlayer = ((Player *)master)->GetObjPlayer(itr->guid); if (tPlayer == NULL) continue; //healing others if (tPlayer->isAlive() && isTimerReady(uiOthersHeal_Timer) && tPlayer->GetGUID() != master->GetGUID() && tPlayer->GetHealth() * 100 / tPlayer->GetMaxHealth() < 75 && CanCast(tPlayer, GetSpellStore()->LookupEntry(SPELL_CHAIN_HEAL))) { doCast(tPlayer, SPELL_CHAIN_HEAL, false); uiOthersHeal_Timer = 100; } //rezzes if (tPlayer->isDead() && !me->isInCombat() && me->GetDistance(tPlayer) < 40 && isTimerReady(uiRez_Timer)) { char* str = (char *)malloc(32); sprintf(str, "Resucitando a %s", tPlayer->GetName()); me->MonsterSay(str, LANG_UNIVERSAL, NULL); free(str); doCast(tPlayer, SPELL_ANCESTRAL_SPIRIT, false); uiRez_Timer = 160; } } /* TESTING */ if ((master->GetHealth() * 100 / master->GetMaxHealth() < 90) && uiLesserHealing_Timer <= 0) { doCast(master, SPELL_LESSER_HEALING); uiLesserHealing_Timer = 90; uiHeal_Timer = uiHeal_Timer + 5; //wait 5 seconds before casting a real heal return; } else if (uiLesserHealing_Timer >= 0) --uiLesserHealing_Timer; if ((master->GetHealth() * 100 / master->GetMaxHealth() < 75) && isTimerReady(uiHeal_Timer)) { doCast(master, SPELL_CHAIN_HEAL); uiHeal_Timer = 10; } if (me->GetHealth() * 100 / me->GetMaxHealth() < 90) { if (uiSelfLesserHealing_Timer <= 0) { doCast(me, SPELL_LESSER_HEALING); uiSelfLesserHealing_Timer = 90; return; } else if (uiSelfLesserHealing_Timer >= 0) --uiSelfLesserHealing_Timer; } }
void UpdateAI(const uint32 diff) { DoMeleeAttackIfReady(); decrementTimers(); if (IAmDead()) return; if (me->GetPower(POWER_MANA) < 400 && isTimerReady(uiPotion_Timer)) { doCast(me, SPELL_MANA_POTION); uiPotion_Timer = 150; } if (me->GetPower(POWER_MANA)/me->GetMaxPower(POWER_MANA) < 10) { if (uiOom_Timer == 0) uiOom_Timer = 1; } BuffAndHealGroup(master); // Heal myself HealTarget (me, me->GetHealth() * 100 / me->GetMaxHealth()); //the rest are combat so return if not fighting opponent = SelectTarget(SELECT_TARGET_TOPAGGRO, 0); if (!opponent && !me->getVictim()) { DoNonCombatActions(); ResetOrGetNextTarget(); return; } //Cast totems. if (me->isInCombat() && isTimerReady(uiEarthTotem_Timer) && !master->HasAura(SPELL_STONE_SKIN_AURA, 0)) { doCast(me, SPELL_STONE_SKIN_TOTEM); GiveManaBack(); uiEarthTotem_Timer = 90; return; } if (me->isInCombat() && isTimerReady(uiFireTotem_Timer)) { doCast(me, SPELL_SEARING_TOTEM); GiveManaBack(); uiFireTotem_Timer = 180; return; } if (me->isInCombat() && isTimerReady(uiWindTotem_Timer)) { doCast(me, SPELL_WINDFURY_TOTEM); GiveManaBack(); uiWindTotem_Timer = 180; return; } if (me->isInCombat()) { switch(master->getClass()) { case CLASS_WARRIOR: case CLASS_DEATH_KNIGHT: case CLASS_ROGUE: if (isTimerReady(uiWaterTotem_Timer) && !master->HasAura(SPELL_HEALING_STREAM_AURA)) { doCast(me, SPELL_HEALING_STREAM_TOTEM); uiWaterTotem_Timer = 90; GiveManaBack(); return; } break; default: //everyone else gets a mana totem if (isTimerReady (uiWaterTotem_Timer) && !master->HasAura(SPELL_MANA_SPRING_AURA, 0)) { doCast(me, SPELL_MANA_SPRING_TOTEM); uiWaterTotem_Timer = 90; GiveManaBack(); return; } } } if (isTimerReady(uiFlameShock_Timer)) { doCast(opponent, SPELL_FLAME_SHOCK); uiFlameShock_Timer = 120; return; } if (isTimerReady(uiLightningBolt_Timer)) { doCast(opponent, SPELL_LIGHTNING_BOLT); uiLightningBolt_Timer = 180; return; } if (isTimerReady(uiEarthShock_Timer)) { doCast(opponent, SPELL_EARTH_SHOCK); uiEarthShock_Timer = 250; return; } //now try to heal bots and pets. DoSelectLowestHpFriendly will get //everyone in group including bots and pets. Unfortunately it can //not be triggered for % of lost HP, so we just set it to -1000. //This means low level players wont be healed because they wont have //enough HP. Unit* target = DoSelectLowestHpFriendly(40, 1000); if (target) { if (CanCast(target, GetSpellStore()->LookupEntry (SPELL_CHAIN_HEAL))) { doCast(target, SPELL_CHAIN_HEAL, false); uiOthersHeal_Timer = 50; } } else { target = DoSelectLowestHpFriendly(40, 500); //now try someone with less HP lost if (target) { if (CanCast(target, GetSpellStore()->LookupEntry (SPELL_CHAIN_HEAL))) { doCast(target, SPELL_CHAIN_HEAL, false); uiOthersHeal_Timer = 100; } } } ScriptedAI::UpdateAI(diff); }
bool PlayerbotClassAI::castSelfCCBreakers (uint32 castList[]) { uint32 dispelSpell = 0; Player *dTarget = GetPlayerBot(); /* dispelSpell = (uint32) R_ESCAPE_ARTIST; // this is script effect, Unit::AuraMap const& auras = dTarget->GetOwnedAuras(); for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); itr++) { Aura * aura = itr->second; AuraApplication * aurApp = aura->GetApplicationOfTarget(dTarget->GetGUID()); if (!aurApp) continue; if ( ( aura->GetSpellProto()->Mechanic == MECHANIC_SNARE ) || ( aura->GetSpellProto()->Mechanic == MECHANIC_ROOT ) ) { if(aura->GetSpellProto()->Dispel == DISPEL_MAGIC) { bool positive = aurApp->IsPositive() ? (!(aura->GetSpellProto()->AttributesEx & SPELL_ATTR0_UNK7)) : false; // do not remove positive auras if friendly target // negative auras if non-friendly target if(positive == dTarget->IsFriendlyTo(caster)) continue; } return castSpell(dispelSpell, dTarget); } } return false; */ // racial abilities /* if( GetPlayerBot()->getRace() == RACE_BLOODELF && !pTarget->HasAura( ARCANE_TORRENT,0 ) && castSpell( ARCANE_TORRENT,pTarget ) ) { //GetPlayerBot()->Say("Arcane Torrent!", LANG_UNIVERSAL); } else if( GetPlayerBot()->getRace() == RACE_HUMAN && (GetPlayerBot()->HasUnitState( UNIT_STAT_STUNNED ) || GetPlayerBot()->HasAuraType( SPELL_AURA_MOD_FEAR ) || GetPlayerBot()->HasAuraType( SPELL_AURA_MOD_DECREASE_SPEED ) || GetPlayerBot()->HasAuraType( SPELL_AURA_MOD_CHARM )) && castSpell( EVERY_MAN_FOR_HIMSELF, GetPlayerBot() ) ) { //GetPlayerBot()->Say("EVERY MAN FOR HIMSELF!", LANG_UNIVERSAL); } else if( GetPlayerBot()->getRace() == RACE_UNDEAD_PLAYER && (GetPlayerBot()->HasAuraType( SPELL_AURA_MOD_FEAR ) || GetPlayerBot()->HasAuraType( SPELL_AURA_MOD_CHARM )) && castSpell( WILL_OF_THE_FORSAKEN, GetPlayerBot() ) ) { // GetPlayerBot()->Say("WILL OF THE FORSAKEN!", LANG_UNIVERSAL); } else if( GetPlayerBot()->getRace() == RACE_DWARF && GetPlayerBot()->HasAuraState( AURA_STATE_DEADLY_POISON ) && castSpell( STONEFORM, GetPlayerBot() ) ) { //GetPlayerBot()->Say("STONEFORM!", LANG_UNIVERSAL); } else if( GetPlayerBot()->getRace() == RACE_GNOME && (GetPlayerBot()->HasUnitState( UNIT_STAT_STUNNED ) || GetPlayerBot()->HasAuraType( SPELL_AURA_MOD_DECREASE_SPEED )) && castSpell( ESCAPE_ARTIST, GetPlayerBot() ) ) { // GetPlayerBot()->Say("ESCAPE ARTIST!", LANG_UNIVERSAL); } */ for (uint8 j = 0; j < sizeof (castList); j++) { dispelSpell = castList[j]; if (dispelSpell == 0 || !dTarget->HasSpell(dispelSpell) || !CanCast(dispelSpell, dTarget, true)) continue; SpellEntry const *dSpell = GetSpellStore()->LookupEntry(dispelSpell); if (!dSpell) continue; for (uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++i) { if (dSpell->Effect[i] != (uint32)SPELL_EFFECT_DISPEL && dSpell->Effect[i] != (uint32)SPELL_EFFECT_APPLY_AURA) continue; if (dSpell->Effect[i] == (uint32)SPELL_EFFECT_APPLY_AURA && ( (dSpell->EffectApplyAuraName[i] != (uint32) SPELL_AURA_MECHANIC_IMMUNITY) || (dSpell->EffectApplyAuraName[i] != (uint32) SPELL_AURA_DISPEL_IMMUNITY) )) continue; Unit::AuraMap const& auras = dTarget->GetOwnedAuras(); for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); itr++) { Aura * aura = itr->second; AuraApplication * aurApp = aura->GetApplicationOfTarget(dTarget->GetGUID()); if (!aurApp) continue; if (aura->GetSpellProto() && ( (dSpell->Effect[i] == (uint32)SPELL_EFFECT_DISPEL && ((1<<aura->GetSpellProto()->Dispel) & GetDispellMask(DispelType(dSpell->EffectMiscValue[i]))) ) || (dSpell->EffectApplyAuraName[i] == (uint32) SPELL_AURA_MECHANIC_IMMUNITY && ( GetAllSpellMechanicMask(aura->GetSpellProto()) & ( 1 << dSpell->EffectMiscValue[i]) ) ) || (dSpell->EffectApplyAuraName[i] == (uint32) SPELL_AURA_DISPEL_IMMUNITY && ( (1<<aura->GetSpellProto()->Dispel) & GetDispellMask(DispelType(dSpell->EffectMiscValue[i])) ) ) ) ) { if(aura->GetSpellProto()->Dispel == DISPEL_MAGIC) { bool positive = aurApp->IsPositive() ? (!(aura->GetSpellProto()->AttributesEx & SPELL_ATTR0_UNK7)) : false; if(positive)continue; } return CastSpell(dispelSpell, dTarget, false); } } } } return false; }
void PlayerbotDeathKnightAI::DoNextCombatManeuver(Unit *pTarget) { if (!pTarget || pTarget->isDead()) return; PlayerbotAI *ai = GetAI(); if (!ai) return; Player *m_bot = GetPlayerBot(); if (!m_bot || m_bot->isDead()) return; Unit *pVictim = pTarget->getVictim(); Unit *m_tank = FindMainTankInRaid(GetMaster()); if (!m_tank && m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup()) { FindMainTankInRaid(m_bot); } if (!m_tank) { m_tank = m_bot; } uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth(); float pDist = m_bot->GetDistance(pTarget); uint8 pThreat = GetThreatPercent(pTarget); Pet *pet = m_bot->GetPet(); std::ostringstream out; if (!m_pulling) { m_role = BOT_ROLE_DPS_MELEE; #pragma region Choose Role/Presence // Choose Presence if (m_tank->GetGUID() == m_bot->GetGUID()) // Hey! I am Main Tank { if (CastSpell(FROST_PRESENCE,m_bot)) { m_role = BOT_ROLE_TANK; return; } } else if (isUnderAttack()) // I am under attack { if (pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist <= 2) {} // My target is almost up to me, no need to search else //Have to select nearest target { Unit *curAtt = GetNearestAttackerOf(m_bot); if (curAtt && curAtt->GetGUID() != pTarget->GetGUID()) { m_bot->SetSelection(curAtt->GetGUID()); //ai->AddLootGUID(curAtt->GetGUID()); DoNextCombatManeuver(curAtt); //Restart new update to get variables fixed.. return; } } //my target is attacking me //if (m_bot->getRace() == (uint8) RACE_NIGHTELF && CastSpell(R_SHADOWMELD,m_bot) ) { return; } if (CastSpell(FROST_PRESENCE,m_bot)) { m_role = BOT_ROLE_OFFTANK; return; } } else if (TALENT_UNHOLY) { if (CastSpell(UNHOLY_PRESENCE,m_bot)) return; } else if (CastSpell(BLOOD_PRESENCE,m_bot)) return; #pragma endregion } // Cast CC breakers if any match found (does not work yet) // uint32 ccSpells[6] = { LICHBORNE, ICEBOUND_FORTITUDE, R_ESCAPE_ARTIST, R_EVERY_MAN_FOR_HIMSELF, R_WILL_OF_FORSAKEN, R_STONEFORM }; // if (castSelfCCBreakers(ccSpells)) { } //most of them dont have gcd TakePosition(pTarget); if (m_pulling) { if (GetAI()->CastSpell(DEATH_GRIP,pTarget)) { m_pulling = false; GetAI()->SetCombatOrder(ORDERS_NONE); GetAI()->Follow(*GetMaster()); GetAI()->SetIgnoreUpdateTime(2); if (m_bot->GetPet()) pet->SetReactState (REACT_DEFENSIVE); } return; } // If there's a cast stop if(m_bot->HasUnitState(UNIT_STATE_CASTING)) { return; } #pragma region Buff Heal Interrupt //Buff UP if (CastSpell(HORN_OF_WINTER,m_bot)) { return; } if (CastSpell(BONE_SHIELD,m_bot)) { return; } //HEAL UP && PROTECT UP if (ai->GetHealthPercent() < 80 && ai->GetHealthPercent() > 20 && CastSpell(VAMPIRIC_BLOOD,m_bot)) { } //NO GCD if (ai->GetHealthPercent() < 65 && CastSpell(RUNE_TAP,m_bot)) { } //NO GCD if (CanCast(DEATH_STRIKE,pTarget,true) && ai->GetHealthPercent() < 90 && (pTarget->HasAura(FROST_FEVER,m_bot->GetGUID()) ||pTarget->HasAura(BLOOD_PLAGUE,m_bot->GetGUID()) ) && CastSpell(DEATH_STRIKE,pTarget,false) ) {return;} if (m_bot->getRace() == (uint8) RACE_DWARF && ai->GetHealthPercent() < 75 && CastSpell(R_STONEFORM,m_bot)) { } //no gcd if (m_bot->getRace() == (uint8) RACE_DRAENEI && ai->GetHealthPercent() < 55 && CastSpell(R_GIFT_OF_NAARU,m_bot)) { return; } //no Gcd, but has cast if (pet && ai->GetHealthPercent() < 50 && CastSpell(DEATH_PACT,m_bot)) { return; } if (pet && ai->GetHealthPercent() < 60 && CastSpell(MARK_OF_BLOOD,pTarget)) { return; } if (ai->GetHealthPercent() < 65 && CastSpell(ICEBOUND_FORTITUDE,m_bot)) { } //No GCD if (ai->GetHealthPercent() < 65 && CastSpell(UNBREAKABLE_ARMOR,m_bot)) { return; } //Break spells being cast if (pTarget->IsNonMeleeSpellCasted(true)) { if (CastSpell(MIND_FREEZE,pTarget)) {} // No GCD if (CastSpell(STRANGULATE,pTarget)) { return; } if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && CastSpell(R_ARCANE_TORRENT, pTarget)) { } //no gcd if (CastSpell(ANTI_MAGIC_ZONE,m_bot)) { return; } if (CastSpell(ANTI_MAGIC_SHELL,m_bot)) {} //NO GCD } //Catch if (pTarget->HasUnitMovementFlag(UNIT_FLAG_FLEEING)) { if (CastSpell(DEATH_GRIP,pTarget)) return; if (CastSpell(CHAINS_OF_ICE,pTarget)) return; } #pragma endregion #pragma region Taunt / Threat // if i am main tank, protect master by taunt if(m_tank->GetGUID() == m_bot->GetGUID()) { // Taunt if needed (Only for master) Unit *curAtt = GetAttackerOf(GetMaster()); if (curAtt && CastSpell(DARK_COMMAND, curAtt)) { } //No gcd // My target is not attacking me, taunt.. if (pVictim && pVictim->GetGUID() != m_bot->GetGUID() && CastSpell(DARK_COMMAND, pTarget) ) { } // No gcd } // If not in Frost Presence slow down due to threat if (pThreat > threatThreshold && !m_bot->HasAura(FROST_PRESENCE) && m_tank->GetGUID() != m_bot->GetGUID() && !isUnderAttack()) { if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) // I am attacking wrong target!! { m_bot->SetSelection(m_tank->getVictim()->GetGUID()); return; } else { return; } //DK has no threat reducing spells, just slow down } #pragma endregion #pragma region Dps //Dps up if (CastSpell(EMPOWER_WEAPON,m_bot)) {} //NO GCD if (ai->GetHealthPercent() > 90 && CastSpell(HYSTERIA,m_bot)) {} //NO GCD if (m_bot->getRace() == (uint8) RACE_TROLL && CastSpell(R_BERSERKING,m_bot)) {} //no GCD if (m_bot->getRace() == (uint8) RACE_ORC && CastSpell(R_BLOOD_FURY,m_bot)) {} //no GCD // Use up excess Runic Power if (ai->GetRunicPower() > 60 && CastSpell(FROST_STRIKE,pTarget)) { return; } else if (ai->GetRunicPower() > 60 && CastSpell(DEATH_COIL,pTarget,true,true,true)) { return; } if ((isUnderAttack() || ai->GetRunicPower() > 70) && CastSpell(RUNE_STRIKE,pTarget)) {} //Next attack spell // Build Diseases if (!pTarget->HasAura(FROST_FEVER,m_bot->GetGUID()) && CastSpell(ICY_TOUCH,pTarget)) { return; } if (!pTarget->HasAura(BLOOD_PLAGUE,m_bot->GetGUID()) && CastSpell(PLAGUE_STRIKE,pTarget)) { return; } // Use AOEs summons if (isUnderAttack(m_tank,4) && CastSpell(DEATH_AND_DECAY,pTarget)) { return; } if (isUnderAttack(m_tank,4) && CastSpell(HOWLING_BLAST,pTarget)) { return; } if (CanCast(PESTILENCE,pTarget,true) && isUnderAttack(m_tank,4) && (pTarget->HasAura(FROST_FEVER,m_bot->GetGUID()) && pTarget->HasAura(BLOOD_PLAGUE,m_bot->GetGUID()) ) && CastSpell(PESTILENCE,pTarget,false)) { return; } if (CanCast(BLOOD_BOIL,pTarget,true) && isUnderAttack(m_tank,4) && (pTarget->HasAura(FROST_FEVER,m_bot->GetGUID()) || pTarget->HasAura(BLOOD_PLAGUE,m_bot->GetGUID()) ) && CastSpell(BLOOD_BOIL,pTarget,false)) { return; } if (m_bot->getRace() == (uint8) RACE_TAUREN && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) { return; } //no gcd but is cast if (isUnderAttack(m_tank,6) && CastSpell(ARMY_OF_THE_DEAD,m_bot)) { return; } if (isUnderAttack(m_tank,4) && CastSpell(SUMMON_GARGOYLE,pTarget)) { return; } //This should be somewhat different // Use standard damage spells if (CastSpell(HEART_STRIKE,pTarget,true,true)) { return; } if (CastSpell(BLOOD_STRIKE,pTarget)) { return; } if (TALENT_FROST && CastSpell(OBLITERATE,pTarget)) { return; } else if (TALENT_UNHOLY && CastSpell(SCOURGE_STRIKE,pTarget)) { return; } else if (CastSpell(DEATH_STRIKE,pTarget)) { return; } #pragma endregion } // end DoNextCombatManeuver