Core/Movement: Fix LoS issue of NPCs chasing targets
Port From (https://github.com/TrinityCore/TrinityCore/commit/f012d4b7fcf0376de75f09c2b59509247fd133cb)
This commit is contained in:
@@ -3023,7 +3023,7 @@ namespace Game.Entities
|
|||||||
return GetMap().IsInLineOfSight(GetPhaseShift(), x, y, z, ox, oy, oz, checks, ignoreFlags);
|
return GetMap().IsInLineOfSight(GetPhaseShift(), x, y, z, ox, oy, oz, checks, ignoreFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
Position GetHitSpherePointFor(Position dest)
|
public Position GetHitSpherePointFor(Position dest)
|
||||||
{
|
{
|
||||||
Vector3 vThis = new(GetPositionX(), GetPositionY(), GetPositionZ() + GetCollisionHeight());
|
Vector3 vThis = new(GetPositionX(), GetPositionY(), GetPositionZ() + GetCollisionHeight());
|
||||||
Vector3 vObj = new(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ());
|
Vector3 vObj = new(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ());
|
||||||
@@ -3032,7 +3032,7 @@ namespace Game.Entities
|
|||||||
return new Position(contactPoint.X, contactPoint.Y, contactPoint.Z, GetAbsoluteAngle(contactPoint.X, contactPoint.Y));
|
return new Position(contactPoint.X, contactPoint.Y, contactPoint.Z, GetAbsoluteAngle(contactPoint.X, contactPoint.Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetHitSpherePointFor(Position dest, out float x, out float y, out float z)
|
public void GetHitSpherePointFor(Position dest, out float x, out float y, out float z)
|
||||||
{
|
{
|
||||||
Position pos = GetHitSpherePointFor(dest);
|
Position pos = GetHitSpherePointFor(dest);
|
||||||
x = pos.GetPositionX();
|
x = pos.GetPositionX();
|
||||||
|
|||||||
@@ -259,7 +259,11 @@ namespace Game.Movement
|
|||||||
return false;
|
return false;
|
||||||
if (maxDistance.HasValue && distSq > MathF.Sqrt(maxDistance.Value))
|
if (maxDistance.HasValue && distSq > MathF.Sqrt(maxDistance.Value))
|
||||||
return false;
|
return false;
|
||||||
return !angle.HasValue || angle.Value.IsAngleOkay(target.GetRelativeAngle(owner));
|
if (angle.HasValue && !angle.Value.IsAngleOkay(target.GetRelativeAngle(owner)))
|
||||||
|
return false;
|
||||||
|
if (!owner.IsWithinLOSInMap(target))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DoMovementInform(Unit owner, Unit target)
|
static void DoMovementInform(Unit owner, Unit target)
|
||||||
|
|||||||
@@ -892,6 +892,10 @@ namespace Game.Movement
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
int i = _pathPoints.Length - 1;
|
int i = _pathPoints.Length - 1;
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
float collisionHeight = _sourceUnit.GetCollisionHeight();
|
||||||
// find the first i s.t.:
|
// find the first i s.t.:
|
||||||
// - _pathPoints[i] is still too close
|
// - _pathPoints[i] is still too close
|
||||||
// - _pathPoints[i-1] is too far away
|
// - _pathPoints[i-1] is too far away
|
||||||
@@ -902,6 +906,15 @@ namespace Game.Movement
|
|||||||
if ((_pathPoints[i - 1] - target).LengthSquared() >= distSq)
|
if ((_pathPoints[i - 1] - target).LengthSquared() >= distSq)
|
||||||
break; // bingo!
|
break; // bingo!
|
||||||
|
|
||||||
|
// check if the shortened path is still in LoS with the target
|
||||||
|
_sourceUnit.GetHitSpherePointFor(new Position(_pathPoints[i - 1].X, _pathPoints[i - 1].Y, _pathPoints[i - 1].Z + collisionHeight), out x, out y, out z);
|
||||||
|
if (!_sourceUnit.GetMap().IsInLineOfSight(_sourceUnit.GetPhaseShift(), x, y, z, _pathPoints[i - 1].X, _pathPoints[i - 1].Y, _pathPoints[i - 1].Z + collisionHeight, LineOfSightChecks.All, ModelIgnoreFlags.Nothing))
|
||||||
|
{
|
||||||
|
// whenver we find a point that is not in LoS anymore, simply use last valid path
|
||||||
|
Array.Resize(ref _pathPoints, i + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (--i == 0)
|
if (--i == 0)
|
||||||
{
|
{
|
||||||
// no point found that fulfills the condition
|
// no point found that fulfills the condition
|
||||||
|
|||||||
Reference in New Issue
Block a user