forked from mirror/openmw-tes3mp
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/containerutil.hpp
|
||||||
mwworld/player.hpp
|
mwworld/player.hpp
|
||||||
mwworld/doingphysics.hpp
|
mwworld/doingphysics.hpp
|
||||||
|
mwworld/cellfunctors.hpp
|
||||||
)
|
)
|
||||||
source_group(apps\\openmw\\mwworld FILES ${GAMEWORLD} ${GAMEWORLD_HEADER})
|
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
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
int DoingPhysics::sCounter = 0;
|
int DoingPhysics::sCounter = 0;
|
||||||
|
int DoingPhysics::sSuppress = 0;
|
||||||
|
|
||||||
DoingPhysics::DoingPhysics()
|
DoingPhysics::DoingPhysics()
|
||||||
{
|
{
|
||||||
|
@ -17,6 +18,16 @@ namespace MWWorld
|
||||||
|
|
||||||
bool DoingPhysics::isDoingPhysics()
|
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
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
///< Scope guard for blocking physics updates during physics simulation.
|
class SuppressDoingPhysics;
|
||||||
|
|
||||||
|
/// Scope guard for blocking physics updates during physics simulation.
|
||||||
class DoingPhysics
|
class DoingPhysics
|
||||||
{
|
{
|
||||||
static int sCounter;
|
static int sCounter;
|
||||||
|
static int sSuppress;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -20,6 +23,23 @@ namespace MWWorld
|
||||||
~DoingPhysics();
|
~DoingPhysics();
|
||||||
|
|
||||||
static bool isDoingPhysics();
|
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 "refdata.hpp"
|
||||||
#include "globals.hpp"
|
#include "globals.hpp"
|
||||||
#include "doingphysics.hpp"
|
#include "doingphysics.hpp"
|
||||||
|
#include "cellfunctors.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -271,6 +272,15 @@ namespace MWWorld
|
||||||
|
|
||||||
void World::unloadCell (CellRenderCollection::iterator iter)
|
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);
|
removeScripts (iter->first);
|
||||||
mEnvironment.mMechanicsManager->dropActors (iter->first);
|
mEnvironment.mMechanicsManager->dropActors (iter->first);
|
||||||
iter->second->destroy();
|
iter->second->destroy();
|
||||||
|
@ -616,6 +626,8 @@ namespace MWWorld
|
||||||
|
|
||||||
void World::changeCell (int X, int Y, const ESM::Position& position)
|
void World::changeCell (int X, int Y, const ESM::Position& position)
|
||||||
{
|
{
|
||||||
|
SuppressDoingPhysics scopeGuard;
|
||||||
|
|
||||||
// remove active
|
// remove active
|
||||||
CellRenderCollection::iterator active = mActiveCells.begin();
|
CellRenderCollection::iterator active = mActiveCells.begin();
|
||||||
|
|
||||||
|
@ -782,13 +794,13 @@ namespace MWWorld
|
||||||
if (mCurrentCell->cell->data.gridX!=cellX || mCurrentCell->cell->data.gridY!=cellY)
|
if (mCurrentCell->cell->data.gridX!=cellX || mCurrentCell->cell->data.gridY!=cellY)
|
||||||
{
|
{
|
||||||
changeCell (cellX, cellY, mPlayer->getPlayer().getCellRef().pos);
|
changeCell (cellX, cellY, mPlayer->getPlayer().getCellRef().pos);
|
||||||
|
}
|
||||||
|
|
||||||
if (!DoingPhysics::isDoingPhysics())
|
if (!DoingPhysics::isDoingPhysics())
|
||||||
mScene.moveObject (ptr.getRefData().getHandle(), Ogre::Vector3 (x, y, z));
|
mScene.moveObject (ptr.getRefData().getHandle(), Ogre::Vector3 (x, y, z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// TODO cell change for non-player ref
|
// TODO cell change for non-player ref
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,48 @@ namespace ESMS
|
||||||
loadRefs(store, esm);
|
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:
|
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)
|
void loadRefs(const ESMStore &store, ESMReader &esm)
|
||||||
{
|
{
|
||||||
assert (cell);
|
assert (cell);
|
||||||
|
|
Loading…
Reference in a new issue