void PlayerbotDruidAI::_DoNextPVECombatManeuverMeleeDPS(Unit* pTarget) { PlayerbotAI* ai = GetAI(); if (!ai) return; // True, bear form is set up for tanking but even then it's better DPS for levels 10-19 than humanoid form if (CAT_FORM == 0 && BEAR_FORM > 0) // but only go there if you can get into bear form. else stay here. if (ai->CastSpell(BEAR_FORM)) return _DoNextPVECombatManeuverBear(pTarget); //uint32 masterHP = GetMaster()->GetHealth() * 100 / GetMaster()->GetMaxHealth(); Player *m_bot = GetPlayerBot(); Unit* pVictim = pTarget->getVictim(); if (!m_bot->HasInArc(M_PI_F, pTarget)) { m_bot->SetFacingTo(m_bot->GetAngle(pTarget)); if (pVictim) pVictim->Attack(pTarget, true); } if (CAT_FORM > 0 && !m_bot->HasAura(CAT_FORM, EFFECT_INDEX_0)) if (!ai->CastSpell(CAT_FORM)) { if (ai->GetManaPercent() < 30) // TODO: tweak this value. Pretty sure bear form mana Req is way less than 30% of base mana, let alone total mana return; // conserve mana else _DoNextPVECombatManeuverSpellDPS(pTarget); } // Commented out: Above should take care of it //// Technically bear form is better than no form for melee druids levels 10-19. //if (m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) //{ // m_bot->RemoveAurasDueToSpell(BEAR_FORM_1); // //ai->TellMaster("FormClearBear"); // return; //} //if (m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0)) //{ // m_bot->RemoveAurasDueToSpell(DIRE_BEAR_FORM_1); // //ai->TellMaster("FormClearDireBear"); // return; //} //if (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) //{ // m_bot->RemoveAurasDueToSpell(MOONKIN_FORM_1); // //ai->TellMaster("FormClearMoonkin"); // return; //} //if (COWER > 0 && m_bot->GetComboPoints() == 1 && ai->GetEnergyAmount() >= 20) // && HasAnyAggroWhereSecondAggroIsNotHealer() //{ // ai->CastSpell(COWER); // //ai->TellMaster("Cower"); //} if (MAIM > 0 && m_bot->GetComboPoints() >= 1 && pTarget->IsNonMeleeSpellCasted(true)) { ai->CastSpell(MAIM, *pTarget); //ai->TellMaster("SpellPreventing Maim"); return; } if (RAKE > 0 && m_bot->GetComboPoints() < 1 && ai->GetEnergyAmount() >= 40) // should be replaced by a check for the bleed effect it causes (along with Combo != 5) { ai->CastSpell(RAKE, *pTarget); //ai->TellMaster("Rake"); return; } if (MANGLE > 0 && m_bot->GetComboPoints() == 1 && ai->GetEnergyAmount() >= 45) { ai->CastSpell(MANGLE, *pTarget); //ai->TellMaster("Mangle"); return; } if (CLAW > 0 && m_bot->GetComboPoints() < 5 && ai->GetEnergyAmount() >= 45) { ai->CastSpell(CLAW, *pTarget); //ai->TellMaster("Claw"); return; } if (m_bot->GetComboPoints() == 5) { if (RIP > 0 && pTarget->getClass() == CLASS_ROGUE && ai->GetEnergyAmount() >= 30) ai->CastSpell(RIP, *pTarget); else if (FEROCIOUS_BITE > 0 && ai->GetEnergyAmount() >= 35 && (pTarget->getClass() == CLASS_HUNTER || pTarget->getClass() == CLASS_WARRIOR || pTarget->getClass() == CLASS_PALADIN || pTarget->getClass() == CLASS_DEATH_KNIGHT)) ai->CastSpell(FEROCIOUS_BITE, *pTarget); else if (ai->GetEnergyAmount() >= 35) { //ai->TellMaster("Else Maim, Ferocious Bite or Rip."); // MAIM must be first check, best option against other classes if (MAIM > 0) ai->CastSpell(MAIM, *pTarget); else if (FEROCIOUS_BITE > 0) ai->CastSpell(FEROCIOUS_BITE, *pTarget); else if (RIP > 0) // Fair enough, only needs 30 energy... but that means 35 is plenty ai->CastSpell(RIP, *pTarget); } return; } }
void UpdateAI(const uint32 diff) { if (SayTimer <= diff) { if (Event) SayTimer = NextStep(++Step); } else SayTimer -= diff; if (Attack) { Player* player = Unit::GetPlayer(*me, PlayerGUID); me->setFaction(14); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); if (player) { Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20); if (Creepjack) { Creepjack->Attack(player, true); Creepjack->setFaction(14); Creepjack->GetMotionMaster()->MoveChase(player); Creepjack->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20); if (Malone) { Malone->Attack(player, true); Malone->setFaction(14); Malone->GetMotionMaster()->MoveChase(player); Malone->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } DoStartMovement(player); AttackStart(player); } Attack = false; } if (HealthBelowPct(5) && !Done) { me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->RemoveAllAuras(); Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20); if (Creepjack) { CAST_CRE(Creepjack)->AI()->EnterEvadeMode(); Creepjack->setFaction(1194); Creepjack->GetMotionMaster()->MoveTargetedHome(); Creepjack->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20); if (Malone) { CAST_CRE(Malone)->AI()->EnterEvadeMode(); Malone->setFaction(1194); Malone->GetMotionMaster()->MoveTargetedHome(); Malone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } me->setFaction(1194); Done = true; Talk(SAY_GIVEUP); me->DeleteThreatList(); me->CombatStop(); me->GetMotionMaster()->MoveTargetedHome(); Player* player = Unit::GetPlayer(*me, PlayerGUID); if (player) CAST_PLR(player)->GroupEventHappens(QUEST_WBI, me); } DoMeleeAttackIfReady(); }
void WorldSession::HandlePetAction(WorldPacket& recv_data) { ObjectGuid petGuid; uint32 data; ObjectGuid targetGuid; recv_data >> petGuid; recv_data >> data; recv_data >> targetGuid; uint32 spellid = UNIT_ACTION_BUTTON_ACTION(data); uint8 flag = UNIT_ACTION_BUTTON_TYPE(data); // delete = 0x07 CastSpell = C1 DETAIL_LOG("HandlePetAction: %s flag is %u, spellid is %u, target %s.", petGuid.GetString().c_str(), uint32(flag), spellid, targetGuid.GetString().c_str()); // used also for charmed creature/player Unit* petUnit = _player->GetMap()->GetUnit(petGuid); if (!petUnit) { sLog.outError("HandlePetAction: %s not exist.", petGuid.GetString().c_str()); return; } if (_player->GetObjectGuid() != petUnit->GetMasterGuid()) { sLog.outError("HandlePetAction: %s isn't controlled by %s.", petGuid.GetString().c_str(), _player->GetGuidStr().c_str()); return; } if (!petUnit->isAlive()) return; CharmInfo* charmInfo = petUnit->GetCharmInfo(); if (!charmInfo) { sLog.outError("WorldSession::HandlePetAction: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", petUnit->GetGUIDLow(), petUnit->GetTypeId()); return; } Pet* pet = nullptr; Creature* creature = nullptr; if (petUnit->GetTypeId() == TYPEID_UNIT) { creature = static_cast<Creature*>(petUnit); if (creature->IsPet()) { pet = static_cast<Pet*>(petUnit); if (pet->GetModeFlags() & PET_MODE_DISABLE_ACTIONS) return; } } if (!pet) { if (petUnit->hasUnitState(UNIT_STAT_POSSESSED)) { // possess case if (flag != uint8(ACT_COMMAND)) { sLog.outError("PetHAndler: unknown PET flag Action %i and spellid %i. For possessed %s", uint32(flag), spellid, petUnit->GetGuidStr().c_str()); return; } switch (spellid) { case COMMAND_STAY: case COMMAND_FOLLOW: charmInfo->SetCommandState(CommandStates(spellid)); break; case COMMAND_ATTACK: { Unit* targetUnit = targetGuid ? _player->GetMap()->GetUnit(targetGuid) : nullptr; if (targetUnit && targetUnit != petUnit && petUnit->CanAttack(targetUnit)) { // This is true if pet has no target or has target but targets differs. if (petUnit->getVictim() != targetUnit) petUnit->Attack(targetUnit, true); } break; } case COMMAND_DISMISS: _player->BreakCharmOutgoing(petUnit); break; default: sLog.outError("PetHandler: Not allowed action %i and spellid %i. Pet %s owner is %s", uint32(flag), spellid, petUnit->GetGuidStr().c_str(), _player->GetGuidStr().c_str()); break; } } if (!petUnit->HasCharmer()) return; } switch (flag) { case ACT_COMMAND: // 0x07 switch (spellid) { case COMMAND_STAY: // flat=1792 // STAY { if (!petUnit->hasUnitState(UNIT_STAT_POSSESSED)) { petUnit->StopMoving(); petUnit->GetMotionMaster()->Clear(); } petUnit->AttackStop(true, true); charmInfo->SetCommandState(COMMAND_STAY); break; } case COMMAND_FOLLOW: // spellid=1792 // FOLLOW { if (!petUnit->hasUnitState(UNIT_STAT_POSSESSED)) { petUnit->StopMoving(); petUnit->GetMotionMaster()->Clear(); charmInfo->SetIsRetreating(true); } petUnit->AttackStop(true, true); charmInfo->SetCommandState(COMMAND_FOLLOW); break; } case COMMAND_ATTACK: // spellid=1792 // ATTACK { charmInfo->SetIsRetreating(); charmInfo->SetSpellOpener(); Unit* targetUnit = targetGuid ? _player->GetMap()->GetUnit(targetGuid) : nullptr; if (targetUnit && targetUnit != petUnit && petUnit->CanAttack(targetUnit) && targetUnit->isInAccessablePlaceFor((Creature*)petUnit)) { // This is true if pet has no target or has target but targets differs. if (petUnit->getVictim() != targetUnit) { petUnit->AttackStop(); if (!petUnit->hasUnitState(UNIT_STAT_POSSESSED)) { petUnit->GetMotionMaster()->Clear(); petUnit->AI()->AttackStart(targetUnit); if (pet) { // 10% chance to play special warlock pet attack talk, else growl if (pet->getPetType() == SUMMON_PET && roll_chance_i(10)) pet->SendPetTalk((uint32)PET_TALK_ATTACK); pet->SendPetAIReaction(); } } else petUnit->Attack(targetUnit, true); } } break; } case COMMAND_DISMISS: // dismiss permanent pet, remove temporary pet, uncharm unit { if (pet) { pet->PlayDismissSound(); // No action for Hunter pets, Hunters must use their Dismiss Pet spell if (pet->getPetType() != HUNTER_PET) pet->ForcedDespawn(); } else { // dismissing a summoned pet is like killing them (this prevents returning a soulshard...) if (creature && creature->IsTemporarySummon()) creature->ForcedDespawn(); else _player->BreakCharmOutgoing(petUnit); } charmInfo->SetStayPosition(); break; } default: sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); } break; case ACT_REACTION: // 0x6 switch (spellid) { case REACT_PASSIVE: // passive { petUnit->AttackStop(true, true); charmInfo->SetSpellOpener(); } case REACT_DEFENSIVE: // recovery case REACT_AGGRESSIVE: // activete { petUnit->AI()->SetReactState(ReactStates(spellid)); break; } } break; case ACT_DISABLED: // 0x81 spell (disabled), ignore case ACT_PASSIVE: // 0x01 case ACT_ENABLED: // 0xC1 spell { charmInfo->SetIsRetreating(); charmInfo->SetSpellOpener(); Unit* unit_target = targetGuid ? _player->GetMap()->GetUnit(targetGuid) : nullptr; // do not cast unknown spells SpellEntry const* spellInfo = sSpellTemplate.LookupEntry<SpellEntry>(spellid); if (!spellInfo) { sLog.outError("WORLD: unknown PET spell id %i", spellid); return; } // do not cast not learned spells if (IsPassiveSpell(spellInfo) || !petUnit->HasSpell(spellid)) return; if (!petUnit->IsSpellReady(*spellInfo)) return; for (unsigned int i : spellInfo->EffectImplicitTargetA) { if (i == TARGET_ENUM_UNITS_ENEMY_AOE_AT_SRC_LOC || i == TARGET_ENUM_UNITS_ENEMY_AOE_AT_DEST_LOC || i == TARGET_ENUM_UNITS_ENEMY_AOE_AT_DYNOBJ_LOC) return; } petUnit->clearUnitState(UNIT_STAT_MOVING); uint32 flags = TRIGGERED_NONE; if (!petUnit->hasUnitState(UNIT_STAT_POSSESSED)) flags |= TRIGGERED_PET_CAST; Spell* spell = new Spell(petUnit, spellInfo, flags); SpellCastResult result = spell->CheckPetCast(unit_target); const SpellRangeEntry* sRange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex); if (unit_target && !(petUnit->IsWithinDistInMap(unit_target, sRange->maxRange) && petUnit->IsWithinLOSInMap(unit_target)) && petUnit->CanAttackNow(unit_target)) { charmInfo->SetSpellOpener(spellid, sRange->minRange, sRange->maxRange); spell->finish(false); delete spell; petUnit->AttackStop(); if (!petUnit->hasUnitState(UNIT_STAT_POSSESSED)) { petUnit->GetMotionMaster()->Clear(); petUnit->AI()->AttackStart(unit_target); // 10% chance to play special warlock pet attack talk, else growl if (pet && pet->getPetType() == SUMMON_PET && pet != unit_target && roll_chance_i(10)) petUnit->SendPetTalk((uint32)PET_TALK_ATTACK); petUnit->SendPetAIReaction(); } else petUnit->Attack(unit_target, true); return; } // auto turn to target unless possessed if (result == SPELL_FAILED_UNIT_NOT_INFRONT && !petUnit->hasUnitState(UNIT_STAT_POSSESSED)) { if (unit_target) { petUnit->SetInFront(unit_target); if (unit_target->GetTypeId() == TYPEID_PLAYER) petUnit->SendCreateUpdateToPlayer((Player*)unit_target); } else if (Unit* unit_target2 = spell->m_targets.getUnitTarget()) { petUnit->SetInFront(unit_target2); if (unit_target2->GetTypeId() == TYPEID_PLAYER) petUnit->SendCreateUpdateToPlayer((Player*)unit_target2); } if (Unit* powner = petUnit->GetMaster()) if (powner->GetTypeId() == TYPEID_PLAYER) petUnit->SendCreateUpdateToPlayer((Player*)powner); result = SPELL_CAST_OK; } if (result == SPELL_CAST_OK) { charmInfo->SetSpellOpener(); spell->SpellStart(&(spell->m_targets)); } else { if (creature && creature->IsSpellReady(*spellInfo)) GetPlayer()->SendClearCooldown(spellid, petUnit); charmInfo->SetSpellOpener(); spell->finish(false); delete spell; } break; } default: sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); } }
void PlayerbotDruidAI::_DoNextPVECombatManeuverBear(Unit* pTarget) { PlayerbotAI* ai = GetAI(); if (!ai) return; //uint32 masterHP = GetMaster()->GetHealth() * 100 / GetMaster()->GetMaxHealth(); Player *m_bot = GetPlayerBot(); Unit* pVictim = pTarget->getVictim(); // Face your enemy! if (!m_bot->HasInArc(M_PI_F, pTarget)) { m_bot->SetFacingTo(m_bot->GetAngle(pTarget)); if (pVictim) pVictim->Attack(pTarget, true); } // Try and go into [dire] bear form first if (DIRE_BEAR_FORM > 0 && !m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0)) ai->CastSpell(DIRE_BEAR_FORM); else if (BEAR_FORM > 0 && DIRE_BEAR_FORM == 0 && !m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0) && !m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) ai->CastSpell(BEAR_FORM); else if (DEMORALIZING_ROAR > 0 && (m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0) || m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) && !pTarget->HasAura(DEMORALIZING_ROAR, EFFECT_INDEX_0) && ai->GetRageAmount() >= 10) ai->CastSpell(DEMORALIZING_ROAR, *pTarget); // entire tank spell sequence is predicated on being in [dire] bear form. If not in it, exit (*before* going out of other forms) if (!m_bot->HasAura(DIRE_BEAR_FORM) && !m_bot->HasAura(BEAR_FORM)) return _DoNextPVECombatManeuverMeleeDPS(pTarget); // bear = melee so... // Impossible due to check above // If still in cat/moonkin/tree form, go out of it //if (m_bot->HasAura(CAT_FORM, EFFECT_INDEX_0)) // m_bot->RemoveAurasDueToSpell(CAT_FORM_1); //if (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) // m_bot->RemoveAurasDueToSpell(MOONKIN_FORM_1); //if (m_bot->HasAura(TREE_OF_LIFE, EFFECT_INDEX_0)) // m_bot->RemoveAurasDueToSpell(TREE_OF_LIFE_1); if (FAERIE_FIRE_FERAL > 0 && DruidSpellCombat < 1 && !pTarget->HasAura(FAERIE_FIRE_FERAL, EFFECT_INDEX_0)) { ai->CastSpell(FAERIE_FIRE, *pTarget); return; } DruidSpellCombat++; if (ENRAGE > 0 && DruidSpellCombat < 2 && !m_bot->HasAura(ENRAGE, EFFECT_INDEX_0)) { ai->CastSpell(ENRAGE, *m_bot); return; } DruidSpellCombat++; if (SWIPE > 0 && DruidSpellCombat < 3 && ai->GetRageAmount() >= 20) { ai->CastSpell(SWIPE, *pTarget); DruidSpellCombat += 2; return; } DruidSpellCombat++; if (MAUL > 0 && DruidSpellCombat < 4 && ai->GetRageAmount() >= 15) { ai->CastSpell(MAUL, *pTarget); DruidSpellCombat += 2; return; } DruidSpellCombat++; if (BASH > 0 && !pTarget->HasAura(BASH, EFFECT_INDEX_0) && DruidSpellCombat < 5 && ai->GetRageAmount() >= 10) { ai->CastSpell(BASH, *pTarget); DruidSpellCombat += 2; return; } DruidSpellCombat++; if (CHALLENGING_ROAR > 0 && pVictim != m_bot && DruidSpellCombat < 6 && !pTarget->HasAura(CHALLENGING_ROAR, EFFECT_INDEX_0) && !pTarget->HasAura(GROWL, EFFECT_INDEX_0) && ai->GetRageAmount() >= 15) { ai->CastSpell(CHALLENGING_ROAR, *pTarget); DruidSpellCombat += 2; return; } DruidSpellCombat++; if (GROWL > 0 && pVictim != m_bot && DruidSpellCombat < 7 && !pTarget->HasAura(CHALLENGING_ROAR, EFFECT_INDEX_0) && !pTarget->HasAura(GROWL, EFFECT_INDEX_0)) { ai->CastSpell(GROWL, *pTarget); DruidSpellCombat += 2; return; } DruidSpellCombat = 0; }
void WorldSession::HandlePetAction(WorldPacket& recv_data) { ObjectGuid petGuid; uint32 data; ObjectGuid targetGuid; float x, y, z; recv_data >> petGuid; recv_data >> data; recv_data >> targetGuid; recv_data >> x >> y >> z; uint32 spellid = UNIT_ACTION_BUTTON_ACTION(data); uint8 flag = UNIT_ACTION_BUTTON_TYPE(data); // delete = 0x07 CastSpell = C1 DETAIL_LOG("HandlePetAction: %s flag is %u, spellid is %u, target %s.", petGuid.GetString().c_str(), uint32(flag), spellid, targetGuid.GetString().c_str()); // used also for charmed creature/player Unit* pet = _player->GetMap()->GetUnit(petGuid); if (!pet) { sLog.outError("HandlePetAction: %s not exist.", petGuid.GetString().c_str()); return; } if (_player->GetObjectGuid() != pet->GetCharmerOrOwnerGuid()) { sLog.outError("HandlePetAction: %s isn't controlled by %s.", petGuid.GetString().c_str(), _player->GetGuidStr().c_str()); return; } if (!pet->isAlive()) return; if (pet->GetTypeId() == TYPEID_PLAYER && pet->GetCharmer()->GetTypeId() == TYPEID_PLAYER) { // controller player cannot use controlled player's spells if (flag != (ACT_COMMAND || ACT_REACTION)) return; } else if (((Creature*)pet)->IsPet()) { // pet can have action bar disabled if (((Pet*)pet)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS) return; } CharmInfo* charmInfo = pet->GetCharmInfo(); if (!charmInfo) { sLog.outError("WorldSession::HandlePetAction: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); return; } switch (flag) { case ACT_COMMAND: // 0x07 switch (spellid) { case COMMAND_STAY: // flat=1792 // STAY { pet->StopMoving(); pet->AttackStop(true, true); pet->GetMotionMaster()->Clear(); ((Pet*)pet)->SetStayPosition(true); ((Pet*)pet)->SetIsRetreating(); ((Pet*)pet)->SetSpellOpener(); charmInfo->SetCommandState(COMMAND_STAY); break; } case COMMAND_FOLLOW: // spellid=1792 // FOLLOW { pet->StopMoving(); pet->AttackStop(true, true); pet->GetMotionMaster()->Clear(); ((Pet*)pet)->SetStayPosition(); ((Pet*)pet)->SetIsRetreating(true); ((Pet*)pet)->SetSpellOpener(); charmInfo->SetCommandState(COMMAND_FOLLOW); break; } case COMMAND_ATTACK: // spellid=1792 // ATTACK { ((Pet*)pet)->SetIsRetreating(); ((Pet*)pet)->SetSpellOpener(); Unit* targetUnit = targetGuid ? _player->GetMap()->GetUnit(targetGuid) : nullptr; if (targetUnit && targetUnit != pet && targetUnit->isTargetableForAttack() && targetUnit->isInAccessablePlaceFor((Creature*)pet)) { _player->SetInCombatState(true, targetUnit); // This is true if pet has no target or has target but targets differs. if (pet->getVictim() != targetUnit) { pet->AttackStop(); pet->GetMotionMaster()->Clear(); if (((Creature*)pet)->AI()) { ((Creature*)pet)->AI()->AttackStart(targetUnit); // 10% chance to play special warlock pet attack talk, else growl if (((Creature*)pet)->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && roll_chance_i(10)) pet->SendPetTalk((uint32)PET_TALK_ATTACK); pet->SendPetAIReaction(); } else pet->Attack(targetUnit, true); } } break; } case COMMAND_ABANDON: // abandon (hunter pet) or dismiss (summoned pet) { Creature* petC = (Creature*)pet; if (petC->IsPet()) { Pet* p = (Pet*)petC; if (p->getPetType() == HUNTER_PET) p->Unsummon(PET_SAVE_AS_DELETED, _player); else // dismissing a summoned pet is like killing them (this prevents returning a soulshard...) p->SetDeathState(CORPSE); } else // charmed _player->Uncharm(); if (petC->IsTemporarySummon()) // special case when pet was temporary summon through DoSummonPossesed { petC->ForcedDespawn(); return; } ((Pet*)pet)->SetStayPosition(); break; } default: sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); } break; case ACT_REACTION: // 0x6 switch (spellid) { case REACT_PASSIVE: // passive { pet->AttackStop(true, true); ((Pet*)pet)->SetSpellOpener(); } case REACT_DEFENSIVE: // recovery case REACT_AGGRESSIVE: // activete { charmInfo->SetReactState(ReactStates(spellid)); break; } } break; case ACT_DISABLED: // 0x81 spell (disabled), ignore case ACT_PASSIVE: // 0x01 case ACT_ENABLED: // 0xC1 spell { ((Pet*)pet)->SetIsRetreating(); ((Pet*)pet)->SetSpellOpener(); Unit* unit_target = targetGuid ? _player->GetMap()->GetUnit(targetGuid) : nullptr; // do not cast unknown spells SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid); if (!spellInfo) { sLog.outError("WORLD: unknown PET spell id %i", spellid); return; } if (pet->GetCharmInfo() && pet->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo)) return; for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(i)); if (!spellEffect) continue; if (spellEffect->EffectImplicitTargetA == TARGET_ALL_ENEMY_IN_AREA || spellEffect->EffectImplicitTargetA == TARGET_ALL_ENEMY_IN_AREA_INSTANT || spellEffect->EffectImplicitTargetA == TARGET_ALL_ENEMY_IN_AREA_CHANNELED) return; } // do not cast not learned spells if (!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo)) return; pet->clearUnitState(UNIT_STAT_MOVING); Spell* spell = new Spell(pet, spellInfo, false); SpellCastResult result = spell->CheckPetCast(unit_target); const SpellRangeEntry* sRange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex); if (unit_target && !(pet->IsWithinDistInMap(unit_target, sRange->maxRange) && pet->IsWithinLOSInMap(unit_target)) && !(GetPlayer()->IsFriendlyTo(unit_target) || pet->HasAuraType(SPELL_AURA_MOD_POSSESS))) { ((Pet*)pet)->SetSpellOpener(spellid, sRange->minRange, sRange->maxRange); spell->finish(false); delete spell; pet->AttackStop(); pet->GetMotionMaster()->Clear(); ((Creature*)pet)->AI()->AttackStart(unit_target); // 10% chance to play special warlock pet attack talk, else growl if (((Creature*)pet)->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != unit_target && roll_chance_i(10)) pet->SendPetTalk((uint32)PET_TALK_ATTACK); pet->SendPetAIReaction(); return; } // auto turn to target unless possessed if (result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) { if (unit_target) { pet->SetInFront(unit_target); if (unit_target->GetTypeId() == TYPEID_PLAYER) pet->SendCreateUpdateToPlayer((Player*)unit_target); } else if (Unit* unit_target2 = spell->m_targets.getUnitTarget()) { pet->SetInFront(unit_target2); if (unit_target2->GetTypeId() == TYPEID_PLAYER) pet->SendCreateUpdateToPlayer((Player*)unit_target2); } if (Unit* powner = pet->GetCharmerOrOwner()) if (powner->GetTypeId() == TYPEID_PLAYER) pet->SendCreateUpdateToPlayer((Player*)powner); result = SPELL_CAST_OK; } if (result == SPELL_CAST_OK) { ((Creature*)pet)->AddCreatureSpellCooldown(spellid); unit_target = spell->m_targets.getUnitTarget(); if (unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) { // This is true if pet has no target or has target but targets differs. if (pet->getVictim() != unit_target) { pet->AttackStop(); pet->GetMotionMaster()->Clear(); _player->SetInCombatState(true, unit_target); if (((Creature*)pet)->AI()) { ((Creature*)pet)->AI()->AttackStart(unit_target); // 10% chance to play special warlock pet attack talk, else growl if (((Creature*)pet)->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != unit_target && roll_chance_i(10)) pet->SendPetTalk((uint32)PET_TALK_ATTACK); pet->SendPetAIReaction(); } else pet->Attack(unit_target, true); } } ((Pet*)pet)->SetSpellOpener(); spell->SpellStart(&(spell->m_targets)); } else { if (pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) Spell::SendCastResult(GetPlayer(), spellInfo, 0, result); else { Unit* owner = pet->GetCharmerOrOwner(); if (owner && owner->GetTypeId() == TYPEID_PLAYER) Spell::SendCastResult((Player*)owner, spellInfo, 0, result, true); } if (!((Creature*)pet)->HasSpellCooldown(spellid)) GetPlayer()->SendClearCooldown(spellid, pet); ((Pet*)pet)->SetSpellOpener(); spell->finish(false); delete spell; } break; } default: sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); } }
void WorldSession::HandlePetAction( WorldPacket & recv_data ) { ObjectGuid petGuid; uint32 data; ObjectGuid targetGuid; recv_data >> petGuid; recv_data >> data; recv_data >> targetGuid; uint32 spellid = UNIT_ACTION_BUTTON_ACTION(data); uint8 flag = UNIT_ACTION_BUTTON_TYPE(data); //delete = 0x07 CastSpell = C1 DETAIL_LOG("HandlePetAction: %s flag is %u, spellid is %u, target %s.", petGuid.GetString().c_str(), uint32(flag), spellid, targetGuid.GetString().c_str()); // used also for charmed creature/player Unit* pet = _player->GetMap()->GetUnit(petGuid); if (!pet) { sLog.outError("HandlePetAction: %s not exist.", petGuid.GetString().c_str()); return; } if (GetPlayer()->GetGUID() != pet->GetCharmerOrOwnerGUID()) { sLog.outError("HandlePetAction: %s isn't controlled by %s.", petGuid.GetString().c_str(), GetPlayer()->GetObjectGuid().GetString().c_str()); return; } if (!pet->isAlive()) return; if (pet->GetTypeId() == TYPEID_PLAYER) { // controller player can only do melee attack if (!(flag == ACT_COMMAND && spellid == COMMAND_ATTACK)) return; } else if (((Creature*)pet)->IsPet()) { // pet can have action bar disabled if(((Pet*)pet)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS) return; } CharmInfo *charmInfo = pet->GetCharmInfo(); if(!charmInfo) { sLog.outError("WorldSession::HandlePetAction: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); return; } switch(flag) { case ACT_COMMAND: //0x07 switch(spellid) { case COMMAND_STAY: //flat=1792 //STAY pet->StopMoving(); pet->GetMotionMaster()->Clear(false); pet->GetMotionMaster()->MoveIdle(); charmInfo->SetCommandState( COMMAND_STAY ); break; case COMMAND_FOLLOW: //spellid=1792 //FOLLOW pet->AttackStop(); pet->GetMotionMaster()->MoveFollow(_player,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE); charmInfo->SetCommandState( COMMAND_FOLLOW ); break; case COMMAND_ATTACK: //spellid=1792 //ATTACK { Unit *TargetUnit = _player->GetMap()->GetUnit(targetGuid); if(!TargetUnit) return; // not let attack friendly units. if(GetPlayer()->IsFriendlyTo(TargetUnit)) return; // Not let attack through obstructions if(!pet->IsWithinLOSInMap(TargetUnit)) return; // This is true if pet has no target or has target but targets differs. if(pet->getVictim() != TargetUnit) { if (pet->getVictim()) pet->AttackStop(); if (pet->hasUnitState(UNIT_STAT_CONTROLLED)) { pet->Attack(TargetUnit, true); pet->SendPetAIReaction(); } else { pet->GetMotionMaster()->Clear(); if (((Creature*)pet)->AI()) ((Creature*)pet)->AI()->AttackStart(TargetUnit); // 10% chance to play special pet attack talk, else growl if(((Creature*)pet)->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && roll_chance_i(10)) pet->SendPetTalk((uint32)PET_TALK_ATTACK); else { // 90% chance for pet and 100% chance for charmed creature pet->SendPetAIReaction(); } } } break; } case COMMAND_ABANDON: // abandon (hunter pet) or dismiss (summoned pet) if(((Creature*)pet)->IsPet()) { Pet* p = (Pet*)pet; if(p->getPetType() == HUNTER_PET) _player->RemovePet(p,PET_SAVE_AS_DELETED); else //dismissing a summoned pet is like killing them (this prevents returning a soulshard...) p->SetDeathState(CORPSE); } else // charmed _player->Uncharm(); break; default: sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); } break; case ACT_REACTION: // 0x6 switch(spellid) { case REACT_PASSIVE: //passive case REACT_DEFENSIVE: //recovery case REACT_AGGRESSIVE: //activete charmInfo->SetReactState( ReactStates(spellid) ); break; } break; case ACT_DISABLED: // 0x81 spell (disabled), ignore case ACT_PASSIVE: // 0x01 case ACT_ENABLED: // 0xC1 spell { Unit* unit_target = NULL; if (!targetGuid.IsEmpty()) unit_target = _player->GetMap()->GetUnit(targetGuid); // do not cast unknown spells SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid ); if (!spellInfo) { sLog.outError("WORLD: unknown PET spell id %i", spellid); return; } if (pet->GetCharmInfo() && pet->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo)) return; for(int i = 0; i < MAX_EFFECT_INDEX;++i) { if(spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_INSTANT || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED) return; } // do not cast not learned spells if(!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo)) return; pet->clearUnitState(UNIT_STAT_MOVING); Spell *spell = new Spell(pet, spellInfo, false); SpellCastResult result = spell->CheckPetCast(unit_target); //auto turn to target unless possessed if(result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) { if(unit_target) { pet->SetInFront(unit_target); if (unit_target->GetTypeId() == TYPEID_PLAYER) pet->SendCreateUpdateToPlayer( (Player*)unit_target ); } else if(Unit *unit_target2 = spell->m_targets.getUnitTarget()) { pet->SetInFront(unit_target2); if (unit_target2->GetTypeId() == TYPEID_PLAYER) pet->SendCreateUpdateToPlayer( (Player*)unit_target2 ); } if (Unit* powner = pet->GetCharmerOrOwner()) if(powner->GetTypeId() == TYPEID_PLAYER) pet->SendCreateUpdateToPlayer((Player*)powner); result = SPELL_CAST_OK; } if(result == SPELL_CAST_OK) { ((Creature*)pet)->AddCreatureSpellCooldown(spellid); unit_target = spell->m_targets.getUnitTarget(); //10% chance to play special pet attack talk, else growl //actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell if(((Creature*)pet)->IsPet() && (((Pet*)pet)->getPetType() == SUMMON_PET) && (pet != unit_target) && (urand(0, 100) < 10)) pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL); else { pet->SendPetAIReaction(); } if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) { // This is true if pet has no target or has target but targets differs. if (pet->getVictim() != unit_target) { if (pet->getVictim()) pet->AttackStop(); pet->GetMotionMaster()->Clear(); if (((Creature*)pet)->AI()) ((Creature*)pet)->AI()->AttackStart(unit_target); } } spell->prepare(&(spell->m_targets)); } else { if(pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) Spell::SendCastResult(GetPlayer(),spellInfo,0,result); else pet->SendPetCastFail(spellid, result); if (!((Creature*)pet)->HasSpellCooldown(spellid)) GetPlayer()->SendClearCooldown(spellid, pet); spell->finish(false); delete spell; } break; } default: sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); } }
void PlayerbotDruidAI::DoNextCombatManeuver(Unit *pTarget) { PlayerbotAI* ai = GetAI(); if (!ai) return; switch (ai->GetScenarioType()) { case PlayerbotAI::SCENARIO_DUEL: ai->CastSpell(MOONFIRE); return; default: break; } uint32 masterHP = GetMaster()->GetHealth() * 100 / GetMaster()->GetMaxHealth(); Player *m_bot = GetPlayerBot(); Unit* pVictim = pTarget->getVictim(); if (ai->GetCombatOrder() == PlayerbotAI::ORDERS_HEAL) // && ai->GetMovementOrder() == PlayerbotAI::MOVEMENT_STAY) SpellSequence = DruidHeal; else if (IsFeral() && ai->GetCombatOrder() == PlayerbotAI::ORDERS_ASSIST) // && ai->GetMovementOrder() == PlayerbotAI::MOVEMENT_STAY) SpellSequence = DruidCombat; else if (IsFeral() && ai->GetCombatOrder() == PlayerbotAI::ORDERS_TANK) SpellSequence = DruidTank; else SpellSequence = DruidSpell; switch (SpellSequence) { case DruidTank: // Its now a tank druid! //ai->TellMaster("DruidTank"); if (!m_bot->HasInArc(M_PI_F, pTarget)) { m_bot->SetFacingTo(m_bot->GetAngle(pTarget)); if (pVictim) pVictim->Attack(pTarget, true); } if (m_bot->HasAura(CAT_FORM, EFFECT_INDEX_0)) m_bot->RemoveAurasDueToSpell(768); //ai->TellMaster("FormClearCat"); if (MOONKIN_FORM > 0 && !m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) ai->CastSpell (MOONKIN_FORM); else if (DIRE_BEAR_FORM > 0 && !m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0) && !m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0)) ai->CastSpell (DIRE_BEAR_FORM); else if (BEAR_FORM > 0 && !m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0) && !m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0) && !m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) ai->CastSpell (BEAR_FORM); else if (DEMORALIZING_ROAR > 0 && (m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0) || m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) && !m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0) && !pTarget->HasAura(DEMORALIZING_ROAR, EFFECT_INDEX_0) && ai->GetRageAmount() >= 10) ai->CastSpell(DEMORALIZING_ROAR, *pTarget); if (FAERIE_FIRE > 0 && DruidSpellCombat < 1 && !pTarget->HasAura(FAERIE_FIRE, EFFECT_INDEX_0)) { ai->CastSpell(FAERIE_FIRE, *pTarget); DruidSpellCombat++; break; } else if (MOONFIRE > 0 && m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0) && DruidSpellCombat < 2 && !pTarget->HasAura(MOONFIRE, EFFECT_INDEX_0) && ai->GetManaPercent() >= 24) { ai->CastSpell(MOONFIRE, *pTarget); DruidSpellCombat++; break; } else if (ROOTS > 0 && m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0) && DruidSpellCombat < 3 && !pTarget->HasAura(ROOTS, EFFECT_INDEX_0) && ai->GetManaPercent() >= 8) { ai->CastSpell(ROOTS, *pTarget); DruidSpellCombat++; break; } else if (HURRICANE > 0 && m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0) && ai->GetAttackerCount() >= 5 && DruidSpellCombat < 4 && ai->GetManaPercent() >= 91) { //ai->TellMaster("casting hurricane!"); ai->CastSpell(HURRICANE, *pTarget); ai->SetIgnoreUpdateTime(10); DruidSpellCombat++; break; } else if (WRATH > 0 && m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0) && DruidSpellCombat < 5 && ai->GetManaPercent() >= 13) { ai->CastSpell(WRATH, *pTarget); DruidSpellCombat++; break; } else if (INSECT_SWARM > 0 && m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0) && DruidSpellCombat < 6 && !pTarget->HasAura(INSECT_SWARM, EFFECT_INDEX_0) && ai->GetManaPercent() >= 9) { ai->CastSpell(INSECT_SWARM, *pTarget); DruidSpellCombat++; break; } else if (STARFIRE > 0 && m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0) && DruidSpellCombat < 7 && ai->GetManaPercent() >= 18) { ai->CastSpell(STARFIRE, *pTarget); DruidSpellCombat++; break; } else if (FORCE_OF_NATURE > 0 && m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0) && DruidSpellCombat < 8 && ai->GetManaPercent() >= 12) { //ai->TellMaster("summoning treants."); ai->CastSpell(FORCE_OF_NATURE); DruidSpellCombat++; break; } else if (STARFALL > 0 && m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0) && !m_bot->HasAura(STARFALL, EFFECT_INDEX_0) && ai->GetAttackerCount() >= 3 && DruidSpellCombat < 9 && ai->GetManaPercent() >= 39) { ai->CastSpell(STARFALL, *pTarget); DruidSpellCombat++; break; } else if (BARKSKIN > 0 && pVictim == m_bot && m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0) && ai->GetHealthPercent() < 75 && DruidSpellCombat < 10 && !m_bot->HasAura(BARKSKIN, EFFECT_INDEX_0)) { ai->CastSpell(BARKSKIN, *m_bot); DruidSpellCombat++; break; } else if (INNERVATE > 0 && m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0) && ai->GetManaPercent() < 50 && DruidSpellCombat < 11 && !m_bot->HasAura(INNERVATE, EFFECT_INDEX_0)) { ai->CastSpell(INNERVATE, *m_bot); DruidSpellCombat++; break; } else if (ENRAGE > 0 && (m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0) || m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) && DruidSpellCombat < 2 && !m_bot->HasAura(ENRAGE, EFFECT_INDEX_0)) { ai->CastSpell(ENRAGE, *m_bot); DruidSpellCombat = DruidSpellCombat + 2; break; } else if (SWIPE > 0 && (m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0) || m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) && DruidSpellCombat < 4 && ai->GetRageAmount() >= 20) { ai->CastSpell(SWIPE, *pTarget); DruidSpellCombat = DruidSpellCombat + 2; break; } else if (MAUL > 0 && (m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0) || m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) && DruidSpellCombat < 6 && ai->GetRageAmount() >= 15) { ai->CastSpell(MAUL, *pTarget); DruidSpellCombat = DruidSpellCombat + 2; break; } else if (BASH > 0 && (m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0) || m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) && !pTarget->HasAura(BASH, EFFECT_INDEX_0) && DruidSpellCombat < 8 && ai->GetRageAmount() >= 10) { ai->CastSpell(BASH, *pTarget); DruidSpellCombat = DruidSpellCombat + 2; break; } else if (CHALLENGING_ROAR > 0 && (m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0) || m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) && pVictim != m_bot && DruidSpellCombat < 10 && !pTarget->HasAura(CHALLENGING_ROAR, EFFECT_INDEX_0) && !pTarget->HasAura(GROWL, EFFECT_INDEX_0) && ai->GetRageAmount() >= 15) { ai->CastSpell(CHALLENGING_ROAR, *pTarget); DruidSpellCombat = DruidSpellCombat + 2; break; } else if (GROWL > 0 && (m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0) || m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) && pVictim != m_bot && DruidSpellCombat < 12 && !pTarget->HasAura(CHALLENGING_ROAR, EFFECT_INDEX_0) && !pTarget->HasAura(GROWL, EFFECT_INDEX_0)) { ai->CastSpell(GROWL, *pTarget); DruidSpellCombat = DruidSpellCombat + 2; break; } else if (DruidSpellCombat > 13) { DruidSpellCombat = 0; break; } else { DruidSpellCombat = 0; break; } break; case DruidSpell: //ai->TellMaster("DruidSpell"); if (m_bot->HasAura(CAT_FORM, EFFECT_INDEX_0)) { m_bot->RemoveAurasDueToSpell(768); //ai->TellMaster("FormClearCat"); break; } if (m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) { m_bot->RemoveAurasDueToSpell(5487); //ai->TellMaster("FormClearBear"); break; } if (m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0)) { m_bot->RemoveAurasDueToSpell(9634); //ai->TellMaster("FormClearDireBear"); break; } if (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) { m_bot->RemoveAurasDueToSpell(24858); //ai->TellMaster("FormClearMoonkin"); break; } if (FAERIE_FIRE > 0 && DruidSpellCombat < 1 && !pTarget->HasAura(FAERIE_FIRE, EFFECT_INDEX_0) && ai->GetManaPercent() >= 8) { ai->CastSpell(FAERIE_FIRE, *pTarget); DruidSpellCombat++; break; } else if (MOONFIRE > 0 && DruidSpellCombat < 2 && !pTarget->HasAura(MOONFIRE, EFFECT_INDEX_0) && ai->GetManaPercent() >= 24) { ai->CastSpell(MOONFIRE, *pTarget); DruidSpellCombat++; break; } else if (ROOTS > 0 && DruidSpellCombat < 3 && !pTarget->HasAura(ROOTS, EFFECT_INDEX_0) && ai->GetManaPercent() >= 8) { ai->CastSpell(ROOTS, *pTarget); DruidSpellCombat++; break; } else if (HURRICANE > 0 && ai->GetAttackerCount() >= 5 && DruidSpellCombat < 4 && ai->GetManaPercent() >= 91) { //ai->TellMaster("casting hurricane!"); ai->CastSpell(HURRICANE, *pTarget); ai->SetIgnoreUpdateTime(10); DruidSpellCombat++; break; } else if (WRATH > 0 && DruidSpellCombat < 5 && ai->GetManaPercent() >= 13) { ai->CastSpell(WRATH, *pTarget); DruidSpellCombat++; break; } else if (INSECT_SWARM > 0 && DruidSpellCombat < 6 && !pTarget->HasAura(INSECT_SWARM, EFFECT_INDEX_0) && ai->GetManaPercent() >= 9) { ai->CastSpell(INSECT_SWARM, *pTarget); DruidSpellCombat++; break; } else if (STARFIRE > 0 && DruidSpellCombat < 7 && ai->GetManaPercent() >= 18) { ai->CastSpell(STARFIRE, *pTarget); DruidSpellCombat++; break; } else if (FORCE_OF_NATURE > 0 && DruidSpellCombat < 8 && ai->GetManaPercent() >= 12) { //ai->TellMaster("summoning treants."); ai->CastSpell(FORCE_OF_NATURE); DruidSpellCombat++; break; } else if (STARFALL > 0 && !m_bot->HasAura(STARFALL, EFFECT_INDEX_0) && ai->GetAttackerCount() >= 3 && DruidSpellCombat < 9 && ai->GetManaPercent() >= 39) { ai->CastSpell(STARFALL, *pTarget); DruidSpellCombat++; break; } else if (BARKSKIN > 0 && pVictim == m_bot && ai->GetHealthPercent() < 75 && DruidSpellCombat < 10 && !m_bot->HasAura(BARKSKIN, EFFECT_INDEX_0)) { ai->CastSpell(BARKSKIN, *m_bot); DruidSpellCombat++; break; } else if (INNERVATE > 0 && ai->GetManaPercent() < 50 && DruidSpellCombat < 11 && !m_bot->HasAura(INNERVATE, EFFECT_INDEX_0)) { ai->CastSpell(INNERVATE, *m_bot); DruidSpellCombat++; break; } else if (DruidSpellCombat > 13) { DruidSpellCombat = 0; break; } else { DruidSpellCombat = 0; break; } break; case DruidHeal: //ai->TellMaster("DruidHeal"); if (m_bot->HasAura(CAT_FORM, EFFECT_INDEX_0)) { m_bot->RemoveAurasDueToSpell(768); //ai->TellMaster("FormClearCat"); break; } if (m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) { m_bot->RemoveAurasDueToSpell(5487); //ai->TellMaster("FormClearBear"); break; } if (m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0)) { m_bot->RemoveAurasDueToSpell(9634); //ai->TellMaster("FormClearDireBear"); break; } if (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) { m_bot->RemoveAurasDueToSpell(24858); //ai->TellMaster("FormClearMoonkin"); break; } if (ai->GetHealthPercent() <= 40) { HealTarget (m_bot); break; } if (masterHP <= 40) { HealTarget (GetMaster()); break; } else { DruidSpellCombat = 0; break; } break; case DruidCombat: //ai->TellMaster("DruidCombat"); if (!m_bot->HasInArc(M_PI_F, pTarget)) { m_bot->SetFacingTo(m_bot->GetAngle(pTarget)); if (pVictim) pVictim->Attack(pTarget, true); } if (m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) { m_bot->RemoveAurasDueToSpell(5487); //ai->TellMaster("FormClearBear"); break; } if (m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0)) { m_bot->RemoveAurasDueToSpell(9634); //ai->TellMaster("FormClearDireBear"); break; } if (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) { m_bot->RemoveAurasDueToSpell(24858); //ai->TellMaster("FormClearMoonkin"); break; } if (CAT_FORM > 0 && !m_bot->HasAura(CAT_FORM, EFFECT_INDEX_0)) ai->CastSpell (CAT_FORM); /* if (COWER > 0 && m_bot->GetComboPoints() == 1 && ai->GetEnergyAmount() >= 20) { ai->CastSpell(COWER); //ai->TellMaster("Cower"); }*/ if (MAIM > 0 && m_bot->GetComboPoints() >= 1 && pTarget->IsNonMeleeSpellCasted(true)) { ai->CastSpell(MAIM, *pTarget); //ai->TellMaster("SpellPreventing Maim"); break; } if (RAKE > 0 && m_bot->GetComboPoints() <= 1 && ai->GetEnergyAmount() >= 40) { ai->CastSpell (RAKE, *pTarget); //ai->TellMaster("Rake"); break; } else if (CLAW > 0 && m_bot->GetComboPoints() <= 2 && ai->GetEnergyAmount() >= 45) { ai->CastSpell (CLAW, *pTarget); //ai->TellMaster("Claw"); break; } else if (MANGLE > 0 && m_bot->GetComboPoints() <= 3 && ai->GetEnergyAmount() >= 45) { ai->CastSpell (MANGLE, *pTarget); //ai->TellMaster("Mangle"); break; } else if (CLAW > 0 && m_bot->GetComboPoints() <= 4 && ai->GetEnergyAmount() >= 45) { ai->CastSpell (CLAW, *pTarget); //ai->TellMaster("Claw2"); break; } if (m_bot->GetComboPoints() == 5) { if (RIP > 0 && pTarget->getClass() == CLASS_ROGUE && ai->GetEnergyAmount() >= 30) ai->CastSpell(RIP, *pTarget); //ai->TellMaster("Rogue Rip"); else if (MAIM > 0 && pTarget->getClass() == CLASS_DRUID && ai->GetEnergyAmount() >= 35) ai->CastSpell(MAIM, *pTarget); //ai->TellMaster("Druid Maim"); else if (MAIM > 0 && pTarget->getClass() == CLASS_SHAMAN && ai->GetEnergyAmount() >= 35) ai->CastSpell(MAIM, *pTarget); //ai->TellMaster("Shaman Maim"); else if (MAIM > 0 && pTarget->getClass() == CLASS_WARLOCK && ai->GetEnergyAmount() >= 35) ai->CastSpell(MAIM, *pTarget); //ai->TellMaster("Warlock Maim"); else if (FEROCIOUS_BITE > 0 && pTarget->getClass() == CLASS_HUNTER && ai->GetEnergyAmount() >= 35) ai->CastSpell(FEROCIOUS_BITE, *pTarget); //ai->TellMaster("Hunter Ferocious Bite"); else if (FEROCIOUS_BITE > 0 && pTarget->getClass() == CLASS_WARRIOR && ai->GetEnergyAmount() >= 35) ai->CastSpell(FEROCIOUS_BITE, *pTarget); //ai->TellMaster("Warrior Ferocious Bite"); else if (FEROCIOUS_BITE > 0 && pTarget->getClass() == CLASS_PALADIN && ai->GetEnergyAmount() >= 35) ai->CastSpell(FEROCIOUS_BITE, *pTarget); //ai->TellMaster("Paladin Ferocious Bite"); else if (MAIM > 0 && pTarget->getClass() == CLASS_MAGE && ai->GetEnergyAmount() >= 35) ai->CastSpell(MAIM, *pTarget); //ai->TellMaster("Mage Maim"); else if (MAIM > 0 && pTarget->getClass() == CLASS_PRIEST && ai->GetEnergyAmount() >= 35) ai->CastSpell(MAIM, *pTarget); //ai->TellMaster("Priest Maim"); else if (MAIM > 0 && ai->GetEnergyAmount() >= 35) ai->CastSpell(MAIM, *pTarget); //ai->TellMaster("Else Maim"); break; } else { DruidSpellCombat = 0; break; } break; } } // end DoNextCombatManeuver
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; //---------------Ground phase start-------------------------- if (phase == 2) // Ground { if (PhaseSwitch_timer <= diff) { phase = 3; // to Air me->AddUnitMovementFlag(MOVEFLAG_ROOT); me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); me->AddUnitMovementFlag(MOVEFLAG_LEVITATING | MOVEFLAG_ONTRANSPORT); me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MoveIdle(); me->SetHover(true); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); PhaseSwitch_timer = 120000; PhaseSwitch_timer2 = 60000; } else PhaseSwitch_timer -= diff; if (rain_of_fire_timer <= diff) { Unit* pTarget = NULL; pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); if (pTarget) { DoCast(pTarget, SPELL_RAIN_OF_FIRE); } rain_of_fire_timer = 20000; } else rain_of_fire_timer -= diff; if (fel_fireball_timer <= diff) { Unit* pTarget = NULL; pTarget = SelectUnit(SELECT_TARGET_TOPAGGRO, 0); if (pTarget) DoCast(pTarget, SPELL_FEL_FIREBALL); fel_fireball_timer = 10000; } else fel_fireball_timer -= diff; if (dragons_breath_timer <= diff) { DoCast(me->getVictim(), SPELL_DRAGONS_BREATH); dragons_breath_timer = 25000; } else dragons_breath_timer -= diff; if (fire_nova_timer <= diff) { DoCast(me, SPELL_FIRE_NOVA); fire_nova_timer = 35000; } else fire_nova_timer -= diff; if (ground_summon_timer <= diff) { Unit* pTarget = NULL; Unit* Creature; pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); Creature = me->SummonCreature(NPC_GROUNDER, me->GetPositionX() + 5, me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000); Creature = me->SummonCreature(NPC_GROUNDER, me->GetPositionX() - 5, me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000); if (pTarget) Creature->Attack(pTarget, false); ground_summon_timer = 19000; } else ground_summon_timer -= diff; } //----------------Ground phase end----------------------- //----------------Fly phase start--------------------- if (phase == 3) // Air { if (PhaseSwitch_timer2 <= diff) { phase = 2; // Back to ground me->SetSpeed(MOVE_RUN, 1.0f); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->RemoveUnitMovementFlag(MOVEFLAG_ROOT); me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); me->RemoveUnitMovementFlag(MOVEFLAG_LEVITATING | MOVEFLAG_ONTRANSPORT); me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MoveChase(me->getVictim()); me->SetHover(true); PhaseSwitch_timer = 60000; PhaseSwitch_timer2 = 120000; } else PhaseSwitch_timer2 -= diff; if (rain_of_fire_timer <= diff) { for (int i = 0; i < 6; i++) { Unit* pTarget = NULL; pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); if (pTarget) { DoCast(pTarget, SPELL_RAIN_OF_FIRE); } } rain_of_fire_timer = 20000; } else rain_of_fire_timer -= diff; if (flight_summon_timer <= diff) { Unit* pTarget = NULL; Unit* Creature; pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); Creature = me->SummonCreature(NPC_GROUNDER_FLIGHT, me->GetPositionX() + 5, me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000); Creature = me->SummonCreature(NPC_GROUNDER_FLIGHT, me->GetPositionX() - 5, me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000); if (pTarget) Creature->Attack(pTarget, false); flight_summon_timer = 6000; } else flight_summon_timer -= diff; } //--------------Fly phase end------------------------- if (phase != 3 && phase != 1) DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (SayTimer <= diff) { if (Event) SayTimer = NextStep(++Step); } else SayTimer -= diff; if (Attack) { Player* pPlayer = Unit::GetPlayer(*me, PlayerGUID); me->SetFaction(14); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); if (pPlayer) { Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20); if (Creepjack) { Creepjack->Attack(pPlayer, true); Creepjack->SetFaction(14); Creepjack->GetMotionMaster()->MoveChase(pPlayer); Creepjack->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20); if (Malone) { Malone->Attack(pPlayer, true); Malone->SetFaction(14); Malone->GetMotionMaster()->MoveChase(pPlayer); Malone->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } DoStartMovement(pPlayer); AttackStart(pPlayer); } Attack = false; } if ((me->GetHealth() * 100) / me->GetMaxHealth() < 15 && !Done) { Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20); if (Creepjack) { CAST_CRE(Creepjack)->AI()->EnterEvadeMode(); Creepjack->SetFaction(1194); Creepjack->GetMotionMaster()->MoveTargetedHome(); Creepjack->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20); if (Malone) { CAST_CRE(Malone)->AI()->EnterEvadeMode(); Malone->SetFaction(1194); Malone->GetMotionMaster()->MoveTargetedHome(); Malone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetFaction(1194); Done = true; DoScriptText(SAY_GIVEUP, me, NULL); me->DeleteThreatList(); me->CombatStop(); me->GetMotionMaster()->MoveTargetedHome(); Player* player = Unit::GetPlayer(*me, PlayerGUID); if (player) player->GroupEventHappens(QUEST_WBI, me); reset_timer = 30000; } if (Done == true && reset_timer <= diff) { Reset(); } else reset_timer -= diff; DoMeleeAttackIfReady(); }
void createClassMirrors() { for (int i = 0; i <= 5; i++) { Map* pMap = m_creature->GetMap(); Map::PlayerList const &players = pMap->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { if(Unit* target = m_creature->GetMap()->GetUnit(itr->getSource()->GetGUID())) { Unit* pClone = m_creature->SummonCreature(m_bIsRegularMode ? CLONE : CLONE_H, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); if (pClone) { pClone->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_PASSIVE); pClone->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NOT_SELECTABLE); pClone->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_OOC_NOT_ATTACKABLE); pClone->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_UNK_6); pClone->SetDisplayId(target->GetNativeDisplayId()); pClone->SetName(target->GetName()); pClone->setFaction(FAC_HOSTILE); switch (target->getClass()) { case CLASS_PRIEST: pClone->SetMaxHealth(m_bIsRegularMode ? CLONE_HEALTH_PRIEST : CLONE_HEALTH_PRIEST_H); break; case CLASS_PALADIN: pClone->SetMaxHealth(m_bIsRegularMode ? CLONE_HEALTH_PALA : CLONE_HEALTH_PALA_H); break; case CLASS_WARLOCK: pClone->SetMaxHealth(m_bIsRegularMode ? CLONE_HEALTH_WARLOCK : CLONE_HEALTH_WARLOCK_H); break; case CLASS_MAGE: pClone->SetMaxHealth(m_bIsRegularMode ? CLONE_HEALTH_MAGE : CLONE_HEALTH_MAGE_H); break; case CLASS_ROGUE: pClone->SetMaxHealth(m_bIsRegularMode ? CLONE_HEALTH_ROGUE : CLONE_HEALTH_ROGUE_H); break; case CLASS_WARRIOR: pClone->SetMaxHealth(m_bIsRegularMode ? CLONE_HEALTH_WARRIOR : CLONE_HEALTH_WARRIOR_H); break; case CLASS_DRUID: pClone->SetMaxHealth(m_bIsRegularMode ? CLONE_HEALTH_DRUID : CLONE_HEALTH_DRUID_H); break; case CLASS_SHAMAN: pClone->SetMaxHealth(m_bIsRegularMode ? CLONE_HEALTH_SHAMAN : CLONE_HEALTH_SHAMAN_H); break; case CLASS_HUNTER: pClone->SetMaxHealth(m_bIsRegularMode ? CLONE_HEALTH_HUNT : CLONE_HEALTH_HUNT_H); break; case CLASS_DEATH_KNIGHT: pClone->SetMaxHealth(m_bIsRegularMode ? CLONE_HEALTH_DK : CLONE_HEALTH_DK_H); break; default: break; } pClone->SetHealth(pClone->GetMaxHealth()); pClone->Attack(target, true); pClone->AddThreat(target, 10.0f); cloneGUIDList.push_back(pClone->GetGUID()); } switch(i) { case 1: pClone->SetPhaseMask(16, true); clone16GUIDList.push_back(pClone->GetGUID()); break; case 2: pClone->SetPhaseMask(32, true); clone32GUIDList.push_back(pClone->GetGUID()); break; case 3: pClone->SetPhaseMask(64, true); clone64GUIDList.push_back(pClone->GetGUID()); break; case 4: pClone->SetPhaseMask(128, true); clone128GUIDList.push_back(pClone->GetGUID()); break; case 5: pClone->SetPhaseMask(256, true); clone256GUIDList.push_back(pClone->GetGUID()); break; default: break; } } } } }
CombatManeuverReturns PlayerbotDruidAI::_DoNextPVECombatManeuverCat(Unit* pTarget) { if (!m_ai) return RETURN_NO_ACTION_ERROR; if (!m_bot) return RETURN_NO_ACTION_ERROR; if (!m_bot->HasAura(CAT_FORM)) return RETURN_NO_ACTION_UNKNOWN; //Used to determine if this bot is highest on threat Unit *newTarget = m_ai->FindAttacker((PlayerbotAI::ATTACKERINFOTYPE) (PlayerbotAI::AIT_VICTIMSELF | PlayerbotAI::AIT_HIGHESTTHREAT), m_bot); Unit* pVictim = pTarget->getVictim(); // Face enemy, make sure you're attacking if (!m_bot->HasInArc(M_PI_F, pTarget)) { m_bot->SetFacingTo(m_bot->GetAngle(pTarget)); if (pVictim) pVictim->Attack(pTarget, true); } // Attempt to do a finishing move if (m_bot->GetComboPoints() >= 5) { // 25 Energy if (SAVAGE_ROAR > 0 && !m_bot->HasAura(SAVAGE_ROAR)) { if (CastSpell(SAVAGE_ROAR, pTarget)) return RETURN_CONTINUE; } // 30 Energy else if (RIP > 0 && !pTarget->HasAura(RIP, EFFECT_INDEX_0)) { if (CastSpell(RIP, pTarget)) return RETURN_CONTINUE; } // 35 Energy else if (FEROCIOUS_BITE > 0) { if (CastSpell(FEROCIOUS_BITE, pTarget)) return RETURN_CONTINUE; } } // End 5 ComboPoints if (newTarget && COWER > 0 && !m_bot->HasSpellCooldown(COWER) && CastSpell(COWER, pTarget)) return RETURN_CONTINUE; if (FAERIE_FIRE_FERAL > 0 && m_ai->In_Reach(pTarget,FAERIE_FIRE_FERAL) && !pTarget->HasAura(FAERIE_FIRE_FERAL, EFFECT_INDEX_0) && CastSpell(FAERIE_FIRE_FERAL, pTarget)) return RETURN_CONTINUE; if (TIGERS_FURY > 0 && !m_bot->HasSpellCooldown(TIGERS_FURY) && CastSpell(TIGERS_FURY)) return RETURN_CONTINUE; if (MANGLE_CAT > 0 && !pTarget->HasAura(MANGLE_CAT) && CastSpell(MANGLE_CAT)) return RETURN_CONTINUE; if (RAKE > 0 && !pTarget->HasAura(RAKE) && CastSpell(RAKE, pTarget)) return RETURN_CONTINUE; if (CLAW > 0 && CastSpell(CLAW, pTarget)) return RETURN_CONTINUE; return RETURN_NO_ACTION_UNKNOWN; }
void PlayerbotDruidAI::DoNextCombatManeuver(Unit *pTarget) { PlayerbotAI* ai = GetAI(); if (!ai) return; switch (ai->GetScenarioType()) { case PlayerbotAI::SCENARIO_DUEL: ai->CastSpell(MOONFIRE); return; } uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth(); ai->SetInFront( pTarget ); Player *m_bot = GetPlayerBot(); Unit* pVictim = pTarget->getVictim(); if (pVictim && ai->GetHealthPercent() >= 40) { if (pVictim == m_bot) SpellSequence = DruidTank; } else if (pTarget->GetHealth() > pTarget->GetMaxHealth()*0.8 && pVictim) { if (pVictim != m_bot) SpellSequence = DruidSpell; } else if (ai->GetHealthPercent() <= 40 || GetMaster()->GetHealth() < GetMaster()->GetMaxHealth()*0.8) SpellSequence = DruidHeal; else SpellSequence = DruidCombat; switch (SpellSequence) { case DruidTank: // Its not a tank druid, only self protecting from heavy damage if got aggro. ai->TellMaster("DruidTank"); if( !m_bot->HasInArc(M_PI, pTarget)) { m_bot->SetInFront(pTarget); if (pVictim) pVictim->Attack(pTarget, true); } if(m_bot->HasAura(CAT_FORM, 0)) { m_bot->RemoveAurasDueToSpell(768); //ai->TellMaster("FormClearCat"); } if (MOONKIN_FORM > 0 && !m_bot->HasAura(MOONKIN_FORM, 0)) { ai->CastSpell (MOONKIN_FORM); } else if (DIRE_BEAR_FORM > 0 && !m_bot->HasAura(MOONKIN_FORM, 0) && !m_bot->HasAura(DIRE_BEAR_FORM, 0)) { ai->CastSpell (DIRE_BEAR_FORM); } else if (BEAR_FORM > 0 && !m_bot->HasAura(MOONKIN_FORM, 0) && !m_bot->HasAura(DIRE_BEAR_FORM, 0) && !m_bot->HasAura(BEAR_FORM, 0)) { ai->CastSpell (BEAR_FORM); } else if (DEMORALIZING_ROAR > 0 && m_bot->HasAura(DIRE_BEAR_FORM, 0) || m_bot->HasAura(BEAR_FORM, 0) && !m_bot->HasAura(MOONKIN_FORM, 0) && !pTarget->HasAura(DEMORALIZING_ROAR, 0) && ai->GetRageAmount() >= 10) { ai->CastSpell(DEMORALIZING_ROAR, *pTarget); } if (FAERIE_FIRE > 0 && DruidSpellCombat < 1 && !pTarget->HasAura(FAERIE_FIRE, 0)) { ai->CastSpell(FAERIE_FIRE, *pTarget); DruidSpellCombat++; break; } else if (MOONFIRE > 0 && m_bot->HasAura(MOONKIN_FORM, 0) && DruidSpellCombat < 2 && !pTarget->HasAura(MOONFIRE, 0) && ai->GetManaPercent() >= 24) { ai->CastSpell(MOONFIRE, *pTarget); DruidSpellCombat++; break; } else if (ROOTS > 0 && m_bot->HasAura(MOONKIN_FORM, 0) && DruidSpellCombat < 3 && !pTarget->HasAura(ROOTS, 0) && ai->GetManaPercent() >= 8) { ai->CastSpell(ROOTS, *pTarget); DruidSpellCombat++; break; } else if (HURRICANE > 0 && m_bot->HasAura(MOONKIN_FORM, 0) && ai->GetAttackerCount()>=5 && DruidSpellCombat < 4 && ai->GetManaPercent() >= 91) { //ai->TellMaster("casting hurricane!"); ai->CastSpell(HURRICANE, *pTarget); ai->SetIgnoreUpdateTime(10); DruidSpellCombat++; break; } else if (WRATH > 0 && m_bot->HasAura(MOONKIN_FORM, 0) && DruidSpellCombat < 5 && ai->GetManaPercent() >= 13) { ai->CastSpell(WRATH, *pTarget); DruidSpellCombat++; break; } else if (INSECT_SWARM > 0 && m_bot->HasAura(MOONKIN_FORM, 0) && DruidSpellCombat < 6 && !pTarget->HasAura(INSECT_SWARM, 0) && ai->GetManaPercent() >= 9) { ai->CastSpell(INSECT_SWARM , *pTarget); DruidSpellCombat++; break; } else if (STARFIRE > 0 && m_bot->HasAura(MOONKIN_FORM, 0) && DruidSpellCombat < 7 && ai->GetManaPercent() >= 18) { ai->CastSpell(STARFIRE, *pTarget); DruidSpellCombat++; break; } else if (FORCE_OF_NATURE > 0 && m_bot->HasAura(MOONKIN_FORM, 0) && DruidSpellCombat < 8 && ai->GetManaPercent() >= 12) { //ai->TellMaster("summoning treants."); ai->CastSpell(FORCE_OF_NATURE); DruidSpellCombat++; break; } else if (STARFALL > 0 && m_bot->HasAura(MOONKIN_FORM, 0) && ai->GetAttackerCount()>=3 && DruidSpellCombat < 9 && ai->GetManaPercent() >= 39) { ai->CastSpell(STARFALL, *pTarget); DruidSpellCombat++; break; } else if (BARKSKIN > 0 && m_bot->HasAura(MOONKIN_FORM, 0) && ai->GetHealthPercent() < 50 && DruidSpellCombat < 10 && !m_bot->HasAura(BARKSKIN, 0)) { ai->CastSpell(BARKSKIN, *m_bot); DruidSpellCombat++; break; } else if (INNERVATE > 0 && m_bot->HasAura(MOONKIN_FORM, 0) && ai->GetManaPercent() < 50 && DruidSpellCombat < 11 && !m_bot->HasAura(INNERVATE, 0)) { ai->CastSpell(INNERVATE, *m_bot); DruidSpellCombat++; break; } else if (THORNS > 0 && m_bot->HasAura(MOONKIN_FORM, 0) && ai->GetManaPercent() >= 19 && DruidSpellCombat < 12 && !m_bot->HasAura(THORNS, 0)) { ai->CastSpell(THORNS, *m_bot); DruidSpellCombat++; break; } else if (DruidSpellCombat > 13) { DruidSpellCombat = 0; break; } else { DruidSpellCombat = 0; break; } break; case DruidSpell: //ai->TellMaster("DruidSpell"); if(m_bot->HasAura(CAT_FORM, 0)) { m_bot->RemoveAurasDueToSpell(768); //ai->TellMaster("FormClearCat"); break; } if(m_bot->HasAura(BEAR_FORM, 0)) { m_bot->RemoveAurasDueToSpell(5487); //ai->TellMaster("FormClearBear"); break; } if(m_bot->HasAura(DIRE_BEAR_FORM, 0)) { m_bot->RemoveAurasDueToSpell(9634); //ai->TellMaster("FormClearDireBear"); break; } if(m_bot->HasAura(MOONKIN_FORM, 0)) { m_bot->RemoveAurasDueToSpell(24858); //ai->TellMaster("FormClearMoonkin"); break; } if (FAERIE_FIRE > 0 && DruidSpellCombat < 1 && !pTarget->HasAura(FAERIE_FIRE, 0) && ai->GetManaPercent() >= 8) { ai->CastSpell(FAERIE_FIRE, *pTarget); DruidSpellCombat++; break; } else if (MOONFIRE > 0 && DruidSpellCombat < 2 && (!pTarget->HasAura(MOONFIRE, 0)) && ai->GetManaPercent() >= 24) { ai->CastSpell(MOONFIRE, *pTarget); DruidSpellCombat++; break; } else if (ROOTS > 0 && DruidSpellCombat < 3 && (!pTarget->HasAura(ROOTS, 0)) && ai->GetManaPercent() >= 8) { ai->CastSpell(ROOTS, *pTarget); DruidSpellCombat++; break; } else if (HURRICANE > 0 && ai->GetAttackerCount()>=5 && DruidSpellCombat < 4 && ai->GetManaPercent() >= 91) { //ai->TellMaster("casting hurricane!"); ai->CastSpell(HURRICANE, *pTarget); ai->SetIgnoreUpdateTime(10); DruidSpellCombat++; break; } else if (INNERVATE > 0 && ai->GetManaPercent() < 50 && DruidSpellCombat < 5 && !m_bot->HasAura(INNERVATE, 0)) { ai->CastSpell(INNERVATE, *m_bot); DruidSpellCombat++; break; } else if (WRATH > 0 && DruidSpellCombat < 6 && ai->GetManaPercent() >= 13) { ai->CastSpell(WRATH, *pTarget); DruidSpellCombat++; break; } else if (INSECT_SWARM > 0 && DruidSpellCombat < 7 && !pTarget->HasAura(INSECT_SWARM, 0) && ai->GetManaPercent() >= 9) { ai->CastSpell(INSECT_SWARM , *pTarget); DruidSpellCombat++; break; } else if (STARFIRE > 0 && DruidSpellCombat < 8 && ai->GetManaPercent() >= 18) { ai->CastSpell(STARFIRE, *pTarget); DruidSpellCombat++; break; } else if (FORCE_OF_NATURE > 0 && DruidSpellCombat < 9 && ai->GetManaPercent() >= 12) { //ai->TellMaster("summoning treants."); ai->CastSpell(FORCE_OF_NATURE); DruidSpellCombat++; break; } else if (STARFALL > 0 && ai->GetAttackerCount()>=3 && DruidSpellCombat < 10 && ai->GetManaPercent() >= 39) { ai->CastSpell(STARFALL, *pTarget); DruidSpellCombat++; break; } else if (BARKSKIN > 0 && ai->GetHealthPercent() < 50 && DruidSpellCombat < 11 && !m_bot->HasAura(BARKSKIN, 0)) { ai->CastSpell(BARKSKIN, *m_bot); DruidSpellCombat++; break; } else if (MANA_REJUVENATION > 0 && ai->GetManaPercent() < 50 && DruidSpellCombat < 12 && !m_bot->HasAura(MANA_REJUVENATION, 0)) { ai->CastSpell(MANA_REJUVENATION, *m_bot); DruidSpellCombat++; break; } else if (DruidSpellCombat > 13) { DruidSpellCombat = 0; break; } else { DruidSpellCombat = 0; break; } break; case DruidHeal: //ai->TellMaster("DruidHeal"); if(m_bot->HasAura(CAT_FORM, 0)) { m_bot->RemoveAurasDueToSpell(768); //ai->TellMaster("FormClearCat"); break; } if(m_bot->HasAura(BEAR_FORM, 0)) { m_bot->RemoveAurasDueToSpell(5487); //ai->TellMaster("FormClearBear"); break; } if(m_bot->HasAura(DIRE_BEAR_FORM, 0)) { m_bot->RemoveAurasDueToSpell(9634); //ai->TellMaster("FormClearDireBear"); break; } if(m_bot->HasAura(MOONKIN_FORM, 0)) { m_bot->RemoveAurasDueToSpell(24858); //ai->TellMaster("FormClearMoonkin"); break; } if (ai->GetHealthPercent() < 70) { HealTarget (*GetPlayerBot(), ai->GetHealthPercent()); break; } if (masterHP < 70) { HealTarget (*GetMaster(), masterHP); break; } else { DruidSpellCombat = 0; break; } break; case DruidCombat: //ai->TellMaster("DruidCombat"); if( !m_bot->HasInArc(M_PI, pTarget)) { m_bot->SetInFront(pTarget); if (pVictim) pVictim->Attack(pTarget, true); } if(m_bot->HasAura(BEAR_FORM, 0)) { m_bot->RemoveAurasDueToSpell(5487); //ai->TellMaster("FormClearBear"); break; } if(m_bot->HasAura(DIRE_BEAR_FORM, 0)) { m_bot->RemoveAurasDueToSpell(9634); //ai->TellMaster("FormClearDireBear"); break; } if(m_bot->HasAura(MOONKIN_FORM, 0)) { m_bot->RemoveAurasDueToSpell(24858); //ai->TellMaster("FormClearMoonkin"); break; } if (CAT_FORM > 0 && !m_bot->HasAura(CAT_FORM, 0)) ai->CastSpell (CAT_FORM); /* if (COWER > 0 && m_bot->GetComboPoints() == 1 && ai->GetEnergyAmount() >= 20) { ai->CastSpell(COWER); //ai->TellMaster("Cower"); }*/ if (MAIM > 0 && m_bot->GetComboPoints() >= 1 && pTarget->IsNonMeleeSpellCasted(true)) { ai->CastSpell(MAIM, *pTarget); //ai->TellMaster("SpellPreventing Maim"); break; } if (RAKE > 0 && m_bot->GetComboPoints() <= 1 && ai->GetEnergyAmount() >= 40) { ai->CastSpell (RAKE, *pTarget); //ai->TellMaster("Rake"); break; } else if (CLAW > 0 && m_bot->GetComboPoints() <= 2 && ai->GetEnergyAmount() >= 45) { ai->CastSpell (CLAW, *pTarget); //ai->TellMaster("Claw"); break; } else if (MANGLE > 0 && m_bot->GetComboPoints() <= 3 && ai->GetEnergyAmount() >= 45) { ai->CastSpell (MANGLE, *pTarget); //ai->TellMaster("Mangle"); break; } else if (CLAW > 0 && m_bot->GetComboPoints() <= 4 && ai->GetEnergyAmount() >= 45) { ai->CastSpell (CLAW, *pTarget); //ai->TellMaster("Claw2"); break; } if (m_bot->GetComboPoints() == 5) { if (RIP > 0 && pTarget->getClass() == CLASS_ROGUE && ai->GetEnergyAmount() >= 30) { ai->CastSpell(RIP, *pTarget); //ai->TellMaster("Rogue Rip"); } else if (MAIM > 0 && pTarget->getClass() == CLASS_DRUID && ai->GetEnergyAmount() >= 35) { ai->CastSpell(MAIM, *pTarget); //ai->TellMaster("Druid Maim"); } else if (MAIM > 0 && pTarget->getClass() == CLASS_SHAMAN && ai->GetEnergyAmount() >= 35) { ai->CastSpell(MAIM, *pTarget); //ai->TellMaster("Shaman Maim"); } else if (MAIM > 0 && pTarget->getClass() == CLASS_WARLOCK && ai->GetEnergyAmount() >= 35) { ai->CastSpell(MAIM, *pTarget); //ai->TellMaster("Warlock Maim"); } else if (FEROCIOUS_BITE > 0 && pTarget->getClass() == CLASS_HUNTER && ai->GetEnergyAmount() >= 35) { ai->CastSpell(FEROCIOUS_BITE, *pTarget); //ai->TellMaster("Hunter Ferocious Bite"); } else if (FEROCIOUS_BITE > 0 && pTarget->getClass() == CLASS_WARRIOR && ai->GetEnergyAmount() >= 35) { ai->CastSpell(FEROCIOUS_BITE, *pTarget); //ai->TellMaster("Warrior Ferocious Bite"); } else if (FEROCIOUS_BITE > 0 && pTarget->getClass() == CLASS_PALADIN && ai->GetEnergyAmount() >= 35) { ai->CastSpell(FEROCIOUS_BITE, *pTarget); //ai->TellMaster("Paladin Ferocious Bite"); } else if (FEROCIOUS_BITE > 0 && pTarget->getClass() == CLASS_DEATH_KNIGHT && ai->GetEnergyAmount() >= 25) { ai->CastSpell(FEROCIOUS_BITE, *pTarget); //ai->TellMaster("DK Ferocious Bite"); } else if (MAIM > 0 && pTarget->getClass() == CLASS_MAGE && ai->GetEnergyAmount() >= 35) { ai->CastSpell(MAIM, *pTarget); //ai->TellMaster("Mage Maim"); } else if (MAIM > 0 && pTarget->getClass() == CLASS_PRIEST && ai->GetEnergyAmount() >= 35) { ai->CastSpell(MAIM, *pTarget); //ai->TellMaster("Priest Maim"); } else if (MAIM > 0 && ai->GetEnergyAmount() >= 35) { ai->CastSpell(MAIM, *pTarget); //ai->TellMaster("Else Maim"); } break; } else { DruidSpellCombat = 0; break; } break; } } // end DoNextCombatManeuver
bool PlayerbotDruidAI::DoNextCombatManeuver(Unit *pTarget) { PlayerbotAI* ai = GetAI(); if (!ai) return false; Player* pMaster = ai->GetMaster(); if (!pMaster) return false; uint32 masterHP = pMaster->GetHealth() * 100 / pMaster->GetMaxHealth(); ai->SetInFront(pTarget); Player *m_bot = GetPlayerBot(); Unit* pVictim = pTarget->getVictim(); if (pVictim && (ai->GetHealthPercent() >= 40) && (pMaster->GetHealth() >= pMaster->GetMaxHealth() * 0.4)) { if (pVictim == m_bot) SpellSequence = DruidTank; } else if (pVictim && (pTarget->GetHealth() > pTarget->GetMaxHealth() * 0.8)) { if (pVictim != m_bot) SpellSequence = DruidSpell; } else if (ai->GetHealthPercent() <= 40 || pMaster->GetHealth() <= pMaster->GetMaxHealth() * 0.4) SpellSequence = DruidHeal; else SpellSequence = DruidCombat; switch (SpellSequence) { case DruidTank: m_bot->SetInFront(pTarget); if (pVictim) pVictim->Attack(pTarget, true); if (m_bot->HasAura(CAT_FORM, EFFECT_INDEX_0)) m_bot->RemoveAurasDueToSpell(768); if ((MOONKIN_FORM > 0) && (!m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) && (ai->CastSpell(MOONKIN_FORM))) return true; if ((DIRE_BEAR_FORM > 0) && (!m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) && (!m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0)) && (ai->CastSpell(DIRE_BEAR_FORM))) return true; if ((BEAR_FORM > 0) && (!m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) && (!m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0)) && (!m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) && (ai->CastSpell(BEAR_FORM))) return true; if ((DEMORALIZING_ROAR > 0) && ((m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0))|| m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) && (!m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) && (!pTarget->HasAura(DEMORALIZING_ROAR, EFFECT_INDEX_0)) && (ai->GetRageAmount() >= 10) && (ai->CastSpell(DEMORALIZING_ROAR, *pTarget))) return true; if ((FAERIE_FIRE > 0) && (DruidSpellCombat < 1) && (!pTarget->HasAura(FAERIE_FIRE, EFFECT_INDEX_0)) && (ai->CastSpell(FAERIE_FIRE, *pTarget))) { DruidSpellCombat++; return true; } if ((MOONFIRE > 0) && (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) && (DruidSpellCombat < 2) && (!pTarget->HasAura(MOONFIRE, EFFECT_INDEX_0)) && (ai->GetManaPercent() >= 24) && (ai->CastSpell(MOONFIRE, *pTarget))) { DruidSpellCombat++; return true; } if ((ROOTS > 0) && (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) && (DruidSpellCombat < 3) && (!pTarget->HasAura(ROOTS, EFFECT_INDEX_0)) && (ai->GetManaPercent() >= 8) && (ai->CastSpell(ROOTS, *pTarget))) { DruidSpellCombat++; return true; } if ((HURRICANE > 0) && (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) && (ai->GetAttackerCount() >= 5) && (DruidSpellCombat < 4) && (ai->GetManaPercent() >= 91) && (ai->CastSpell(HURRICANE, *pTarget))) { ai->SetIgnoreUpdateTime(10); DruidSpellCombat++; return true; } if ((WRATH > 0) && (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) && (DruidSpellCombat < 5) && (ai->GetManaPercent() >= 13) && (ai->CastSpell(WRATH, *pTarget))) { DruidSpellCombat++; return true; } if ((INSECT_SWARM > 0) && (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) && (DruidSpellCombat < 6) && (!pTarget->HasAura(INSECT_SWARM, EFFECT_INDEX_0)) && (ai->GetManaPercent() >= 9) && (ai->CastSpell(INSECT_SWARM , *pTarget))) { DruidSpellCombat++; return true; } if ((STARFIRE > 0) && (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) && (DruidSpellCombat < 7) && (ai->GetManaPercent() >= 18) && (ai->CastSpell(STARFIRE, *pTarget))) { DruidSpellCombat++; return true; } if ((FORCE_OF_NATURE > 0) && (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) && (DruidSpellCombat < 8) && (ai->GetManaPercent() >= 12) && (ai->CastSpell(FORCE_OF_NATURE))) { DruidSpellCombat++; return true; } if ((STARFALL > 0) && (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) && (!m_bot->HasAura(STARFALL, EFFECT_INDEX_0)) && (ai->GetAttackerCount() >= 3) && (DruidSpellCombat < 9) && (ai->GetManaPercent() >= 39) && (ai->CastSpell(STARFALL, *pTarget))) { DruidSpellCombat++; return true; } if ((BARKSKIN > 0) && (pVictim == m_bot) && (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) && (ai->GetHealthPercent() < 75) && (DruidSpellCombat < 10) && (!m_bot->HasAura(BARKSKIN, EFFECT_INDEX_0)) && (ai->CastSpell(BARKSKIN, *m_bot))) { DruidSpellCombat++; return true; } if ((INNERVATE > 0) && (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) && (ai->GetManaPercent() < 50) && (DruidSpellCombat < 11) && (!m_bot->HasAura(INNERVATE, EFFECT_INDEX_0)) && (ai->CastSpell(INNERVATE, *m_bot))) { DruidSpellCombat++; return true; } if ((MANA_REJUVENATION > 0) && (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) && (ai->GetManaPercent() < 50) && (!m_bot->HasAura(INNERVATE, EFFECT_INDEX_0)) && (DruidSpellCombat < 12) && (!m_bot->HasAura(MANA_REJUVENATION, EFFECT_INDEX_0)) && (ai->CastSpell(MANA_REJUVENATION, *m_bot))) { DruidSpellCombat++; return true; } if ((ENRAGE > 0) && ((m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0))|| m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) && (DruidSpellCombat < 2) && (!m_bot->HasAura(ENRAGE, EFFECT_INDEX_0)) && (ai->CastSpell(ENRAGE, *m_bot))) { DruidSpellCombat++; DruidSpellCombat++; return true; } if ((SWIPE > 0) && ((m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0))|| m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) && (DruidSpellCombat < 4) && (ai->GetRageAmount() >= 20) && (ai->CastSpell(SWIPE, *pTarget))) { DruidSpellCombat++; DruidSpellCombat++; return true; } if ((MAUL > 0) && ((m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0))|| m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) && (DruidSpellCombat < 6) && (ai->GetRageAmount() >= 15) && (ai->CastSpell(MAUL, *pTarget))) { DruidSpellCombat++; DruidSpellCombat++; return true; } if ((BASH > 0) && ((m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0))|| m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) && (!pTarget->HasAura(BASH, EFFECT_INDEX_0)) && (DruidSpellCombat < 8) && (ai->GetRageAmount() >= 10) && (ai->CastSpell(BASH, *pTarget))) { DruidSpellCombat++; DruidSpellCombat++; return true; } if ((CHALLENGING_ROAR > 0) && ((m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0))|| m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) && (pVictim != m_bot) && (DruidSpellCombat < 10) && (!pTarget->HasAura(CHALLENGING_ROAR, EFFECT_INDEX_0)) && (!pTarget->HasAura(GROWL, EFFECT_INDEX_0)) && (ai->GetRageAmount() >= 15) && (ai->CastSpell(CHALLENGING_ROAR, *pTarget))) { DruidSpellCombat++; DruidSpellCombat++; return true; } if ((GROWL > 0) && ((m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0))|| m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) && (pVictim != m_bot) && (DruidSpellCombat < 12) && (!pTarget->HasAura(CHALLENGING_ROAR, EFFECT_INDEX_0)) && (!pTarget->HasAura(GROWL, EFFECT_INDEX_0)) && (ai->CastSpell(GROWL, *pTarget))) { DruidSpellCombat++; DruidSpellCombat++; return true; } DruidSpellCombat = 0; break; case DruidSpell: if (m_bot->HasAura(CAT_FORM, EFFECT_INDEX_0)) m_bot->RemoveAurasDueToSpell(768); if (m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) m_bot->RemoveAurasDueToSpell(5487); if (m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0)) m_bot->RemoveAurasDueToSpell(9634); if (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) m_bot->RemoveAurasDueToSpell(24858); if ((FAERIE_FIRE > 0) && (DruidSpellCombat < 1) && (!pTarget->HasAura(FAERIE_FIRE, EFFECT_INDEX_0)) && (ai->GetManaPercent() >= 8) && (ai->CastSpell(FAERIE_FIRE, *pTarget))) { DruidSpellCombat++; return true; } if ((MOONFIRE > 0) && (DruidSpellCombat < 2) && (!pTarget->HasAura(MOONFIRE, EFFECT_INDEX_0)) && (ai->GetManaPercent() >= 24) && (ai->CastSpell(MOONFIRE, *pTarget))) { DruidSpellCombat++; return true; } if ((ROOTS > 0) && (DruidSpellCombat < 3) && (!pTarget->HasAura(ROOTS, EFFECT_INDEX_0)) && (ai->GetManaPercent() >= 8) && (ai->CastSpell(ROOTS, *pTarget))) { DruidSpellCombat++; return true; } if ((HURRICANE > 0) && (ai->GetAttackerCount() >= 5) && (DruidSpellCombat < 4) && (ai->GetManaPercent() >= 91) && (ai->CastSpell(HURRICANE, *pTarget))) { ai->SetIgnoreUpdateTime(10); DruidSpellCombat++; return true; } if ((WRATH > 0) && (DruidSpellCombat < 5) && (ai->GetManaPercent() >= 13) && (ai->CastSpell(WRATH, *pTarget))) { DruidSpellCombat++; return true; } if ((INSECT_SWARM > 0) && (DruidSpellCombat < 6) && (!pTarget->HasAura(INSECT_SWARM, EFFECT_INDEX_0)) && (ai->GetManaPercent() >= 9) && (ai->CastSpell(INSECT_SWARM , *pTarget))) { DruidSpellCombat++; return true; } if ((STARFIRE > 0) && (DruidSpellCombat < 7) && (ai->GetManaPercent() >= 18) && (ai->CastSpell(STARFIRE, *pTarget))) { DruidSpellCombat++; return true; } if ((FORCE_OF_NATURE > 0) && (DruidSpellCombat < 8) && (ai->GetManaPercent() >= 12) && (ai->CastSpell(FORCE_OF_NATURE))) { DruidSpellCombat++; return true; } if ((STARFALL > 0) && (!m_bot->HasAura(STARFALL, EFFECT_INDEX_0)) && (ai->GetAttackerCount() >= 3) && (DruidSpellCombat < 9) && (ai->GetManaPercent() >= 39) && (ai->CastSpell(STARFALL, *pTarget))) { DruidSpellCombat++; return true; } if ((BARKSKIN > 0) && (pVictim == m_bot) && (ai->GetHealthPercent() < 75) && (DruidSpellCombat < 10) && (!m_bot->HasAura(BARKSKIN, EFFECT_INDEX_0)) && (ai->CastSpell(BARKSKIN, *m_bot))) { DruidSpellCombat++; return true; } if ((INNERVATE > 0) && (ai->GetManaPercent() < 50) && (DruidSpellCombat < 11) && (!m_bot->HasAura(INNERVATE, EFFECT_INDEX_0)) && (ai->CastSpell(INNERVATE, *m_bot))) { DruidSpellCombat++; return true; } if ((MANA_REJUVENATION > 0) && (ai->GetManaPercent() < 50) && (DruidSpellCombat < 12) && (!m_bot->HasAura(INNERVATE, EFFECT_INDEX_0)) && (!m_bot->HasAura(MANA_REJUVENATION, EFFECT_INDEX_0)) && (ai->CastSpell(MANA_REJUVENATION, *m_bot))) { DruidSpellCombat++; return true; } DruidSpellCombat = 0; break; case DruidHeal: if (m_bot->HasAura(CAT_FORM, EFFECT_INDEX_0)) m_bot->RemoveAurasDueToSpell(768); if (m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) m_bot->RemoveAurasDueToSpell(5487); if (m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0)) m_bot->RemoveAurasDueToSpell(9634); if (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) m_bot->RemoveAurasDueToSpell(24858); if ((ai->GetHealthPercent() <= 40) && HealTarget(*m_bot, ai->GetHealthPercent())) return true; if ((masterHP <= 40) && HealTarget(*pMaster, masterHP)) return true; DruidSpellCombat = 0; break; case DruidCombat: m_bot->SetInFront(pTarget); if (pVictim) pVictim->Attack(pTarget, true); if (m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) m_bot->RemoveAurasDueToSpell(5487); if (m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0)) m_bot->RemoveAurasDueToSpell(9634); if (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) m_bot->RemoveAurasDueToSpell(24858); if ((CAT_FORM > 0) && (!m_bot->HasAura(CAT_FORM, EFFECT_INDEX_0)) && (ai->CastSpell(CAT_FORM))) return true; if ((MAIM > 0) && (m_bot->GetComboPoints() >= 1) && (pTarget->IsNonMeleeSpellCasted(true)) && (ai->CastSpell(MAIM, *pTarget))) return true; if ((RAKE > 0) && (m_bot->GetComboPoints() <= 1) && (ai->GetEnergyAmount() >= 40) && (ai->CastSpell(RAKE, *pTarget))) return true; if ((CLAW > 0) && (m_bot->GetComboPoints() <= 2) && (ai->GetEnergyAmount() >= 45) && (ai->CastSpell(CLAW, *pTarget))) return true; if ((MANGLE > 0) && (m_bot->GetComboPoints() <= 3) && (ai->GetEnergyAmount() >= 45) && (ai->CastSpell(MANGLE, *pTarget))) return true; if ((CLAW > 0) && (m_bot->GetComboPoints() <= 4) && (ai->GetEnergyAmount() >= 45) && (ai->CastSpell(CLAW, *pTarget))) return true; if (m_bot->GetComboPoints() == 5) { if ((RIP > 0) && (pTarget->getClass() == CLASS_ROGUE) && (ai->GetEnergyAmount() >= 30) && (ai->CastSpell(RIP, *pTarget))) return true; if ((MAIM > 0) && (pTarget->getClass() == CLASS_DRUID) && (ai->GetEnergyAmount() >= 35) && (ai->CastSpell(MAIM, *pTarget))) return true; if ((MAIM > 0) && (pTarget->getClass() == CLASS_SHAMAN) && (ai->GetEnergyAmount() >= 35) && (ai->CastSpell(MAIM, *pTarget))) return true; if ((MAIM > 0) && (pTarget->getClass() == CLASS_WARLOCK) && (ai->GetEnergyAmount() >= 35) && (ai->CastSpell(MAIM, *pTarget))) return true; if ((FEROCIOUS_BITE > 0) && (pTarget->getClass() == CLASS_HUNTER) && (ai->GetEnergyAmount() >= 35) && (ai->CastSpell(FEROCIOUS_BITE, *pTarget))) return true; if ((FEROCIOUS_BITE > 0) && (pTarget->getClass() == CLASS_WARRIOR) && (ai->GetEnergyAmount() >= 35) && (ai->CastSpell(FEROCIOUS_BITE, *pTarget))) return true; if ((FEROCIOUS_BITE > 0) && (pTarget->getClass() == CLASS_PALADIN) && (ai->GetEnergyAmount() >= 35) && (ai->CastSpell(FEROCIOUS_BITE, *pTarget))) return true; if ((FEROCIOUS_BITE > 0) && (pTarget->getClass() == CLASS_DEATH_KNIGHT) && (ai->GetEnergyAmount() >= 25) && (ai->CastSpell(FEROCIOUS_BITE, *pTarget))) return true; if ((MAIM > 0) && (pTarget->getClass() == CLASS_MAGE) && (ai->GetEnergyAmount() >= 35) && (ai->CastSpell(MAIM, *pTarget))) return true; if ((MAIM > 0) && (pTarget->getClass() == CLASS_PRIEST) && (ai->GetEnergyAmount() >= 35) && (ai->CastSpell(MAIM, *pTarget))) return true; if ((MAIM > 0) && (ai->GetEnergyAmount() >= 35) && (ai->CastSpell(MAIM, *pTarget))) return true; } DruidSpellCombat = 0; break; } return false; }