forked from teamnwah/openmw-tes3coop
Fix swim height, use fSwimHeightScale GMST
This commit is contained in:
parent
57a259c526
commit
c98b7db4c1
3 changed files with 24 additions and 43 deletions
|
@ -303,26 +303,15 @@ namespace MWWorld
|
||||||
Ogre::Vector3 halfExtents = physicActor->getHalfExtents();
|
Ogre::Vector3 halfExtents = physicActor->getHalfExtents();
|
||||||
position.z += halfExtents.z;
|
position.z += halfExtents.z;
|
||||||
|
|
||||||
waterlevel -= halfExtents.z * 0.5;
|
static const float fSwimHeightScale = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
/*
|
.find("fSwimHeightScale")->getFloat();
|
||||||
* A 3/4 submerged example
|
float swimlevel = waterlevel + halfExtents.z - (halfExtents.z * 2 * fSwimHeightScale);
|
||||||
*
|
|
||||||
* +---+
|
|
||||||
* | |
|
|
||||||
* | | <- (original waterlevel)
|
|
||||||
* | |
|
|
||||||
* | | <- position <- waterlevel
|
|
||||||
* | |
|
|
||||||
* | |
|
|
||||||
* | |
|
|
||||||
* +---+ <- (original position)
|
|
||||||
*/
|
|
||||||
|
|
||||||
OEngine::Physic::ActorTracer tracer;
|
OEngine::Physic::ActorTracer tracer;
|
||||||
Ogre::Vector3 inertia = physicActor->getInertialForce();
|
Ogre::Vector3 inertia = physicActor->getInertialForce();
|
||||||
Ogre::Vector3 velocity;
|
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)*
|
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;
|
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;
|
Ogre::Vector3 nextpos = newPosition + velocity * remainingTime;
|
||||||
|
|
||||||
// If not able to fly, don't allow to swim up into the air
|
// 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
|
if(newPosition.z < swimlevel &&
|
||||||
// where the creature gets above the waterline for some reason
|
|
||||||
if(newPosition.z < waterlevel && // started 3/4 under water
|
|
||||||
!isFlying && // can't fly
|
!isFlying && // can't fly
|
||||||
nextpos.z > waterlevel && // but about to go above water
|
nextpos.z > swimlevel && // but about to go above water
|
||||||
newPosition.z <= waterlevel)
|
newPosition.z <= swimlevel)
|
||||||
{
|
{
|
||||||
const Ogre::Vector3 down(0,0,-1);
|
const Ogre::Vector3 down(0,0,-1);
|
||||||
Ogre::Real movelen = velocity.normalise();
|
Ogre::Real movelen = velocity.normalise();
|
||||||
|
@ -423,7 +410,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
// don't let pure water creatures move out of water after stepMove
|
// don't let pure water creatures move out of water after stepMove
|
||||||
if (ptr.getClass().isPureWaterCreature(ptr)
|
if (ptr.getClass().isPureWaterCreature(ptr)
|
||||||
&& newPosition.z > (waterlevel - halfExtents.z * 0.5))
|
&& newPosition.z + halfExtents.z > waterlevel)
|
||||||
newPosition = oldPosition;
|
newPosition = oldPosition;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -444,13 +431,13 @@ namespace MWWorld
|
||||||
|
|
||||||
// Do not allow sliding upward if there is gravity. Stepping will have taken
|
// Do not allow sliding upward if there is gravity. Stepping will have taken
|
||||||
// care of that.
|
// care of that.
|
||||||
if(!(newPosition.z < waterlevel || isFlying))
|
if(!(newPosition.z < swimlevel || isFlying))
|
||||||
velocity.z = std::min(velocity.z, 0.0f);
|
velocity.z = std::min(velocity.z, 0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isOnGround = false;
|
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 from = newPosition;
|
||||||
Ogre::Vector3 to = newPosition - (physicActor->getOnGround() ?
|
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));
|
physicActor->setInertialForce(Ogre::Vector3(0.0f));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -187,6 +187,8 @@ namespace MWWorld
|
||||||
mStore.setUp();
|
mStore.setUp();
|
||||||
mStore.movePlayerRecord();
|
mStore.movePlayerRecord();
|
||||||
|
|
||||||
|
mSwimHeightScale = mStore.get<ESM::GameSetting>().find("fSwimHeightScale")->getFloat();
|
||||||
|
|
||||||
mGlobalVariables.fill (mStore);
|
mGlobalVariables.fill (mStore);
|
||||||
|
|
||||||
mWorldScene = new Scene(*mRendering, mPhysics);
|
mWorldScene = new Scene(*mRendering, mPhysics);
|
||||||
|
@ -1952,8 +1954,7 @@ namespace MWWorld
|
||||||
mRendering->getTriangleBatchCount(triangles, batches);
|
mRendering->getTriangleBatchCount(triangles, batches);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool World::isFlying(const MWWorld::Ptr &ptr) const
|
||||||
World::isFlying(const MWWorld::Ptr &ptr) const
|
|
||||||
{
|
{
|
||||||
const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
|
const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
|
||||||
bool isParalyzed = (stats.getMagicEffects().get(ESM::MagicEffect::Paralyze).getMagnitude() > 0);
|
bool isParalyzed = (stats.getMagicEffects().get(ESM::MagicEffect::Paralyze).getMagnitude() > 0);
|
||||||
|
@ -1978,8 +1979,7 @@ namespace MWWorld
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool World::isSlowFalling(const MWWorld::Ptr &ptr) const
|
||||||
World::isSlowFalling(const MWWorld::Ptr &ptr) const
|
|
||||||
{
|
{
|
||||||
if(!ptr.getClass().isActor())
|
if(!ptr.getClass().isActor())
|
||||||
return false;
|
return false;
|
||||||
|
@ -1993,27 +1993,21 @@ namespace MWWorld
|
||||||
|
|
||||||
bool World::isSubmerged(const MWWorld::Ptr &object) const
|
bool World::isSubmerged(const MWWorld::Ptr &object) const
|
||||||
{
|
{
|
||||||
const float neckDeep = 1.85f;
|
return isUnderwater(object, 1.0/mSwimHeightScale);
|
||||||
return isUnderwater(object, neckDeep);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool World::isSwimming(const MWWorld::Ptr &object) const
|
||||||
World::isSwimming(const MWWorld::Ptr &object) const
|
|
||||||
{
|
{
|
||||||
/// \todo add check ifActor() - only actors can swim
|
return isUnderwater(object, mSwimHeightScale);
|
||||||
/// \fixme 3/4ths submerged?
|
|
||||||
return isUnderwater(object, 1.5f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool World::isWading(const MWWorld::Ptr &object) const
|
||||||
World::isWading(const MWWorld::Ptr &object) const
|
|
||||||
{
|
{
|
||||||
const float kneeDeep = 0.5f;
|
const float kneeDeep = 0.25f;
|
||||||
return isUnderwater(object, kneeDeep);
|
return isUnderwater(object, kneeDeep);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool World::isUnderwater(const MWWorld::Ptr &object, const float heightRatio) const
|
||||||
World::isUnderwater(const MWWorld::Ptr &object, const float heightRatio) const
|
|
||||||
{
|
{
|
||||||
const float *fpos = object.getRefData().getPosition().pos;
|
const float *fpos = object.getRefData().getPosition().pos;
|
||||||
Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
|
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());
|
const OEngine::Physic::PhysicActor *actor = mPhysEngine->getCharacter(object.getRefData().getHandle());
|
||||||
if (actor)
|
if (actor)
|
||||||
{
|
{
|
||||||
pos.z += heightRatio*actor->getHalfExtents().z;
|
pos.z += heightRatio*2*actor->getHalfExtents().z;
|
||||||
}
|
}
|
||||||
|
|
||||||
return isUnderwater(object.getCell(), pos);
|
return isUnderwater(object.getCell(), pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool World::isUnderwater(const MWWorld::CellStore* cell, const Ogre::Vector3 &pos) const
|
||||||
World::isUnderwater(const MWWorld::CellStore* cell, const Ogre::Vector3 &pos) const
|
|
||||||
{
|
{
|
||||||
if (!(cell->getCell()->mData.mFlags & ESM::Cell::HasWater)) {
|
if (!(cell->getCell()->mData.mFlags & ESM::Cell::HasWater)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -139,6 +139,7 @@ namespace MWWorld
|
||||||
void loadContentFiles(const Files::Collections& fileCollections,
|
void loadContentFiles(const Files::Collections& fileCollections,
|
||||||
const std::vector<std::string>& content, ContentLoader& contentLoader);
|
const std::vector<std::string>& content, ContentLoader& contentLoader);
|
||||||
|
|
||||||
|
float mSwimHeightScale;
|
||||||
bool isUnderwater(const MWWorld::Ptr &object, const float heightRatio) const;
|
bool isUnderwater(const MWWorld::Ptr &object, const float heightRatio) const;
|
||||||
///< helper function for implementing isSwimming(), isSubmerged(), isWading()
|
///< helper function for implementing isSwimming(), isSubmerged(), isWading()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue