forked from mirror/openmw-tes3mp
Merged pull request #1828
This commit is contained in:
commit
aac580da6b
6 changed files with 48 additions and 5 deletions
|
@ -30,6 +30,7 @@
|
|||
Bug #4125: OpenMW logo cropped on bugtracker
|
||||
Bug #4215: OpenMW shows book text after last EOL tag
|
||||
Bug #4221: Characters get stuck in V-shaped terrain
|
||||
Bug #4230: AiTravel package issues break some Tribunal quests
|
||||
Bug #4251: Stationary NPCs do not return to their position after combat
|
||||
Bug #4274: Pre-0.43 death animations are not forward-compatible with 0.43+
|
||||
Bug #4286: Scripted animations can be interrupted
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -53,7 +53,23 @@ namespace MWMechanics
|
|||
if (!isWithinMaxRange(osg::Vec3f(mX, mY, mZ), pos.asVec3()))
|
||||
return false;
|
||||
|
||||
if (pathTo(actor, ESM::Pathgrid::Point(static_cast<int>(mX), static_cast<int>(mY), static_cast<int>(mZ)), duration))
|
||||
// Unfortunately, with vanilla assets destination is sometimes blocked by other actor.
|
||||
// If we got close to target, check for actors nearby. If they are, finish AI package.
|
||||
int destinationTolerance = 64;
|
||||
ESM::Pathgrid::Point dest(static_cast<int>(mX), static_cast<int>(mY), static_cast<int>(mZ));
|
||||
if (distance(pos.pos, dest) <= destinationTolerance)
|
||||
{
|
||||
std::vector<MWWorld::Ptr> targetActors;
|
||||
std::pair<MWWorld::Ptr, osg::Vec3f> result = MWBase::Environment::get().getWorld()->getHitContact(actor, destinationTolerance, targetActors);
|
||||
|
||||
if (!result.first.isEmpty())
|
||||
{
|
||||
actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (pathTo(actor, dest, duration))
|
||||
{
|
||||
actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
|
||||
return true;
|
||||
|
|
|
@ -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