[7826] Avoid use GetDistance* that used slow sqrt call where possible, other related speedups.

This commit is contained in:
VladimirMangos 2009-05-14 18:16:03 +04:00
parent ff80f14d2d
commit 788cdf9b3a
21 changed files with 158 additions and 93 deletions

View file

@ -89,7 +89,7 @@ struct MANGOS_DLL_DECL ScriptedAI : public CreatureAI
// Is unit visible for MoveInLineOfSight // Is unit visible for MoveInLineOfSight
bool IsVisible(Unit* who) const bool IsVisible(Unit* who) const
{ {
return !who->HasStealthAura() && m_creature->GetDistance(who) <= VISIBLE_RANGE; return !who->HasStealthAura() && m_creature->IsWithinDist(who,VISIBLE_RANGE);
} }
// Called at World update tick // Called at World update tick

View file

@ -140,7 +140,7 @@ AggressorAI::UpdateAI(const uint32 /*diff*/)
bool bool
AggressorAI::IsVisible(Unit *pl) const AggressorAI::IsVisible(Unit *pl) const
{ {
return m_creature->GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_MONSTER) return m_creature->IsWithinDist(pl,sWorld.getConfig(CONFIG_SIGHT_MONSTER))
&& pl->isVisibleForOrDetect(m_creature,true); && pl->isVisibleForOrDetect(m_creature,true);
} }

View file

@ -1778,12 +1778,12 @@ bool Creature::IsOutOfThreatArea(Unit* pVictim) const
if(sMapStore.LookupEntry(GetMapId())->IsDungeon()) if(sMapStore.LookupEntry(GetMapId())->IsDungeon())
return false; return false;
float length = pVictim->GetDistance(CombatStartX,CombatStartY,CombatStartZ);
float AttackDist = GetAttackDistance(pVictim); float AttackDist = GetAttackDistance(pVictim);
uint32 ThreatRadius = sWorld.getConfig(CONFIG_THREAT_RADIUS); uint32 ThreatRadius = sWorld.getConfig(CONFIG_THREAT_RADIUS);
//Use AttackDistance in distance check if threat radius is lower. This prevents creature bounce in and out of combat every update tick. //Use AttackDistance in distance check if threat radius is lower. This prevents creature bounce in and out of combat every update tick.
return ( length > (ThreatRadius > AttackDist ? ThreatRadius : AttackDist)); return !pVictim->IsWithinDist(CombatStartX,CombatStartY,CombatStartZ,
ThreatRadius > AttackDist ? ThreatRadius : AttackDist);
} }
CreatureDataAddon const* Creature::GetCreatureAddon() const CreatureDataAddon const* Creature::GetCreatureAddon() const

View file

@ -1277,13 +1277,10 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
break; break;
case EVENT_T_RANGE: case EVENT_T_RANGE:
if (Combat) if (Combat)
{ if (m_creature->IsInMap(m_creature->getVictim()))
if (m_creature->IsWithinDistInMap(m_creature->getVictim(),(float)(*i).Event.event_param2)) if (m_creature->IsInRange(m_creature->getVictim(),
{ (float)(*i).Event.event_param1,(float)(*i).Event.event_param2))
if (m_creature->GetDistance(m_creature->getVictim()) >= (float)(*i).Event.event_param1)
ProcessEvent(*i); ProcessEvent(*i);
}
}
break; break;
} }
} }
@ -1305,7 +1302,7 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
bool CreatureEventAI::IsVisible(Unit *pl) const bool CreatureEventAI::IsVisible(Unit *pl) const
{ {
return m_creature->GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_MONSTER) return m_creature->IsWithinDist(pl,sWorld.getConfig(CONFIG_SIGHT_MONSTER))
&& pl->isVisibleForOrDetect(m_creature,true); && pl->isVisibleForOrDetect(m_creature,true);
} }
@ -1584,7 +1581,7 @@ bool CreatureEventAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Trigge
return false; return false;
//Unit is out of range of this spell //Unit is out of range of this spell
if (m_creature->GetDistance(Target) > TempRange->maxRange || m_creature->GetDistance(Target) < TempRange->minRange) if (!m_creature->IsInRange(Target,TempRange->minRange,TempRange->minRange))
return false; return false;
return true; return true;

View file

