1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-01 00:15:32 +00:00

Fix rebuild path for walking actors

Ignore z coordinate for not swimming nor flying actors to calculate
distance from actor destination to last path point. If walking actor
destination point is floating above the ground then a point on navmesh
may be too far away when z coordinate is included. In this case path
will be rebuild on each AI_REACTION_TIME.
This commit is contained in:
elsid 2019-10-07 20:19:12 +02:00
parent e37bcc26ac
commit d1d6ba3ed0
No known key found for this signature in database
GPG key ID: B845CB9FEE18AB40
2 changed files with 26 additions and 5 deletions

View file

@ -22,6 +22,27 @@
#include <osg/Quat>
namespace MWMechanics
{
static float distance(const osg::Vec2f& lhs, const osg::Vec2f& rhs)
{
return (lhs - rhs).length2();
}
static float distanceIgnoreZ(const osg::Vec3f& lhs, const osg::Vec3f& rhs)
{
return distance(osg::Vec2f(lhs.x(), lhs.y()), osg::Vec2f(rhs.x(), rhs.y()));
}
static float distance(const osg::Vec3f& lhs, const osg::Vec3f& rhs, const MWWorld::Ptr& actor)
{
const auto world = MWBase::Environment::get().getWorld();
if (world->isSwimming(actor) || world->isFlying(actor))
return distance(lhs, rhs);
return distanceIgnoreZ(lhs, rhs);
}
}
MWMechanics::AiPackage::~AiPackage() {}
MWMechanics::AiPackage::AiPackage() :
@ -133,7 +154,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f&
if (!mIsShortcutting)
{
if (wasShortcutting || doesPathNeedRecalc(dest, actor.getCell())) // if need to rebuild path
if (wasShortcutting || doesPathNeedRecalc(dest, actor)) // if need to rebuild path
{
const auto pathfindingHalfExtents = world->getPathfindingHalfExtents(actor);
mPathFinder.buildPath(actor, position, dest, actor.getCell(), getPathGridGraph(actor.getCell()),
@ -328,11 +349,11 @@ bool MWMechanics::AiPackage::checkWayIsClearForActor(const osg::Vec3f& startPoin
return false;
}
bool MWMechanics::AiPackage::doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::CellStore* currentCell)
bool MWMechanics::AiPackage::doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::Ptr& actor) const
{
return mPathFinder.getPath().empty()
|| (distance(mPathFinder.getPath().back(), newDest) > 10)
|| mPathFinder.getPathCell() != currentCell;
|| distance(mPathFinder.getPath().back(), newDest, actor) > 10
|| mPathFinder.getPathCell() != actor.getCell();
}
bool MWMechanics::AiPackage::isNearInactiveCell(osg::Vec3f position)

View file

@ -120,7 +120,7 @@ namespace MWMechanics
/// Check if the way to the destination is clear, taking into account actor speed
bool checkWayIsClearForActor(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const MWWorld::Ptr& actor);
bool doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::CellStore* currentCell);
bool doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::Ptr& actor) const;
void evadeObstacles(const MWWorld::Ptr& actor);