mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-15 01:59:09 +00:00
Merge branch 'master' of https://github.com/azerothcore/azerothcore-wotlk into dir-restructure
This commit is contained in:
@@ -1095,9 +1095,13 @@ bool WorldObject::IsWithinLOSInMap(const WorldObject* obj) const
|
||||
if (!IsInMap(obj))
|
||||
return false;
|
||||
|
||||
float ox, oy, oz;
|
||||
obj->GetPosition(ox, oy, oz);
|
||||
return IsWithinLOS(ox, oy, oz);
|
||||
float x, y, z;
|
||||
if (obj->GetTypeId() == TYPEID_PLAYER)
|
||||
obj->GetPosition(x, y, z);
|
||||
else
|
||||
obj->GetHitSpherePointFor(GetPosition(), x, y, z);
|
||||
|
||||
return IsWithinLOS(x, y, z);
|
||||
}
|
||||
|
||||
bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const
|
||||
@@ -1107,11 +1111,36 @@ bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const
|
||||
VMAP::IVMapManager* vMapManager = VMAP::VMapFactory::createOrGetVMapManager();
|
||||
return vMapManager->isInLineOfSight(GetMapId(), x, y, z+2.0f, ox, oy, oz+2.0f);*/
|
||||
if (IsInWorld())
|
||||
return GetMap()->isInLineOfSight(GetPositionX(), GetPositionY(), GetPositionZ()+2.f, ox, oy, oz+2.f, GetPhaseMask());
|
||||
{
|
||||
float x, y, z;
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
GetPosition(x, y, z);
|
||||
else
|
||||
GetHitSpherePointFor({ ox, oy, oz }, x, y, z);
|
||||
|
||||
return GetMap()->isInLineOfSight(x, y, z + 2.0f, ox, oy, oz + 2.0f, GetPhaseMask());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Position WorldObject::GetHitSpherePointFor(Position const& dest) const
|
||||
{
|
||||
G3D::Vector3 vThis(GetPositionX(), GetPositionY(), GetPositionZ());
|
||||
G3D::Vector3 vObj(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ());
|
||||
G3D::Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * std::min(dest.GetExactDist(this), GetObjectSize());
|
||||
|
||||
return Position(contactPoint.x, contactPoint.y, contactPoint.z, GetAngle(contactPoint.x, contactPoint.y));
|
||||
}
|
||||
|
||||
void WorldObject::GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z) const
|
||||
{
|
||||
Position pos = GetHitSpherePointFor(dest);
|
||||
x = pos.GetPositionX();
|
||||
y = pos.GetPositionY();
|
||||
z = pos.GetPositionZ();
|
||||
}
|
||||
|
||||
bool WorldObject::GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D /* = true */) const
|
||||
{
|
||||
float dx1 = GetPositionX() - obj1->GetPositionX();
|
||||
@@ -2402,123 +2431,33 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y,
|
||||
else
|
||||
UpdateAllowedPositionZ(x, y, z);
|
||||
|
||||
/*
|
||||
// if detection disabled, return first point
|
||||
if (!sWorld->getIntConfig(CONFIG_DETECT_POS_COLLISION))
|
||||
{
|
||||
UpdateGroundPositionZ(x, y, z); // update to LOS height if available
|
||||
if (!sWorld->getBoolConfig(CONFIG_DETECT_POS_COLLISION))
|
||||
return;
|
||||
}
|
||||
|
||||
// or remember first point
|
||||
// return if the point is already in LoS
|
||||
if (IsWithinLOS(x, y, z))
|
||||
return;
|
||||
|
||||
// remember first point
|
||||
float first_x = x;
|
||||
float first_y = y;
|
||||
bool first_los_conflict = false; // first point LOS problems
|
||||
float first_z = z;
|
||||
|
||||
// prepare selector for work
|
||||
ObjectPosSelector selector(GetPositionX(), GetPositionY(), GetObjectSize(), distance2d+searcher_size);
|
||||
|
||||
// adding used positions around object
|
||||
// loop in a circle to look for a point in LoS using small steps
|
||||
for (float angle = float(M_PI) / 8; angle < float(M_PI) * 2; angle += float(M_PI) / 8)
|
||||
{
|
||||
CellCoord p(Trinity::ComputeCellCoord(GetPositionX(), GetPositionY()));
|
||||
Cell cell(p);
|
||||
cell.SetNoCreate();
|
||||
|
||||
Trinity::NearUsedPosDo u_do(*this, searcher, absAngle, selector);
|
||||
Trinity::WorldObjectWorker<Trinity::NearUsedPosDo> worker(this, u_do);
|
||||
|
||||
TypeContainerVisitor<Trinity::WorldObjectWorker<Trinity::NearUsedPosDo>, GridTypeMapContainer > grid_obj_worker(worker);
|
||||
TypeContainerVisitor<Trinity::WorldObjectWorker<Trinity::NearUsedPosDo>, WorldTypeMapContainer > world_obj_worker(worker);
|
||||
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
cell_lock->Visit(cell_lock, grid_obj_worker, *GetMap(), *this, distance2d);
|
||||
cell_lock->Visit(cell_lock, world_obj_worker, *GetMap(), *this, distance2d);
|
||||
}
|
||||
|
||||
// maybe can just place in primary position
|
||||
if (selector.CheckOriginal())
|
||||
{
|
||||
UpdateGroundPositionZ(x, y, z); // update to LOS height if available
|
||||
|
||||
if (IsWithinLOS(x, y, z))
|
||||
return;
|
||||
|
||||
first_los_conflict = true; // first point have LOS problems
|
||||
}
|
||||
|
||||
float angle; // candidate of angle for free pos
|
||||
|
||||
// special case when one from list empty and then empty side preferred
|
||||
if (selector.FirstAngle(angle))
|
||||
{
|
||||
GetNearPoint2D(x, y, distance2d, absAngle+angle);
|
||||
GetNearPoint2D(x, y, distance2d + searcher_size, absAngle + angle);
|
||||
z = GetPositionZ();
|
||||
UpdateGroundPositionZ(x, y, z); // update to LOS height if available
|
||||
|
||||
UpdateAllowedPositionZ(x, y, z);
|
||||
if (IsWithinLOS(x, y, z))
|
||||
return;
|
||||
}
|
||||
|
||||
// set first used pos in lists
|
||||
selector.InitializeAngle();
|
||||
|
||||
// select in positions after current nodes (selection one by one)
|
||||
while (selector.NextAngle(angle)) // angle for free pos
|
||||
{
|
||||
GetNearPoint2D(x, y, distance2d, absAngle+angle);
|
||||
z = GetPositionZ();
|
||||
UpdateGroundPositionZ(x, y, z); // update to LOS height if available
|
||||
|
||||
if (IsWithinLOS(x, y, z))
|
||||
return;
|
||||
}
|
||||
|
||||
// BAD NEWS: not free pos (or used or have LOS problems)
|
||||
// Attempt find _used_ pos without LOS problem
|
||||
|
||||
if (!first_los_conflict)
|
||||
{
|
||||
x = first_x;
|
||||
y = first_y;
|
||||
|
||||
UpdateGroundPositionZ(x, y, z); // update to LOS height if available
|
||||
return;
|
||||
}
|
||||
|
||||
// special case when one from list empty and then empty side preferred
|
||||
if (selector.IsNonBalanced())
|
||||
{
|
||||
if (!selector.FirstAngle(angle)) // _used_ pos
|
||||
{
|
||||
GetNearPoint2D(x, y, distance2d, absAngle+angle);
|
||||
z = GetPositionZ();
|
||||
UpdateGroundPositionZ(x, y, z); // update to LOS height if available
|
||||
|
||||
if (IsWithinLOS(x, y, z))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// set first used pos in lists
|
||||
selector.InitializeAngle();
|
||||
|
||||
// select in positions after current nodes (selection one by one)
|
||||
while (selector.NextUsedAngle(angle)) // angle for used pos but maybe without LOS problem
|
||||
{
|
||||
GetNearPoint2D(x, y, distance2d, absAngle+angle);
|
||||
z = GetPositionZ();
|
||||
UpdateGroundPositionZ(x, y, z); // update to LOS height if available
|
||||
|
||||
if (IsWithinLOS(x, y, z))
|
||||
return;
|
||||
}
|
||||
|
||||
// BAD BAD NEWS: all found pos (free and used) have LOS problem :(
|
||||
// still not in LoS, give up and return first position found
|
||||
x = first_x;
|
||||
y = first_y;
|
||||
|
||||
UpdateGroundPositionZ(x, y, z); // update to LOS height if available
|
||||
*/
|
||||
z = first_z;
|
||||
}
|
||||
|
||||
bool WorldObject::GetClosePoint(float &x, float &y, float &z, float size, float distance2d, float angle, const WorldObject* forWho, bool force) const
|
||||
|
||||
Reference in New Issue
Block a user