aboutsummaryrefslogtreecommitdiff
path: root/src/game/PetAI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/PetAI.cpp')
-rw-r--r--src/game/PetAI.cpp56
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;
}
}