aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGiacomo Pozzoni <giacomopoz@gmail.com>2020-05-15 18:43:12 +0000
committerShauren <shauren.trinity@gmail.com>2022-01-04 15:33:04 +0100
commit89afeed41b4f040e4852b35183f30291588662d7 (patch)
tree10f88ce2a0be2ec04099396bac72dd8176c9323d /src
parent406c7219ad6454a3f3855c9e0732245dcc34b2dc (diff)
Core/MMAPs: Adjust walkable climb and fix a lot of mmap raycast issues (#24539)
* Core/MMAPs: Adjust walkable climb Adjust walkable climb as recast using walkableClimb also to find the poly from a position, giving priority to polys that are below the position but closer than walkableClimb. * Temporarily disable static collision (the whole check should be removed) * Core/Spells: removed deprecated mmap path check for TARGET_DEST_CASTER_FRONT_LEAP * Core/Objects: allow flying units to use the helper as well (flying units casting radius based spells) * Code refactor * Handle raycasts that end in a point with no height in the mmap mesh as PATHFIND_NOPATH * Walk back a bit from raycast hitpoints as sometime the 2D result point is outside of the polygons due to floating point errors. * Remove whitespace * Revert 4a197ba22af4eed01be632ea2dd7d103a963f043 as a raycast point path should have the Z retrieved with getPolyHeight(). Raycast will only return a 2-point path with Start and Hitpoint/End * Cleanup PathGenerator raycast case * Fix PathGenerator raycast broken if start and end are on same poly. Fix PathGenerator raycast broken if no wall is hit. Remove unused case of using raycast with an existing previous path (can be added back properly if needed). Remove forcing poly length to 2 when we actually have already the right number. * Use closestPointOnPolyBoundary on the second try of finding a point on poly for raycast. Note that in this case the mesh height is not used which might cause issues. The poly boundary height will be used instead. * Handle cases where getPolyHeight() fails because the point is on polygon border (and caused by floating point imprecision) * Add far from poly flags * Set PATHFIND_INCOMPLETE in raycast case if startFarFromPoly or endFarFromPoly * Fix blink close to walls with no valid polygon behind the wall * Require to re-extract mmaps Co-authored-by: Ovah <dreadkiller@gmx.de> (cherry picked from commit c0b75bf40da8b447a2f3533dabbfad9eba7c6ea1)
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Object/Object.cpp10
-rw-r--r--src/server/game/Movement/PathGenerator.cpp175
-rw-r--r--src/server/game/Movement/PathGenerator.h7
-rw-r--r--src/server/game/Spells/Spell.cpp18
-rw-r--r--src/server/scripts/Commands/cs_mmaps.cpp11
-rw-r--r--src/server/scripts/Spells/spell_warrior.cpp10
-rw-r--r--src/tools/mmaps_generator/MapBuilder.cpp2
7 files changed, 106 insertions, 127 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 5e24ce2d606..0026d42a968 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -3211,10 +3211,11 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
// Use a detour raycast to get our first collision point
PathGenerator path(this);
- path.CalculatePath(destx, desty, destz, false, true);
+ path.SetUseRaycast(true);
+ path.CalculatePath(destx, desty, destz, false);
// We have a invalid path result. Skip further processing.
- if (path.GetPathType() & ~(PATHFIND_NORMAL | PATHFIND_SHORTCUT | PATHFIND_INCOMPLETE | PATHFIND_FARFROMPOLY_END))
+ if (path.GetPathType() & ~(PATHFIND_NORMAL | PATHFIND_SHORTCUT | PATHFIND_INCOMPLETE | PATHFIND_FARFROMPOLY_END | PATHFIND_NOT_USING_PATH))
return;
G3D::Vector3 result = path.GetPath().back();
@@ -3224,7 +3225,9 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
// check static LOS
float halfHeight = GetCollisionHeight() * 0.5f;
- bool col = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(PhasingHandler::GetTerrainMapId(GetPhaseShift(), GetMap(), pos.m_positionX, pos.m_positionY),
+ bool col;
+ /*
+ col = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(PhasingHandler::GetTerrainMapId(GetPhaseShift(), GetMap(), pos.m_positionX, pos.m_positionY),
pos.m_positionX, pos.m_positionY, pos.m_positionZ + halfHeight,
destx, desty, destz + halfHeight,
destx, desty, destz, -0.5f);
@@ -3238,6 +3241,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
desty -= CONTACT_DISTANCE * std::sin(angle);
dist = std::sqrt((pos.m_positionX - destx) * (pos.m_positionX - destx) + (pos.m_positionY - desty) * (pos.m_positionY - desty));
}
+ */
// check dynamic collision
col = GetMap()->getObjectHitPos(GetPhaseShift(),
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index 593a347f424..77d59afdbad 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -30,7 +30,7 @@
////////////////// PathGenerator //////////////////
PathGenerator::PathGenerator(WorldObject const* owner) :
_polyLength(0), _type(PATHFIND_BLANK), _useStraightPath(false),
- _forceDestination(false), _pointPathLimit(MAX_POINT_PATH_LENGTH), _straightLine(false),
+ _forceDestination(false), _pointPathLimit(MAX_POINT_PATH_LENGTH), _useRaycast(false),
_endPosition(G3D::Vector3::zero()), _source(owner), _navMesh(nullptr),
_navMeshQuery(nullptr)
{
@@ -54,7 +54,7 @@ PathGenerator::~PathGenerator()
TC_LOG_DEBUG("maps.mmaps", "++ PathGenerator::~PathGenerator() for %s", _source->GetGUID().ToString().c_str());
}
-bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool forceDest, bool straightLine)
+bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool forceDest)
{
float x, y, z;
_source->GetPosition(x, y, z);
@@ -71,7 +71,6 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo
SetStartPosition(start);
_forceDestination = forceDest;
- _straightLine = straightLine;
TC_LOG_DEBUG("maps.mmaps", "++ PathGenerator::CalculatePath() for %s", _source->GetGUID().ToString().c_str());
@@ -156,6 +155,7 @@ dtPolyRef PathGenerator::GetPolyByLocation(float const* point, float* distance)
return polyRef;
}
+ *distance = FLT_MAX;
return INVALID_POLYREF;
}
@@ -170,6 +170,8 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
dtPolyRef startPoly = GetPolyByLocation(startPoint, &distToStartPoly);
dtPolyRef endPoly = GetPolyByLocation(endPoint, &distToEndPoly);
+ _type = PathType(PATHFIND_NORMAL);
+
// we have a hole in our mesh
// make shortcut path and mark it as NOPATH ( with flying and swimming exception )
// its up to caller how he will use this info
@@ -195,8 +197,18 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
}
}
- _type = (path || waterPath) ? PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH) : PATHFIND_NOPATH;
- return;
+ if (path || waterPath)
+ {
+ _type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH);
+ return;
+ }
+
+ // raycast doesn't need endPoly to be valid
+ if (!_useRaycast)
+ {
+ _type = PATHFIND_NOPATH;
+ return;
+ }
}
// we may need a better number here
@@ -234,10 +246,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
BuildShortcut();
_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH);
- if (startFarFromPoly)
- _type = PathType(_type | PATHFIND_FARFROMPOLY_START);
- if (endFarFromPoly)
- _type = PathType(_type | PATHFIND_FARFROMPOLY_END);
+ AddFarFromPolyFlags(startFarFromPoly, endFarFromPoly);
return;
}
@@ -253,10 +262,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
_type = PathType(PATHFIND_INCOMPLETE);
- if (startFarFromPoly)
- _type = PathType(_type | PATHFIND_FARFROMPOLY_START);
- if (endFarFromPoly)
- _type = PathType(_type | PATHFIND_FARFROMPOLY_END);
+ AddFarFromPolyFlags(startFarFromPoly, endFarFromPoly);
}
}
@@ -264,9 +270,10 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
// start and end are on same polygon
// handle this case as if they were 2 different polygons, building a line path split in some few points
- if (startPoly == endPoly)
+ if (startPoly == endPoly && !_useRaycast)
{
TC_LOG_DEBUG("maps.mmaps", "++ BuildPolyPath :: (startPoly == endPoly)");
+
_pathPolyRefs[0] = startPoly;
_polyLength = 1;
@@ -274,10 +281,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
{
_type = PathType(PATHFIND_INCOMPLETE);
- if (startFarFromPoly)
- _type = PathType(_type | PATHFIND_FARFROMPOLY_START);
- if (endFarFromPoly)
- _type = PathType(_type | PATHFIND_FARFROMPOLY_END);
+ AddFarFromPolyFlags(startFarFromPoly, endFarFromPoly);
}
else
_type = PATHFIND_NORMAL;
@@ -376,39 +380,12 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
uint32 suffixPolyLength = 0;
dtStatus dtResult;
- if (_straightLine)
+ if (_useRaycast)
{
- 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
- Clear();
- _polyLength = 2;
- _pathPoints.resize(2);
- _pathPoints[0] = GetStartPosition();
- float hitPos[3];
- dtVlerp(hitPos, startPoint, endPoint, hit);
- _pathPoints[1] = G3D::Vector3(hitPos[2], hitPos[0], hitPos[1]);
-
- NormalizePath();
- _type = PATHFIND_INCOMPLETE;
- return;
- }
+ TC_LOG_ERROR("maps.mmaps", "PathGenerator::BuildPolyPath() called with _useRaycast with a previous path for unit %s", _source->GetGUID().ToString().c_str());
+ BuildShortcut();
+ _type = PATHFIND_NOPATH;
+ return;
}
else
{
@@ -448,7 +425,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
Clear();
dtStatus dtResult;
- if (_straightLine)
+ if (_useRaycast)
{
float hit = 0;
float hitNormal[3];
@@ -465,24 +442,57 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
(int*)&_polyLength,
MAX_PATH_LENGTH);
+ if (!_polyLength || dtStatusFailed(dtResult))
+ {
+ BuildShortcut();
+ _type = PATHFIND_NOPATH;
+ AddFarFromPolyFlags(startFarFromPoly, endFarFromPoly);
+ return;
+ }
+
// 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
- Clear();
- _polyLength = 2;
- _pathPoints.resize(2);
- _pathPoints[0] = GetStartPosition();
float hitPos[3];
+
+ // Walk back a bit from the hit point to make sure it's in the mesh (sometimes the point is actually outside of the polygons due to float precision issues)
+ hit *= 0.99f;
dtVlerp(hitPos, startPoint, endPoint, hit);
+
+ // if it fails again, clamp to poly boundary
+ if (dtStatusFailed(_navMeshQuery->getPolyHeight(_pathPolyRefs[_polyLength - 1], hitPos, &hitPos[1])))
+ _navMeshQuery->closestPointOnPolyBoundary(_pathPolyRefs[_polyLength - 1], hitPos, hitPos);
+
+ _pathPoints.resize(2);
+ _pathPoints[0] = GetStartPosition();
_pathPoints[1] = G3D::Vector3(hitPos[2], hitPos[0], hitPos[1]);
NormalizePath();
_type = PATHFIND_INCOMPLETE;
+ AddFarFromPolyFlags(startFarFromPoly, false);
return;
}
else
- _navMeshQuery->getPolyHeight(_pathPolyRefs[_polyLength - 1], endPoint, &endPoint[1]);
+ {
+ // clamp to poly boundary if we fail to get the height
+ if (dtStatusFailed(_navMeshQuery->getPolyHeight(_pathPolyRefs[_polyLength - 1], endPoint, &endPoint[1])))
+ _navMeshQuery->closestPointOnPolyBoundary(_pathPolyRefs[_polyLength - 1], endPoint, endPoint);
+
+ _pathPoints.resize(2);
+ _pathPoints[0] = GetStartPosition();
+ _pathPoints[1] = G3D::Vector3(endPoint[2], endPoint[0], endPoint[1]);
+
+ NormalizePath();
+ if (startFarFromPoly || endFarFromPoly)
+ {
+ _type = PathType(PATHFIND_INCOMPLETE);
+
+ AddFarFromPolyFlags(startFarFromPoly, endFarFromPoly);
+ }
+ else
+ _type = PATHFIND_NORMAL;
+ return;
+ }
}
else
{
@@ -513,10 +523,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
else
_type = PATHFIND_INCOMPLETE;
- if (startFarFromPoly)
- _type = PathType(_type | PATHFIND_FARFROMPOLY_START);
- if (endFarFromPoly)
- _type = PathType(_type | PATHFIND_FARFROMPOLY_END);
+ AddFarFromPolyFlags(startFarFromPoly, endFarFromPoly);
// generate the point-path out of our up-to-date poly-path
BuildPointPath(startPoint, endPoint);
@@ -527,37 +534,13 @@ 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 (_straightLine)
+ if (_useRaycast)
{
- dtResult = DT_SUCCESS;
- pointCount = 1;
- memcpy(&pathPoints[VERTEX_SIZE * 0], startPoint, sizeof(float)* 3); // first point
-
- // path has to be split into polygons with dist SMOOTH_PATH_STEP_SIZE between them
- G3D::Vector3 startVec = G3D::Vector3(startPoint[0], startPoint[1], startPoint[2]);
- G3D::Vector3 endVec = G3D::Vector3(endPoint[0], endPoint[1], endPoint[2]);
- G3D::Vector3 diffVec = (endVec - startVec);
- G3D::Vector3 prevVec = startVec;
- float len = diffVec.length();
- diffVec *= SMOOTH_PATH_STEP_SIZE / len;
-
- // If the path is short PATHFIND_SHORT will be set as type
- while (len > SMOOTH_PATH_STEP_SIZE && pointCount < MAX_POINT_PATH_LENGTH)
- {
- len -= SMOOTH_PATH_STEP_SIZE;
- prevVec += diffVec;
- pathPoints[VERTEX_SIZE * pointCount + 0] = prevVec.x;
- pathPoints[VERTEX_SIZE * pointCount + 1] = prevVec.y;
- pathPoints[VERTEX_SIZE * pointCount + 2] = prevVec.z;
- ++pointCount;
- }
-
- // If the path is short PATHFIND_SHORT will be set as type
- if (pointCount < MAX_POINT_PATH_LENGTH)
- {
- memcpy(&pathPoints[VERTEX_SIZE * pointCount], endPoint, sizeof(float) * 3); // last point
- ++pointCount;
- }
+ // _straightLine uses raycast and it currently doesn't support building a point path, only a 2-point path with start and hitpoint/end is returned
+ TC_LOG_ERROR("maps.mmaps", "PathGenerator::BuildPointPath() called with _useRaycast for unit %s", _source->GetGUID().ToString().c_str());
+ BuildShortcut();
+ _type = PATHFIND_NOPATH;
+ return;
}
else if (_useStraightPath)
{
@@ -841,7 +824,7 @@ dtStatus PathGenerator::FindSmoothPath(float const* startPos, float const* endPo
if (polyPathSize > 1)
{
- // Pick the closest poitns on poly border
+ // Pick the closest points on poly border
if (dtStatusFailed(_navMeshQuery->closestPointOnPolyBoundary(polys[0], startPos, iterPos)))
return DT_FAILURE;
@@ -1041,3 +1024,11 @@ bool PathGenerator::IsInvalidDestinationZ(WorldObject const* target) const
{
return (target->GetPositionZ() - GetActualEndPosition().z) > 5.0f;
}
+
+void PathGenerator::AddFarFromPolyFlags(bool startFarFromPoly, bool endFarFromPoly)
+{
+ if (startFarFromPoly)
+ _type = PathType(_type | PATHFIND_FARFROMPOLY_START);
+ if (endFarFromPoly)
+ _type = PathType(_type | PATHFIND_FARFROMPOLY_END);
+}
diff --git a/src/server/game/Movement/PathGenerator.h b/src/server/game/Movement/PathGenerator.h
index 769e396c3a1..64ad8393436 100644
--- a/src/server/game/Movement/PathGenerator.h
+++ b/src/server/game/Movement/PathGenerator.h
@@ -60,12 +60,13 @@ class TC_GAME_API 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 straightLine = false);
+ bool CalculatePath(float destX, float destY, float destZ, bool forceDest = false);
bool IsInvalidDestinationZ(WorldObject const* target) const;
// option setters - use optional
void SetUseStraightPath(bool useStraightPath) { _useStraightPath = useStraightPath; }
void SetPathLengthLimit(float distance) { _pointPathLimit = std::min<uint32>(uint32(distance/SMOOTH_PATH_STEP_SIZE), MAX_POINT_PATH_LENGTH); }
+ void SetUseRaycast(bool useRaycast) { _useRaycast = useRaycast; }
// result getters
G3D::Vector3 const& GetStartPosition() const { return _startPosition; }
@@ -90,7 +91,7 @@ class TC_GAME_API 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
+ bool _useRaycast; // 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
@@ -136,6 +137,8 @@ class TC_GAME_API PathGenerator
dtStatus FindSmoothPath(float const* startPos, float const* endPos,
dtPolyRef const* polyPath, uint32 polyPathSize,
float* smoothPath, int* smoothPathSize, uint32 smoothPathMaxSize);
+
+ void AddFarFromPolyFlags(bool startFarFromPoly, bool endFarFromPoly);
};
#endif
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 66ec7cbad4d..7632a0c6993 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -1422,21 +1422,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffectInfo const& spellEffectIn
Position pos = dest._position;
unitCaster->MovePositionToFirstCollision(pos, dist, angle);
- // Generate path to that point.
- if (!m_preGeneratedPath)
- m_preGeneratedPath = std::make_unique<PathGenerator>(unitCaster);
-
- m_preGeneratedPath->SetPathLengthLimit(dist);
-
- // Should we use straightline here ? What do we do when we don't have a full path ?
- bool pathResult = m_preGeneratedPath->CalculatePath(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), false, true);
- if (pathResult && m_preGeneratedPath->GetPathType() & (PATHFIND_NORMAL | PATHFIND_SHORTCUT))
- {
- pos.m_positionX = m_preGeneratedPath->GetActualEndPosition().x;
- pos.m_positionY = m_preGeneratedPath->GetActualEndPosition().y;
- pos.m_positionZ = m_preGeneratedPath->GetActualEndPosition().z;
- dest.Relocate(pos);
- }
+ dest.Relocate(pos);
break;
}
case TARGET_DEST_CASTER_GROUND:
@@ -5757,7 +5743,7 @@ SpellCastResult Spell::CheckCast(bool strict, int32* param1 /*= nullptr*/, int32
m_preGeneratedPath->SetPathLengthLimit(range);
// first try with raycast, if it fails fall back to normal path
- bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false, false);
+ bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
return SPELL_FAILED_NOPATH;
else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp
index 20213f392d2..04d14913170 100644
--- a/src/server/scripts/Commands/cs_mmaps.cpp
+++ b/src/server/scripts/Commands/cs_mmaps.cpp
@@ -85,9 +85,9 @@ public:
if (para && strcmp(para, "true") == 0)
useStraightPath = true;
- bool useStraightLine = false;
- if (para && strcmp(para, "line") == 0)
- useStraightLine = true;
+ bool useRaycast = false;
+ if (para && (strcmp(para, "line") == 0 || strcmp(para, "ray") == 0 || strcmp(para, "raycast") == 0))
+ useRaycast = true;
// unit locations
float x, y, z;
@@ -96,11 +96,12 @@ public:
// path
PathGenerator path(target);
path.SetUseStraightPath(useStraightPath);
- bool result = path.CalculatePath(x, y, z, false, useStraightLine);
+ path.SetUseRaycast(useRaycast);
+ bool result = path.CalculatePath(x, y, z, false);
Movement::PointsArray const& pointPath = path.GetPath();
handler->PSendSysMessage("%s's path to %s:", target->GetName().c_str(), player->GetName().c_str());
- handler->PSendSysMessage("Building: %s", useStraightPath ? "StraightPath" : useStraightLine ? "Raycast" : "SmoothPath");
+ handler->PSendSysMessage("Building: %s", useStraightPath ? "StraightPath" : useRaycast ? "Raycast" : "SmoothPath");
handler->PSendSysMessage("Result: %s - Length: %zu - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType());
G3D::Vector3 const& start = path.GetStartPosition();
diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp
index 2376a3d13fe..d008fec0db8 100644
--- a/src/server/scripts/Spells/spell_warrior.cpp
+++ b/src/server/scripts/Spells/spell_warrior.cpp
@@ -283,17 +283,11 @@ public:
PathGenerator generatedPath(GetCaster());
generatedPath.SetPathLengthLimit(range);
- bool result = generatedPath.CalculatePath(dest->GetPositionX(), dest->GetPositionY(), dest->GetPositionZ(), false, true);
+ bool result = generatedPath.CalculatePath(dest->GetPositionX(), dest->GetPositionY(), dest->GetPositionZ(), false);
if (generatedPath.GetPathType() & PATHFIND_SHORT)
return SPELL_FAILED_OUT_OF_RANGE;
else if (!result || generatedPath.GetPathType() & PATHFIND_NOPATH)
- {
- result = generatedPath.CalculatePath(dest->GetPositionX(), dest->GetPositionY(), dest->GetPositionZ(), false, false);
- if (generatedPath.GetPathType() & PATHFIND_SHORT)
- return SPELL_FAILED_OUT_OF_RANGE;
- else if (!result || generatedPath.GetPathType() & PATHFIND_NOPATH)
- return SPELL_FAILED_NOPATH;
- }
+ return SPELL_FAILED_NOPATH;
}
else if (dest->GetPositionZ() > GetCaster()->GetPositionZ() + 4.0f)
return SPELL_FAILED_NOPATH;
diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp
index f75d571046c..6e3adc79a04 100644
--- a/src/tools/mmaps_generator/MapBuilder.cpp
+++ b/src/tools/mmaps_generator/MapBuilder.cpp
@@ -986,7 +986,7 @@ namespace MMAP
config.walkableHeight = m_bigBaseUnit ? 3 : 6;
// a value >= 3|6 allows npcs to walk over some fences
// a value >= 4|8 allows npcs to walk over all fences
- config.walkableClimb = m_bigBaseUnit ? 4 : 8;
+ config.walkableClimb = m_bigBaseUnit ? 3 : 6;
config.minRegionArea = rcSqr(60);
config.mergeRegionArea = rcSqr(50);
config.maxSimplificationError = 1.8f; // eliminates most jagged edges (tiny polygons)