Merge branch 'master' of https://github.com/azerothcore/azerothcore-wotlk into dir-restructure

This commit is contained in:
Yehonal
2017-12-21 11:26:43 +01:00
445 changed files with 49192 additions and 15431 deletions

View File

@@ -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