aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Movement/PathGenerator.cpp110
-rw-r--r--src/server/game/Movement/PathGenerator.h3
-rw-r--r--src/server/game/Spells/Spell.cpp2
3 files changed, 92 insertions, 23 deletions
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index 2cda9b21c20..38a2e7a10c7 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -29,7 +29,7 @@
////////////////// PathGenerator //////////////////
PathGenerator::PathGenerator(const Unit* owner) :
_polyLength(0), _type(PATHFIND_BLANK), _useStraightPath(false),
- _forceDestination(false), _pointPathLimit(MAX_POINT_PATH_LENGTH),
+ _forceDestination(false), _pointPathLimit(MAX_POINT_PATH_LENGTH), _straightLine(false),
_endPosition(G3D::Vector3::zero()), _sourceUnit(owner), _navMesh(NULL),
_navMeshQuery(NULL)
{
@@ -53,7 +53,7 @@ PathGenerator::~PathGenerator()
TC_LOG_DEBUG("maps", "++ PathGenerator::~PathGenerator() for %u \n", _sourceUnit->GetGUIDLow());
}
-bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool forceDest)
+bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool forceDest, bool straightLine)
{
float x, y, z;
_sourceUnit->GetPosition(x, y, z);
@@ -68,6 +68,7 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo
SetStartPosition(start);
_forceDestination = forceDest;
+ _straightLine = straightLine;
TC_LOG_DEBUG("maps", "++ PathGenerator::CalculatePath() for %u \n", _sourceUnit->GetGUIDLow());
@@ -338,15 +339,45 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
// generate suffix
uint32 suffixPolyLength = 0;
- dtStatus dtResult = _navMeshQuery->findPath(
- suffixStartPoly, // start polygon
- endPoly, // end polygon
- suffixEndPoint, // start position
- endPoint, // end position
- &_filter, // polygon search filter
- _pathPolyRefs + prefixPolyLength - 1, // [out] path
- (int*)&suffixPolyLength,
- MAX_PATH_LENGTH-prefixPolyLength); // max number of polygons in output path
+
+ dtStatus dtResult;
+ if (_straightLine)
+ {
+ float hit = 0;
+ float hitNormal[3];
+ memset(hitNormal, 0, sizeof(hitNormal));
+
+ dtResult = _navMeshQuery->raycast(
+ suffixStartPoly,
+ suffixEndPoint,
+ endPoint,
+ &_filter,
+ &hit,
+ hitNormal,
+ _pathPolyRefs + prefixPolyLength - 1,
+ (int*)&suffixPolyLength,
+ MAX_PATH_LENGTH - prefixPolyLength);
+
+ // raycast() sets hit to FLT_MAX if there is a ray between start and end
+ if (hit != FLT_MAX)
+ {
+ // the ray hit something, return no path instead of the incomplete one
+ _type = PATHFIND_NOPATH;
+ return;
+ }
+ }
+ else
+ {
+ dtResult = _navMeshQuery->findPath(
+ suffixStartPoly, // start polygon
+ endPoly, // end polygon
+ suffixEndPoint, // start position
+ endPoint, // end position
+ &_filter, // polygon search filter
+ _pathPolyRefs + prefixPolyLength - 1, // [out] path
+ (int*)&suffixPolyLength,
+ MAX_PATH_LENGTH - prefixPolyLength); // max number of polygons in output path
+ }
if (!suffixPolyLength || dtStatusFailed(dtResult))
{
@@ -372,15 +403,44 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
// free and invalidate old path data
Clear();
- dtStatus dtResult = _navMeshQuery->findPath(
- startPoly, // start polygon
- endPoly, // end polygon
- startPoint, // start position
- endPoint, // end position
- &_filter, // polygon search filter
- _pathPolyRefs, // [out] path
- (int*)&_polyLength,
- MAX_PATH_LENGTH); // max number of polygons in output path
+ dtStatus dtResult;
+ if (_straightLine)
+ {
+ float hit = 0;
+ float hitNormal[3];
+ memset(hitNormal, 0, sizeof(hitNormal));
+
+ dtResult = _navMeshQuery->raycast(
+ startPoly,
+ startPoint,
+ endPoint,
+ &_filter,
+ &hit,
+ hitNormal,
+ _pathPolyRefs,
+ (int*)&_polyLength,
+ MAX_PATH_LENGTH);
+
+ // raycast() sets hit to FLT_MAX if there is a ray between start and end
+ if (hit != FLT_MAX)
+ {
+ // the ray hit something, return no path instead of the incomplete one
+ _type = PATHFIND_NOPATH;
+ return;
+ }
+ }
+ else
+ {
+ dtResult = _navMeshQuery->findPath(
+ startPoly, // start polygon
+ endPoly, // end polygon
+ startPoint, // start position
+ endPoint, // end position
+ &_filter, // polygon search filter
+ _pathPolyRefs, // [out] path
+ (int*)&_polyLength,
+ MAX_PATH_LENGTH); // max number of polygons in output path
+ }
if (!_polyLength || dtStatusFailed(dtResult))
{
@@ -407,7 +467,15 @@ void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoin
float pathPoints[MAX_POINT_PATH_LENGTH*VERTEX_SIZE];
uint32 pointCount = 0;
dtStatus dtResult = DT_FAILURE;
- if (_useStraightPath)
+ if (_straightLine)
+ {
+ // if the path is a straight line then start and end position are enough
+ dtResult = DT_SUCCESS;
+ pointCount = 2;
+ memcpy(&pathPoints[0], startPoint, sizeof(float)* 3);
+ memcpy(&pathPoints[3], endPoint, sizeof(float)* 3);
+ }
+ else if (_useStraightPath)
{
dtResult = _navMeshQuery->findStraightPath(
startPoint, // start position
diff --git a/src/server/game/Movement/PathGenerator.h b/src/server/game/Movement/PathGenerator.h
index ac66b7cec57..6e0d72ec8da 100644
--- a/src/server/game/Movement/PathGenerator.h
+++ b/src/server/game/Movement/PathGenerator.h
@@ -57,7 +57,7 @@ class PathGenerator
// Calculate the path from owner to given destination
// return: true if new path was calculated, false otherwise (no change needed)
- bool CalculatePath(float destX, float destY, float destZ, bool forceDest = false);
+ bool CalculatePath(float destX, float destY, float destZ, bool forceDest = false, bool straightLine = false);
// option setters - use optional
void SetUseStraightPath(bool useStraightPath) { _useStraightPath = useStraightPath; }
@@ -83,6 +83,7 @@ class PathGenerator
bool _useStraightPath; // type of path will be generated
bool _forceDestination; // when set, we will always arrive at given point
uint32 _pointPathLimit; // limit point path size; min(this, MAX_POINT_PATH_LENGTH)
+ bool _straightLine; // use raycast if true for a straight line path
G3D::Vector3 _startPosition; // {x, y, z} of current location
G3D::Vector3 _endPosition; // {x, y, z} of the destination
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index bf6f95d8c92..8b88ec9af92 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -5000,7 +5000,7 @@ SpellCastResult Spell::CheckCast(bool strict)
target->GetFirstCollisionPosition(pos, CONTACT_DISTANCE, target->GetRelativeAngle(m_caster));
m_preGeneratedPath.SetPathLengthLimit(m_spellInfo->GetMaxRange(true) * 1.5f);
- bool result = m_preGeneratedPath.CalculatePath(pos.m_positionX, pos.m_positionY, pos.m_positionZ + target->GetObjectSize());
+ bool result = m_preGeneratedPath.CalculatePath(pos.m_positionX, pos.m_positionY, pos.m_positionZ + target->GetObjectSize(), false, true);
if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT)
return SPELL_FAILED_OUT_OF_RANGE;
else if (!result || m_preGeneratedPath.GetPathType() & PATHFIND_NOPATH)