1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-04-01 07:36:44 +00:00

Improve getLOS (use eye level). Also, don't crash when used with non-actors.

This commit is contained in:
scrawl 2014-06-19 04:53:25 +02:00
parent 185ff279a3
commit 4648524df4
4 changed files with 22 additions and 11 deletions

View file

@ -407,7 +407,7 @@ namespace MWBase
virtual void getItemsOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out) = 0; virtual void getItemsOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out) = 0;
///< get all items in active cells owned by this Npc ///< get all items in active cells owned by this Npc
virtual bool getLOS(const MWWorld::Ptr& npc,const MWWorld::Ptr& targetNpc) = 0; virtual bool getLOS(const MWWorld::Ptr& actor,const MWWorld::Ptr& targetActor) = 0;
///< get Line of Sight (morrowind stupid implementation) ///< get Line of Sight (morrowind stupid implementation)
virtual float getDistToNearestRayHit(const Ogre::Vector3& from, const Ogre::Vector3& dir, float maxDist) = 0; virtual float getDistToNearestRayHit(const Ogre::Vector3& from, const Ogre::Vector3& dir, float maxDist) = 0;

View file

@ -371,6 +371,12 @@ namespace MWScript
MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPtr(actorID, true); MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPtr(actorID, true);
if(!actor.getClass().isActor() || !observer.getClass().isActor())
{
runtime.push(0);
return;
}
Interpreter::Type_Integer value = Interpreter::Type_Integer value =
MWBase::Environment::get().getWorld()->getLOS(observer, actor) && MWBase::Environment::get().getWorld()->getLOS(observer, actor) &&
MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor, observer); MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor, observer);
@ -392,9 +398,10 @@ namespace MWScript
std::string actorID = runtime.getStringLiteral (runtime[0].mInteger); std::string actorID = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop(); runtime.pop();
MWWorld::Ptr dest = MWBase::Environment::get().getWorld()->getPtr(actorID,true); MWWorld::Ptr dest = MWBase::Environment::get().getWorld()->getPtr(actorID,true);
bool value = false; bool value = false;
if(dest != MWWorld::Ptr() ) if(dest != MWWorld::Ptr() && source.getClass().isActor() && dest.getClass().isActor())
{ {
value = MWBase::Environment::get().getWorld()->getLOS(source,dest); value = MWBase::Environment::get().getWorld()->getLOS(source,dest);
} }

View file

@ -2031,20 +2031,24 @@ namespace MWWorld
} }
} }
bool World::getLOS(const MWWorld::Ptr& npc,const MWWorld::Ptr& targetNpc) bool World::getLOS(const MWWorld::Ptr& actor,const MWWorld::Ptr& targetActor)
{ {
if (!targetNpc.getRefData().isEnabled() || !npc.getRefData().isEnabled()) if (!targetActor.getRefData().isEnabled() || !actor.getRefData().isEnabled())
return false; // cannot get LOS unless both NPC's are enabled return false; // cannot get LOS unless both NPC's are enabled
Ogre::Vector3 halfExt1 = mPhysEngine->getCharacter(npc.getRefData().getHandle())->getHalfExtents(); if (!targetActor.getRefData().getBaseNode() || !targetActor.getRefData().getBaseNode())
const float* pos1 = npc.getRefData().getPosition().pos; return false; // not in active cell
Ogre::Vector3 halfExt2 = mPhysEngine->getCharacter(targetNpc.getRefData().getHandle())->getHalfExtents();
const float* pos2 = targetNpc.getRefData().getPosition().pos;
btVector3 from(pos1[0],pos1[1],pos1[2]+halfExt1.z); Ogre::Vector3 halfExt1 = mPhysEngine->getCharacter(actor.getRefData().getHandle())->getHalfExtents();
btVector3 to(pos2[0],pos2[1],pos2[2]+halfExt2.z); const float* pos1 = actor.getRefData().getPosition().pos;
Ogre::Vector3 halfExt2 = mPhysEngine->getCharacter(targetActor.getRefData().getHandle())->getHalfExtents();
const float* pos2 = targetActor.getRefData().getPosition().pos;
btVector3 from(pos1[0],pos1[1],pos1[2]+halfExt1.z*2*0.9); // eye level
btVector3 to(pos2[0],pos2[1],pos2[2]+halfExt2.z*2*0.9);
std::pair<std::string, float> result = mPhysEngine->rayTest(from, to,false); std::pair<std::string, float> result = mPhysEngine->rayTest(from, to,false);
if(result.first == "") return true; if(result.first == "") return true;
return false; return false;
} }

View file

@ -482,7 +482,7 @@ namespace MWWorld
virtual void getItemsOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out); virtual void getItemsOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out);
///< get all items in active cells owned by this Npc ///< get all items in active cells owned by this Npc
virtual bool getLOS(const MWWorld::Ptr& npc,const MWWorld::Ptr& targetNpc); virtual bool getLOS(const MWWorld::Ptr& actor,const MWWorld::Ptr& targetActor);
///< get Line of Sight (morrowind stupid implementation) ///< get Line of Sight (morrowind stupid implementation)
virtual float getDistToNearestRayHit(const Ogre::Vector3& from, const Ogre::Vector3& dir, float maxDist); virtual float getDistToNearestRayHit(const Ogre::Vector3& from, const Ogre::Vector3& dir, float maxDist);