mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 19:29:56 +00:00
Pathfinding Overhaul - Changed the name of checkIfNextPointReached to a more intuitive name considering what it does (checkPathCompleted) and fixed a minor bug in it, modified buildPath() to take one final parameter, a bool which dictates whether or not to always use pathfinding (like AIWander should be doing) or to allow for "shortcuts", modified all ai packages to work with these two changes.
This commit is contained in:
parent
c080785235
commit
73a9671742
5 changed files with 24 additions and 16 deletions
|
@ -129,10 +129,10 @@ bool MWMechanics::AiEscort::execute (const MWWorld::Ptr& actor)
|
|||
start.mY = pos.pos[1];
|
||||
start.mZ = pos.pos[2];
|
||||
|
||||
mPathFinder.buildPath(start,dest,pathgrid,xCell,yCell);
|
||||
mPathFinder.buildPath(start, dest, pathgrid, xCell, yCell, 1);
|
||||
}
|
||||
|
||||
if(mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2]))
|
||||
if(mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2]))
|
||||
{
|
||||
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0;
|
||||
return true;
|
||||
|
|
|
@ -78,10 +78,10 @@ bool MWMechanics::AiTravel::execute (const MWWorld::Ptr& actor)
|
|||
start.mY = pos.pos[1];
|
||||
start.mZ = pos.pos[2];
|
||||
|
||||
mPathFinder.buildPath(start,dest,pathgrid,xCell,yCell);
|
||||
mPathFinder.buildPath(start, dest, pathgrid, xCell, yCell, 1);
|
||||
}
|
||||
|
||||
if(mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2]))
|
||||
if(mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2]))
|
||||
{
|
||||
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0;
|
||||
return true;
|
||||
|
|
|
@ -235,7 +235,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
|
|||
start.mY = pos.pos[1];
|
||||
start.mZ = pos.pos[2];
|
||||
|
||||
mPathFinder.buildPath(start,dest,mPathgrid,mXCell,mYCell);
|
||||
mPathFinder.buildPath(start, dest, mPathgrid, mXCell, mYCell, 0);
|
||||
mWalking = true;
|
||||
}
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor)
|
|||
actorPos[1] = actorPos[1] - mYCell;
|
||||
float distance = actorPos.squaredDistance(destNodePos);
|
||||
|
||||
if(distance < 1200 || mPathFinder.checkIfNextPointReached(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;
|
||||
|
|
|
@ -148,11 +148,16 @@ namespace MWMechanics
|
|||
}
|
||||
|
||||
void PathFinder::buildPath(ESM::Pathgrid::Point startPoint, ESM::Pathgrid::Point endPoint,
|
||||
const ESM::Pathgrid* pathGrid, float xCell, float yCell)
|
||||
const ESM::Pathgrid* pathGrid, float xCell, float yCell, bool allowShortcuts)
|
||||
{
|
||||
if(allowShortcuts)
|
||||
{
|
||||
if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX, startPoint.mY, startPoint.mZ, endPoint.mX, endPoint.mY,
|
||||
endPoint.mZ))
|
||||
allowShortcuts = false;
|
||||
}
|
||||
//first check if there is an obstacle
|
||||
if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX, startPoint.mY, startPoint.mZ,
|
||||
endPoint.mX, endPoint.mY, endPoint.mZ) )
|
||||
if(!allowShortcuts)
|
||||
{
|
||||
int startNode = getClosestPoint(pathGrid, startPoint.mX - xCell, startPoint.mY - yCell,startPoint.mZ);
|
||||
int endNode = getClosestPoint(pathGrid, endPoint.mX - xCell, endPoint.mY - yCell, endPoint.mZ);
|
||||
|
@ -175,14 +180,14 @@ namespace MWMechanics
|
|||
return 0;
|
||||
|
||||
ESM::Pathgrid::Point nextPoint = *mPath.begin();
|
||||
float dX = nextPoint.mX - x;
|
||||
float dY = nextPoint.mY - y;
|
||||
float h = sqrt(dX * dX + dY * dY);
|
||||
float directionX = nextPoint.mX - x;
|
||||
float directionY = nextPoint.mY - y;
|
||||
float directionResult = sqrt(directionX * directionX + directionY * directionY);
|
||||
|
||||
return Ogre::Radian(acos(dY / h) * sgn(asin(dX / h))).valueDegrees();
|
||||
return Ogre::Radian(acos(directionY / directionResult) * sgn(asin(directionX / directionResult))).valueDegrees();
|
||||
}
|
||||
|
||||
bool PathFinder::checkIfNextPointReached(float x, float y, float z)
|
||||
bool PathFinder::checkPathCompleted(float x, float y, float z)
|
||||
{
|
||||
if(mPath.empty())
|
||||
return true;
|
||||
|
@ -192,7 +197,10 @@ namespace MWMechanics
|
|||
{
|
||||
mPath.pop_front();
|
||||
if(mPath.empty())
|
||||
{
|
||||
mIsPathConstructed = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -13,9 +13,9 @@ namespace MWMechanics
|
|||
|
||||
void clearPath();
|
||||
void buildPath(ESM::Pathgrid::Point startPoint, ESM::Pathgrid::Point endPoint,
|
||||
const ESM::Pathgrid* pathGrid, float xCell = 0, float yCell = 0);
|
||||
const ESM::Pathgrid* pathGrid, float xCell = 0, float yCell = 0, bool allowShortcuts = 1);
|
||||
|
||||
bool checkIfNextPointReached(float x, float y, float z);
|
||||
bool checkPathCompleted(float x, float y, float z);
|
||||
///< \Returns true if the last point of the path has been reached.
|
||||
float getZAngleToNext(float x, float y);
|
||||
|
||||
|
|
Loading…
Reference in a new issue