Fix swim height, use fSwimHeightScale GMST

openmw-35
scrawl 10 years ago
parent 57a259c526
commit c98b7db4c1

@ -303,26 +303,15 @@ namespace MWWorld
Ogre::Vector3 halfExtents = physicActor->getHalfExtents();
position.z += halfExtents.z;
waterlevel -= halfExtents.z * 0.5;
/*
* A 3/4 submerged example
*
* +---+
* | |
* | | <- (original waterlevel)
* | |
* | | <- position <- waterlevel
* | |
* | |
* | |
* +---+ <- (original position)
*/
static const float fSwimHeightScale = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
.find("fSwimHeightScale")->getFloat();
float swimlevel = waterlevel + halfExtents.z - (halfExtents.z * 2 * fSwimHeightScale);
OEngine::Physic::ActorTracer tracer;
Ogre::Vector3 inertia = physicActor->getInertialForce();
Ogre::Vector3 velocity;
if(position.z < waterlevel || isFlying)
if(position.z < swimlevel || isFlying)
{
velocity = (Ogre::Quaternion(Ogre::Radian(refpos.rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z)*
Ogre::Quaternion(Ogre::Radian(refpos.rot[0]), Ogre::Vector3::NEGATIVE_UNIT_X)) * movement;
@ -364,12 +353,10 @@ namespace MWWorld
Ogre::Vector3 nextpos = newPosition + velocity * remainingTime;
// If not able to fly, don't allow to swim up into the air
// TODO: this if condition may not work for large creatures or situations
// where the creature gets above the waterline for some reason
if(newPosition.z < waterlevel && // started 3/4 under water
if(newPosition.z < swimlevel &&
!isFlying && // can't fly
nextpos.z > waterlevel && // but about to go above water
newPosition.z <= waterlevel)
nextpos.z > swimlevel && // but about to go above water
newPosition.z <= swimlevel)
{
const Ogre::Vector3 down(0,0,-1);
Ogre::Real movelen = velocity.normalise();
@ -423,7 +410,7 @@ namespace MWWorld
{
// don't let pure water creatures move out of water after stepMove
if (ptr.getClass().isPureWaterCreature(ptr)
&& newPosition.z > (waterlevel - halfExtents.z * 0.5))
&& newPosition.z + halfExtents.z > waterlevel)
newPosition = oldPosition;
}
else
@ -444,13 +431,13 @@ namespace MWWorld
// Do not allow sliding upward if there is gravity. Stepping will have taken
// care of that.
if(!(newPosition.z < waterlevel || isFlying))
if(!(newPosition.z < swimlevel || isFlying))
velocity.z = std::min(velocity.z, 0.0f);
}
}
bool isOnGround = false;
if (!(inertia.z > 0.f) && !(newPosition.z < waterlevel))
if (!(inertia.z > 0.f) && !(newPosition.z < swimlevel))
{
Ogre::Vector3 from = newPosition;
Ogre::Vector3 to = newPosition - (physicActor->getOnGround() ?
@ -494,7 +481,7 @@ namespace MWWorld
}
}
if(isOnGround || newPosition.z < waterlevel || isFlying)
if(isOnGround || newPosition.z < swimlevel || isFlying)
physicActor->setInertialForce(Ogre::Vector3(0.0f));
else
{

@ -187,6 +187,8 @@ namespace MWWorld
mStore.setUp();
mStore.movePlayerRecord();
mSwimHeightScale = mStore.get<ESM::GameSetting>().find("fSwimHeightScale")->getFloat();
mGlobalVariables.fill (mStore);
mWorldScene = new Scene(*mRendering, mPhysics);
@ -1952,8 +1954,7 @@ namespace MWWorld
mRendering->getTriangleBatchCount(triangles, batches);
}
bool
World::isFlying(const MWWorld::Ptr &ptr) const
bool World::isFlying(const MWWorld::Ptr &ptr) const
{
const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
bool isParalyzed = (stats.getMagicEffects().get(ESM::MagicEffect::Paralyze).getMagnitude() > 0);
@ -1978,8 +1979,7 @@ namespace MWWorld
return false;
}
bool
World::isSlowFalling(const MWWorld::Ptr &ptr) const
bool World::isSlowFalling(const MWWorld::Ptr &ptr) const
{
if(!ptr.getClass().isActor())
return false;
@ -1993,27 +1993,21 @@ namespace MWWorld
bool World::isSubmerged(const MWWorld::Ptr &object) const
{
const float neckDeep = 1.85f;
return isUnderwater(object, neckDeep);
return isUnderwater(object, 1.0/mSwimHeightScale);
}
bool
World::isSwimming(const MWWorld::Ptr &object) const
bool World::isSwimming(const MWWorld::Ptr &object) const
{
/// \todo add check ifActor() - only actors can swim
/// \fixme 3/4ths submerged?
return isUnderwater(object, 1.5f);
return isUnderwater(object, mSwimHeightScale);
}
bool
World::isWading(const MWWorld::Ptr &object) const
bool World::isWading(const MWWorld::Ptr &object) const
{
const float kneeDeep = 0.5f;
const float kneeDeep = 0.25f;
return isUnderwater(object, kneeDeep);
}
bool
World::isUnderwater(const MWWorld::Ptr &object, const float heightRatio) const
bool World::isUnderwater(const MWWorld::Ptr &object, const float heightRatio) const
{
const float *fpos = object.getRefData().getPosition().pos;
Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
@ -2021,14 +2015,13 @@ namespace MWWorld
const OEngine::Physic::PhysicActor *actor = mPhysEngine->getCharacter(object.getRefData().getHandle());
if (actor)
{
pos.z += heightRatio*actor->getHalfExtents().z;
pos.z += heightRatio*2*actor->getHalfExtents().z;
}
return isUnderwater(object.getCell(), pos);
}
bool
World::isUnderwater(const MWWorld::CellStore* cell, const Ogre::Vector3 &pos) const
bool World::isUnderwater(const MWWorld::CellStore* cell, const Ogre::Vector3 &pos) const
{
if (!(cell->getCell()->mData.mFlags & ESM::Cell::HasWater)) {
return false;

@ -139,6 +139,7 @@ namespace MWWorld
void loadContentFiles(const Files::Collections& fileCollections,
const std::vector<std::string>& content, ContentLoader& contentLoader);
float mSwimHeightScale;
bool isUnderwater(const MWWorld::Ptr &object, const float heightRatio) const;
///< helper function for implementing isSwimming(), isSubmerged(), isWading()

Loading…
Cancel
Save