diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index b7d391a9f..1530804cd 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -219,12 +219,6 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) unsigned int randNode = (int)(rand() / ((double)RAND_MAX + 1) * mAllowedNodes.size()); Ogre::Vector3 destNodePos(mAllowedNodes[randNode].mX, mAllowedNodes[randNode].mY, mAllowedNodes[randNode].mZ); - // Remove this node as an option and add back the previously used node (stops NPC from picking the same node): - ESM::Pathgrid::Point temp = mAllowedNodes[randNode]; - mAllowedNodes.erase(mAllowedNodes.begin() + randNode); - mAllowedNodes.push_back(mCurrentNode); - mCurrentNode = temp; - ESM::Pathgrid::Point dest; dest.mX = destNodePos[0] + mXCell; dest.mY = destNodePos[1] + mYCell; @@ -236,7 +230,21 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) start.mZ = pos.pos[2]; mPathFinder.buildPath(start, dest, mPathgrid, mXCell, mYCell, 0); - mWalking = true; + + if(mPathFinder.isPathConstructed()) + { + // Remove this node as an option and add back the previously used node (stops NPC from picking the same node): + ESM::Pathgrid::Point temp = mAllowedNodes[randNode]; + mAllowedNodes.erase(mAllowedNodes.begin() + randNode); + mAllowedNodes.push_back(mCurrentNode); + mCurrentNode = temp; + + mMoveNow = false; + mWalking = true; + } + // Choose a different node and delete this one from possible nodes because it is uncreachable: + else + mAllowedNodes.erase(mAllowedNodes.begin() + randNode); } } @@ -254,14 +262,13 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) actorPos[1] = actorPos[1] - mYCell; float distance = actorPos.squaredDistance(destNodePos); - if(distance < 1200 || mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2])) + if(distance < 1200 || mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2])) { stopWalking(actor); mMoveNow = false; mWalking = false; mChooseAction = true; } - } return false; diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index 78be90804..d3a44e0f9 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -156,7 +156,7 @@ namespace MWMechanics endPoint.mZ)) allowShortcuts = false; } - //first check if there is an obstacle + if(!allowShortcuts) { int startNode = getClosestPoint(pathGrid, startPoint.mX - xCell, startPoint.mY - yCell,startPoint.mZ); @@ -166,16 +166,28 @@ namespace MWMechanics { PathGridGraph graph = buildGraph(pathGrid, xCell, yCell); mPath = findPath(startNode, endNode, graph); + + if(!mPath.empty()) + { + mPath.push_back(endPoint); + mIsPathConstructed = true; + } } } + else + { + mPath.push_back(endPoint); + mIsPathConstructed = true; + } - mPath.push_back(endPoint); - mIsPathConstructed = true; + if(mPath.empty()) + mIsPathConstructed = false; } float PathFinder::getZAngleToNext(float x, float y) { - // This if should never be true: + // This should never happen (programmers should have an if statement checking mIsPathConstructed that prevents this call + // if otherwise). if(mPath.empty()) return 0;