@ -176,14 +176,14 @@ MessageDistDeliverer::Visit(PlayerMapType &m)
{ {
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
{ {
if( (i_toSelf || iter->getSource() != &i_player ) && if ((i_toSelf || iter->getSource() != &i_player ) &&
(!i_ownTeamOnly || iter->getSource()->GetTeam() == i_player.GetTeam() ) && (!i_ownTeamOnly || iter->getSource()->GetTeam() == i_player.GetTeam() ) &&
(!i_dist || iter->getSource()->GetDistance(&i_player) <= i_dist) ) (!i_dist || iter->getSource()->IsWithinDist(&i_player,i_dist)))
{ {
if (!i_player.InSamePhase(iter->getSource())) if (!i_player.InSamePhase(iter->getSource()))
continue; continue;
if(WorldSession* session = iter->getSource()->GetSession()) if (WorldSession* session = iter->getSource()->GetSession())
session->SendPacket(i_message); session->SendPacket(i_message);
} }
} }
@ -194,12 +194,12 @@ ObjectMessageDistDeliverer::Visit(PlayerMapType &m)
{ {
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
{ {
if( !i_dist || iter->getSource()->GetDistance(&i_object) <= i_dist ) if (!i_dist || iter->getSource()->IsWithinDist(&i_object,i_dist))
{ {
if( !i_object.InSamePhase(iter->getSource())) if (!i_object.InSamePhase(iter->getSource()))
continue; continue;
if(WorldSession* session = iter->getSource()->GetSession()) if (WorldSession* session = iter->getSource()->GetSession())
session->SendPacket(i_message); session->SendPacket(i_message);
} }
} }

View file

@ -494,7 +494,7 @@ namespace MaNGOS
void Visit(PlayerMapType &m) void Visit(PlayerMapType &m)
{ {
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
if(itr->getSource()->InSamePhase(i_searcher) && itr->getSource()->GetDistance(i_searcher) <= i_dist) if (itr->getSource()->InSamePhase(i_searcher) && itr->getSource()->IsWithinDist(i_searcher,i_dist))
i_do(itr->getSource()); i_do(itr->getSource());
} }

View file

@ -567,7 +567,7 @@ void Group::GroupLoot(const uint64& playerGUID, Loot *loot, Creature *creature)
continue; continue;
if ( i->AllowedForPlayer(member) ) if ( i->AllowedForPlayer(member) )
{ {
if (member->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) if (member->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false))
{ {
r->playerVote[member->GetGUID()] = NOT_EMITED_YET; r->playerVote[member->GetGUID()] = NOT_EMITED_YET;
++r->totalPlayersRolling; ++r->totalPlayersRolling;
@ -617,7 +617,7 @@ void Group::NeedBeforeGreed(const uint64& playerGUID, Loot *loot, Creature *crea
if (playerToRoll->CanUseItem(item) && i->AllowedForPlayer(playerToRoll) ) if (playerToRoll->CanUseItem(item) && i->AllowedForPlayer(playerToRoll) )
{ {
if (playerToRoll->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) if (playerToRoll->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false))
{ {
r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET; r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET;
++r->totalPlayersRolling; ++r->totalPlayersRolling;
@ -665,7 +665,7 @@ void Group::MasterLoot(const uint64& playerGUID, Loot* /*loot*/, Creature *creat
if (!looter->IsInWorld()) if (!looter->IsInWorld())
continue; continue;
if (looter->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) if (looter->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false))
{ {
data << looter->GetGUID(); data << looter->GetGUID();
++real_count; ++real_count;
@ -677,7 +677,7 @@ void Group::MasterLoot(const uint64& playerGUID, Loot* /*loot*/, Creature *creat
for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next())
{ {
Player *looter = itr->getSource(); Player *looter = itr->getSource();
if (looter->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) if (looter->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false))
looter->GetSession()->SendPacket(&data); looter->GetSession()->SendPacket(&data);
} }
} }
@ -1334,7 +1334,7 @@ void Group::UpdateLooterGuid( Creature* creature, bool ifneed )
{ {
// not update if only update if need and ok // not update if only update if need and ok
Player* looter = ObjectAccessor::FindPlayer(guid_itr->guid); Player* looter = ObjectAccessor::FindPlayer(guid_itr->guid);
if(looter && looter->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) if(looter && looter->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false))
return; return;
} }
++guid_itr; ++guid_itr;
@ -1347,7 +1347,7 @@ void Group::UpdateLooterGuid( Creature* creature, bool ifneed )
{ {
if(Player* pl = ObjectAccessor::FindPlayer(itr->guid)) if(Player* pl = ObjectAccessor::FindPlayer(itr->guid))
{ {
if (pl->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) if (pl->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false))
{ {
bool refresh = pl->GetLootGUID()==creature->GetGUID(); bool refresh = pl->GetLootGUID()==creature->GetGUID();
@ -1368,7 +1368,7 @@ void Group::UpdateLooterGuid( Creature* creature, bool ifneed )
{ {
if(Player* pl = ObjectAccessor::FindPlayer(itr->guid)) if(Player* pl = ObjectAccessor::FindPlayer(itr->guid))
{ {
if (pl->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) if (pl->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false))
{ {
bool refresh = pl->GetLootGUID()==creature->GetGUID(); bool refresh = pl->GetLootGUID()==creature->GetGUID();

View file

@ -125,7 +125,7 @@ void GuardAI::UpdateAI(const uint32 /*diff*/)
bool GuardAI::IsVisible(Unit *pl) const bool GuardAI::IsVisible(Unit *pl) const
{ {
return m_creature->GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_GUARDER) return m_creature->IsWithinDist(pl,sWorld.getConfig(CONFIG_SIGHT_GUARDER))
&& pl->isVisibleForOrDetect(m_creature,true); && pl->isVisibleForOrDetect(m_creature,true);
} }

View file

@ -212,7 +212,7 @@ void WorldSession::HandleLootMoneyOpcode( WorldPacket & /*recv_data*/ )
Player* playerGroup = itr->getSource(); Player* playerGroup = itr->getSource();
if(!playerGroup) if(!playerGroup)
continue; continue;
if (player->GetDistance2d(playerGroup) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) if (player->IsWithinDist(playerGroup,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false))
playersNear.push_back(playerGroup); playersNear.push_back(playerGroup);
} }

View file

@ -674,9 +674,7 @@ void WorldSession::HandleCorpseReclaimOpcode(WorldPacket &recv_data)
if(corpse->GetGhostTime() + GetPlayer()->GetCorpseReclaimDelay(corpse->GetType()==CORPSE_RESURRECTABLE_PVP) > time(NULL)) if(corpse->GetGhostTime() + GetPlayer()->GetCorpseReclaimDelay(corpse->GetType()==CORPSE_RESURRECTABLE_PVP) > time(NULL))
return; return;
float dist = corpse->GetDistance2d(GetPlayer()); if (!corpse->IsWithinDist(GetPlayer(),CORPSE_RECLAIM_RADIUS,false))
sLog.outDebug("Corpse 2D Distance: \t%f",dist);
if (dist > CORPSE_RECLAIM_RADIUS)
return; return;
uint64 guid; uint64 guid;

View file

@ -1087,7 +1087,7 @@ float WorldObject::GetDistance2d(float x, float y) const
return ( dist > 0 ? dist : 0); return ( dist > 0 ? dist : 0);
} }
float WorldObject::GetDistance(const float x, const float y, const float z) const float WorldObject::GetDistance(float x, float y, float z) const
{ {
float dx = GetPositionX() - x; float dx = GetPositionX() - x;
float dy = GetPositionY() - y; float dy = GetPositionY() - y;
@ -1114,10 +1114,24 @@ float WorldObject::GetDistanceZ(const WorldObject* obj) const
return ( dist > 0 ? dist : 0); return ( dist > 0 ? dist : 0);
} }
bool WorldObject::IsWithinDistInMap(const WorldObject* obj, const float dist2compare, const bool is3D) const bool WorldObject::IsWithinDist(float x, float y, float z, float dist2compare, bool is3D) const
{ {
if (!obj || !IsInMap(obj)) return false; float dx = GetPositionX() - x;
float dy = GetPositionY() - y;
float distsq = dx*dx + dy*dy;
if(is3D)
{
float dz = GetPositionZ() - z;
distsq += dz*dz;
}
float sizefactor = GetObjectSize();
float maxdist = dist2compare + sizefactor;
return distsq < maxdist * maxdist;
}
bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const
{
float dx = GetPositionX() - obj->GetPositionX(); float dx = GetPositionX() - obj->GetPositionX();
float dy = GetPositionY() - obj->GetPositionY(); float dy = GetPositionY() - obj->GetPositionY();
float distsq = dx*dx + dy*dy; float distsq = dx*dx + dy*dy;
@ -1140,7 +1154,7 @@ bool WorldObject::IsWithinLOSInMap(const WorldObject* obj) const
return(IsWithinLOS(ox, oy, oz )); return(IsWithinLOS(ox, oy, oz ));
} }
bool WorldObject::IsWithinLOS(const float ox, const float oy, const float oz ) const bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const
{ {
float x,y,z; float x,y,z;
GetPosition(x,y,z); GetPosition(x,y,z);
@ -1148,6 +1162,54 @@ bool WorldObject::IsWithinLOS(const float ox, const float oy, const float oz ) c
return vMapManager->isInLineOfSight(GetMapId(), x, y, z+2.0f, ox, oy, oz+2.0f); return vMapManager->isInLineOfSight(GetMapId(), x, y, z+2.0f, ox, oy, oz+2.0f);
} }
bool WorldObject::GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2) const
{
float dx1 = GetPositionX() - obj1->GetPositionX();
float dy1 = GetPositionY() - obj1->GetPositionY();
float dz1 = GetPositionZ() - obj1->GetPositionZ();
float distsq1 = dx1*dx1 + dy1*dy1 + dz1*dz1;
float dx2 = GetPositionX() - obj2->GetPositionX();
float dy2 = GetPositionY() - obj2->GetPositionY();
float dz2 = GetPositionZ() - obj2->GetPositionZ();
float distsq2 = dx2*dx2 + dy2*dy2 + dz2*dz2;
return distsq1 < distsq2;
}
bool WorldObject::IsInRange(WorldObject const* obj, float minRange, float maxRange) const
{
float dx = GetPositionX() - obj->GetPositionX();
float dy = GetPositionY() - obj->GetPositionY();
float dz = GetPositionZ() - obj->GetPositionZ();
float distsq = dx*dx + dy*dy + dz*dz;
float sizefactor = GetObjectSize() + obj->GetObjectSize();
float mindist = minRange + sizefactor;
if(distsq < mindist * mindist)
return false;
float maxdist = maxRange + sizefactor;
return distsq < maxdist * maxdist;
}
bool WorldObject::IsInRange2d(float x, float y, float minRange, float maxRange) const
{
float dx = GetPositionX() - x;
float dy = GetPositionY() - y;
float distsq = dx*dx + dy*dy;
float sizefactor = GetObjectSize();
float mindist = minRange + sizefactor;
if(distsq < mindist * mindist)
return false;
float maxdist = maxRange + sizefactor;
return distsq < maxdist * maxdist;
}
float WorldObject::GetAngle(const WorldObject* obj) const float WorldObject::GetAngle(const WorldObject* obj) const
{ {
if(!obj) return 0; if(!obj) return 0;
@ -1543,15 +1605,8 @@ namespace MaNGOS
// we must add used pos that can fill places around center // we must add used pos that can fill places around center
void add(WorldObject* u, float x, float y) const void add(WorldObject* u, float x, float y) const
{ {
// dist include size of u // u is too nearest/far away to i_object
float dist2d = i_object.GetDistance2d(x,y); if(!i_object.IsInRange2d(x,y,i_selector.m_dist - i_selector.m_size,i_selector.m_dist + i_selector.m_size))
// u is too nearest to i_object
if(dist2d + i_object.GetObjectSize() + u->GetObjectSize() < i_selector.m_dist - i_selector.m_size)
return;
// u is too far away from i_object
if(dist2d + i_object.GetObjectSize() - u->GetObjectSize() > i_selector.m_dist + i_selector.m_size)
return; return;
float angle = i_object.GetAngle(u)-i_angle; float angle = i_object.GetAngle(u)-i_angle;
@ -1562,6 +1617,8 @@ namespace MaNGOS
while(angle < -M_PI) while(angle < -M_PI)
angle += 2.0f * M_PI; angle += 2.0f * M_PI;
// dist include size of u
float dist2d = i_object.GetDistance2d(x,y);
i_selector.AddUsedPos(u->GetObjectSize(),angle,dist2d + i_object.GetObjectSize()); i_selector.AddUsedPos(u->GetObjectSize(),angle,dist2d + i_object.GetObjectSize());
} }
private: private:

View file

@ -424,18 +424,31 @@ class MANGOS_DLL_SPEC WorldObject : public Object
virtual const char* GetNameForLocaleIdx(int32 /*locale_idx*/) const { return GetName(); } virtual const char* GetNameForLocaleIdx(int32 /*locale_idx*/) const { return GetName(); }
float GetDistance( const WorldObject* obj ) const; float GetDistance( const WorldObject* obj ) const;
float GetDistance(const float x, const float y, const float z) const; float GetDistance(float x, float y, float z) const;
float GetDistance2d(const WorldObject* obj) const; float GetDistance2d(const WorldObject* obj) const;
float GetDistance2d(const float x, const float y) const; float GetDistance2d(float x, float y) const;
float GetDistanceZ(const WorldObject* obj) const; float GetDistanceZ(const WorldObject* obj) const;
bool IsInMap(const WorldObject* obj) const bool IsInMap(const WorldObject* obj) const
{ {
return IsInWorld() && obj->IsInWorld() && GetMapId()==obj->GetMapId() && return IsInWorld() && obj->IsInWorld() && GetMapId()==obj->GetMapId() &&
GetInstanceId()==obj->GetInstanceId() && InSamePhase(obj); GetInstanceId()==obj->GetInstanceId() && InSamePhase(obj);
} }
bool IsWithinDistInMap(const WorldObject* obj, const float dist2compare, const bool is3D = true) const; bool IsWithinDist(float x, float y, float z, float dist2compare, bool is3D = true) const;
bool IsWithinLOS(const float x, const float y, const float z ) const; bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const;
bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true) const
// use only if you will sure about placing both object at same map
{
return obj && _IsWithinDist(obj,dist2compare,is3D);
}
bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true) const
{
return obj && IsInMap(obj) && _IsWithinDist(obj,dist2compare,is3D);
}
bool IsWithinLOS(float x, float y, float z) const;
bool IsWithinLOSInMap(const WorldObject* obj) const; bool IsWithinLOSInMap(const WorldObject* obj) const;
bool GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2) const;
bool IsInRange(WorldObject const* obj, float minRange, float maxRange) const;
bool IsInRange2d(float x, float y, float minRange, float maxRange) const;
float GetAngle( const WorldObject* obj ) const; float GetAngle( const WorldObject* obj ) const;
float GetAngle( const float x, const float y ) const; float GetAngle( const float x, const float y ) const;

View file

@ -288,8 +288,7 @@ void PetAI::UpdateAI(const uint32 diff)
bool PetAI::_isVisible(Unit *u) const bool PetAI::_isVisible(Unit *u) const
{ {
//return false; //( ((Creature*)&i_pet)->GetDistanceSq(u) * 1.0<= sWorld.getConfig(CONFIG_SIGHT_GUARDER) && !u->m_stealth && u->isAlive()); return m_creature->IsWithinDist(u,sWorld.getConfig(CONFIG_SIGHT_GUARDER))
return m_creature->GetDistance(u) < sWorld.getConfig(CONFIG_SIGHT_GUARDER)
&& u->isVisibleForOrDetect(m_creature,true); && u->isVisibleForOrDetect(m_creature,true);
} }

View file

@ -1616,7 +1616,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
if (!(options & TELE_TO_NOT_UNSUMMON_PET)) if (!(options & TELE_TO_NOT_UNSUMMON_PET))
{ {
//same map, only remove pet if out of range for new position //same map, only remove pet if out of range for new position
if(pet && pet->GetDistance(x,y,z) >= OWNER_MAX_DISTANCE) if(pet && !pet->IsWithinDist(x,y,z, OWNER_MAX_DISTANCE))
UnsummonPetTemporaryIfAny(); UnsummonPetTemporaryIfAny();
} }

View file

@ -153,7 +153,7 @@ RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff
creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE); creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE);
_setRandomLocation(creature); _setRandomLocation(creature);
} }
else if(creature.isPet() && creature.GetOwner() && creature.GetDistance(creature.GetOwner()) > PET_FOLLOW_DIST+2.5f) else if(creature.isPet() && creature.GetOwner() && !creature.IsWithinDist(creature.GetOwner(),PET_FOLLOW_DIST+2.5f))
{ {
creature.SetUnitMovementFlags(MOVEMENTFLAG_NONE); creature.SetUnitMovementFlags(MOVEMENTFLAG_NONE);
_setRandomLocation(creature); _setRandomLocation(creature);

View file

@ -1334,7 +1334,7 @@ struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit,
// functor for operator ">" // functor for operator ">"
bool operator()(const Unit* _Left, const Unit* _Right) const bool operator()(const Unit* _Left, const Unit* _Right) const
{ {
return (MainTarget->GetDistance(_Left) < MainTarget->GetDistance(_Right)); return MainTarget->GetDistanceOrder(_Left,_Right);
} }
}; };
@ -1427,7 +1427,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
//Now to get us a random target that's in the initial range of the spell //Now to get us a random target that's in the initial range of the spell
uint32 t = 0; uint32 t = 0;
std::list<Unit *>::iterator itr = tempUnitMap.begin(); std::list<Unit *>::iterator itr = tempUnitMap.begin();
while(itr!= tempUnitMap.end() && (*itr)->GetDistance(m_caster) < radius) while(itr!= tempUnitMap.end() && (*itr)->IsWithinDist(m_caster,radius))
++t, ++itr; ++t, ++itr;
if(!t) if(!t)
@ -1448,7 +1448,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
while(t && next != tempUnitMap.end() ) while(t && next != tempUnitMap.end() )
{ {
if(prev->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS) if(!prev->IsWithinDist(*next,CHAIN_SPELL_JUMP_RADIUS))
break; break;
if(!prev->IsWithinLOSInMap(*next)) if(!prev->IsWithinLOSInMap(*next))
@ -1496,7 +1496,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
//Now to get us a random target that's in the initial range of the spell //Now to get us a random target that's in the initial range of the spell
uint32 t = 0; uint32 t = 0;
std::list<Unit *>::iterator itr = tempUnitMap.begin(); std::list<Unit *>::iterator itr = tempUnitMap.begin();
while(itr!= tempUnitMap.end() && (*itr)->GetDistance(m_caster) < radius) while(itr!= tempUnitMap.end() && (*itr)->IsWithinDist(m_caster,radius))
++t, ++itr; ++t, ++itr;
if(!t) if(!t)
@ -1517,7 +1517,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
while(t && next != tempUnitMap.end() ) while(t && next != tempUnitMap.end() )
{ {
if(prev->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS) if(!prev->IsWithinDist(*next,CHAIN_SPELL_JUMP_RADIUS))
break; break;
if(!prev->IsWithinLOSInMap(*next)) if(!prev->IsWithinLOSInMap(*next))
@ -1602,7 +1602,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
while(t && next != tempUnitMap.end() ) while(t && next != tempUnitMap.end() )
{ {
if(prev->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS) if(!prev->IsWithinDist(*next,CHAIN_SPELL_JUMP_RADIUS))
break; break;
if(!prev->IsWithinLOSInMap(*next)) if(!prev->IsWithinLOSInMap(*next))
@ -2029,7 +2029,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
while(t && next != tempUnitMap.end() ) while(t && next != tempUnitMap.end() )
{ {
if(prev->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS) if(!prev->IsWithinDist(*next,CHAIN_SPELL_JUMP_RADIUS))
break; break;
if(!prev->IsWithinLOSInMap(*next)) if(!prev->IsWithinLOSInMap(*next))
@ -4689,10 +4689,9 @@ SpellCastResult Spell::CheckRange(bool strict)
if(m_targets.m_targetMask == TARGET_FLAG_DEST_LOCATION && m_targets.m_destX != 0 && m_targets.m_destY != 0 && m_targets.m_destZ != 0) if(m_targets.m_targetMask == TARGET_FLAG_DEST_LOCATION && m_targets.m_destX != 0 && m_targets.m_destY != 0 && m_targets.m_destZ != 0)
{ {
float dist = m_caster->GetDistance(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ); if(!m_caster->IsWithinDist(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ,max_range))
if(dist > max_range)
return SPELL_FAILED_OUT_OF_RANGE; return SPELL_FAILED_OUT_OF_RANGE;
if(dist < min_range) if(m_caster->IsWithinDist(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ,min_range))
return SPELL_FAILED_TOO_CLOSE; return SPELL_FAILED_TOO_CLOSE;
} }

View file

@ -621,7 +621,7 @@ namespace MaNGOS
if( i_originalCaster->IsFriendlyTo(pPlayer) ) if( i_originalCaster->IsFriendlyTo(pPlayer) )
continue; continue;
if( pPlayer->GetDistance(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ) < i_radius ) if( pPlayer->IsWithinDist(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ,i_radius))
i_data.push_back(pPlayer); i_data.push_back(pPlayer);
} }
} }
@ -656,6 +656,10 @@ namespace MaNGOS
if( !itr->getSource()->isAlive() || (itr->getSource()->GetTypeId() == TYPEID_PLAYER && ((Player*)itr->getSource())->isInFlight())) if( !itr->getSource()->isAlive() || (itr->getSource()->GetTypeId() == TYPEID_PLAYER && ((Player*)itr->getSource())->isInFlight()))
continue; continue;
// mostly phase check
if(!itr->getSource()->IsInMap(i_originalCaster))
continue;
switch (i_TargetType) switch (i_TargetType)
{ {
case SPELL_TARGETS_HOSTILE: case SPELL_TARGETS_HOSTILE:
@ -701,23 +705,23 @@ namespace MaNGOS
switch(i_push_type) switch(i_push_type)
{ {
case PUSH_IN_FRONT: case PUSH_IN_FRONT:
if(i_spell.GetCaster()->isInFront((Unit*)(itr->getSource()), i_radius, 2*M_PI/3 )) if(i_spell.GetCaster()->isInFrontInMap((Unit*)(itr->getSource()), i_radius, 2*M_PI/3 ))
i_data->push_back(itr->getSource()); i_data->push_back(itr->getSource());
break; break;
case PUSH_IN_BACK: case PUSH_IN_BACK:
if(i_spell.GetCaster()->isInBack((Unit*)(itr->getSource()), i_radius, 2*M_PI/3 )) if(i_spell.GetCaster()->isInBackInMap((Unit*)(itr->getSource()), i_radius, 2*M_PI/3 ))
i_data->push_back(itr->getSource()); i_data->push_back(itr->getSource());
break; break;
case PUSH_SELF_CENTER: case PUSH_SELF_CENTER:
if(i_spell.GetCaster()->IsWithinDistInMap((Unit*)(itr->getSource()), i_radius)) if(i_spell.GetCaster()->IsWithinDist((Unit*)(itr->getSource()), i_radius))
i_data->push_back(itr->getSource()); i_data->push_back(itr->getSource());
break; break;
case PUSH_DEST_CENTER: case PUSH_DEST_CENTER:
if((itr->getSource()->GetDistance(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ) < i_radius )) if(itr->getSource()->IsWithinDist(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ,i_radius))
i_data->push_back(itr->getSource()); i_data->push_back(itr->getSource());
break; break;
case PUSH_TARGET_CENTER: case PUSH_TARGET_CENTER:
if(i_spell.m_targets.getUnitTarget()->IsWithinDistInMap((Unit*)(itr->getSource()), i_radius)) if(i_spell.m_targets.getUnitTarget()->IsWithinDist((Unit*)(itr->getSource()), i_radius))
i_data->push_back(itr->getSource()); i_data->push_back(itr->getSource());
break; break;
} }

View file

@ -459,30 +459,30 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
{ {
CHECK_PACKET_SIZE(recvPacket,8); CHECK_PACKET_SIZE(recvPacket,8);
if( GetPlayer()->pTrader ) if (GetPlayer()->pTrader)
return; return;
uint64 ID; uint64 ID;
if( !GetPlayer()->isAlive() ) if (!GetPlayer()->isAlive())
{ {
SendTradeStatus(TRADE_STATUS_YOU_DEAD); SendTradeStatus(TRADE_STATUS_YOU_DEAD);
return; return;
} }
if( GetPlayer()->hasUnitState(UNIT_STAT_STUNNED) ) if (GetPlayer()->hasUnitState(UNIT_STAT_STUNNED))
{ {
SendTradeStatus(TRADE_STATUS_YOU_STUNNED); SendTradeStatus(TRADE_STATUS_YOU_STUNNED);
return; return;
} }
if( isLogingOut() ) if (isLogingOut())
{ {
SendTradeStatus(TRADE_STATUS_YOU_LOGOUT); SendTradeStatus(TRADE_STATUS_YOU_LOGOUT);
return; return;
} }
if( GetPlayer()->isInFlight() ) if (GetPlayer()->isInFlight())
{ {
SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR);
return; return;
@ -492,55 +492,55 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
Player* pOther = ObjectAccessor::FindPlayer( ID ); Player* pOther = ObjectAccessor::FindPlayer( ID );
if( !pOther ) if (!pOther)
{ {
SendTradeStatus(TRADE_STATUS_NO_TARGET); SendTradeStatus(TRADE_STATUS_NO_TARGET);
return; return;
} }
if( pOther == GetPlayer() || pOther->pTrader ) if (pOther == GetPlayer() || pOther->pTrader)
{ {
SendTradeStatus(TRADE_STATUS_BUSY); SendTradeStatus(TRADE_STATUS_BUSY);
return; return;
} }
if( !pOther->isAlive() ) if (!pOther->isAlive())
{ {
SendTradeStatus(TRADE_STATUS_TARGET_DEAD); SendTradeStatus(TRADE_STATUS_TARGET_DEAD);
return; return;
} }
if( pOther->isInFlight() ) if (pOther->isInFlight())
{ {
SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR);
return; return;
} }
if( pOther->hasUnitState(UNIT_STAT_STUNNED) ) if (pOther->hasUnitState(UNIT_STAT_STUNNED))
{ {
SendTradeStatus(TRADE_STATUS_TARGET_STUNNED); SendTradeStatus(TRADE_STATUS_TARGET_STUNNED);
return; return;
} }
if( pOther->GetSession()->isLogingOut() ) if (pOther->GetSession()->isLogingOut())
{ {
SendTradeStatus(TRADE_STATUS_TARGET_LOGOUT); SendTradeStatus(TRADE_STATUS_TARGET_LOGOUT);
return; return;
} }
if( pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()) ) if (pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
{ {
SendTradeStatus(TRADE_STATUS_IGNORE_YOU); SendTradeStatus(TRADE_STATUS_IGNORE_YOU);
return; return;
} }
if(pOther->GetTeam() !=_player->GetTeam() ) if (pOther->GetTeam() !=_player->GetTeam() )
{ {
SendTradeStatus(TRADE_STATUS_WRONG_FACTION); SendTradeStatus(TRADE_STATUS_WRONG_FACTION);
return; return;
} }
if( pOther->GetDistance2d( _player ) > 10.0f ) if (!pOther->IsWithinDistInMap(_player,10.0f,false))
{ {
SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR);
return; return;

View file

@ -3200,7 +3200,7 @@ Spell* Unit::FindCurrentSpellBySpellId(uint32 spell_id) const
return NULL; return NULL;
} }
bool Unit::isInFront(Unit const* target, float distance, float arc) const bool Unit::isInFrontInMap(Unit const* target, float distance, float arc) const
{ {
return IsWithinDistInMap(target, distance) && HasInArc( arc, target ); return IsWithinDistInMap(target, distance) && HasInArc( arc, target );
} }
@ -3210,7 +3210,7 @@ void Unit::SetInFront(Unit const* target)
SetOrientation(GetAngle(target)); SetOrientation(GetAngle(target));
} }
bool Unit::isInBack(Unit const* target, float distance, float arc) const bool Unit::isInBackInMap(Unit const* target, float distance, float arc) const
{ {
return IsWithinDistInMap(target, distance) && !HasInArc( 2 * M_PI - arc, target ); return IsWithinDistInMap(target, distance) && !HasInArc( 2 * M_PI - arc, target );
} }
@ -9070,9 +9070,7 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList,
return true; return true;
// If there is collision rogue is seen regardless of level difference // If there is collision rogue is seen regardless of level difference
// TODO: check sizes in DB if (IsWithinDist(u,0.24f))
float distance = GetDistance(u);
if (distance < 0.24f)
return true; return true;
//If a mob or player is stunned he will not be able to detect stealth //If a mob or player is stunned he will not be able to detect stealth
@ -9083,14 +9081,14 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList,
if(u->GetTypeId() != TYPEID_PLAYER) if(u->GetTypeId() != TYPEID_PLAYER)
{ {
//Always invisible from back and out of aggro range //Always invisible from back and out of aggro range
bool isInFront = u->isInFront(this,((Creature const*)u)->GetAttackDistance(this)); bool isInFront = u->isInFrontInMap(this,((Creature const*)u)->GetAttackDistance(this));
if(!isInFront) if(!isInFront)
return false; return false;
} }
else else
{ {
//Always invisible from back //Always invisible from back
bool isInFront = u->isInFront(this,(GetTypeId()==TYPEID_PLAYER || GetCharmerOrOwnerGUID()) ? World::GetMaxVisibleDistanceForPlayer() : World::GetMaxVisibleDistanceForCreature()); bool isInFront = u->isInFrontInMap(this,(GetTypeId()==TYPEID_PLAYER || GetCharmerOrOwnerGUID()) ? World::GetMaxVisibleDistanceForPlayer() : World::GetMaxVisibleDistanceForCreature());
if(!isInFront) if(!isInFront)
return false; return false;
} }
@ -9116,7 +9114,7 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList,
//based on wowwiki every 5 mod we have 1 more level diff in calculation //based on wowwiki every 5 mod we have 1 more level diff in calculation
visibleDistance += (int32(u->GetTotalAuraModifier(SPELL_AURA_MOD_DETECT)) - stealthMod)/5.0f; visibleDistance += (int32(u->GetTotalAuraModifier(SPELL_AURA_MOD_DETECT)) - stealthMod)/5.0f;
if(distance > visibleDistance) if(!IsWithinDist(u,visibleDistance))
return false; return false;
} }

View file

@ -1240,9 +1240,9 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
float GetWeaponDamageRange(WeaponAttackType attType ,WeaponDamageRange type) const; float GetWeaponDamageRange(WeaponAttackType attType ,WeaponDamageRange type) const;
void SetBaseWeaponDamage(WeaponAttackType attType ,WeaponDamageRange damageRange, float value) { m_weaponDamage[attType][damageRange] = value; } void SetBaseWeaponDamage(WeaponAttackType attType ,WeaponDamageRange damageRange, float value) { m_weaponDamage[attType][damageRange] = value; }
bool isInFront(Unit const* target,float distance, float arc = M_PI) const; bool isInFrontInMap(Unit const* target,float distance, float arc = M_PI) const;
void SetInFront(Unit const* target); void SetInFront(Unit const* target);
bool isInBack(Unit const* target, float distance, float arc = M_PI) const; bool isInBackInMap(Unit const* target, float distance, float arc = M_PI) const;
// Visibility system // Visibility system
UnitVisibility GetVisibility() const { return m_Visibility; } UnitVisibility GetVisibility() const { return m_Visibility; }

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "7825" #define REVISION_NR "7826"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__