//Gets the first found attacker of Unit if not nearestToAttacked > finds the one nearest to bot Unit *PlayerbotClassAI::GetNearestAttackerOf(Unit *pAttacked, bool nearestToAttacked) { if (!pAttacked) { pAttacked = m_bot; if (!pAttacked) return NULL;} Unit::AttackerSet fAttackerSet = pAttacked->getAttackers(); if (fAttackerSet.size() <= 0) { return NULL; } Unit *nearestTo = m_bot; if (nearestToAttacked) { nearestTo = pAttacked; } Unit *curAtt = NULL; float minDist = 30; for (Unit::AttackerSet::const_iterator itr = fAttackerSet.begin(); itr != fAttackerSet.end(); ++itr) { Unit *tAtt = (*itr); if (!tAtt) break; // Something is wrong.. How can a non existing mob attack? if (tAtt->isDead()) break; if (m_bot->GetDistance(tAtt) >= minDist) continue; //Get the nearest one curAtt = tAtt; minDist = tAtt->GetDistance(nearestTo); } return curAtt; }
void TotemAI::UpdateAI(const uint32 /*diff*/) { if (me->ToTotem()->GetTotemType() != TOTEM_ACTIVE) return; if (!me->isAlive() || me->IsNonMeleeSpellCasted(false)) return; // Search spell SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(me->ToTotem()->GetSpell()); if (!spellInfo) return; // Get spell range float max_range = spellInfo->GetMaxRange(false); // SPELLMOD_RANGE not applied in this place just because not existence range mods for attacking totems // pointer to appropriate target if found any Unit* victim = i_victimGuid ? ObjectAccessor::GetUnit(*me, i_victimGuid) : NULL; Unit* tmpvictim = 0; // Search victim if no, not attackable, or out of range, or friendly (possible in case duel end) if (!victim || (!victim->isTargetableForAttack() || !me->IsWithinDistInMap(victim, max_range) || me->IsFriendlyTo(victim) || !me->canSeeOrDetect(victim))) { Trinity::NearestAttackableUnitInObjectRangeCheck u_check(me, me, max_range); Trinity::UnitLastSearcher<Trinity::NearestAttackableUnitInObjectRangeCheck> checker(me, victim, u_check); me->VisitNearbyObject(max_range, checker); tmpvictim = victim; } else if(!(victim->HasAura(FLAME_SHOCK, me->GetOwnerGUID()) || victim->HasAura(STORMSTRIKE, me->GetOwnerGUID()))) tmpvictim = victim; Unit* owner = me->GetOwner(); // looking for attacker with specific auras, do only if new victim found in radius or current victim has no aura if (owner && tmpvictim) { if (Unit* ownervictim = owner->getVictim()) { //Owner's target is priority if (me->IsWithinDistInMap(ownervictim, max_range) && (ownervictim->HasAura(FLAME_SHOCK, owner->GetGUID()) || ownervictim->HasAura(STORMSTRIKE, owner->GetGUID()))) victim = ownervictim; else { Unit::AttackerSet attackers = owner->getAttackers(); for (Unit::AttackerSet::iterator itr = attackers.begin(); itr != attackers.end(); ++itr) { tmpvictim = *itr; if (me->IsWithinDistInMap(tmpvictim, max_range) && (tmpvictim->HasAura(FLAME_SHOCK, owner->GetGUID()) || tmpvictim->HasAura(STORMSTRIKE, owner->GetGUID()))) victim = tmpvictim; } } } } // If have target if (victim) { // remember i_victimGuid = victim->GetGUID(); // attack me->SetInFront(victim); // client change orientation by self me->CastSpell(victim, me->ToTotem()->GetSpell(), false, NULL, NULL, me->GetOwnerGUID()); } else i_victimGuid = 0; }