mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-20 17:09:40 +00:00
handle physics during player changing cells
This commit is contained in:
parent
5486c70edf
commit
6a14ea8ec3
6 changed files with 121 additions and 5 deletions
|
@ -145,6 +145,7 @@ set(GAMEWORLD_HEADER
|
|||
mwworld/containerutil.hpp
|
||||
mwworld/player.hpp
|
||||
mwworld/doingphysics.hpp
|
||||
mwworld/cellfunctors.hpp
|
||||
)
|
||||
source_group(apps\\openmw\\mwworld FILES ${GAMEWORLD} ${GAMEWORLD_HEADER})
|
||||
|
||||
|
|
31
apps/openmw/mwworld/cellfunctors.hpp
Normal file
31
apps/openmw/mwworld/cellfunctors.hpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef GAME_MWWORLD_CELLFUNCTORS_H
|
||||
#define GAME_MWWORLD_CELLFUNCTORS_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "refdata.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
class CellRef;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
/// List all (Ogre-)handles.
|
||||
struct ListHandles
|
||||
{
|
||||
std::vector<std::string> mHandles;
|
||||
|
||||
bool operator() (ESM::CellRef& ref, RefData& data)
|
||||
{
|
||||
std::string handle = data.getHandle();
|
||||
if (!handle.empty())
|
||||
mHandles.push_back (handle);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -4,6 +4,7 @@
|
|||
namespace MWWorld
|
||||
{
|
||||
int DoingPhysics::sCounter = 0;
|
||||
int DoingPhysics::sSuppress = 0;
|
||||
|
||||
DoingPhysics::DoingPhysics()
|
||||
{
|
||||
|
@ -17,6 +18,16 @@ namespace MWWorld
|
|||
|
||||
bool DoingPhysics::isDoingPhysics()
|
||||
{
|
||||
return sCounter>0;
|
||||
return sCounter>0 || sSuppress>0;
|
||||
}
|
||||
|
||||
SuppressDoingPhysics::SuppressDoingPhysics()
|
||||
{
|
||||
++DoingPhysics::sSuppress;
|
||||
}
|
||||
|
||||
SuppressDoingPhysics::~SuppressDoingPhysics()
|
||||
{
|
||||
--DoingPhysics::sSuppress;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,13 @@
|
|||
|
||||
namespace MWWorld
|
||||
{
|
||||
///< Scope guard for blocking physics updates during physics simulation.
|
||||
class SuppressDoingPhysics;
|
||||
|
||||
/// Scope guard for blocking physics updates during physics simulation.
|
||||
class DoingPhysics
|
||||
{
|
||||
static int sCounter;
|
||||
static int sSuppress;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -20,6 +23,23 @@ namespace MWWorld
|
|||
~DoingPhysics();
|
||||
|
||||
static bool isDoingPhysics();
|
||||
|
||||
friend class SuppressDoingPhysics;
|
||||
};
|
||||
|
||||
/// Scope guard for temporarily lifting the block issues by DoingPhysics
|
||||
class SuppressDoingPhysics
|
||||
{
|
||||
private:
|
||||
|
||||
SuppressDoingPhysics (const SuppressDoingPhysics&);
|
||||
SuppressDoingPhysics& operator= (const SuppressDoingPhysics&);
|
||||
|
||||
public:
|
||||
|
||||
SuppressDoingPhysics();
|
||||
|
||||
~SuppressDoingPhysics();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "refdata.hpp"
|
||||
#include "globals.hpp"
|
||||
#include "doingphysics.hpp"
|
||||
#include "cellfunctors.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -271,6 +272,15 @@ namespace MWWorld
|
|||
|
||||
void World::unloadCell (CellRenderCollection::iterator iter)
|
||||
{
|
||||
ListHandles functor;
|
||||
iter->first->forEach (functor);
|
||||
|
||||
{ // silence annoying g++ warning
|
||||
for (std::vector<std::string>::const_iterator iter (functor.mHandles.begin());
|
||||
iter!=functor.mHandles.end(); ++iter)
|
||||
mScene.removeObject (*iter);
|
||||
}
|
||||
|
||||
removeScripts (iter->first);
|
||||
mEnvironment.mMechanicsManager->dropActors (iter->first);
|
||||
iter->second->destroy();
|
||||
|
@ -616,6 +626,8 @@ namespace MWWorld
|
|||
|
||||
void World::changeCell (int X, int Y, const ESM::Position& position)
|
||||
{
|
||||
SuppressDoingPhysics scopeGuard;
|
||||
|
||||
// remove active
|
||||
CellRenderCollection::iterator active = mActiveCells.begin();
|
||||
|
||||
|
@ -782,10 +794,10 @@ namespace MWWorld
|
|||
if (mCurrentCell->cell->data.gridX!=cellX || mCurrentCell->cell->data.gridY!=cellY)
|
||||
{
|
||||
changeCell (cellX, cellY, mPlayer->getPlayer().getCellRef().pos);
|
||||
|
||||
if (!DoingPhysics::isDoingPhysics())
|
||||
mScene.moveObject (ptr.getRefData().getHandle(), Ogre::Vector3 (x, y, z));
|
||||
}
|
||||
|
||||
if (!DoingPhysics::isDoingPhysics())
|
||||
mScene.moveObject (ptr.getRefData().getHandle(), Ogre::Vector3 (x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,7 +133,48 @@ namespace ESMS
|
|||
loadRefs(store, esm);
|
||||
}
|
||||
|
||||
/// Call functor (ref) for each reference. functor must return a bool. Returning
|
||||
/// false will abort the iteration.
|
||||
/// \return Iteration completed?
|
||||
template<class Functor>
|
||||
bool forEach (Functor& functor)
|
||||
{
|
||||
return
|
||||
forEachImp (functor, activators) &&
|
||||
forEachImp (functor, potions) &&
|
||||
forEachImp (functor, appas) &&
|
||||
forEachImp (functor, armors) &&
|
||||
forEachImp (functor, books) &&
|
||||
forEachImp (functor, clothes) &&
|
||||
forEachImp (functor, containers) &&
|
||||
forEachImp (functor, creatures) &&
|
||||
forEachImp (functor, doors) &&
|
||||
forEachImp (functor, ingreds) &&
|
||||
forEachImp (functor, creatureLists) &&
|
||||
forEachImp (functor, itemLists) &&
|
||||
forEachImp (functor, lights) &&
|
||||
forEachImp (functor, lockpicks) &&
|
||||
forEachImp (functor, miscItems) &&
|
||||
forEachImp (functor, npcs) &&
|
||||
forEachImp (functor, probes) &&
|
||||
forEachImp (functor, repairs) &&
|
||||
forEachImp (functor, statics) &&
|
||||
forEachImp (functor, weapons);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template<class Functor, class List>
|
||||
bool forEachImp (Functor& functor, List& list)
|
||||
{
|
||||
for (typename List::List::iterator iter (list.list.begin()); iter!=list.list.end();
|
||||
++iter)
|
||||
if (!functor (iter->ref, iter->mData))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void loadRefs(const ESMStore &store, ESMReader &esm)
|
||||
{
|
||||
assert (cell);
|
||||
|
|
Loading…
Reference in a new issue