Pathfinding Overhaul - Fixed selecting cells that are inaccessable from AIWander and pathfinding in general (sadly requires minor effort on the AI Packages implementation but it is the quickest way I can see), minor cleanup again (there is a lot to cleanup, this will prolly be in every commit).

This commit is contained in:
Torben Carrington 2013-05-31 17:01:42 -07:00
parent 73a9671742
commit a4caec56cf
2 changed files with 32 additions and 13 deletions

View file

@ -219,12 +219,6 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
unsigned int randNode = (int)(rand() / ((double)RAND_MAX + 1) * mAllowedNodes.size()); unsigned int randNode = (int)(rand() / ((double)RAND_MAX + 1) * mAllowedNodes.size());
Ogre::Vector3 destNodePos(mAllowedNodes[randNode].mX, mAllowedNodes[randNode].mY, mAllowedNodes[randNode].mZ); 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; ESM::Pathgrid::Point dest;
dest.mX = destNodePos[0] + mXCell; dest.mX = destNodePos[0] + mXCell;
dest.mY = destNodePos[1] + mYCell; dest.mY = destNodePos[1] + mYCell;
@ -236,7 +230,21 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
start.mZ = pos.pos[2]; start.mZ = pos.pos[2];
mPathFinder.buildPath(start, dest, mPathgrid, mXCell, mYCell, 0); 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; actorPos[1] = actorPos[1] - mYCell;
float distance = actorPos.squaredDistance(destNodePos); 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); stopWalking(actor);
mMoveNow = false; mMoveNow = false;
mWalking = false; mWalking = false;
mChooseAction = true; mChooseAction = true;
} }
} }
return false; return false;

View file

@ -156,7 +156,7 @@ namespace MWMechanics
endPoint.mZ)) endPoint.mZ))
allowShortcuts = false; allowShortcuts = false;
} }
//first check if there is an obstacle
if(!allowShortcuts) if(!allowShortcuts)
{ {
int startNode = getClosestPoint(pathGrid, startPoint.mX - xCell, startPoint.mY - yCell,startPoint.mZ); int startNode = getClosestPoint(pathGrid, startPoint.mX - xCell, startPoint.mY - yCell,startPoint.mZ);
@ -166,16 +166,28 @@ namespace MWMechanics
{ {
PathGridGraph graph = buildGraph(pathGrid, xCell, yCell); PathGridGraph graph = buildGraph(pathGrid, xCell, yCell);
mPath = findPath(startNode, endNode, graph); 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); if(mPath.empty())
mIsPathConstructed = true; mIsPathConstructed = false;
} }
float PathFinder::getZAngleToNext(float x, float y) 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()) if(mPath.empty())
return 0; return 0;