Core/Movement: Fix LoS issue of NPCs chasing targets

Port From (https://github.com/TrinityCore/TrinityCore/commit/f012d4b7fcf0376de75f09c2b59509247fd133cb)
This commit is contained in:
hondacrx
2022-01-04 20:09:33 -05:00
parent 12c9ea08ac
commit 7f053ea099
3 changed files with 20 additions and 3 deletions
+2 -2
View File
@@ -3023,7 +3023,7 @@ namespace Game.Entities
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 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));
}
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);
x = pos.GetPositionX();
@@ -259,7 +259,11 @@ namespace Game.Movement
return false;
if (maxDistance.HasValue && distSq > MathF.Sqrt(maxDistance.Value))
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)
@@ -892,6 +892,10 @@ namespace Game.Movement
return;
int i = _pathPoints.Length - 1;
float x;
float y;
float z;
float collisionHeight = _sourceUnit.GetCollisionHeight();
// find the first i s.t.:
// - _pathPoints[i] is still too close
// - _pathPoints[i-1] is too far away
@@ -902,6 +906,15 @@ namespace Game.Movement
if ((_pathPoints[i - 1] - target).LengthSquared() >= distSq)
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)
{
// no point found that fulfills the condition