mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-20 06:23:52 +00:00
Merge pull request #2667 from Capostrophic/infinitefall
Add an infinite fall failsafe (feature 1415)
This commit is contained in:
commit
3bbd32fe98
3 changed files with 28 additions and 3 deletions
|
@ -198,6 +198,7 @@
|
|||
Bug #5261: Creatures can sometimes become stuck playing idles and never wander again
|
||||
Bug #5269: Editor: Cell lighting in resaved cleaned content files is corrupted
|
||||
Bug #5278: Console command Show doesn't fall back to global variable after local var not found
|
||||
Feature #1415: Infinite fall failsafe
|
||||
Feature #1774: Handle AvoidNode
|
||||
Feature #2229: Improve pathfinding AI
|
||||
Feature #3025: Analogue gamepad movement controls
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "../mwphysics/object.hpp"
|
||||
#include "../mwphysics/heightfield.hpp"
|
||||
|
||||
#include "actionteleport.hpp"
|
||||
#include "player.hpp"
|
||||
#include "localscripts.hpp"
|
||||
#include "esmstore.hpp"
|
||||
|
@ -255,12 +256,22 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
struct AdjustPositionVisitor
|
||||
struct PositionVisitor
|
||||
{
|
||||
float mLowestPos = std::numeric_limits<float>::max();
|
||||
|
||||
bool operator() (const MWWorld::Ptr& ptr)
|
||||
{
|
||||
if (!ptr.getRefData().isDeleted() && ptr.getRefData().isEnabled())
|
||||
{
|
||||
if (!ptr.getClass().isActor())
|
||||
{
|
||||
float objectPosZ = ptr.getRefData().getPosition().pos[2];
|
||||
if (objectPosZ < mLowestPos)
|
||||
mLowestPos = objectPosZ;
|
||||
}
|
||||
ptr.getClass().adjustPosition (ptr, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -487,6 +498,16 @@ namespace MWWorld
|
|||
const auto player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
navigator->update(player.getRefData().getPosition().asVec3());
|
||||
|
||||
const float fallThreshold = 90.f;
|
||||
if (mCurrentCell && !mCurrentCell->isExterior() && pos.z() < mLowestPos - fallThreshold)
|
||||
{
|
||||
ESM::Position newPos;
|
||||
std::string cellName = mCurrentCell->getCell()->mName;
|
||||
MWBase::Environment::get().getWorld()->findInteriorPosition(cellName, newPos);
|
||||
if (newPos.pos[2] >= mLowestPos - fallThreshold)
|
||||
MWWorld::ActionTeleport(cellName, newPos, false).execute(player);
|
||||
}
|
||||
|
||||
if (!mCurrentCell || !mCurrentCell->isExterior())
|
||||
return;
|
||||
|
||||
|
@ -877,8 +898,10 @@ namespace MWWorld
|
|||
insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, *mPhysics, mNavigator); });
|
||||
|
||||
// do adjustPosition (snapping actors to ground) after objects are loaded, so we don't depend on the loading order
|
||||
AdjustPositionVisitor adjustPosVisitor;
|
||||
cell.forEach (adjustPosVisitor);
|
||||
// Also note the lowest object position in the cell to allow infinite fall fail safe to work
|
||||
PositionVisitor posVisitor;
|
||||
cell.forEach (posVisitor);
|
||||
mLowestPos = posVisitor.mLowestPos;
|
||||
}
|
||||
|
||||
void Scene::addObjectToScene (const Ptr& ptr)
|
||||
|
|
|
@ -84,6 +84,7 @@ namespace MWWorld
|
|||
float mPredictionTime;
|
||||
|
||||
osg::Vec3f mLastPlayerPos;
|
||||
float mLowestPos;
|
||||
|
||||
void insertCell (CellStore &cell, Loading::Listener* loadingListener, bool test = false);
|
||||
|
||||
|
|
Loading…
Reference in a new issue