diff options
Diffstat (limited to 'src/game/PetAI.cpp')
-rw-r--r-- | src/game/PetAI.cpp | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp index 7851ee6773f..0fcc707b104 100644 --- a/src/game/PetAI.cpp +++ b/src/game/PetAI.cpp @@ -74,7 +74,7 @@ void PetAI::_stopAttack() if(owner && m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW)) { - m_creature->GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE); + m_creature->GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST, m_creature->GetFollowAngle()); } else { @@ -112,17 +112,22 @@ void PetAI::UpdateAI(const uint32 diff) if(owner->isInCombat() && !(m_creature->HasReactState(REACT_PASSIVE) || m_creature->GetCharmInfo()->HasCommandState(COMMAND_STAY))) AttackStart(owner->getAttackerForHelper()); else if(m_creature->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW) && !m_creature->hasUnitState(UNIT_STAT_FOLLOW)) - m_creature->GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE); + m_creature->GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST, m_creature->GetFollowAngle()); } + else if (owner && !m_creature->hasUnitState(UNIT_STAT_FOLLOW)) // no charm info and no victim + m_creature->GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST, m_creature->GetFollowAngle()); if(!me->GetCharmInfo()) return; + bool inCombat = me->getVictim(); + + // Autocast (casted only in combat or persistent spells in any state) if (m_creature->GetGlobalCooldown() == 0 && !m_creature->hasUnitState(UNIT_STAT_CASTING)) { - bool inCombat = me->getVictim(); + typedef std::vector<std::pair<Unit*, Spell*> > TargetSpellList; + TargetSpellList targetSpellStore; - //Autocast for (uint8 i = 0; i < m_creature->GetPetAutoSpellSize(); ++i) { uint32 spellID = m_creature->GetPetAutoSpellOnPos(i); @@ -136,20 +141,38 @@ void PetAI::UpdateAI(const uint32 diff) // ignore some combinations of combat state and combat/noncombat spells if (!inCombat) { + // ignore attacking spells, and allow only self/around spells if (!IsPositiveSpell(spellInfo->Id)) continue; + + // non combat spells allowed + // only pet spells have IsNonCombatSpell and not fit this reqs: + // Consume Shadows, Lesser Invisibility, so ignore checks for its + if (!IsNonCombatSpell(spellInfo)) + { + // allow only spell without spell cost or with spell cost but not duration limit + int32 duration = GetSpellDuration(spellInfo); + if ((spellInfo->manaCost || spellInfo->ManaCostPercentage || spellInfo->manaPerSecond) && duration > 0) + continue; + + // allow only spell without cooldown > duration + int32 cooldown = GetSpellRecoveryTime(spellInfo); + if (cooldown >= 0 && duration >= 0 && cooldown > duration) + continue; + } } else { + // just ignore non-combat spells if (IsNonCombatSpell(spellInfo)) continue; } Spell *spell = new Spell(m_creature, spellInfo, false, 0); - if(inCombat && !m_creature->hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(m_creature->getVictim())) + if (inCombat && !m_creature->hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(m_creature->getVictim())) { - m_targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(m_creature->getVictim(), spell)); + targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(m_creature->getVictim(), spell)); continue; } else @@ -165,7 +188,7 @@ void PetAI::UpdateAI(const uint32 diff) if(spell->CanAutoCast(Target)) { - m_targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(Target, spell)); + targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(Target, spell)); spellUsed = true; break; } @@ -176,14 +199,14 @@ void PetAI::UpdateAI(const uint32 diff) } //found units to cast on to - if(!m_targetSpellStore.empty()) + if (!targetSpellStore.empty()) { - uint32 index = urand(0, m_targetSpellStore.size() - 1); + uint32 index = urand(0, targetSpellStore.size() - 1); - Spell* spell = m_targetSpellStore[index].second; - Unit* target = m_targetSpellStore[index].first; + Spell* spell = targetSpellStore[index].second; + Unit* target = targetSpellStore[index].first; - m_targetSpellStore.erase(m_targetSpellStore.begin() + index); + targetSpellStore.erase(targetSpellStore.begin() + index); SpellCastTargets targets; targets.setUnitTarget( target ); @@ -202,11 +225,10 @@ void PetAI::UpdateAI(const uint32 diff) spell->prepare(&targets); } - while (!m_targetSpellStore.empty()) - { - delete m_targetSpellStore.begin()->second; - m_targetSpellStore.erase(m_targetSpellStore.begin()); - } + + // deleted cached Spell objects + for(TargetSpellList::const_iterator itr = targetSpellStore.begin(); itr != targetSpellStore.end(); ++itr) + delete itr->second; } } |