mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-11 06:40:34 +00:00
Fix swim height, use fSwimHeightScale GMST
This commit is contained in:
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…
x
Reference in New Issue
Block a user