aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjackpoz <giacomopoz@gmail.com>2019-09-13 21:06:28 +0200
committerjackpoz <giacomopoz@gmail.com>2019-09-13 21:06:28 +0200
commit215a6cee24896f2def2a5af390c089ac1d947e65 (patch)
tree30ceca9283c1a78317ce1fba51c45d22fb5f8045
parent537c4d1208384f924a144180abd3f7c3cf305a6d (diff)
Core/Movement: Fix LoS issue of NPCs chasing targets
Add Line of Sight checks to ChaseMovementGenerator::Update(), fixing to ChaseMovementGenerator not reaching a point with valid LoS to the target. Fix re-implements 8927a042536d4671e94ad901e9209efcf78ffa2c after 2a84562dc85516f432bb1e5de9add23c28b26ce4 partially removed it. Fix #23724
-rw-r--r--src/server/game/Movement/MovementGenerators/ChaseMovementGenerator.cpp6
-rw-r--r--src/server/game/Movement/PathGenerator.cpp10
2 files changed, 15 insertions, 1 deletions
diff --git a/src/server/game/Movement/MovementGenerators/ChaseMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ChaseMovementGenerator.cpp
index bffda9ae803..50e7e8eb701 100644
--- a/src/server/game/Movement/MovementGenerators/ChaseMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/ChaseMovementGenerator.cpp
@@ -44,7 +44,11 @@ static bool PositionOkay(Unit* owner, Unit* target, Optional<float> minDistance,
return false;
if (maxDistance && distSq > square(*maxDistance))
return false;
- return !angle || angle->IsAngleOkay(target->GetRelativeAngle(owner));
+ if (angle && !angle->IsAngleOkay(target->GetRelativeAngle(owner)))
+ return false;
+ if (!owner->IsWithinLOSInMap(target))
+ return false;
+ return true;
}
static void DoMovementInform(Unit* owner, Unit* target)
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index adf50486136..3321e22c10a 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -926,6 +926,7 @@ void PathGenerator::ShortenPathUntilDist(G3D::Vector3 const& target, float dist)
return;
size_t i = _pathPoints.size()-1;
+ float x, y, z, collisionHeight = _sourceUnit->GetCollisionHeight();
// find the first i s.t.:
// - _pathPoints[i] is still too close
// - _pathPoints[i-1] is too far away
@@ -936,6 +937,15 @@ void PathGenerator::ShortenPathUntilDist(G3D::Vector3 const& target, float dist)
if ((_pathPoints[i-1] - target).squaredLength() >= distSq)
break; // bingo!
+ // check if the shortened path is still in LoS with the target
+ _sourceUnit->GetHitSpherePointFor({ _pathPoints[i - 1].x, _pathPoints[i - 1].y, _pathPoints[i - 1].z + collisionHeight }, x, y, z);
+ if (!_sourceUnit->GetMap()->isInLineOfSight(x, y, z, _pathPoints[i - 1].x, _pathPoints[i - 1].y, _pathPoints[i - 1].z + collisionHeight, _sourceUnit->GetPhaseMask(), LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::Nothing))
+ {
+ // whenver we find a point that is not in LoS anymore, simply use last valid path
+ _pathPoints.resize(i + 1);
+ return;
+ }
+
if (!--i)
{
// no point found that fulfills the condition