本文整理汇总了C++中TargetSpellList::begin方法的典型用法代码示例。如果您正苦于以下问题:C++ TargetSpellList::begin方法的具体用法?C++ TargetSpellList::begin怎么用?C++ TargetSpellList::begin使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类TargetSpellList
的用法示例。
在下文中一共展示了TargetSpellList::begin方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: UpdateAI
//.........这里部分代码省略.........
if (!spellInfo)
continue;
if (m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
continue;
// 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);
SpellPowerEntry const* spellPower = spellInfo->GetSpellPower();
if (spellPower && (spellPower->manaCost || spellPower->ManaCostPercentage || spellPower->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);
if (inCombat && !m_creature->hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(m_creature->getVictim()))
{
targetSpellStore.push_back(TargetSpellList::value_type(m_creature->getVictim(), spell));
continue;
}
else
{
bool spellUsed = false;
for (GuidSet::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
{
Unit* Target = m_creature->GetMap()->GetUnit(*tar);
// only buff targets that are in combat, unless the spell can only be cast while out of combat
if (!Target)
continue;
if (spell->CanAutoCast(Target))
{
targetSpellStore.push_back(TargetSpellList::value_type(Target, spell));
spellUsed = true;
break;
}
}
if (!spellUsed)
delete spell;
}
}
// found units to cast on to
if (!targetSpellStore.empty())
{
uint32 index = urand(0, targetSpellStore.size() - 1);
Spell* spell = targetSpellStore[index].second;
Unit* target = targetSpellStore[index].first;
targetSpellStore.erase(targetSpellStore.begin() + index);
SpellCastTargets targets;
targets.setUnitTarget(target);
if (!m_creature->HasInArc(M_PI_F, target))
{
m_creature->SetInFront(target);
if (target->GetTypeId() == TYPEID_PLAYER)
m_creature->SendCreateUpdateToPlayer((Player*)target);
if (owner && owner->GetTypeId() == TYPEID_PLAYER)
m_creature->SendCreateUpdateToPlayer((Player*)owner);
}
m_creature->AddCreatureSpellCooldown(spell->m_spellInfo->Id);
spell->prepare(&targets);
}
// deleted cached Spell objects
for (TargetSpellList::const_iterator itr = targetSpellStore.begin(); itr != targetSpellStore.end(); ++itr)
delete itr->second;
}
}
示例2: UpdateAI
//.........这里部分代码省略.........
continue;
if (spellInfo->IsPositive())
{
if (spellInfo->CanBeUsedInCombat())
{
// check spell cooldown
if (me->HasSpellCooldown(spellInfo->Id))
continue;
// Check if we're in combat or commanded to attack
if (!me->isInCombat() && !me->GetCharmInfo()->IsCommandAttack())
continue;
}
Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE, 0);
bool spellUsed = false;
// Some spells can target enemy or friendly (DK Ghoul's Leap)
// Check for enemy first (pet then owner)
Unit* target = me->getAttackerForHelper();
if (!target && owner)
target = owner->getAttackerForHelper();
if (target)
{
if (CanAttack(target) && spell->CanAutoCast(target))
{
targetSpellStore.push_back(std::make_pair(target, spell));
spellUsed = true;
}
}
// No enemy, check friendly
if (!spellUsed)
{
for (std::set<uint64>::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
{
Unit* ally = ObjectAccessor::GetUnit(*me, *tar);
//only buff targets that are in combat, unless the spell can only be cast while out of combat
if (!ally)
continue;
if (spell->CanAutoCast(ally))
{
targetSpellStore.push_back(std::make_pair(ally, spell));
spellUsed = true;
break;
}
}
}
// No valid targets at all
if (!spellUsed)
delete spell;
}
else if (me->getVictim() && CanAttack(me->getVictim()) && spellInfo->CanBeUsedInCombat())
{
Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE, 0);
if (spell->CanAutoCast(me->getVictim()))
targetSpellStore.push_back(std::make_pair(me->getVictim(), spell));
else
delete spell;
}
}
//found units to cast on to
if (!targetSpellStore.empty())
{
uint32 index = urand(0, targetSpellStore.size() - 1);
Spell* spell = targetSpellStore[index].second;
Unit* target = targetSpellStore[index].first;
targetSpellStore.erase(targetSpellStore.begin() + index);
SpellCastTargets targets;
targets.SetUnitTarget(target);
if (!me->HasInArc(M_PI, target))
{
me->SetInFront(target);
if (target && target->GetTypeId() == TYPEID_PLAYER)
me->SendUpdateToPlayer(target->ToPlayer());
if (owner && owner->GetTypeId() == TYPEID_PLAYER)
me->SendUpdateToPlayer(owner->ToPlayer());
}
me->AddCreatureSpellCooldown(spell->m_spellInfo->Id);
spell->prepare(&targets);
}
// deleted cached Spell objects
for (TargetSpellList::const_iterator itr = targetSpellStore.begin(); itr != targetSpellStore.end(); ++itr)
delete itr->second;
}
}
示例3: UpdateAI
//.........这里部分代码省略.........
// check spell cooldown
if (me->HasSpellCooldown(spellInfo->Id))
continue;
// Check if we're in combat or commanded to attack
if (!me->isInCombat() && !me->GetCharmInfo()->IsCommandAttack())
continue;
}
Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE, 0);
bool spellUsed = false;
// Some spells can target enemy or friendly (DK Ghoul's Leap)
// Check for enemy first (pet then owner)
Unit* target = me->getAttackerForHelper();
if (!target && owner)
target = owner->getAttackerForHelper();
if (target)
{
if (CanAttack(target) && spell->CanAutoCast(target))
{
targetSpellStore.push_back(std::make_pair(target, spell));
spellUsed = true;
}
}
if (spellInfo->HasEffect(SPELL_EFFECT_JUMP_DEST))
continue; // Pets must only jump to target
// No enemy, check friendly
if (!spellUsed)
{
for (std::set<uint64>::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
{
Unit* ally = ObjectAccessor::GetUnit(*me, *tar);
//only buff targets that are in combat, unless the spell can only be cast while out of combat
if (!ally)
continue;
if (spell->CanAutoCast(ally))
{
targetSpellStore.push_back(std::make_pair(ally, spell));
spellUsed = true;
break;
}
}
}
// No valid targets at all
if (!spellUsed)
delete spell;
}
else if (me->getVictim() && CanAttack(me->getVictim()) && spellInfo->CanBeUsedInCombat())
{
Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE, 0);
if (spell->CanAutoCast(me->getVictim()))
targetSpellStore.push_back(std::make_pair(me->getVictim(), spell));
else
delete spell;
}
}
//found units to cast on to
if (!targetSpellStore.empty())
示例4: UpdateAI
//.........这里部分代码省略.........
continue;
// non combat spells allowed
// only pet spells have IsNonCombatSpell and not fit this requirements:
// Consume Shadows, Lesser Invisibility, so ignore checks for its
if (!IsNonCombatSpell(spellInfo))
{
int32 duration = GetSpellDuration(spellInfo);
int32 cooldown = GetSpellRecoveryTime(spellInfo);
// allow only spell not on cooldown
if (cooldown != 0 && duration < cooldown)
continue;
// not allow instant kill auto casts as full health cost
if (IsSpellHaveEffect(spellInfo, SPELL_EFFECT_INSTAKILL))
continue;
}
}
// just ignore non-combat spells
else if (IsNonCombatSpell(spellInfo))
continue;
Spell* spell = new Spell(m_unit, spellInfo, false);
if (inCombat && !m_unit->hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(victim))
{
targetSpellStore.push_back(TargetSpellList::value_type(victim, spell));
continue;
}
else
{
bool spellUsed = false;
for (GuidSet::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
{
Unit* Target = m_unit->GetMap()->GetUnit(*tar);
// only buff targets that are in combat, unless the spell can only be cast while out of combat
if (!Target)
continue;
if (spell->CanAutoCast(Target))
{
targetSpellStore.push_back(TargetSpellList::value_type(Target, spell));
spellUsed = true;
break;
}
}
if (!spellUsed)
delete spell;
}
}
}
// found units to cast on to
if (!targetSpellStore.empty())
{
uint32 index = urand(0, targetSpellStore.size() - 1);
Spell* spell = targetSpellStore[index].second;
Unit* target = targetSpellStore[index].first;
targetSpellStore.erase(targetSpellStore.begin() + index);
SpellCastTargets targets;
targets.setUnitTarget(target);
示例5: UpdateAI
void PetAI::UpdateAI(const uint32 diff)
{
if (!m_creature->isAlive())
return;
Unit* owner = m_creature->GetCharmerOrOwner();
if (m_updateAlliesTimer <= diff)
// UpdateAllies self set update timer
UpdateAllies();
else
m_updateAlliesTimer -= diff;
// m_creature->getVictim() can't be used for check in case stop fighting, m_creature->getVictim() clear at Unit death etc.
if ( m_creature->getVictim() )
{
if ( _needToStop() )
{
DEBUG_LOG("Pet AI stoped attacking [guid=%u]", m_creature->GetGUIDLow());
_stopAttack();
return;
}
DoMeleeAttackIfReady();
}
else if (owner && m_creature->GetCharmInfo()) //no victim
{
Unit *nextTarget = SelectNextTarget();
if (nextTarget)
AttackStart(nextTarget);
else
HandleReturnMovement();
}
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;
// Autocast (casted only in combat or persistent spells in any state)
if (m_creature->GetGlobalCooldown() == 0 && !m_creature->hasUnitState(UNIT_STAT_CASTING))
{
typedef std::vector<std::pair<Unit*, Spell*> > TargetSpellList;
TargetSpellList targetSpellStore;
for (uint8 i = 0; i < m_creature->GetPetAutoSpellSize(); ++i)
{
uint32 spellID = m_creature->GetPetAutoSpellOnPos(i);
if (!spellID)
continue;
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellID);
if (!spellInfo)
continue;
// ignore some combinations of combat state and combat/noncombat spells
if (!me->getVictim())
{
// 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);
// Fix to allow pets on STAY to autocast
if (me->getVictim() && _CanAttack(me->getVictim()) && spell->CanAutoCast(me->getVictim()))
{
targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(m_creature->getVictim(), spell));
continue;
}
else
{
bool spellUsed = false;
for (std::set<uint64>::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
{
Unit* Target = ObjectAccessor::GetUnit(*m_creature,*tar);
//.........这里部分代码省略.........
示例6: UpdateAI
void PetAI::UpdateAI(const uint32 diff)
{
if (!me->isAlive())
return;
Unit* owner = me->GetCharmerOrOwner();
if (m_updateAlliesTimer <= diff)
// UpdateAllies self set update timer
UpdateAllies();
else
m_updateAlliesTimer -= diff;
// me->getVictim() can't be used for check in case stop fighting, me->getVictim() clear at Unit death etc.
if (me->getVictim())
{
// is only necessary to stop casting, the pet must not exit combat
if (me->getVictim()->HasBreakableByDamageCrowdControlAura(me))
{
me->InterruptNonMeleeSpells(false);
return;
}
if (_needToStop())
{
sLog->outStaticDebug("Pet AI stopped attacking [guid=%u]", me->GetGUIDLow());
_stopAttack();
return;
}
DoMeleeAttackIfReady();
}
else if (owner && me->GetCharmInfo()) //no victim
{
Unit* nextTarget = SelectNextTarget();
if (me->HasReactState(REACT_PASSIVE))
_stopAttack();
else if (nextTarget)
AttackStart(nextTarget);
else
HandleReturnMovement();
}
else if (owner && !me->HasUnitState(UNIT_STATE_FOLLOW)) // no charm info and no victim
me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle());
if (!me->GetCharmInfo())
return;
// Autocast (casted only in combat or persistent spells in any state)
if (!me->HasUnitState(UNIT_STATE_CASTING))
{
typedef std::vector<std::pair<Unit*, Spell*> > TargetSpellList;
TargetSpellList targetSpellStore;
for (uint8 i = 0; i < me->GetPetAutoSpellSize(); ++i)
{
uint32 spellID = me->GetPetAutoSpellOnPos(i);
if (!spellID)
continue;
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID);
if (!spellInfo)
continue;
// Check global cooldown
if (me->GetCharmInfo() && me->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
continue;
// Check spell cooldown
if (me->HasSpellCooldown(spellInfo->Id))
continue;
// Check if pet is in combat and if spell can be cast
if (me->isInCombat() && !spellInfo->CanBeUsedInCombat())
continue;
// Prevent spells like Furious Howl from constantly casting out of
// combat when the cooldown is up
if (!me->isInCombat() && !spellInfo->NeedsToBeTriggeredByCaster())
continue;
// We have a spell we can cast, let's pick a target
if (spellInfo->IsPositive())
{
// These would be buff spells like Furious Howl, Consume Shadows, etc.
Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE, 0);
bool spellUsed = false;
for (std::set<uint64>::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
{
Unit* target = ObjectAccessor::GetUnit(*me, *tar);
if (!target)
continue;
if (spell->CanAutoCast(target))
{
targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(target, spell));
spellUsed = true;
//.........这里部分代码省略.........
示例7: UpdateAI
void PetAI::UpdateAI(const uint32 diff)
{
if (!me->isAlive())
return;
Unit* owner = me->GetCharmerOrOwner();
if (m_updateAlliesTimer <= diff)
// UpdateAllies self set update timer
UpdateAllies();
else
m_updateAlliesTimer -= diff;
// me->getVictim() can't be used for check in case stop fighting, me->getVictim() clear at Unit death etc.
if (me->getVictim())
{
// is only necessary to stop casting, the pet must not exit combat
if (me->getVictim()->HasBreakableByDamageCrowdControlAura())
{
me->InterruptNonMeleeSpells(false);
return;
}
if (_needToStop())
{
sLog->outStaticDebug("Pet AI stopped attacking [guid=%u]", me->GetGUIDLow());
_stopAttack();
return;
}
DoMeleeAttackIfReady();
}
else if (owner && me->GetCharmInfo()) //no victim
{
Unit* nextTarget = SelectNextTarget();
if (me->HasReactState(REACT_PASSIVE))
_stopAttack();
else if (nextTarget)
AttackStart(nextTarget);
else
HandleReturnMovement();
}
else if (owner && !me->HasUnitState(UNIT_STATE_FOLLOW)) // no charm info and no victim
me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle());
if (!me->GetCharmInfo())
return;
// Autocast (casted only in combat or persistent spells in any state)
if (!me->HasUnitState(UNIT_STATE_CASTING))
{
typedef std::vector<std::pair<Unit*, Spell*> > TargetSpellList;
TargetSpellList targetSpellStore;
for (uint8 i = 0; i < me->GetPetAutoSpellSize(); ++i)
{
uint32 spellID = me->GetPetAutoSpellOnPos(i);
if (!spellID)
continue;
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID);
if (!spellInfo)
continue;
if (me->GetCharmInfo() && me->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
continue;
if (spellInfo->IsPositive())
{
// non combat spells allowed
// only pet spells have IsNonCombatSpell and not fit this reqs:
// Consume Shadows, Lesser Invisibility, so ignore checks for its
if (spellInfo->CanBeUsedInCombat())
{
// allow only spell without spell cost or with spell cost but not duration limit
int32 duration = spellInfo->GetDuration();
if ((spellInfo->ManaCost || spellInfo->ManaCostPercentage || spellInfo->ManaPerSecond) && duration > 0)
continue;
// allow only spell without cooldown > duration
int32 cooldown = spellInfo->GetRecoveryTime();
if (cooldown >= 0 && duration >= 0 && cooldown > duration)
continue;
}
Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE, 0);
bool spellUsed = false;
for (std::set<uint64>::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
{
Unit* target = ObjectAccessor::GetUnit(*me, *tar);
//only buff targets that are in combat, unless the spell can only be cast while out of combat
if (!target)
continue;
if (spell->CanAutoCast(target))
{
targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(target, spell));
//.........这里部分代码省略.........
示例8: UpdateAI
//.........这里部分代码省略.........
// check spell cooldown, this should be checked in CheckCast...
if (me->HasSpellCooldown(spellInfo->Id))
continue;
if (spellInfo->IsPositive())
{
if (spellInfo->CanBeUsedInCombat())
{
// Check if we're in combat or commanded to attack
if (!me->IsInCombat() && !me->GetCharmInfo()->IsCommandAttack())
continue;
}
Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE, 0);
spell->LoadScripts(); // xinef: load for CanAutoCast (calling CheckPetCast)
bool spellUsed = false;
// Some spells can target enemy or friendly (DK Ghoul's Leap)
// Check for enemy first (pet then owner)
Unit* target = me->getAttackerForHelper();
if (!target && owner)
target = owner->getAttackerForHelper();
if (target)
{
if (CanAttack(target) && spell->CanAutoCast(target))
{
targetSpellStore.push_back(std::make_pair(target, spell));
spellUsed = true;
}
}
// No enemy, check friendly
if (!spellUsed)
{
for (std::set<uint64>::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
{
Unit* ally = ObjectAccessor::GetUnit(*me, *tar);
//only buff targets that are in combat, unless the spell can only be cast while out of combat
if (!ally)
continue;
if (spell->CanAutoCast(ally))
{
targetSpellStore.push_back(std::make_pair(ally, spell));
spellUsed = true;
break;
}
}
}
// No valid targets at all
if (!spellUsed)
delete spell;
}
else if (me->GetVictim() && CanAttack(me->GetVictim(), spellInfo) && spellInfo->CanBeUsedInCombat())
{
Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE, 0);
if (spell->CanAutoCast(me->GetVictim()))
targetSpellStore.push_back(std::make_pair(me->GetVictim(), spell));
else
delete spell;
}
}
//found units to cast on to
if (!targetSpellStore.empty())
{
uint32 index = urand(0, targetSpellStore.size() - 1);
Spell* spell = targetSpellStore[index].second;
Unit* target = targetSpellStore[index].first;
targetSpellStore.erase(targetSpellStore.begin() + index);
SpellCastTargets targets;
targets.SetUnitTarget(target);
if (!me->HasInArc(M_PI, target))
{
me->SetInFront(target);
if (target && target->GetTypeId() == TYPEID_PLAYER)
me->SendUpdateToPlayer(target->ToPlayer());
if (owner && owner->GetTypeId() == TYPEID_PLAYER)
me->SendUpdateToPlayer(owner->ToPlayer());
}
me->AddSpellCooldown(spell->m_spellInfo->Id, 0, 0);
spell->prepare(&targets);
}
// deleted cached Spell objects
for (TargetSpellList::const_iterator itr = targetSpellStore.begin(); itr != targetSpellStore.end(); ++itr)
delete itr->second;
}
}
示例9: UpdateAI
//.........这里部分代码省略.........
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))
{
int32 duration = GetSpellDuration(spellInfo);
int32 cooldown = GetSpellRecoveryTime(spellInfo);
// allow only spell not on cooldown
if (cooldown != 0 && duration < cooldown)
continue;
// not allow instant kill autocasts as full health cost
if (IsSpellHaveEffect(spellInfo, SPELL_EFFECT_INSTAKILL))
continue;
}
}
// just ignore non-combat spells
else if (IsNonCombatSpell(spellInfo))
continue;
Spell* spell = new Spell(m_creature, spellInfo, false);
if (inCombat && !m_creature->hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(m_creature->getVictim()))
{
targetSpellStore.push_back(TargetSpellList::value_type(m_creature->getVictim(), spell));
continue;
}
else
{
bool spellUsed = false;
for (GuidSet::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
{
Unit* Target = m_creature->GetMap()->GetUnit(*tar);
// only buff targets that are in combat, unless the spell can only be cast while out of combat
if (!Target)
continue;
if (spell->CanAutoCast(Target))
{
targetSpellStore.push_back(TargetSpellList::value_type(Target, spell));
spellUsed = true;
break;
}
}
if (!spellUsed)
delete spell;
}
}
// found units to cast on to
if (!targetSpellStore.empty())
{
uint32 index = urand(0, targetSpellStore.size() - 1);
Spell* spell = targetSpellStore[index].second;
Unit* target = targetSpellStore[index].first;
targetSpellStore.erase(targetSpellStore.begin() + index);
SpellCastTargets targets;
targets.setUnitTarget(target);
示例10: UpdateAI
void PetAI::UpdateAI(const uint32 diff)
{
if (!m_creature->isAlive() || !m_creature->GetCharmInfo())
return;
Unit* owner = m_creature->GetCharmerOrOwner();
if (m_updateAlliesTimer <= diff)
// UpdateAllies self set update timer
UpdateAllies();
else
m_updateAlliesTimer -= diff;
// First checking if we have some taunt on us
Unit* tauntTarget = NULL;
const Unit::AuraList& tauntAuras = m_creature->GetAurasByType(SPELL_AURA_MOD_TAUNT);
if (!tauntAuras.empty())
{
Unit* caster = NULL;
// Auras are pushed_back, last caster will be on the end
Unit::AuraList::const_iterator aura = tauntAuras.end();
while (aura != tauntAuras.begin())
{
--aura;
caster = (*aura)->GetCaster();
if (caster && caster->isTargetableForAttack())
{
tauntTarget = caster;
break;
}
}
if (tauntTarget)
DoAttack(tauntTarget, true);
}
if (m_creature->getVictim() && m_creature->getVictim()->isAlive())
{
if (_needToStop())
{
_stopAttack();
return;
}
if (hasMelee)
{
// Check before attacking to prevent pets from leaving stay position
bool attacked = false;
if (m_creature->GetCharmInfo()->HasCommandState(COMMAND_STAY))
{
if (m_creature->GetCharmInfo()->IsCommandAttack() || (m_creature->GetCharmInfo()->IsAtStay() && m_creature->CanReachWithMeleeAttack(m_creature->getVictim())))
attacked = DoMeleeAttackIfReady();
}
else
attacked = DoMeleeAttackIfReady();
if (attacked && owner)
if (Unit* v = m_creature->getVictim()) // Victim may have died between
owner->SetInCombatWith(v);
}
}
else
{
if (m_creature->HasReactState(REACT_AGGRESSIVE) || m_creature->GetCharmInfo()->IsAtStay())
{
// Every update we need to check targets only in certain cases
// Aggressive - Allow auto select if owner or pet don't have a target
// Stay - Only pick from pet or owner targets / attackers so targets won't run by
// while chasing our owner. Don't do auto select.
// All other cases (ie: defensive) - Targets are assigned by AttackedBy(), OwnerAttackedBy(), OwnerAttacked(), etc.
Unit* nextTarget = SelectNextTarget(m_creature->HasReactState(REACT_AGGRESSIVE));
if (nextTarget)
AttackStart(nextTarget);
else
HandleReturnMovement();
}
else
HandleReturnMovement();
}
// Autocast (casted only in combat or persistent spells in any state)
if (!m_creature->IsNonMeleeSpellCasted(false))
{
typedef std::vector<std::pair<Unit*, Spell*> > TargetSpellList;
TargetSpellList targetSpellStore;
for (uint8 i = 0; i < m_creature->GetPetAutoSpellSize(); ++i)
{
uint32 spellID = m_creature->GetPetAutoSpellOnPos(i);
if (!spellID)
continue;
SpellEntry const *spellInfo = sSpellMgr.GetSpellEntry(spellID);
if (!spellInfo)
continue;
if (m_creature->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
//.........这里部分代码省略.........
示例11: UpdateAI
//.........这里部分代码省略.........
// check spell cooldown
if (!me->GetSpellHistory()->IsReady(spellInfo))
continue;
if (spellInfo->IsPositive())
{
if (spellInfo->CanBeUsedInCombat())
{
// Check if we're in combat or commanded to attack
if (!me->IsInCombat() && !me->GetCharmInfo()->IsCommandAttack())
continue;
}
Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE);
bool spellUsed = false;
// Some spells can target enemy or friendly (DK Ghoul's Leap)
// Check for enemy first (pet then owner)
Unit* target = me->getAttackerForHelper();
if (!target && owner)
target = owner->getAttackerForHelper();
if (target)
{
if (CanAttack(target) && spell->CanAutoCast(target))
{
targetSpellStore.push_back(std::make_pair(target, spell));
spellUsed = true;
}
}
if (spellInfo->HasEffect(SPELL_EFFECT_JUMP_DEST))
{
if (!spellUsed)
delete spell;
continue; // Pets must only jump to target
}
// No enemy, check friendly
if (!spellUsed)
{
for (GuidSet::const_iterator tar = _allySet.begin(); tar != _allySet.end(); ++tar)
{
Unit* ally = ObjectAccessor::GetUnit(*me, *tar);
//only buff targets that are in combat, unless the spell can only be cast while out of combat
if (!ally)
continue;
if (spell->CanAutoCast(ally))
{
targetSpellStore.push_back(std::make_pair(ally, spell));
spellUsed = true;
break;
}
}
}
// No valid targets at all
if (!spellUsed)
delete spell;
}
else if (me->GetVictim() && CanAttack(me->GetVictim()) && spellInfo->CanBeUsedInCombat())
{
Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE);
if (spell->CanAutoCast(me->GetVictim()))
targetSpellStore.push_back(std::make_pair(me->GetVictim(), spell));
else
delete spell;
}
}
// found units to cast on to
if (!targetSpellStore.empty())
{
TargetSpellList::iterator it = targetSpellStore.begin();
std::advance(it, urand(0, targetSpellStore.size() - 1));
Spell* spell = (*it).second;
Unit* target = (*it).first;
targetSpellStore.erase(it);
SpellCastTargets targets;
targets.SetUnitTarget(target);
spell->prepare(targets);
}
// deleted cached Spell objects
for (TargetSpellList::const_iterator itr = targetSpellStore.begin(); itr != targetSpellStore.end(); ++itr)
delete itr->second;
}
// Update speed as needed to prevent dropping too far behind and despawning
me->UpdateSpeed(MOVE_RUN);
me->UpdateSpeed(MOVE_WALK);
me->UpdateSpeed(MOVE_FLIGHT);
}
示例12: UpdateAI
//.........这里部分代码省略.........
else if(m_creature->GetCharmInfo()->HasState(CHARM_STATE_COMMAND,COMMAND_FOLLOW))
{
if (!m_creature->hasUnitState(UNIT_STAT_FOLLOW) )
{
m_creature->GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST, m_creature->IsPet() ? ((Pet*)m_creature)->GetPetFollowAngle() : PET_FOLLOW_ANGLE);
}
}
}
// Autocast (casted only in combat or persistent spells in any state)
if (!m_creature->IsNonMeleeSpellCasted(false) && !m_creature->GetObjectGuid().IsVehicle())
{
typedef std::vector<std::pair<ObjectGuid, uint32> > TargetSpellList;
TargetSpellList targetSpellStore;
for (uint8 i = 0; i < m_creature->GetPetAutoSpellSize(); ++i)
{
uint32 spellID = m_creature->GetPetAutoSpellOnPos(i);
if (!spellID)
continue;
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellID);
if (!spellInfo)
continue;
if (m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
continue;
// 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;
}
if (inCombat && m_creature->getVictim() && !m_creature->hasUnitState(UNIT_STAT_FOLLOW) && CanAutoCast(m_creature->getVictim(), spellInfo))
{
targetSpellStore.push_back(TargetSpellList::value_type(m_creature->getVictim()->GetObjectGuid(), spellInfo->Id));
continue;
}
else
{
for (AllySet::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
{
Unit* Target = m_creature->GetMap()->GetUnit(*tar);
//only buff targets that are in combat, unless the spell can only be cast while out of combat
if (!Target)
continue;
if (CanAutoCast(Target, spellInfo))
{
targetSpellStore.push_back(TargetSpellList::value_type(Target->GetObjectGuid(), spellInfo->Id));
break;
}
}
}
}
//found units to cast on to
if (!targetSpellStore.empty())
{
uint32 index = urand(0, targetSpellStore.size() - 1);
uint32 spellId = targetSpellStore[index].second;
ObjectGuid targetGuid = targetSpellStore[index].first;
if (Unit* target = m_creature->GetMap()->GetUnit(targetGuid))
{
m_creature->DoPetCastSpell(target, spellId);
}
targetSpellStore.erase(targetSpellStore.begin() + index);
}
targetSpellStore.clear();
}
}