forked from teamnwah/openmw-tes3coop
Prevent NPC from chosing farther pathgrid node
This commit is contained in:
parent
9e6cba09a6
commit
75835c8326
4 changed files with 30 additions and 4 deletions
|
@ -297,7 +297,7 @@ namespace MWBase
|
|||
///< Queues movement for \a ptr (in local space), to be applied in the next call to
|
||||
/// doPhysics.
|
||||
|
||||
virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2) = 0;
|
||||
virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2, bool ignoreDoors=false) = 0;
|
||||
///< cast a Ray and return true if there is an object in the ray path.
|
||||
|
||||
virtual bool toggleCollisionMode() = 0;
|
||||
|
|
|
@ -231,6 +231,28 @@ namespace MWMechanics
|
|||
{
|
||||
mPath = pathgridGraph.aStarSearch(startNode, endNode.first);
|
||||
|
||||
// If nearest path node is in opposite direction from second, remove it from path.
|
||||
// Especially useful for wandering actors, if the nearest node is blocked for some reason.
|
||||
if (mPath.size() > 1)
|
||||
{
|
||||
ESM::Pathgrid::Point secondNode = *(++mPath.begin());
|
||||
osg::Vec3f firstNodeVec3f = MakeOsgVec3(mPathgrid->mPoints[startNode]);
|
||||
osg::Vec3f secondNodeVec3f = MakeOsgVec3(secondNode);
|
||||
osg::Vec3f toSecondNodeVec3f = secondNodeVec3f - firstNodeVec3f;
|
||||
osg::Vec3f toStartPointVec3f = startPointInLocalCoords - firstNodeVec3f;
|
||||
if (toSecondNodeVec3f * toStartPointVec3f > 0)
|
||||
{
|
||||
ESM::Pathgrid::Point temp(secondNode);
|
||||
converter.toWorld(temp);
|
||||
// Add Z offset since path node can overlap with other objects.
|
||||
// Also ignore doors in raytesting.
|
||||
bool isPathClear = !MWBase::Environment::get().getWorld()->castRay(
|
||||
startPoint.mX, startPoint.mY, startPoint.mZ+16, temp.mX, temp.mY, temp.mZ+16, true);
|
||||
if (isPathClear)
|
||||
mPath.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
// convert supplied path to world coordinates
|
||||
for (std::list<ESM::Pathgrid::Point>::iterator iter(mPath.begin()); iter != mPath.end(); ++iter)
|
||||
{
|
||||
|
|
|
@ -1471,12 +1471,16 @@ namespace MWWorld
|
|||
moveObjectImp(player->first, player->second.x(), player->second.y(), player->second.z(), false);
|
||||
}
|
||||
|
||||
bool World::castRay (float x1, float y1, float z1, float x2, float y2, float z2)
|
||||
bool World::castRay (float x1, float y1, float z1, float x2, float y2, float z2, bool ignoreDoors)
|
||||
{
|
||||
osg::Vec3f a(x1,y1,z1);
|
||||
osg::Vec3f b(x2,y2,z2);
|
||||
|
||||
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(a, b, MWWorld::Ptr(), std::vector<MWWorld::Ptr>(), MWPhysics::CollisionType_World|MWPhysics::CollisionType_Door);
|
||||
int mask = MWPhysics::CollisionType_World;
|
||||
if (!ignoreDoors)
|
||||
mask |= MWPhysics::CollisionType_Door;
|
||||
|
||||
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(a, b, MWWorld::Ptr(), std::vector<MWWorld::Ptr>(), mask);
|
||||
return result.mHit;
|
||||
}
|
||||
|
||||
|
|
|
@ -400,7 +400,7 @@ namespace MWWorld
|
|||
///< Queues movement for \a ptr (in local space), to be applied in the next call to
|
||||
/// doPhysics.
|
||||
|
||||
bool castRay (float x1, float y1, float z1, float x2, float y2, float z2) override;
|
||||
bool castRay (float x1, float y1, float z1, float x2, float y2, float z2, bool ignoreDoors=false) override;
|
||||
///< cast a Ray and return true if there is an object in the ray path.
|
||||
|
||||
bool toggleCollisionMode() override;
|
||||
|
|
Loading…
Reference in a new issue