aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSebastian Valle <s.v.h21@hotmail.com>2013-10-04 22:23:17 -0500
committerSebastian Valle <s.v.h21@hotmail.com>2013-10-04 22:23:17 -0500
commita27237dedd1b770ab4e66570e7a236a44d2c9e00 (patch)
tree55dc122371571e055b9c6da07aae2d5a9e7e39d3 /src
parente62f64b5912fb1b249680d0bd026b8e4c7d7a022 (diff)
Core/MMaps: MMaps are now correctly loaded into TC
P.S: They do behave better in some places, but are still a bit weird in some others, will have to look into that. P.P.S: I'll have to re-implement all the previous PathGenerator code
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Maps/Map.cpp6
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h2
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp1
-rw-r--r--src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp1
-rw-r--r--src/server/game/Movement/PathGenerator.cpp755
-rw-r--r--src/server/game/Movement/PathGenerator.h52
-rw-r--r--src/server/game/Spells/Spell.cpp1
-rw-r--r--src/server/scripts/Commands/cs_mmaps.cpp68
-rw-r--r--src/tools/mesh_extractor/MeshExtractor.cpp8
-rw-r--r--src/tools/mesh_extractor/TileBuilder.cpp4
10 files changed, 125 insertions, 773 deletions
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 3156a071854..aaeb06462ef 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -121,7 +121,11 @@ bool Map::ExistVMap(uint32 mapid, int gx, int gy)
void Map::LoadMMap(int gx, int gy)
{
- bool mmapLoadResult = MMAP::MMapFactory::CreateOrGetMMapManager()->LoadMapTile(GetId(), gx, gy);
+ bool mmapLoadResult = false;
+ if (GetEntry()->Instanceable())
+ mmapLoadResult = MMAP::MMapFactory::CreateOrGetMMapManager()->LoadMapTile(GetId(), 0, 0); // Ignore the tile entry for instances, as they only have 1 tile.
+ else
+ mmapLoadResult = MMAP::MMapFactory::CreateOrGetMMapManager()->LoadMapTile(GetId(), gx, gy);
if (mmapLoadResult)
TC_LOG_INFO(LOG_FILTER_MAPS, "MMAP loaded name: %s, id: %d, x: %d, y: %d", GetMapName(), GetId(), gx, gy);
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index e561d37ed36..6ed0982e631 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -3541,7 +3541,7 @@ enum PartyResult
};
const uint32 MMAP_MAGIC = 0x4d4d4150; // 'MMAP'
-#define MMAP_VERSION 4
+#define MMAP_VERSION 3
struct MmapTileHeader
{
diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp
index ef24b112253..63b1cf283a4 100755
--- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp
@@ -86,7 +86,6 @@ bool ConfusedMovementGenerator<T>::DoUpdate(T* unit, uint32 diff)
unit->MovePositionToFirstCollision(pos, dest, 0.0f);
PathGenerator path(unit);
- path.SetPathLengthLimit(30.0f);
bool result = path.CalculatePath(pos.m_positionX, pos.m_positionY, pos.m_positionZ);
if (!result || (path.GetPathType() & PATHFIND_NOPATH))
{
diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
index f78411fc547..1c65499fe50 100644
--- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
@@ -44,7 +44,6 @@ void FleeingMovementGenerator<T>::_setTargetLocation(T* owner)
_getPoint(owner, x, y, z);
PathGenerator path(owner);
- path.SetPathLengthLimit(30.0f);
bool result = path.CalculatePath(x, y, z);
if (!result || (path.GetPathType() & PATHFIND_NOPATH))
{
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index 3216cb8103e..c5922156939 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -29,12 +29,10 @@
////////////////// PathGenerator //////////////////
PathGenerator::PathGenerator(const Unit* owner) :
- _polyLength(0), _type(PATHFIND_BLANK), _useStraightPath(false),
- _forceDestination(false), _pointPathLimit(MAX_POINT_PATH_LENGTH),
- _endPosition(G3D::Vector3::zero()), _sourceUnit(owner), _navMesh(NULL),
- _navMeshQuery(NULL)
+ _type(PATHFIND_BLANK), _endPosition(G3D::Vector3::zero()),
+ _sourceUnit(owner), _navMesh(NULL), _navMeshQuery(NULL)
{
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ PathGenerator::PathGenerator for %u \n", _sourceUnit->GetGUIDLow());
+ TC_LOG_DEBUG(LOG_FILTER_MAPS, "PathGenerator::PathGenerator for %u \n", _sourceUnit->GetGUIDLow());
uint32 mapId = _sourceUnit->GetMapId();
if (MMAP::MMapFactory::IsPathfindingEnabled(mapId))
@@ -49,7 +47,7 @@ PathGenerator::PathGenerator(const Unit* owner) :
PathGenerator::~PathGenerator()
{
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ PathGenerator::~PathGenerator() for %u \n", _sourceUnit->GetGUIDLow());
+ TC_LOG_DEBUG(LOG_FILTER_MAPS, "PathGenerator::~PathGenerator() for %u \n", _sourceUnit->GetGUIDLow());
}
bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool forceDest)
@@ -66,463 +64,88 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo
G3D::Vector3 start(x, y, z);
SetStartPosition(start);
- _forceDestination = forceDest;
-
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ PathGenerator::CalculatePath() for %u \n", _sourceUnit->GetGUIDLow());
+ TC_LOG_DEBUG(LOG_FILTER_MAPS, "PathGenerator::CalculatePath() for %u \n", _sourceUnit->GetGUIDLow());
// make sure navMesh works - we can run on map w/o mmap
// check if the start and end point have a .mmtile loaded (can we pass via not loaded tile on the way?)
- if (!_navMesh || !_navMeshQuery || _sourceUnit->HasUnitState(UNIT_STATE_IGNORE_PATHFINDING) ||
- !HaveTile(start) || !HaveTile(dest))
+ if (!_navMesh || !_navMeshQuery || _sourceUnit->HasUnitState(UNIT_STATE_IGNORE_PATHFINDING))
{
- BuildShortcut();
_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH);
return true;
}
UpdateFilter();
- BuildPolyPath(start, dest);
- return true;
-}
-
-dtPolyRef PathGenerator::GetPathPolyByPosition(dtPolyRef const* polyPath, uint32 polyPathSize, float const* point, float* distance) const
-{
- if (!polyPath || !polyPathSize)
- return INVALID_POLYREF;
-
- dtPolyRef nearestPoly = INVALID_POLYREF;
- float minDist2d = FLT_MAX;
- float minDist3d = 0.0f;
+ float startPos[3];
+ startPos[0] = -y;
+ startPos[1] = z;
+ startPos[2] = -x;
- for (uint32 i = 0; i < polyPathSize; ++i)
- {
- float closestPoint[VERTEX_SIZE];
- if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(polyPath[i], point, closestPoint)))
- continue;
-
- float d = dtVdist2DSqr(point, closestPoint);
- if (d < minDist2d)
- {
- minDist2d = d;
- nearestPoly = polyPath[i];
- minDist3d = dtVdistSqr(point, closestPoint);
- }
+ float endPos[3];
+ endPos[0] = -destY;
+ endPos[1] = destZ;
+ endPos[2] = -destX;
- if (minDist2d < 1.0f) // shortcut out - close enough for us
- break;
- }
+ float polyPickExt[3];
+ polyPickExt[0] = 2.5f;
+ polyPickExt[1] = 2.5f;
+ polyPickExt[2] = 2.5f;
- if (distance)
- *distance = dtSqrt(minDist3d);
+ //
+ dtPolyRef startRef;
+ dtPolyRef endRef;
- return (minDist2d < 3.0f) ? nearestPoly : INVALID_POLYREF;
-}
+ float nearestPt[3];
-dtPolyRef PathGenerator::GetPolyByLocation(float const* point, float* distance) const
-{
- // first we check the current path
- // if the current path doesn't contain the current poly,
- // we need to use the expensive navMesh.findNearestPoly
- dtPolyRef polyRef = GetPathPolyByPosition(_pathPolyRefs, _polyLength, point, distance);
- if (polyRef != INVALID_POLYREF)
- return polyRef;
+ _navMeshQuery->findNearestPoly(startPos, polyPickExt, &_filter, &startRef, nearestPt);
+ _navMeshQuery->findNearestPoly(endPos, polyPickExt, &_filter, &endRef, nearestPt);
- // we don't have it in our old path
- // try to get it by findNearestPoly()
- // first try with low search box
- float extents[VERTEX_SIZE] = {3.0f, 5.0f, 3.0f}; // bounds of poly search area
- float closestPoint[VERTEX_SIZE] = {0.0f, 0.0f, 0.0f};
- if (dtStatusSucceed(_navMeshQuery->findNearestPoly(point, extents, &_filter, &polyRef, closestPoint)) && polyRef != INVALID_POLYREF)
+ if (!startRef || !endRef)
{
- *distance = dtVdist(closestPoint, point);
- return polyRef;
- }
-
- // still nothing ..
- // try with bigger search box
- // Note that the extent should not overlap more than 128 polygons in the navmesh (see dtNavMeshQuery::findNearestPoly)
- extents[1] = 50.0f;
-
- if (dtStatusSucceed(_navMeshQuery->findNearestPoly(point, extents, &_filter, &polyRef, closestPoint)) && polyRef != INVALID_POLYREF)
- {
- *distance = dtVdist(closestPoint, point);
- return polyRef;
- }
-
- return INVALID_POLYREF;
-}
-
-void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos)
-{
- // *** getting start/end poly logic ***
-
- float distToStartPoly, distToEndPoly;
- float startPoint[VERTEX_SIZE] = {startPos.y, startPos.z, startPos.x};
- float endPoint[VERTEX_SIZE] = {endPos.y, endPos.z, endPos.x};
-
- dtPolyRef startPoly = GetPolyByLocation(startPoint, &distToStartPoly);
- dtPolyRef endPoly = GetPolyByLocation(endPoint, &distToEndPoly);
-
- // 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
- if (startPoly == INVALID_POLYREF || endPoly == INVALID_POLYREF)
- {
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPoly == 0 || endPoly == 0)\n");
- BuildShortcut();
- bool path = _sourceUnit->GetTypeId() == TYPEID_UNIT && _sourceUnit->ToCreature()->CanFly();
-
- bool waterPath = _sourceUnit->GetTypeId() == TYPEID_UNIT && _sourceUnit->ToCreature()->CanSwim();
- if (waterPath)
- {
- // Check both start and end points, if they're both in water, then we can *safely* let the creature move
- for (uint32 i = 0; i < _pathPoints.size(); ++i)
- {
- ZLiquidStatus status = _sourceUnit->GetBaseMap()->getLiquidStatus(_pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, MAP_ALL_LIQUIDS, NULL);
- // One of the points is not in the water, cancel movement.
- if (status == LIQUID_MAP_NO_WATER)
- {
- waterPath = false;
- break;
- }
- }
- }
-
- _type = (path || waterPath) ? PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH) : PATHFIND_NOPATH;
- return;
- }
-
- // we may need a better number here
- bool farFromPoly = (distToStartPoly > 7.0f || distToEndPoly > 7.0f);
- if (farFromPoly)
- {
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildPolyPath :: farFromPoly distToStartPoly=%.3f distToEndPoly=%.3f\n", distToStartPoly, distToEndPoly);
-
- bool buildShotrcut = false;
- if (_sourceUnit->GetTypeId() == TYPEID_UNIT)
- {
- Creature* owner = (Creature*)_sourceUnit;
-
- G3D::Vector3 const& p = (distToStartPoly > 7.0f) ? startPos : endPos;
- if (_sourceUnit->GetBaseMap()->IsUnderWater(p.x, p.y, p.z))
- {
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildPolyPath :: underWater case\n");
- if (owner->CanSwim())
- buildShotrcut = true;
- }
- else
- {
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildPolyPath :: flying case\n");
- if (owner->CanFly())
- buildShotrcut = true;
- }
- }
-
- if (buildShotrcut)
- {
- BuildShortcut();
- _type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH);
- return;
- }
- else
- {
- float closestPoint[VERTEX_SIZE];
- // we may want to use closestPointOnPolyBoundary instead
- if (dtStatusSucceed(_navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint)))
- {
- dtVcopy(endPoint, closestPoint);
- SetActualEndPosition(G3D::Vector3(endPoint[2], endPoint[0], endPoint[1]));
- }
-
- _type = PATHFIND_INCOMPLETE;
- }
- }
-
- // *** poly path generating logic ***
-
- // start and end are on same polygon
- // just need to move in straight line
- if (startPoly == endPoly)
- {
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPoly == endPoly)\n");
-
- BuildShortcut();
-
- _pathPolyRefs[0] = startPoly;
- _polyLength = 1;
-
- _type = farFromPoly ? PATHFIND_INCOMPLETE : PATHFIND_NORMAL;
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildPolyPath :: path type %d\n", _type);
- return;
- }
-
- // look for startPoly/endPoly in current path
- /// @todo we can merge it with getPathPolyByPosition() loop
- bool startPolyFound = false;
- bool endPolyFound = false;
- uint32 pathStartIndex = 0;
- uint32 pathEndIndex = 0;
-
- if (_polyLength)
- {
- for (; pathStartIndex < _polyLength; ++pathStartIndex)
- {
- // here to carch few bugs
- ASSERT(_pathPolyRefs[pathStartIndex] != INVALID_POLYREF);
-
- if (_pathPolyRefs[pathStartIndex] == startPoly)
- {
- startPolyFound = true;
- break;
- }
- }
-
- for (pathEndIndex = _polyLength-1; pathEndIndex > pathStartIndex; --pathEndIndex)
- if (_pathPolyRefs[pathEndIndex] == endPoly)
- {
- endPolyFound = true;
- break;
- }
- }
-
- if (startPolyFound && endPolyFound)
- {
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPolyFound && endPolyFound)\n");
-
- // we moved along the path and the target did not move out of our old poly-path
- // our path is a simple subpath case, we have all the data we need
- // just "cut" it out
-
- _polyLength = pathEndIndex - pathStartIndex + 1;
- memmove(_pathPolyRefs, _pathPolyRefs + pathStartIndex, _polyLength * sizeof(dtPolyRef));
+ TC_LOG_DEBUG(LOG_FILTER_MAPS, "PathGenerator::CalculatePath() for %u no polygons found for start and end locations\n", _sourceUnit->GetGUIDLow());
+ _type = PATHFIND_NOPATH;
+ return false;
}
- else if (startPolyFound && !endPolyFound)
- {
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildPolyPath :: (startPolyFound && !endPolyFound)\n");
-
- // we are moving on the old path but target moved out
- // so we have atleast part of poly-path ready
-
- _polyLength -= pathStartIndex;
- // try to adjust the suffix of the path instead of recalculating entire length
- // at given interval the target cannot get too far from its last location
- // thus we have less poly to cover
- // sub-path of optimal path is optimal
-
- // take ~80% of the original length
- /// @todo play with the values here
- uint32 prefixPolyLength = uint32(_polyLength * 0.8f + 0.5f);
- memmove(_pathPolyRefs, _pathPolyRefs+pathStartIndex, prefixPolyLength * sizeof(dtPolyRef));
-
- dtPolyRef suffixStartPoly = _pathPolyRefs[prefixPolyLength-1];
-
- // we need any point on our suffix start poly to generate poly-path, so we need last poly in prefix data
- float suffixEndPoint[VERTEX_SIZE];
- if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint)))
- {
- // we can hit offmesh connection as last poly - closestPointOnPoly() don't like that
- // try to recover by using prev polyref
- --prefixPolyLength;
- suffixStartPoly = _pathPolyRefs[prefixPolyLength-1];
- if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint)))
- {
- // suffixStartPoly is still invalid, error state
- BuildShortcut();
- _type = PATHFIND_NOPATH;
- return;
- }
- }
-
- // 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
-
- if (!suffixPolyLength || dtStatusFailed(dtResult))
- {
- // this is probably an error state, but we'll leave it
- // and hopefully recover on the next Update
- // we still need to copy our preffix
- TC_LOG_ERROR(LOG_FILTER_MAPS, "%u's Path Build failed: 0 length path", _sourceUnit->GetGUIDLow());
- }
-
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ m_polyLength=%u prefixPolyLength=%u suffixPolyLength=%u \n", _polyLength, prefixPolyLength, suffixPolyLength);
-
- // new path = prefix + suffix - overlap
- _polyLength = prefixPolyLength + suffixPolyLength - 1;
- }
- else
+ int hops;
+ dtPolyRef* hopBuffer = new dtPolyRef[8192];
+ dtStatus status = _navMeshQuery->findPath(startRef, endRef, startPos, endPos, &_filter, hopBuffer, &hops, 8192);
+
+ if (!dtStatusSucceed(status))
{
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildPolyPath :: (!startPolyFound && !endPolyFound)\n");
-
- // either we have no path at all -> first run
- // or something went really wrong -> we aren't moving along the path to the target
- // just generate new path
-
- // 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
-
- if (!_polyLength || dtStatusFailed(dtResult))
- {
- // only happens if we passed bad data to findPath(), or navmesh is messed up
- TC_LOG_ERROR(LOG_FILTER_MAPS, "%u's Path Build failed: 0 length path", _sourceUnit->GetGUIDLow());
- BuildShortcut();
- _type = PATHFIND_NOPATH;
- return;
- }
+ TC_LOG_DEBUG(LOG_FILTER_MAPS, "PathGenerator::CalculatePath() for %u no path found for start and end locations\n", _sourceUnit->GetGUIDLow());
+ _type = PATHFIND_NOPATH;
+ return false;
}
- // by now we know what type of path we can get
- if (_pathPolyRefs[_polyLength - 1] == endPoly && !(_type & PATHFIND_INCOMPLETE))
- _type = PATHFIND_NORMAL;
- else
- _type = PATHFIND_INCOMPLETE;
-
- // generate the point-path out of our up-to-date poly-path
- BuildPointPath(startPoint, endPoint);
-}
-
-void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoint)
-{
- float pathPoints[MAX_POINT_PATH_LENGTH*VERTEX_SIZE];
- uint32 pointCount = 0;
- dtStatus dtResult = DT_FAILURE;
- if (_useStraightPath)
- {
- dtResult = _navMeshQuery->findStraightPath(
- startPoint, // start position
- endPoint, // end position
- _pathPolyRefs, // current path
- _polyLength, // lenth of current path
- pathPoints, // [out] path corner points
- NULL, // [out] flags
- NULL, // [out] shortened path
- (int*)&pointCount,
- _pointPathLimit); // maximum number of points/polygons to use
- }
- else
- {
- dtResult = FindSmoothPath(
- startPoint, // start position
- endPoint, // end position
- _pathPolyRefs, // current path
- _polyLength, // length of current path
- pathPoints, // [out] path corner points
- (int*)&pointCount,
- _pointPathLimit); // maximum number of points
- }
+ int resultHopCount;
+ float* straightPath = new float[2048 * 3];
+ unsigned char* pathFlags = new unsigned char[2048];
+ dtPolyRef* pathRefs = new dtPolyRef[2048];
- if (pointCount < 2 || dtStatusFailed(dtResult))
+ status = _navMeshQuery->findStraightPath(startPos, endPos, hopBuffer, hops, straightPath, pathFlags, pathRefs, &resultHopCount, 2048);
+ if (!dtStatusSucceed(status))
{
- // only happens if pass bad data to findStraightPath or navmesh is broken
- // single point paths can be generated here
- /// @todo check the exact cases
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ PathGenerator::BuildPointPath FAILED! path sized %d returned\n", pointCount);
- BuildShortcut();
+ TC_LOG_DEBUG(LOG_FILTER_MAPS, "PathGenerator::CalculatePath() for %u no straight path found for start and end locations\n", _sourceUnit->GetGUIDLow());
_type = PATHFIND_NOPATH;
- return;
- }
- else if (pointCount == _pointPathLimit)
- {
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ PathGenerator::BuildPointPath FAILED! path sized %d returned, lower than limit set to %d\n", pointCount, _pointPathLimit);
- BuildShortcut();
- _type = PATHFIND_SHORT;
- return;
+ return false;
}
- _pathPoints.resize(pointCount);
- for (uint32 i = 0; i < pointCount; ++i)
- _pathPoints[i] = G3D::Vector3(pathPoints[i*VERTEX_SIZE+2], pathPoints[i*VERTEX_SIZE], pathPoints[i*VERTEX_SIZE+1]);
+ for (uint32 i = 0; i < resultHopCount; ++i)
+ _pathPoints.push_back(G3D::Vector3(-straightPath[i * 3 + 2], -straightPath[i * 3 + 0], straightPath[i * 3 + 1]));
- NormalizePath();
-
- // first point is always our current location - we need the next one
- SetActualEndPosition(_pathPoints[pointCount-1]);
-
- // force the given destination, if needed
- if (_forceDestination &&
- (!(_type & PATHFIND_NORMAL) || !InRange(GetEndPosition(), GetActualEndPosition(), 1.0f, 1.0f)))
- {
- // we may want to keep partial subpath
- if (Dist3DSqr(GetActualEndPosition(), GetEndPosition()) < 0.3f * Dist3DSqr(GetStartPosition(), GetEndPosition()))
- {
- SetActualEndPosition(GetEndPosition());
- _pathPoints[_pathPoints.size()-1] = GetEndPosition();
- }
- else
- {
- SetActualEndPosition(GetEndPosition());
- BuildShortcut();
- }
-
- _type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH);
- }
-
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ PathGenerator::BuildPointPath path type %d size %d poly-size %d\n", _type, pointCount, _polyLength);
-}
-
-void PathGenerator::NormalizePath()
-{
- for (uint32 i = 0; i < _pathPoints.size(); ++i)
- _sourceUnit->UpdateAllowedPositionZ(_pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z);
-}
-
-void PathGenerator::BuildShortcut()
-{
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "++ BuildShortcut :: making shortcut\n");
-
- Clear();
-
- // make two point path, our curr pos is the start, and dest is the end
- _pathPoints.resize(2);
-
- // set start and a default next position
- _pathPoints[0] = GetStartPosition();
- _pathPoints[1] = GetActualEndPosition();
-
- NormalizePath();
-
- _type = PATHFIND_SHORTCUT;
+ return true;
}
void PathGenerator::CreateFilter()
{
- uint16 includeFlags = 0;
+ uint16 includeFlags = 1 | 2;
uint16 excludeFlags = 0;
-
- if (_sourceUnit->GetTypeId() == TYPEID_UNIT)
- {
- Creature* creature = (Creature*)_sourceUnit;
- if (creature->CanWalk())
- includeFlags |= NAV_GROUND; // walk
-
- // creatures don't take environmental damage
- if (creature->CanSwim())
- includeFlags |= (NAV_WATER | NAV_MAGMA | NAV_SLIME); // swim
- }
- else // assume Player
+
+ if (_sourceUnit->GetTypeId() == TYPEID_UNIT && !_sourceUnit->ToCreature()->CanSwim())
{
- // perfect support not possible, just stay 'safe'
- includeFlags |= (NAV_GROUND | NAV_WATER | NAV_MAGMA | NAV_SLIME);
+ includeFlags = 1;
+ excludeFlags = 2;
}
_filter.setIncludeFlags(includeFlags);
@@ -533,275 +156,5 @@ void PathGenerator::CreateFilter()
void PathGenerator::UpdateFilter()
{
- // allow creatures to cheat and use different movement types if they are moved
- // forcefully into terrain they can't normally move in
- if (_sourceUnit->IsInWater() || _sourceUnit->IsUnderWater())
- {
- uint16 includedFlags = _filter.getIncludeFlags();
- includedFlags |= GetNavTerrain(_sourceUnit->GetPositionX(),
- _sourceUnit->GetPositionY(),
- _sourceUnit->GetPositionZ());
-
- _filter.setIncludeFlags(includedFlags);
- }
-}
-
-NavTerrain PathGenerator::GetNavTerrain(float x, float y, float z)
-{
- LiquidData data;
- ZLiquidStatus liquidStatus = _sourceUnit->GetBaseMap()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &data);
- if (liquidStatus == LIQUID_MAP_NO_WATER)
- return NAV_GROUND;
-
- switch (data.type_flags)
- {
- case MAP_LIQUID_TYPE_WATER:
- case MAP_LIQUID_TYPE_OCEAN:
- return NAV_WATER;
- case MAP_LIQUID_TYPE_MAGMA:
- return NAV_MAGMA;
- case MAP_LIQUID_TYPE_SLIME:
- return NAV_SLIME;
- default:
- return NAV_GROUND;
- }
-}
-
-bool PathGenerator::HaveTile(const G3D::Vector3& p) const
-{
- int tx = -1, ty = -1;
- float point[VERTEX_SIZE] = {p.y, p.z, p.x};
-
- _navMesh->calcTileLoc(point, &tx, &ty);
-
- /// Workaround
- /// For some reason, often the tx and ty variables wont get a valid value
- /// Use this check to prevent getting negative tile coords and crashing on getTileAt
- if (tx < 0 || ty < 0)
- return false;
-
- return (_navMesh->getTileAt(tx, ty, 0) != NULL);
-}
-
-uint32 PathGenerator::FixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, dtPolyRef const* visited, uint32 nvisited)
-{
- int32 furthestPath = -1;
- int32 furthestVisited = -1;
-
- // Find furthest common polygon.
- for (int32 i = npath-1; i >= 0; --i)
- {
- bool found = false;
- for (int32 j = nvisited-1; j >= 0; --j)
- {
- if (path[i] == visited[j])
- {
- furthestPath = i;
- furthestVisited = j;
- found = true;
- }
- }
- if (found)
- break;
- }
-
- // If no intersection found just return current path.
- if (furthestPath == -1 || furthestVisited == -1)
- return npath;
-
- // Concatenate paths.
-
- // Adjust beginning of the buffer to include the visited.
- uint32 req = nvisited - furthestVisited;
- uint32 orig = uint32(furthestPath + 1) < npath ? furthestPath + 1 : npath;
- uint32 size = npath > orig ? npath - orig : 0;
- if (req + size > maxPath)
- size = maxPath-req;
-
- if (size)
- memmove(path + req, path + orig, size * sizeof(dtPolyRef));
-
- // Store visited
- for (uint32 i = 0; i < req; ++i)
- path[i] = visited[(nvisited - 1) - i];
-
- return req+size;
-}
-
-bool PathGenerator::GetSteerTarget(float const* startPos, float const* endPos,
- float minTargetDist, dtPolyRef const* path, uint32 pathSize,
- float* steerPos, unsigned char& steerPosFlag, dtPolyRef& steerPosRef)
-{
- // Find steer target.
- static const uint32 MAX_STEER_POINTS = 3;
- float steerPath[MAX_STEER_POINTS*VERTEX_SIZE];
- unsigned char steerPathFlags[MAX_STEER_POINTS];
- dtPolyRef steerPathPolys[MAX_STEER_POINTS];
- uint32 nsteerPath = 0;
- dtStatus dtResult = _navMeshQuery->findStraightPath(startPos, endPos, path, pathSize,
- steerPath, steerPathFlags, steerPathPolys, (int*)&nsteerPath, MAX_STEER_POINTS);
- if (!nsteerPath || dtStatusFailed(dtResult))
- return false;
-
- // Find vertex far enough to steer to.
- uint32 ns = 0;
- while (ns < nsteerPath)
- {
- // Stop at Off-Mesh link or when point is further than slop away.
- if ((steerPathFlags[ns] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) ||
- !InRangeYZX(&steerPath[ns*VERTEX_SIZE], startPos, minTargetDist, 1000.0f))
- break;
- ns++;
- }
- // Failed to find good point to steer to.
- if (ns >= nsteerPath)
- return false;
-
- dtVcopy(steerPos, &steerPath[ns*VERTEX_SIZE]);
- steerPos[1] = startPos[1]; // keep Z value
- steerPosFlag = steerPathFlags[ns];
- steerPosRef = steerPathPolys[ns];
-
- return true;
-}
-
-dtStatus PathGenerator::FindSmoothPath(float const* startPos, float const* endPos,
- dtPolyRef const* polyPath, uint32 polyPathSize,
- float* smoothPath, int* smoothPathSize, uint32 maxSmoothPathSize)
-{
- *smoothPathSize = 0;
- uint32 nsmoothPath = 0;
-
- dtPolyRef polys[MAX_PATH_LENGTH];
- memcpy(polys, polyPath, sizeof(dtPolyRef)*polyPathSize);
- uint32 npolys = polyPathSize;
-
- float iterPos[VERTEX_SIZE], targetPos[VERTEX_SIZE];
- if (dtStatusFailed(_navMeshQuery->closestPointOnPolyBoundary(polys[0], startPos, iterPos)))
- return DT_FAILURE;
-
- if (dtStatusFailed(_navMeshQuery->closestPointOnPolyBoundary(polys[npolys-1], endPos, targetPos)))
- return DT_FAILURE;
-
- dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos);
- nsmoothPath++;
-
- // Move towards target a small advancement at a time until target reached or
- // when ran out of memory to store the path.
- while (npolys && nsmoothPath < maxSmoothPathSize)
- {
- // Find location to steer towards.
- float steerPos[VERTEX_SIZE];
- unsigned char steerPosFlag;
- dtPolyRef steerPosRef = INVALID_POLYREF;
-
- if (!GetSteerTarget(iterPos, targetPos, SMOOTH_PATH_SLOP, polys, npolys, steerPos, steerPosFlag, steerPosRef))
- break;
-
- bool endOfPath = (steerPosFlag & DT_STRAIGHTPATH_END);
- bool offMeshConnection = (steerPosFlag & DT_STRAIGHTPATH_OFFMESH_CONNECTION);
-
- // Find movement delta.
- float delta[VERTEX_SIZE];
- dtVsub(delta, steerPos, iterPos);
- float len = dtSqrt(dtVdot(delta, delta));
- // If the steer target is end of path or off-mesh link, do not move past the location.
- if ((endOfPath || offMeshConnection) && len < SMOOTH_PATH_STEP_SIZE)
- len = 1.0f;
- else
- len = SMOOTH_PATH_STEP_SIZE / len;
-
- float moveTgt[VERTEX_SIZE];
- dtVmad(moveTgt, iterPos, delta, len);
-
- // Move
- float result[VERTEX_SIZE];
- const static uint32 MAX_VISIT_POLY = 16;
- dtPolyRef visited[MAX_VISIT_POLY];
-
- uint32 nvisited = 0;
- _navMeshQuery->moveAlongSurface(polys[0], iterPos, moveTgt, &_filter, result, visited, (int*)&nvisited, MAX_VISIT_POLY);
- npolys = FixupCorridor(polys, npolys, MAX_PATH_LENGTH, visited, nvisited);
-
- _navMeshQuery->getPolyHeight(polys[0], result, &result[1]);
- result[1] += 0.5f;
- dtVcopy(iterPos, result);
-
- // Handle end of path and off-mesh links when close enough.
- if (endOfPath && InRangeYZX(iterPos, steerPos, SMOOTH_PATH_SLOP, 1.0f))
- {
- // Reached end of path.
- dtVcopy(iterPos, targetPos);
- if (nsmoothPath < maxSmoothPathSize)
- {
- dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos);
- nsmoothPath++;
- }
- break;
- }
- else if (offMeshConnection && InRangeYZX(iterPos, steerPos, SMOOTH_PATH_SLOP, 1.0f))
- {
- // Advance the path up to and over the off-mesh connection.
- dtPolyRef prevRef = INVALID_POLYREF;
- dtPolyRef polyRef = polys[0];
- uint32 npos = 0;
- while (npos < npolys && polyRef != steerPosRef)
- {
- prevRef = polyRef;
- polyRef = polys[npos];
- npos++;
- }
-
- for (uint32 i = npos; i < npolys; ++i)
- polys[i-npos] = polys[i];
-
- npolys -= npos;
-
- // Handle the connection.
- float startPos[VERTEX_SIZE], endPos[VERTEX_SIZE];
- if (dtStatusSucceed(_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos)))
- {
- if (nsmoothPath < maxSmoothPathSize)
- {
- dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], startPos);
- nsmoothPath++;
- }
- // Move position at the other side of the off-mesh link.
- dtVcopy(iterPos, endPos);
- _navMeshQuery->getPolyHeight(polys[0], iterPos, &iterPos[1]);
- iterPos[1] += 0.5f;
- }
- }
-
- // Store results.
- if (nsmoothPath < maxSmoothPathSize)
- {
- dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos);
- nsmoothPath++;
- }
- }
-
- *smoothPathSize = nsmoothPath;
-
- // this is most likely a loop
- return nsmoothPath < MAX_POINT_PATH_LENGTH ? DT_SUCCESS : DT_FAILURE;
-}
-
-bool PathGenerator::InRangeYZX(const float* v1, const float* v2, float r, float h) const
-{
- const float dx = v2[0] - v1[0];
- const float dy = v2[1] - v1[1]; // elevation
- const float dz = v2[2] - v1[2];
- return (dx * dx + dz * dz) < r * r && fabsf(dy) < h;
-}
-
-bool PathGenerator::InRange(G3D::Vector3 const& p1, G3D::Vector3 const& p2, float r, float h) const
-{
- G3D::Vector3 d = p1 - p2;
- return (d.x * d.x + d.y * d.y) < r * r && fabsf(d.z) < h;
-}
-
-float PathGenerator::Dist3DSqr(G3D::Vector3 const& p1, G3D::Vector3 const& p2) const
-{
- return (p1 - p2).squaredLength();
-}
+
+} \ No newline at end of file
diff --git a/src/server/game/Movement/PathGenerator.h b/src/server/game/Movement/PathGenerator.h
index ac66b7cec57..507f8e8defb 100644
--- a/src/server/game/Movement/PathGenerator.h
+++ b/src/server/game/Movement/PathGenerator.h
@@ -26,18 +26,6 @@
class Unit;
-// 74*4.0f=296y number_of_points*interval = max_path_len
-// this is way more than actual evade range
-// I think we can safely cut those down even more
-#define MAX_PATH_LENGTH 74
-#define MAX_POINT_PATH_LENGTH 74
-
-#define SMOOTH_PATH_STEP_SIZE 4.0f
-#define SMOOTH_PATH_SLOP 0.3f
-
-#define VERTEX_SIZE 3
-#define INVALID_POLYREF 0
-
enum PathType
{
PATHFIND_BLANK = 0x00, // path not built yet
@@ -59,10 +47,6 @@ class PathGenerator
// return: true if new path was calculated, false otherwise (no change needed)
bool CalculatePath(float destX, float destY, float destZ, bool forceDest = false);
- // 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); }
-
// result getters
G3D::Vector3 const& GetStartPosition() const { return _startPosition; }
G3D::Vector3 const& GetEndPosition() const { return _endPosition; }
@@ -73,17 +57,9 @@ class PathGenerator
PathType GetPathType() const { return _type; }
private:
-
- dtPolyRef _pathPolyRefs[MAX_PATH_LENGTH]; // array of detour polygon references
- uint32 _polyLength; // number of polygons in the path
-
Movement::PointsArray _pathPoints; // our actual (x,y,z) path to the target
PathType _type; // tells what kind of path this is
- 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)
-
G3D::Vector3 _startPosition; // {x, y, z} of current location
G3D::Vector3 _endPosition; // {x, y, z} of the destination
G3D::Vector3 _actualEndPosition; // {x, y, z} of the closest possible point to given destination
@@ -97,37 +73,9 @@ class PathGenerator
void SetStartPosition(G3D::Vector3 const& point) { _startPosition = point; }
void SetEndPosition(G3D::Vector3 const& point) { _actualEndPosition = point; _endPosition = point; }
void SetActualEndPosition(G3D::Vector3 const& point) { _actualEndPosition = point; }
- void NormalizePath();
-
- void Clear()
- {
- _polyLength = 0;
- _pathPoints.clear();
- }
-
- bool InRange(G3D::Vector3 const& p1, G3D::Vector3 const& p2, float r, float h) const;
- float Dist3DSqr(G3D::Vector3 const& p1, G3D::Vector3 const& p2) const;
- bool InRangeYZX(float const* v1, float const* v2, float r, float h) const;
- dtPolyRef GetPathPolyByPosition(dtPolyRef const* polyPath, uint32 polyPathSize, float const* Point, float* Distance = NULL) const;
- dtPolyRef GetPolyByLocation(float const* Point, float* Distance) const;
- bool HaveTile(G3D::Vector3 const& p) const;
-
- void BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos);
- void BuildPointPath(float const* startPoint, float const* endPoint);
- void BuildShortcut();
-
- NavTerrain GetNavTerrain(float x, float y, float z);
void CreateFilter();
void UpdateFilter();
-
- // smooth path aux functions
- uint32 FixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, dtPolyRef const* visited, uint32 nvisited);
- bool GetSteerTarget(float const* startPos, float const* endPos, float minTargetDist, dtPolyRef const* path, uint32 pathSize, float* steerPos,
- unsigned char& steerPosFlag, dtPolyRef& steerPosRef);
- dtStatus FindSmoothPath(float const* startPos, float const* endPos,
- dtPolyRef const* polyPath, uint32 polyPathSize,
- float* smoothPath, int* smoothPathSize, uint32 smoothPathMaxSize);
};
#endif
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index b2e8a89c86d..804a7f25a12 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -5162,7 +5162,6 @@ SpellCastResult Spell::CheckCast(bool strict)
target->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ);
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());
if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT)
return SPELL_FAILED_OUT_OF_RANGE;
diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp
index d0b1fdc2abd..0beb10af4fc 100644
--- a/src/server/scripts/Commands/cs_mmaps.cpp
+++ b/src/server/scripts/Commands/cs_mmaps.cpp
@@ -92,10 +92,10 @@ public:
player->GetPosition(x, y, z);
// path
- PathGenerator path(target);
+ /*PathGenerator path(target);
path.SetUseStraightPath(useStraightPath);
bool result = path.CalculatePath(x, y, z);
-
+
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" : "SmoothPath");
@@ -108,13 +108,63 @@ public:
handler->PSendSysMessage("StartPosition (%.3f, %.3f, %.3f)", start.x, start.y, start.z);
handler->PSendSysMessage("EndPosition (%.3f, %.3f, %.3f)", end.x, end.y, end.z);
handler->PSendSysMessage("ActualEndPosition (%.3f, %.3f, %.3f)", actualEnd.x, actualEnd.y, actualEnd.z);
+ */
+ float m_spos[3];
+ m_spos[0] = -y;
+ m_spos[1] = z;
+ m_spos[2] = -x;
+
+ //
+ float m_epos[3];
+ m_epos[0] = -target->GetPositionY();
+ m_epos[1] = target->GetPositionZ();
+ m_epos[2] = -target->GetPositionX();
+
+ //
+ dtQueryFilter m_filter;
+ m_filter.setIncludeFlags(3);
+ m_filter.setExcludeFlags(2);
+
+ //
+ float m_polyPickExt[3];
+ m_polyPickExt[0] = 2.5f;
+ m_polyPickExt[1] = 2.5f;
+ m_polyPickExt[2] = 2.5f;
+
+ //
+ dtPolyRef m_startRef;
+ dtPolyRef m_endRef;
+
+ const dtNavMesh* navMesh = MMAP::MMapFactory::CreateOrGetMMapManager()->GetNavMesh(player->GetMapId());
+ const dtNavMeshQuery* navMeshQuery = MMAP::MMapFactory::CreateOrGetMMapManager()->GetNavMeshQuery(player->GetMapId(), handler->GetSession()->GetPlayer()->GetInstanceId());
+
+ float nearestPt[3];
+
+ navMeshQuery->findNearestPoly(m_spos, m_polyPickExt, &m_filter, &m_startRef, nearestPt);
+ navMeshQuery->findNearestPoly(m_epos, m_polyPickExt, &m_filter, &m_endRef, nearestPt);
+
+ if ( !m_startRef || !m_endRef )
+ {
+ std::cerr << "Could not find any nearby poly's (" << m_startRef << "," << m_endRef << ")" << std::endl;
+ return 0;
+ }
+
+ int hops;
+ dtPolyRef* hopBuffer = new dtPolyRef[8192];
+ dtStatus status = navMeshQuery->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, hopBuffer, &hops, 8192);
+
+ int resultHopCount;
+ float* straightPath = new float[2048*3];
+ unsigned char* pathFlags = new unsigned char[2048];
+ dtPolyRef* pathRefs = new dtPolyRef[2048];
+
+ status = navMeshQuery->findStraightPath(m_spos, m_epos, hopBuffer, hops, straightPath, pathFlags, pathRefs, &resultHopCount, 2048);
+ for (uint32 i = 0; i < resultHopCount; ++i)
+ player->SummonCreature(VISUAL_WAYPOINT, -straightPath[i * 3 + 2], -straightPath[i * 3 + 0], straightPath[i * 3 + 1], 0, TEMPSUMMON_TIMED_DESPAWN, 9000);
if (!player->IsGameMaster())
handler->PSendSysMessage("Enable GM mode to see the path points.");
- for (uint32 i = 0; i < pointPath.size(); ++i)
- player->SummonCreature(VISUAL_WAYPOINT, pointPath[i].x, pointPath[i].y, pointPath[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 9000);
-
return true;
}
@@ -143,8 +193,8 @@ public:
float const* min = navmesh->getParams()->orig;
float x, y, z;
player->GetPosition(x, y, z);
- float location[VERTEX_SIZE] = {y, z, x};
- float extents[VERTEX_SIZE] = {3.0f, 5.0f, 3.0f};
+ float location[] = {y, z, x};
+ float extents[] = {3.0f, 5.0f, 3.0f};
int32 tilex = int32((y - min[0]) / SIZE_OF_GRIDS);
int32 tiley = int32((x - min[2]) / SIZE_OF_GRIDS);
@@ -153,14 +203,14 @@ public:
// navmesh poly -> navmesh tile location
dtQueryFilter filter = dtQueryFilter();
- dtPolyRef polyRef = INVALID_POLYREF;
+ dtPolyRef polyRef = 0;
if (dtStatusFailed(navmeshquery->findNearestPoly(location, extents, &filter, &polyRef, NULL)))
{
handler->PSendSysMessage("Dt [??,??] (invalid poly, probably no tile loaded)");
return true;
}
- if (polyRef == INVALID_POLYREF)
+ if (polyRef == 0)
handler->PSendSysMessage("Dt [??, ??] (invalid poly, probably no tile loaded)");
else
{
diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp
index 9cc7eea5509..51b13ce6fd0 100644
--- a/src/tools/mesh_extractor/MeshExtractor.cpp
+++ b/src/tools/mesh_extractor/MeshExtractor.cpp
@@ -381,8 +381,8 @@ int main(int argc, char* argv[])
if (extractFlags & Constants::EXTRACT_FLAG_TEST)
{
- float start[] = { 16226.200195f, 16257.000000f, 13.202200f };
- float end[] = { 16245.725586f, 16382.465820f, 47.384956f };
+ float start[] = { -1.37402868f, -21.7641087f, -20.1751060f };
+ float end[] = { -22.756405f, -62.745014f, -21.371508f };
//
float m_spos[3];
@@ -411,7 +411,7 @@ int main(int argc, char* argv[])
dtPolyRef m_startRef;
dtPolyRef m_endRef;
- FILE* mmap = fopen("mmaps/001.mmap", "rb");
+ FILE* mmap = fopen("mmaps/389.mmap", "rb");
dtNavMeshParams params;
int count = fread(&params, sizeof(dtNavMeshParams), 1, mmap);
fclose(mmap);
@@ -430,7 +430,7 @@ int main(int argc, char* argv[])
for (int j = 0; j <= 32; ++j)
{
char buff[100];
- sprintf(buff, "mmaps/001%02i%02i.mmtile", i, j);
+ sprintf(buff, "mmaps/389%02i%02i.mmtile", i, j);
LoadTile(navMesh, buff);
}
}
diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp
index 51df91d2652..cdc3131b3db 100644
--- a/src/tools/mesh_extractor/TileBuilder.cpp
+++ b/src/tools/mesh_extractor/TileBuilder.cpp
@@ -42,13 +42,13 @@ TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x,
InstanceConfig.mergeRegionArea = 100;
InstanceConfig.walkableSlopeAngle = 50.0f;
InstanceConfig.detailSampleDist = 3.0f;
- InstanceConfig.detailSampleMaxError = 1.5f;
+ InstanceConfig.detailSampleMaxError = 1.25f;
InstanceConfig.walkableClimb = 1.0f / InstanceConfig.ch;
InstanceConfig.walkableHeight = 2.1f / InstanceConfig.ch;
InstanceConfig.walkableRadius = 0.6f / InstanceConfig.cs;
InstanceConfig.maxEdgeLen = 8 * InstanceConfig.walkableRadius;
InstanceConfig.maxVertsPerPoly = 6;
- InstanceConfig.maxSimplificationError = 1.25f;
+ InstanceConfig.maxSimplificationError = 1.3f;
InstanceConfig.borderSize = 0;
Context = new rcContext;