Open door when it is on the way to a next path point

pull/541/head
elsid 5 years ago
parent 17991164e4
commit c32872fb16
No known key found for this signature in database
GPG Key ID: B845CB9FEE18AB40

@ -306,6 +306,8 @@ namespace MWBase
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) = 0;
virtual MWWorld::Ptr castRay(const osg::Vec3f& from, const osg::Vec3f& to, int mask) const = 0;
virtual void setActorCollisionMode(const MWWorld::Ptr& ptr, bool internal, bool external) = 0; virtual void setActorCollisionMode(const MWWorld::Ptr& ptr, bool internal, bool external) = 0;
virtual bool isActorCollisionEnabled(const MWWorld::Ptr& ptr) = 0; virtual bool isActorCollisionEnabled(const MWWorld::Ptr& ptr) = 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"
@ -234,6 +236,9 @@ void MWMechanics::AiPackage::openDoors(const MWWorld::Ptr& actor)
// note: AiWander currently does not open doors // note: AiWander currently does not open doors
if (getTypeId() != TypeIdWander && !door.getCellRef().getTeleport() && door.getClass().getDoorState(door) == 0) if (getTypeId() != TypeIdWander && !door.getCellRef().getTeleport() && door.getClass().getDoorState(door) == 0)
{ {
if (!isDoorOnTheWay(actor, door))
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);
@ -402,3 +407,16 @@ DetourNavigator::Flags MWMechanics::AiPackage::getNavigatorFlags(const MWWorld::
return result; return result;
} }
bool MWMechanics::AiPackage::isDoorOnTheWay(const MWWorld::Ptr& actor, const MWWorld::Ptr& door) const
{
if (mPathFinder.getPathSize() == 0)
return false;
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 = mPathFinder.getPath().front() + osg::Vec3f(0, 0, halfExtents.z());
return world->castRay(position, destination, MWPhysics::CollisionType_Door) == door;
}

@ -147,6 +147,8 @@ namespace MWMechanics
private: private:
bool isNearInactiveCell(osg::Vec3f position); bool isNearInactiveCell(osg::Vec3f position);
bool isDoorOnTheWay(const MWWorld::Ptr& actor, const MWWorld::Ptr& door) const;
}; };
} }

@ -1610,8 +1610,13 @@ namespace MWWorld
osg::Vec3f a(x1,y1,z1); osg::Vec3f a(x1,y1,z1);
osg::Vec3f b(x2,y2,z2); osg::Vec3f b(x2,y2,z2);
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(a, b, MWWorld::Ptr(), std::vector<MWWorld::Ptr>(), mask); return !castRay(a, b, mask).isEmpty();
return result.mHit; }
MWWorld::Ptr World::castRay(const osg::Vec3f& from, const osg::Vec3f& to, int mask) const
{
const auto result = mPhysics->castRay(from, to, MWWorld::Ptr(), std::vector<MWWorld::Ptr>(), mask);
return result.mHit ? result.mHitObject : MWWorld::Ptr();
} }
void World::processDoors(float duration) void World::processDoors(float duration)

@ -420,6 +420,8 @@ namespace MWWorld
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) override;
MWWorld::Ptr castRay (const osg::Vec3f& from, const osg::Vec3f& to, int mask) const override;
void setActorCollisionMode(const Ptr& ptr, bool internal, bool external) override; void setActorCollisionMode(const Ptr& ptr, bool internal, bool external) override;
bool isActorCollisionEnabled(const Ptr& ptr) override; bool isActorCollisionEnabled(const Ptr& ptr) override;

Loading…
Cancel
Save