mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-20 09:23:52 +00:00
Open door when it is on the way to a next path point
This commit is contained in:
parent
653a391084
commit
209e33f5ce
4 changed files with 42 additions and 0 deletions
|
@ -614,6 +614,8 @@ namespace MWBase
|
||||||
|
|
||||||
/// Return physical half extents of the given actor to be used in pathfinding
|
/// Return physical half extents of the given actor to be used in pathfinding
|
||||||
virtual osg::Vec3f getPathfindingHalfExtents(const MWWorld::ConstPtr& actor) const = 0;
|
virtual osg::Vec3f getPathfindingHalfExtents(const MWWorld::ConstPtr& actor) const = 0;
|
||||||
|
|
||||||
|
virtual bool hasCollisionWithDoor(const MWWorld::ConstPtr& door, const osg::Vec3f& position, const osg::Vec3f& destination) const = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include "../mwworld/cellstore.hpp"
|
#include "../mwworld/cellstore.hpp"
|
||||||
#include "../mwworld/inventorystore.hpp"
|
#include "../mwworld/inventorystore.hpp"
|
||||||
|
|
||||||
|
#include "../mwphysics/collisiontype.hpp"
|
||||||
|
|
||||||
#include "pathgrid.hpp"
|
#include "pathgrid.hpp"
|
||||||
#include "creaturestats.hpp"
|
#include "creaturestats.hpp"
|
||||||
#include "movement.hpp"
|
#include "movement.hpp"
|
||||||
|
@ -222,6 +224,19 @@ void MWMechanics::AiPackage::evadeObstacles(const MWWorld::Ptr& actor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
bool isDoorOnTheWay(const MWWorld::Ptr& actor, const MWWorld::Ptr& door, const osg::Vec3f& nextPathPoint)
|
||||||
|
{
|
||||||
|
const auto world = MWBase::Environment::get().getWorld();
|
||||||
|
const auto halfExtents = world->getHalfExtents(actor);
|
||||||
|
const auto position = actor.getRefData().getPosition().asVec3() + osg::Vec3f(0, 0, halfExtents.z());
|
||||||
|
const auto destination = nextPathPoint + osg::Vec3f(0, 0, halfExtents.z());
|
||||||
|
|
||||||
|
return world->hasCollisionWithDoor(door, position, destination);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MWMechanics::AiPackage::openDoors(const MWWorld::Ptr& actor)
|
void MWMechanics::AiPackage::openDoors(const MWWorld::Ptr& actor)
|
||||||
{
|
{
|
||||||
// note: AiWander currently does not open doors
|
// note: AiWander currently does not open doors
|
||||||
|
@ -240,6 +255,9 @@ void MWMechanics::AiPackage::openDoors(const MWWorld::Ptr& actor)
|
||||||
|
|
||||||
if (!door.getCellRef().getTeleport() && door.getClass().getDoorState(door) == MWWorld::DoorState::Idle)
|
if (!door.getCellRef().getTeleport() && door.getClass().getDoorState(door) == MWWorld::DoorState::Idle)
|
||||||
{
|
{
|
||||||
|
if (!isDoorOnTheWay(actor, door, mPathFinder.getPath().front()))
|
||||||
|
return;
|
||||||
|
|
||||||
if ((door.getCellRef().getTrap().empty() && door.getCellRef().getLockLevel() <= 0 ))
|
if ((door.getCellRef().getTrap().empty() && door.getCellRef().getLockLevel() <= 0 ))
|
||||||
{
|
{
|
||||||
world->activate(door, actor);
|
world->activate(door, actor);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <components/misc/constants.hpp>
|
#include <components/misc/constants.hpp>
|
||||||
#include <components/misc/resourcehelpers.hpp>
|
#include <components/misc/resourcehelpers.hpp>
|
||||||
#include <components/misc/rng.hpp>
|
#include <components/misc/rng.hpp>
|
||||||
|
#include <components/misc/convert.hpp>
|
||||||
|
|
||||||
#include <components/files/collections.hpp>
|
#include <components/files/collections.hpp>
|
||||||
|
|
||||||
|
@ -3851,4 +3852,23 @@ namespace MWWorld
|
||||||
return getHalfExtents(actor);
|
return getHalfExtents(actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool World::hasCollisionWithDoor(const MWWorld::ConstPtr& door, const osg::Vec3f& position, const osg::Vec3f& destination) const
|
||||||
|
{
|
||||||
|
const auto object = mPhysics->getObject(door);
|
||||||
|
|
||||||
|
if (!object)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
btVector3 aabbMin;
|
||||||
|
btVector3 aabbMax;
|
||||||
|
object->getShapeInstance()->getCollisionShape()->getAabb(btTransform::getIdentity(), aabbMin, aabbMax);
|
||||||
|
|
||||||
|
const auto toLocal = object->getCollisionObject()->getWorldTransform().inverse();
|
||||||
|
const auto localFrom = toLocal(Misc::Convert::toBullet(position));
|
||||||
|
const auto localTo = toLocal(Misc::Convert::toBullet(destination));
|
||||||
|
|
||||||
|
btScalar hitDistance = 1;
|
||||||
|
btVector3 hitNormal;
|
||||||
|
return btRayAabb(localFrom, localTo, aabbMin, aabbMax, hitDistance, hitNormal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -719,6 +719,8 @@ namespace MWWorld
|
||||||
|
|
||||||
/// Return physical half extents of the given actor to be used in pathfinding
|
/// Return physical half extents of the given actor to be used in pathfinding
|
||||||
osg::Vec3f getPathfindingHalfExtents(const MWWorld::ConstPtr& actor) const override;
|
osg::Vec3f getPathfindingHalfExtents(const MWWorld::ConstPtr& actor) const override;
|
||||||
|
|
||||||
|
bool hasCollisionWithDoor(const MWWorld::ConstPtr& door, const osg::Vec3f& position, const osg::Vec3f& destination) const override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue