void AiCombat::buildNewPath(const MWWorld::Ptr& actor) { //Construct path to target ESM::Pathgrid::Point dest; dest.mX = mTarget.getRefData().getPosition().pos[0]; dest.mY = mTarget.getRefData().getPosition().pos[1]; dest.mZ = mTarget.getRefData().getPosition().pos[2]; Ogre::Vector3 newPathTarget = Ogre::Vector3(dest.mX, dest.mY, dest.mZ); float dist = -1; //hack to indicate first time, to construct a new path if(!mPathFinder.getPath().empty()) { ESM::Pathgrid::Point lastPt = mPathFinder.getPath().back(); Ogre::Vector3 currPathTarget(lastPt.mX, lastPt.mY, lastPt.mZ); dist = Ogre::Math::Abs((newPathTarget - currPathTarget).length()); } float targetPosThreshold; bool isOutside = actor.getCell()->getCell()->isExterior(); if (isOutside) targetPosThreshold = 300; else targetPosThreshold = 100; if((dist < 0) || (dist > targetPosThreshold)) { //construct new path only if target has moved away more than on <targetPosThreshold> ESM::Position pos = actor.getRefData().getPosition(); ESM::Pathgrid::Point start; start.mX = pos.pos[0]; start.mY = pos.pos[1]; start.mZ = pos.pos[2]; if(!mPathFinder.isPathConstructed()) mPathFinder.buildPath(start, dest, actor.getCell(), isOutside); else { PathFinder newPathFinder; newPathFinder.buildPath(start, dest, actor.getCell(), isOutside); //TO EXPLORE: //maybe here is a mistake (?): PathFinder::getPathSize() returns number of grid points in the path, //not the actual path length. Here we should know if the new path is actually more effective. //if(pathFinder2.getPathSize() < mPathFinder.getPathSize()) if(!mPathFinder.getPath().empty()) { newPathFinder.syncStart(mPathFinder.getPath()); mPathFinder = newPathFinder; } } } }
bool AiCombat::doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell) { if (!mPathFinder.getPath().empty()) { osg::Vec3f currPathTarget(PathFinder::MakeOsgVec3(mPathFinder.getPath().back())); osg::Vec3f newPathTarget = PathFinder::MakeOsgVec3(dest); float dist = (newPathTarget - currPathTarget).length(); float targetPosThreshold = (cell->isExterior()) ? 300.0f : 100.0f; return dist > targetPosThreshold; } else { // necessarily construct a new path return true; } }
void AiCombat::buildNewPath(const MWWorld::Ptr& actor, const MWWorld::Ptr& target) { Ogre::Vector3 newPathTarget = Ogre::Vector3(target.getRefData().getPosition().pos); float dist; if(!mPathFinder.getPath().empty()) { ESM::Pathgrid::Point lastPt = mPathFinder.getPath().back(); Ogre::Vector3 currPathTarget(lastPt.mX, lastPt.mY, lastPt.mZ); dist = (newPathTarget - currPathTarget).length(); } else dist = 1e+38F; // necessarily construct a new path float targetPosThreshold = (actor.getCell()->getCell()->isExterior())? 300 : 100; //construct new path only if target has moved away more than on [targetPosThreshold] if(dist > targetPosThreshold) { ESM::Position pos = actor.getRefData().getPosition(); ESM::Pathgrid::Point start; start.mX = pos.pos[0]; start.mY = pos.pos[1]; start.mZ = pos.pos[2]; ESM::Pathgrid::Point dest; dest.mX = newPathTarget.x; dest.mY = newPathTarget.y; dest.mZ = newPathTarget.z; if(!mPathFinder.isPathConstructed()) mPathFinder.buildPath(start, dest, actor.getCell(), false); else { PathFinder newPathFinder; newPathFinder.buildPath(start, dest, actor.getCell(), false); if(!mPathFinder.getPath().empty()) { newPathFinder.syncStart(mPathFinder.getPath()); mPathFinder = newPathFinder; } } } }