mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 01:23:53 +00:00
Merge remote-tracking branch 'scrawl/master'
This commit is contained in:
commit
8da04bf76f
3 changed files with 54 additions and 3 deletions
|
@ -515,6 +515,7 @@ namespace MWPhysics
|
|||
public:
|
||||
Object(const MWWorld::Ptr& ptr, osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance)
|
||||
: mShapeInstance(shapeInstance)
|
||||
, mSolid(true)
|
||||
{
|
||||
mPtr = ptr;
|
||||
|
||||
|
@ -549,6 +550,17 @@ namespace MWPhysics
|
|||
return mCollisionObject.get();
|
||||
}
|
||||
|
||||
/// Return solid flag. Not used by the object itself, true by default.
|
||||
bool isSolid() const
|
||||
{
|
||||
return mSolid;
|
||||
}
|
||||
|
||||
void setSolid(bool solid)
|
||||
{
|
||||
mSolid = solid;
|
||||
}
|
||||
|
||||
bool isAnimated() const
|
||||
{
|
||||
return !mShapeInstance->mAnimatedShapes.empty();
|
||||
|
@ -618,6 +630,7 @@ namespace MWPhysics
|
|||
private:
|
||||
std::auto_ptr<btCollisionObject> mCollisionObject;
|
||||
osg::ref_ptr<Resource::BulletShapeInstance> mShapeInstance;
|
||||
bool mSolid;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
@ -684,6 +697,35 @@ namespace MWPhysics
|
|||
return mDebugDrawEnabled;
|
||||
}
|
||||
|
||||
void PhysicsSystem::markAsNonSolid(const MWWorld::Ptr &ptr)
|
||||
{
|
||||
ObjectMap::iterator found = mObjects.find(ptr);
|
||||
if (found == mObjects.end())
|
||||
return;
|
||||
|
||||
found->second->setSolid(false);
|
||||
}
|
||||
|
||||
bool PhysicsSystem::isOnSolidGround (const MWWorld::Ptr& actor) const
|
||||
{
|
||||
const Actor* physactor = getActor(actor);
|
||||
if (!physactor->getOnGround())
|
||||
return false;
|
||||
|
||||
CollisionMap::const_iterator found = mStandingCollisions.find(actor);
|
||||
if (found == mStandingCollisions.end())
|
||||
return true; // assume standing on terrain (which is a non-object, so not collision tracked)
|
||||
|
||||
ObjectMap::const_iterator foundObj = mObjects.find(found->second);
|
||||
if (foundObj == mObjects.end())
|
||||
return false;
|
||||
|
||||
if (!foundObj->second->isSolid())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class DeepestNotMeContactTestResultCallback : public btCollisionWorld::ContactResultCallback
|
||||
{
|
||||
const btCollisionObject* mMe;
|
||||
|
|
|
@ -153,6 +153,12 @@ namespace MWPhysics
|
|||
|
||||
bool toggleDebugRendering();
|
||||
|
||||
/// Mark the given object as a 'non-solid' object. A non-solid object means that
|
||||
/// \a isOnSolidGround will return false for actors standing on that object.
|
||||
void markAsNonSolid (const MWWorld::Ptr& ptr);
|
||||
|
||||
bool isOnSolidGround (const MWWorld::Ptr& actor) const;
|
||||
|
||||
private:
|
||||
|
||||
void updateWater();
|
||||
|
|
|
@ -2059,11 +2059,10 @@ namespace MWWorld
|
|||
if (!actor)
|
||||
throw std::runtime_error("can't find player");
|
||||
|
||||
if((!actor->getOnGround()&&actor->getCollisionMode()) || isUnderwater(currentCell, playerPos) || isWalkingOnWater(player))
|
||||
if ((actor->getCollisionMode() && !mPhysics->isOnSolidGround(player)) || isUnderwater(currentCell, playerPos))
|
||||
return 2;
|
||||
|
||||
if((currentCell->getCell()->mData.mFlags&ESM::Cell::NoSleep) ||
|
||||
player.getClass().getNpcStats(player).isWerewolf())
|
||||
if((currentCell->getCell()->mData.mFlags&ESM::Cell::NoSleep) || player.getClass().getNpcStats(player).isWerewolf())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
@ -2155,6 +2154,8 @@ namespace MWWorld
|
|||
health.setCurrent(health.getCurrent()-healthPerSecond*MWBase::Environment::get().getFrameDuration());
|
||||
stats.setHealth(health);
|
||||
|
||||
mPhysics->markAsNonSolid (object);
|
||||
|
||||
if (healthPerSecond > 0.0f)
|
||||
{
|
||||
if (actor == getPlayerPtr())
|
||||
|
@ -2183,6 +2184,8 @@ namespace MWWorld
|
|||
health.setCurrent(health.getCurrent()-healthPerSecond*MWBase::Environment::get().getFrameDuration());
|
||||
stats.setHealth(health);
|
||||
|
||||
mPhysics->markAsNonSolid (object);
|
||||
|
||||
if (healthPerSecond > 0.0f)
|
||||
{
|
||||
if (actor == getPlayerPtr())
|
||||
|
|
Loading…
Reference in a new issue