added function to retrieve a live cell ref via name

pull/7/head
Marc Zinnschlag 15 years ago
parent 5786addab5
commit cc0c21cf35

@ -3,6 +3,10 @@
#include "OgreCamera.h"
#include <components/esm_store/cell_store.hpp>
#include "../mwworld/refdata.hpp"
namespace MWRender
{
// This class keeps track of the player position. It takes care of
@ -10,19 +14,22 @@ namespace MWRender
// (to be done).
class PlayerPos
{
float x, y, z;
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> mPlayer;
Ogre::Camera *camera;
public:
PlayerPos(Ogre::Camera *cam) :
x(0), y(0), z(0), camera(cam) {}
PlayerPos(Ogre::Camera *cam, const ESM::NPC *player) :
camera(cam)
{
mPlayer.base = player;
}
// Set the player position. Uses Morrowind coordinates.
void setPos(float _x, float _y, float _z)
{
x = _x;
y = _y;
z = _z;
mPlayer.ref.pos.pos[0] = _x;
mPlayer.ref.pos.pos[1] = _y;
mPlayer.ref.pos.pos[2] = _z;
// TODO: Update sound listener
}
@ -33,6 +40,7 @@ namespace MWRender
// orientation. After the call, the new position is returned.
void moveRel(float &relX, float &relY, float &relZ)
{
// TODO: Update mPlayer state
using namespace Ogre;
// Move camera relative to its own direction
@ -53,6 +61,16 @@ namespace MWRender
// Set the position
setPos(relX, relY, relZ);
}
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *getPlayer()
{
return &mPlayer;
}
const ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *getPlayer() const
{
return &mPlayer;
}
};
}
#endif

@ -23,6 +23,11 @@ namespace MWWorld
Ptr() : mCellRef (0), mRefData (0) {}
bool isEmpty() const
{
return mPtr.empty();
}
template<typename T>
Ptr (ESMS::LiveCellRef<T, RefData> *liveCellRef)
{

@ -56,9 +56,74 @@ namespace MWWorld
listCellScripts (mStore, cell.weapons, mLocalScripts);
}
Ptr World::getPtr (const std::string& name, CellStore& cell)
{
if (ESMS::LiveCellRef<ESM::Activator, RefData> *ref = cell.activators.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::Potion, RefData> *ref = cell.potions.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::Apparatus, RefData> *ref = cell.appas.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::Armor, RefData> *ref = cell.armors.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::Book, RefData> *ref = cell.books.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::Clothing, RefData> *ref = cell.clothes.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::Container, RefData> *ref = cell.containers.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::Creature, RefData> *ref = cell.creatures.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::Door, RefData> *ref = cell.doors.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::Ingredient, RefData> *ref = cell.ingreds.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::CreatureLevList, RefData> *ref = cell.creatureLists.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::ItemLevList, RefData> *ref = cell.itemLists.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::Light, RefData> *ref = cell.lights.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::Tool, RefData> *ref = cell.lockpicks.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::Misc, RefData> *ref = cell.miscItems.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::NPC, RefData> *ref = cell.npcs.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::Tool, RefData> *ref = cell.probes.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::Tool, RefData> *ref = cell.repairs.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::Static, RefData> *ref = cell.statics.find (name))
return ref;
if (ESMS::LiveCellRef<ESM::Weapon, RefData> *ref = cell.weapons.find (name))
return ref;
return Ptr();
}
World::World (Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir,
const std::string& master, const std::string& startCell, bool newGame)
: mSkyManager (0), mScene (renderer), mPlayerPos (mScene.getCamera())
: mSkyManager (0), mScene (renderer), mPlayerPos (0)
{
boost::filesystem::path masterPath (dataDir);
masterPath /= master;
@ -73,6 +138,8 @@ namespace MWWorld
insertInteriorScripts (mInteriors[startCell]);
mPlayerPos = new MWRender::PlayerPos (mScene.getCamera(), mStore.npcs.find ("player"));
// global variables
for (ESMS::RecListT<ESM::Global>::MapType::const_iterator iter
(mStore.globals.list.begin());
@ -114,12 +181,13 @@ namespace MWWorld
iter!=mBufferedCells.end(); ++iter)
delete iter->second;
delete mPlayerPos;
delete mSkyManager;
}
MWRender::PlayerPos& World::getPlayerPos()
{
return mPlayerPos;
return *mPlayerPos;
}
ESMS::ESMStore& World::getStore()
@ -147,4 +215,33 @@ namespace MWWorld
return iter->second;
}
std::pair<Ptr, World::CellStore *> World::getPtr (const std::string& name, bool activeOnly)
{
// the player is always in an active cell.
if (name=="player")
{
// TODO: find real cell (might need to be stored in playerPos). For now we
// use the first active cell. This will fail the moment we move into an
// exterior cell.
return std::make_pair (mPlayerPos->getPlayer(), mActiveCells.begin()->first);
}
// active cells
for (CellRenderCollection::iterator iter (mActiveCells.begin());
iter!=mActiveCells.end(); ++iter)
{
Ptr ptr = getPtr (name, *iter->first);
if (!ptr.isEmpty())
return std::make_pair (ptr, iter->first);
}
if (!activeOnly)
{
// TODO: inactive cells
}
throw std::runtime_error ("unknown ID: " + name);
}
}

@ -36,15 +36,15 @@ namespace MWWorld
public:
typedef std::vector<std::pair<std::string, Ptr> > ScriptList;
typedef ESMS::CellStore<RefData> CellStore;
private:
typedef ESMS::CellStore<RefData> CellStore;
typedef std::map<CellStore *, MWRender::CellRender *> CellRenderCollection;
MWRender::SkyManager* mSkyManager;
MWRender::MWScene mScene;
MWRender::PlayerPos mPlayerPos;
MWRender::PlayerPos *mPlayerPos;
CellRenderCollection mActiveCells;
CellRenderCollection mBufferedCells; // loaded, but not active (buffering not implementd yet)
ESM::ESMReader mEsm;
@ -59,6 +59,8 @@ namespace MWWorld
void insertInteriorScripts (ESMS::CellStore<RefData>& cell);
Ptr getPtr (const std::string& name, CellStore& cellStore);
public:
World (Render::OgreRenderer& renderer, const boost::filesystem::path& master,
@ -77,6 +79,10 @@ namespace MWWorld
///< Has the player moved to a different cell, since the last frame?
Interpreter::Type_Data& getGlobalVariable (const std::string& name);
std::pair<Ptr, CellStore *> getPtr (const std::string& name, bool activeOnly);
///< Return a pointer to a liveCellRef with the given name.
/// \param activeOnly do non search inactive cells.
};
}

@ -63,6 +63,17 @@ namespace ESMS
list.push_back(lr);
}
LiveRef *find (const std::string& name)
{
for (typename std::list<LiveRef>::iterator iter (list.begin()); iter!=list.end(); ++iter)
{
if (iter->ref.refID==name)
return &*iter;
}
return 0;
}
};
/// A storage struct for one single cell reference.

Loading…
Cancel
Save