diff options
author | maximius <none@none> | 2009-10-17 15:35:07 -0700 |
---|---|---|
committer | maximius <none@none> | 2009-10-17 15:35:07 -0700 |
commit | 26b5e033ffde3d161382fc9addbfa99738379641 (patch) | |
tree | a344f369ca32945f787a02dee35c3dbe342bed7e /src/game/PetAI.cpp | |
parent | f21f47005dcb6b76e1abc9f35fbcd03eed191bff (diff) |
*Massive cleanup (\n\n -> \n, *\n -> \n, cleanup for(...) to for (...), and some other cleanups by hand)
*Fix a possible crash in Spell::DoAllEffectOnTarget
--HG--
branch : trunk
Diffstat (limited to 'src/game/PetAI.cpp')
-rw-r--r-- | src/game/PetAI.cpp | 75 |
1 files changed, 0 insertions, 75 deletions
diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp index 534500e51ea..64cf01b383d 100644 --- a/src/game/PetAI.cpp +++ b/src/game/PetAI.cpp @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "PetAI.h" #include "Errors.h" #include "Pet.h" @@ -29,34 +28,27 @@ #include "Creature.h" #include "World.h" #include "Util.h" - int PetAI::Permissible(const Creature *creature) { if( creature->isPet()) return PERMIT_BASE_SPECIAL; - return PERMIT_BASE_NO; } - PetAI::PetAI(Creature *c) : CreatureAI(c), i_tracker(TIME_INTERVAL_LOOK) { m_AllySet.clear(); UpdateAllies(); } - void PetAI::EnterEvadeMode() { } - bool PetAI::_needToStop() const { // This is needed for charmed creatures, as once their target was reset other effects can trigger threat if(m_creature->isCharmed() && m_creature->getVictim() == m_creature->GetCharmer()) return true; - return !m_creature->canAttack(m_creature->getVictim()); } - void PetAI::_stopAttack() { if( !m_creature->isAlive() ) @@ -66,25 +58,20 @@ void PetAI::_stopAttack() m_creature->GetMotionMaster()->MoveIdle(); m_creature->CombatStop(); m_creature->getHostilRefManager().deleteReferences(); - return; } - m_creature->AttackStop(); me->GetCharmInfo()->SetIsCommandAttack(false); HandleReturnMovement(); } - void PetAI::UpdateAI(const uint32 diff) { 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() ) { @@ -94,13 +81,11 @@ void PetAI::UpdateAI(const uint32 diff) _stopAttack(); return; } - DoMeleeAttackIfReady(); } else if(owner && m_creature->GetCharmInfo()) //no victim { Unit *nextTarget = SelectNextTarget(); - if (nextTarget) AttackStart(nextTarget); else @@ -108,35 +93,28 @@ void PetAI::UpdateAI(const uint32 diff) } 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)) { 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 (!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 @@ -146,7 +124,6 @@ void PetAI::UpdateAI(const uint32 diff) 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) @@ -159,9 +136,7 @@ void PetAI::UpdateAI(const uint32 diff) if (IsNonCombatSpell(spellInfo)) continue; } - Spell *spell = new Spell(m_creature, spellInfo, false, 0); - // Fix to allow pets on STAY to autocast if (inCombat && _CanAttack(me->getVictim()) && spell->CanAutoCast(me->getVictim())) { @@ -174,11 +149,9 @@ void PetAI::UpdateAI(const uint32 diff) for(std::set<uint64>::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar) { Unit* Target = ObjectAccessor::GetUnit(*m_creature,*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)); @@ -190,60 +163,46 @@ void PetAI::UpdateAI(const uint32 diff) 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, target) ) { m_creature->SetInFront(target); if( target->GetTypeId() == TYPEID_PLAYER ) m_creature->SendUpdateToPlayer( (Player*)target ); - if(owner && owner->GetTypeId() == TYPEID_PLAYER) m_creature->SendUpdateToPlayer( (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; } } - void PetAI::UpdateAllies() { Unit* owner = m_creature->GetCharmerOrOwner(); Group *pGroup = NULL; - m_updateAlliesTimer = 10*IN_MILISECONDS; //update friendly targets every 10 seconds, lesser checks increase performance - if(!owner) return; else if(owner->GetTypeId() == TYPEID_PLAYER) pGroup = ((Player*)owner)->GetGroup(); - //only pet and owner/not in group->ok if(m_AllySet.size() == 2 && !pGroup) return; //owner is in group; group members filled in already (no raid -> subgroupcount = whole count) if(pGroup && !pGroup->isRaidGroup() && m_AllySet.size() == (pGroup->GetMembersCount() + 2)) return; - m_AllySet.clear(); m_AllySet.insert(m_creature->GetGUID()); if(pGroup) //add group @@ -253,47 +212,38 @@ void PetAI::UpdateAllies() Player* Target = itr->getSource(); if(!Target || !pGroup->SameSubGroup((Player*)owner, Target)) continue; - if(Target->GetGUID() == owner->GetGUID()) continue; - m_AllySet.insert(Target->GetGUID()); } } else //remove group m_AllySet.insert(owner->GetGUID()); } - void PetAI::KilledUnit(Unit *victim) { // Called from Unit::Kill() in case where pet or owner kills something // if owner killed this victim, pet may still be attacking something else if (me->getVictim() && me->getVictim() != victim) return; - // Clear target just in case. May help problem where health / focus / mana // regen gets stuck. Also resets attack command. // Can't use _stopAttack() because that activates movement handlers and ignores // next target selection me->AttackStop(); me->GetCharmInfo()->SetIsCommandAttack(false); - Unit *nextTarget = SelectNextTarget(); - if (nextTarget) AttackStart(nextTarget); else HandleReturnMovement(); // Return } - void PetAI::AttackStart(Unit *target) { // Overrides Unit::AttackStart to correctly evaluate Pet states - // Check all pet states to decide if we can attack this target if (!_CanAttack(target)) return; - // We can attack, should we chase or not? if (me->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW)) DoAttack(target,true); // FOLLOW, attack with chase @@ -305,36 +255,28 @@ void PetAI::AttackStart(Unit *target) DoAttack(target,false); // STAY, target in range, attack not clicked so attack without chase } } - Unit *PetAI::SelectNextTarget() { // Provides next target selection after current target death - // Passive pets don't do next target selection if (me->HasReactState(REACT_PASSIVE)) return NULL; - // Check pet's attackers first to prevent dragging mobs back // to owner if (me->getAttackerForHelper()) return me->getAttackerForHelper(); - // Check owner's attackers if pet didn't have any if (me->GetCharmerOrOwner()->getAttackerForHelper()) return me->GetCharmerOrOwner()->getAttackerForHelper(); - // 3.0.2 - Pets now start attacking their owners target in defensive mode as soon as the hunter does if (me->GetCharmerOrOwner()->getVictim()) return me->GetCharmerOrOwner()->getVictim(); - // Default return NULL; } - void PetAI::HandleReturnMovement() { // Handles moving the pet back to stay or owner - if (me->GetCharmInfo()->HasCommandState(COMMAND_STAY)) { if (!me->GetCharmInfo()->IsAtStay() && !me->GetCharmInfo()->IsReturning()) @@ -343,7 +285,6 @@ void PetAI::HandleReturnMovement() if (!me->GetCharmInfo()->IsCommandAttack()) { float x,y,z; - me->GetCharmInfo()->GetStayPosition(x, y, z); me->GetCharmInfo()->SetIsReturning(true); me->GetMotionMaster()->Clear(); @@ -363,20 +304,15 @@ void PetAI::HandleReturnMovement() } } } - } - void PetAI::DoAttack(Unit *target, bool chase) { // Handles attack with or without chase and also resets all // PetAI flags for next update / creature kill - // me->GetCharmInfo()->SetIsCommandAttack(false); - // The following conditions are true if chase == true // (Follow && (Aggressive || Defensive)) // ((Stay || Follow) && (Passive && player clicked attack)) - if (chase) { if (me->Attack(target,true)) @@ -396,7 +332,6 @@ void PetAI::DoAttack(Unit *target, bool chase) me->Attack(target,true); } } - void PetAI::MovementInform(uint32 moveType, uint32 data) { // Receives notification when pet reaches stay or follow owner @@ -417,7 +352,6 @@ void PetAI::MovementInform(uint32 moveType, uint32 data) } } break; - case TARGETED_MOTION_TYPE: { // If data is owner's GUIDLow then we've reached follow point, @@ -432,39 +366,30 @@ void PetAI::MovementInform(uint32 moveType, uint32 data) } } break; - default: break; } } - bool PetAI::_CanAttack(Unit *target) { // Evaluates wether a pet can attack a specific // target based on CommandState, ReactState and other flags - // Returning - check first since pets returning ignore attacks if (me->GetCharmInfo()->IsReturning()) return false; - // Passive - check now so we don't have to worry about passive in later checks if (me->HasReactState(REACT_PASSIVE)) return me->GetCharmInfo()->IsCommandAttack(); - // Pets commanded to attack should not stop their approach if attacked by another creature if (me->getVictim() && (me->getVictim() != target)) return !me->GetCharmInfo()->IsCommandAttack(); - // From this point on, pet will always be either aggressive or defensive - // Stay - can attack if target is within range or commanded to if (me->GetCharmInfo()->HasCommandState(COMMAND_STAY)) return (me->IsWithinMeleeRange(target, MIN_MELEE_REACH) || me->GetCharmInfo()->IsCommandAttack()); - // Follow if (me->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW)) return true; - // default, though we shouldn't ever get here return false; } |