1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-19 23:23:54 +00:00

Fixed a crash when there were cells with no data, refactored to remove non mutable data from CellStore

This commit is contained in:
Jacob Essex 2012-03-27 09:20:22 +01:00
parent 99b2b6b648
commit b76b62e5e4
7 changed files with 144 additions and 129 deletions

View file

@ -23,7 +23,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
:mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mAmbientMode(0), mDebugging(engine) :mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mAmbientMode(0), mDebugging(engine)
{ {
mRendering.createScene("PlayerCam", 55, 5); mRendering.createScene("PlayerCam", 55, 5);
mTerrainManager = new TerrainManager(mRendering.getScene()); mTerrainManager = new TerrainManager(mRendering.getScene(),
environment);
//The fog type must be set before any terrain objects are created as if the //The fog type must be set before any terrain objects are created as if the
//fog type is set to FOG_NONE then the initially created terrain won't have any fog //fog type is set to FOG_NONE then the initially created terrain won't have any fog

View file

@ -1,12 +1,12 @@
#include <OgreTerrain.h> #include <OgreTerrain.h>
#include <OgreTerrainGroup.h> #include <OgreTerrainGroup.h>
#include <boost/lexical_cast.hpp>
#include "../mwworld/world.hpp"
#include "terrainmaterial.hpp" #include "terrainmaterial.hpp"
#include "terrain.hpp" #include "terrain.hpp"
#include "components/esm/loadland.hpp"
#include <boost/lexical_cast.hpp>
using namespace Ogre; using namespace Ogre;
@ -15,7 +15,8 @@ namespace MWRender
//---------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------
TerrainManager::TerrainManager(SceneManager* mgr) TerrainManager::TerrainManager(Ogre::SceneManager* mgr, const MWWorld::Environment& evn) :
mEnvironment(evn)
{ {
mTerrainGlobals = OGRE_NEW TerrainGlobalOptions(); mTerrainGlobals = OGRE_NEW TerrainGlobalOptions();
@ -102,6 +103,12 @@ namespace MWRender
const int cellX = store->cell->getGridX(); const int cellX = store->cell->getGridX();
const int cellY = store->cell->getGridY(); const int cellY = store->cell->getGridY();
ESM::Land* land = mEnvironment.mWorld->getStore().lands.search(cellX, cellY);
if ( land != NULL )
{
land->loadData();
}
//split the cell terrain into four segments //split the cell terrain into four segments
const int numTextures = ESM::Land::LAND_TEXTURE_SIZE/2; const int numTextures = ESM::Land::LAND_TEXTURE_SIZE/2;
@ -122,6 +129,8 @@ namespace MWRender
mLandSize*mLandSize, mLandSize*mLandSize,
MEMCATEGORY_GEOMETRY); MEMCATEGORY_GEOMETRY);
if ( land != NULL )
{
//copy the height data row by row //copy the height data row by row
for ( int terrainCopyY = 0; terrainCopyY < mLandSize; terrainCopyY++ ) for ( int terrainCopyY = 0; terrainCopyY < mLandSize; terrainCopyY++ )
{ {
@ -132,12 +141,17 @@ namespace MWRender
const size_t xOffset = x * (mLandSize-1); const size_t xOffset = x * (mLandSize-1);
memcpy(&terrainData.inputFloat[terrainCopyY*mLandSize], memcpy(&terrainData.inputFloat[terrainCopyY*mLandSize],
&store->land[1][1]->landData->heights[yOffset + xOffset], &land->landData->heights[yOffset + xOffset],
mLandSize*sizeof(float)); mLandSize*sizeof(float));
} }
}
else
{
memset(terrainData.inputFloat, 0, mLandSize*mLandSize*sizeof(float));
}
std::map<uint16_t, int> indexes; std::map<uint16_t, int> indexes;
initTerrainTextures(&terrainData, store, initTerrainTextures(&terrainData, cellX, cellY,
x * numTextures, y * numTextures, x * numTextures, y * numTextures,
numTextures, indexes); numTextures, indexes);
@ -148,16 +162,18 @@ namespace MWRender
mTerrainGroup->loadTerrain(terrainX, terrainY, true); mTerrainGroup->loadTerrain(terrainX, terrainY, true);
Terrain* terrain = mTerrainGroup->getTerrain(terrainX, terrainY); Terrain* terrain = mTerrainGroup->getTerrain(terrainX, terrainY);
initTerrainBlendMaps(terrain, store, initTerrainBlendMaps(terrain,
cellX, cellY,
x * numTextures, y * numTextures, x * numTextures, y * numTextures,
numTextures, numTextures,
indexes); indexes);
if ( store->land[1][1]->landData->usingColours ) if ( land->landData->usingColours )
{ {
// disable or enable global colour map (depends on available vertex colours) // disable or enable global colour map (depends on available vertex colours)
mActiveProfile->setGlobalColourMapEnabled(true); mActiveProfile->setGlobalColourMapEnabled(true);
TexturePtr vertex = getVertexColours(store, TexturePtr vertex = getVertexColours(land,
cellX, cellY,
x*(mLandSize-1), x*(mLandSize-1),
y*(mLandSize-1), y*(mLandSize-1),
mLandSize); mLandSize);
@ -197,11 +213,10 @@ namespace MWRender
//---------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------
void TerrainManager::initTerrainTextures(Terrain::ImportData* terrainData, void TerrainManager::initTerrainTextures(Terrain::ImportData* terrainData,
MWWorld::Ptr::CellStore* store, int cellX, int cellY,
int fromX, int fromY, int size, int fromX, int fromY, int size,
std::map<uint16_t, int>& indexes) std::map<uint16_t, int>& indexes)
{ {
assert(store != NULL && "store must be a valid pointer");
assert(terrainData != NULL && "Must have valid terrain data"); assert(terrainData != NULL && "Must have valid terrain data");
assert(fromX >= 0 && fromY >= 0 && assert(fromX >= 0 && fromY >= 0 &&
"Can't get a terrain texture on terrain outside the current cell"); "Can't get a terrain texture on terrain outside the current cell");
@ -219,7 +234,7 @@ namespace MWRender
{ {
for ( int x = fromX - 1; x < fromX + size + 1; x++ ) for ( int x = fromX - 1; x < fromX + size + 1; x++ )
{ {
ltexIndexes.insert(getLtexIndexAt(store, x, y)); ltexIndexes.insert(getLtexIndexAt(cellX, cellY, x, y));
} }
} }
@ -244,7 +259,7 @@ namespace MWRender
{ {
//NB: All vtex ids are +1 compared to the ltex ids //NB: All vtex ids are +1 compared to the ltex ids
assert( (int)store->landTextures->ltex.size() >= (int)ltexIndex - 1 && assert( (int)mEnvironment.mWorld->getStore().landTexts.getSize() >= (int)ltexIndex - 1 &&
"LAND.VTEX must be within the bounds of the LTEX array"); "LAND.VTEX must be within the bounds of the LTEX array");
std::string texture; std::string texture;
@ -254,7 +269,7 @@ namespace MWRender
} }
else else
{ {
texture = store->landTextures->ltex[ltexIndex-1].texture; texture = mEnvironment.mWorld->getStore().landTexts.search(ltexIndex-1)->texture;
//TODO this is needed due to MWs messed up texture handling //TODO this is needed due to MWs messed up texture handling
texture = texture.substr(0, texture.rfind(".")) + ".dds"; texture = texture.substr(0, texture.rfind(".")) + ".dds";
} }
@ -280,11 +295,10 @@ namespace MWRender
//---------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------
void TerrainManager::initTerrainBlendMaps(Terrain* terrain, void TerrainManager::initTerrainBlendMaps(Terrain* terrain,
MWWorld::Ptr::CellStore* store, int cellX, int cellY,
int fromX, int fromY, int size, int fromX, int fromY, int size,
const std::map<uint16_t, int>& indexes) const std::map<uint16_t, int>& indexes)
{ {
assert(store != NULL && "store must be a valid pointer");
assert(terrain != NULL && "Must have valid terrain"); assert(terrain != NULL && "Must have valid terrain");
assert(fromX >= 0 && fromY >= 0 && assert(fromX >= 0 && fromY >= 0 &&
"Can't get a terrain texture on terrain outside the current cell"); "Can't get a terrain texture on terrain outside the current cell");
@ -313,7 +327,7 @@ namespace MWRender
{ {
for ( int texX = fromX - 1; texX < fromX + size + 1; texX++ ) for ( int texX = fromX - 1; texX < fromX + size + 1; texX++ )
{ {
const uint16_t ltexIndex = getLtexIndexAt(store, texX, texY); const uint16_t ltexIndex = getLtexIndexAt(cellX, cellY, texX, texY);
//check if it is the base texture (which isn't in the map) and //check if it is the base texture (which isn't in the map) and
//if it is don't bother altering the blend map for it //if it is don't bother altering the blend map for it
@ -332,8 +346,10 @@ namespace MWRender
float* const pBlend = terrain->getLayerBlendMap(layerIndex) float* const pBlend = terrain->getLayerBlendMap(layerIndex)
->getBlendPointer(); ->getBlendPointer();
for ( int y = -1; y < splatSize + 1; y++ ){ for ( int y = -1; y < splatSize + 1; y++ )
for ( int x = -1; x < splatSize + 1; x++ ){ {
for ( int x = -1; x < splatSize + 1; x++ )
{
//Note: Y is reversed //Note: Y is reversed
const int splatY = blendMapSize - 1 - relY * splatSize - y; const int splatY = blendMapSize - 1 - relY * splatSize - y;
@ -373,7 +389,7 @@ namespace MWRender
//---------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------
int TerrainManager::getLtexIndexAt(MWWorld::Ptr::CellStore* store, int TerrainManager::getLtexIndexAt(int cellX, int cellY,
int x, int y) int x, int y)
{ {
//check texture index falls within the 9 cell bounds //check texture index falls within the 9 cell bounds
@ -386,12 +402,6 @@ namespace MWRender
y < 2*ESM::Land::LAND_TEXTURE_SIZE && y < 2*ESM::Land::LAND_TEXTURE_SIZE &&
"Trying to get land textures that are out of bounds"); "Trying to get land textures that are out of bounds");
assert(store != NULL && "Store pointer must be valid");
//default center cell is indexed at (1,1)
int cellX = 1;
int cellY = 1;
if ( x < 0 ) if ( x < 0 )
{ {
cellX--; cellX--;
@ -414,22 +424,32 @@ namespace MWRender
y -= ESM::Land::LAND_TEXTURE_SIZE; y -= ESM::Land::LAND_TEXTURE_SIZE;
} }
return store->land[cellX][cellY]
->landData ESM::Land* land = mEnvironment.mWorld->getStore().lands.search(cellX, cellY);
if ( land != NULL )
{
land->loadData();
return land->landData
->textures[y * ESM::Land::LAND_TEXTURE_SIZE + x]; ->textures[y * ESM::Land::LAND_TEXTURE_SIZE + x];
} }
else
{
return 0;
}
}
//---------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------
TexturePtr TerrainManager::getVertexColours(MWWorld::Ptr::CellStore* store, TexturePtr TerrainManager::getVertexColours(ESM::Land* land,
int cellX, int cellY,
int fromX, int fromY, int size) int fromX, int fromY, int size)
{ {
TextureManager* const texMgr = TextureManager::getSingletonPtr(); TextureManager* const texMgr = TextureManager::getSingletonPtr();
const std::string colourTextureName = "VtexColours_" + const std::string colourTextureName = "VtexColours_" +
boost::lexical_cast<std::string>(store->cell->getGridX()) + boost::lexical_cast<std::string>(cellX) +
"_" + "_" +
boost::lexical_cast<std::string>(store->cell->getGridY()) + boost::lexical_cast<std::string>(cellY) +
"_" + "_" +
boost::lexical_cast<std::string>(fromX) + boost::lexical_cast<std::string>(fromX) +
"_" + "_" +
@ -452,14 +472,16 @@ namespace MWRender
uint8* pDest = static_cast<uint8*>(pixelBox.data); uint8* pDest = static_cast<uint8*>(pixelBox.data);
const char* const colours = store->land[1][1]->landData->colours; if ( land != NULL )
{
const char* const colours = land->landData->colours;
for ( int y = 0; y < size; y++ ) for ( int y = 0; y < size; y++ )
{ {
for ( int x = 0; x < size; x++ ) for ( int x = 0; x < size; x++ )
{ {
const size_t colourOffset = (y+fromY)*3*65 + (x+fromX)*3; const size_t colourOffset = (y+fromY)*3*65 + (x+fromX)*3;
assert( colourOffset >= 0 && colourOffset < 65*65*3 && assert( colourOffset < 65*65*3 &&
"Colour offset is out of the expected bounds of record" ); "Colour offset is out of the expected bounds of record" );
const unsigned char r = colours[colourOffset + 0]; const unsigned char r = colours[colourOffset + 0];
@ -473,6 +495,20 @@ namespace MWRender
pDest[imageOffset + 2] = r; pDest[imageOffset + 2] = r;
} }
} }
}
else
{
for ( int y = 0; y < size; y++ )
{
for ( int x = 0; x < size; x++ )
{
for ( int k = 0; k < 3; k++ )
{
*pDest++ = 0;
}
}
}
}
pixelBuffer->unlock(); pixelBuffer->unlock();

View file

@ -23,7 +23,7 @@ namespace MWRender{
*/ */
class TerrainManager{ class TerrainManager{
public: public:
TerrainManager(Ogre::SceneManager*); TerrainManager(Ogre::SceneManager* mgr, const MWWorld::Environment& env);
virtual ~TerrainManager(); virtual ~TerrainManager();
void setDiffuse(const Ogre::ColourValue& diffuse); void setDiffuse(const Ogre::ColourValue& diffuse);
@ -35,6 +35,8 @@ namespace MWRender{
Ogre::TerrainGlobalOptions* mTerrainGlobals; Ogre::TerrainGlobalOptions* mTerrainGlobals;
Ogre::TerrainGroup* mTerrainGroup; Ogre::TerrainGroup* mTerrainGroup;
const MWWorld::Environment& mEnvironment;
Ogre::TerrainMaterialGeneratorB::SM2Profile* mActiveProfile; Ogre::TerrainMaterialGeneratorB::SM2Profile* mActiveProfile;
/** /**
@ -53,7 +55,8 @@ namespace MWRender{
* layer * layer
* *
* @param terrainData the terrain data to setup the textures for * @param terrainData the terrain data to setup the textures for
* @param store the cell store for the given terrain cell * @param cellX the coord of the cell
* @param cellY the coord of the cell
* @param fromX the ltex index in the current cell to start making the texture from * @param fromX the ltex index in the current cell to start making the texture from
* @param fromY the ltex index in the current cell to start making the texture from * @param fromY the ltex index in the current cell to start making the texture from
* @param size the size (number of splats) to get * @param size the size (number of splats) to get
@ -61,7 +64,7 @@ namespace MWRender{
* can be used by initTerrainBlendMaps * can be used by initTerrainBlendMaps
*/ */
void initTerrainTextures(Ogre::Terrain::ImportData* terrainData, void initTerrainTextures(Ogre::Terrain::ImportData* terrainData,
MWWorld::Ptr::CellStore* store, int cellX, int cellY,
int fromX, int fromY, int size, int fromX, int fromY, int size,
std::map<uint16_t, int>& indexes); std::map<uint16_t, int>& indexes);
@ -69,14 +72,15 @@ namespace MWRender{
* Creates the blend (splatting maps) for the given terrain from the ltex data. * Creates the blend (splatting maps) for the given terrain from the ltex data.
* *
* @param terrain the terrain object for the current cell * @param terrain the terrain object for the current cell
* @param store the cell store for the given terrain cell * @param cellX the coord of the cell
* @param cellY the coord of the cell
* @param fromX the ltex index in the current cell to start making the texture from * @param fromX the ltex index in the current cell to start making the texture from
* @param fromY the ltex index in the current cell to start making the texture from * @param fromY the ltex index in the current cell to start making the texture from
* @param size the size (number of splats) to get * @param size the size (number of splats) to get
* @param indexes the mapping of ltex to blend map produced by initTerrainTextures * @param indexes the mapping of ltex to blend map produced by initTerrainTextures
*/ */
void initTerrainBlendMaps(Ogre::Terrain* terrain, void initTerrainBlendMaps(Ogre::Terrain* terrain,
MWWorld::Ptr::CellStore* store, int cellX, int cellY,
int fromX, int fromY, int size, int fromX, int fromY, int size,
const std::map<uint16_t, int>& indexes); const std::map<uint16_t, int>& indexes);
@ -85,22 +89,25 @@ namespace MWRender{
* starts at (0,0). This supports getting values from the surrounding * starts at (0,0). This supports getting values from the surrounding
* cells so negative x, y is acceptable * cells so negative x, y is acceptable
* *
* @param store the cell store for the current cell * @param cellX the coord of the cell
* @param cellY the coord of the cell
* @param x, y the splat position of the ltex index to get relative to the * @param x, y the splat position of the ltex index to get relative to the
* first splat of the current cell * first splat of the current cell
*/ */
int getLtexIndexAt(MWWorld::Ptr::CellStore* store, int x, int y); int getLtexIndexAt(int cellX, int cellY, int x, int y);
/** /**
* Due to the fact that Ogre terrain doesn't support vertex colours * Due to the fact that Ogre terrain doesn't support vertex colours
* we have to generate them manually * we have to generate them manually
* *
* @param store the cell store for the given terrain cell * @param cellX the coord of the cell
* @param cellY the coord of the cell
* @param fromX the *vertex* index in the current cell to start making texture from * @param fromX the *vertex* index in the current cell to start making texture from
* @param fromY the *vertex* index in the current cell to start making the texture from * @param fromY the *vertex* index in the current cell to start making the texture from
* @param size the size (number of vertexes) to get * @param size the size (number of vertexes) to get
*/ */
Ogre::TexturePtr getVertexColours(MWWorld::Ptr::CellStore* store, Ogre::TexturePtr getVertexColours(ESM::Land* land,
int cellX, int cellY,
int fromX, int fromY, int size); int fromX, int fromY, int size);
}; };

View file

@ -4,6 +4,8 @@ namespace ESM
{ {
void Land::load(ESMReader &esm) void Land::load(ESMReader &esm)
{ {
mEsm = &esm;
// Get the grid location // Get the grid location
esm.getSubNameIs("INTV"); esm.getSubNameIs("INTV");
esm.getSubHeaderIs(8); esm.getSubHeaderIs(8);
@ -51,7 +53,7 @@ void Land::load(ESMReader &esm)
landData = NULL; landData = NULL;
} }
void Land::loadData(ESMReader &esm) void Land::loadData()
{ {
if (dataLoaded) if (dataLoaded)
{ {
@ -62,17 +64,17 @@ void Land::loadData(ESMReader &esm)
if (hasData) if (hasData)
{ {
esm.restoreContext(context); mEsm->restoreContext(context);
//esm.getHNExact(landData->normals, sizeof(VNML), "VNML"); //esm.getHNExact(landData->normals, sizeof(VNML), "VNML");
if (esm.isNextSub("VNML")) if (mEsm->isNextSub("VNML"))
{ {
esm.skipHSubSize(12675); mEsm->skipHSubSize(12675);
} }
VHGT rawHeights; VHGT rawHeights;
esm.getHNExact(&rawHeights, sizeof(VHGT), "VHGT"); mEsm->getHNExact(&rawHeights, sizeof(VHGT), "VHGT");
int currentHeightOffset = rawHeights.heightOffset; int currentHeightOffset = rawHeights.heightOffset;
for (int y = 0; y < LAND_SIZE; y++) for (int y = 0; y < LAND_SIZE; y++)
{ {
@ -87,20 +89,20 @@ void Land::loadData(ESMReader &esm)
} }
} }
if (esm.isNextSub("WNAM")) if (mEsm->isNextSub("WNAM"))
{ {
esm.skipHSubSize(81); mEsm->skipHSubSize(81);
} }
if (esm.isNextSub("VCLR")) if (mEsm->isNextSub("VCLR"))
{ {
landData->usingColours = true; landData->usingColours = true;
esm.getHExact(&landData->colours, 3*LAND_NUM_VERTS); mEsm->getHExact(&landData->colours, 3*LAND_NUM_VERTS);
}else{ }else{
landData->usingColours = false; landData->usingColours = false;
} }
//TODO fix magic numbers //TODO fix magic numbers
uint16_t vtex[512]; uint16_t vtex[512];
esm.getHNExact(&vtex, 512, "VTEX"); mEsm->getHNExact(&vtex, 512, "VTEX");
int readPos = 0; //bit ugly, but it works int readPos = 0; //bit ugly, but it works
for ( int y1 = 0; y1 < 4; y1++ ) for ( int y1 = 0; y1 < 4; y1++ )

View file

@ -17,6 +17,7 @@ struct Land
// File context. This allows the ESM reader to be 'reset' to this // File context. This allows the ESM reader to be 'reset' to this
// location later when we are ready to load the full data set. // location later when we are ready to load the full data set.
ESMReader* mEsm;
ESM_Context context; ESM_Context context;
bool hasData; bool hasData;
@ -70,7 +71,7 @@ struct Land
/** /**
* Actually loads data * Actually loads data
*/ */
void loadData(ESMReader &esm); void loadData();
/** /**
* Frees memory allocated for land data * Frees memory allocated for land data

View file

@ -124,9 +124,6 @@ namespace ESMS
CellRefList<Static, D> statics; CellRefList<Static, D> statics;
CellRefList<Weapon, D> weapons; CellRefList<Weapon, D> weapons;
const Land* land[3][3];
const LTexList* landTextures;
void load (const ESMStore &store, ESMReader &esm) void load (const ESMStore &store, ESMReader &esm)
{ {
if (mState!=State_Loaded) if (mState!=State_Loaded)
@ -138,21 +135,6 @@ namespace ESMS
loadRefs (store, esm); loadRefs (store, esm);
if ( ! (cell->data.flags & ESM::Cell::Interior) )
{
for ( size_t x = 0; x < 3; x++ )
{
for ( size_t y = 0; y < 3; y++ )
{
land[x][y] = loadTerrain(cell->data.gridX + x - 1,
cell->data.gridY + y - 1,
store,
esm);
}
}
landTextures = &store.landTexts;
}
mState = State_Loaded; mState = State_Loaded;
} }
} }
@ -198,24 +180,6 @@ namespace ESMS
private: private:
Land* loadTerrain(int X, int Y, const ESMStore &store, ESMReader &esm)
{
// load terrain
Land *land = store.lands.search(X, Y);
if (land != NULL)
{
land->loadData(esm);
}
return land;
}
void unloadTerrain(int X, int Y, const ESMStore &store) {
assert (false &&
"This function is not implemented due to the fact that we now store overlapping land blocks so" &&
"we cannot be sure that the land segment is not being used by another CellStore");
}
template<class Functor, class List> template<class Functor, class List>
bool forEachImp (Functor& functor, List& list) bool forEachImp (Functor& functor, List& list)
{ {

View file

@ -201,15 +201,21 @@ namespace ESMS
// TODO: For multiple ESM/ESP files we need one list per file. // TODO: For multiple ESM/ESP files we need one list per file.
std::vector<LandTexture> ltex; std::vector<LandTexture> ltex;
int count;
LTexList() : count(0) LTexList()
{ {
// More than enough to hold Morrowind.esm. // More than enough to hold Morrowind.esm.
ltex.reserve(128); ltex.reserve(128);
} }
int getSize() { return count; } const LandTexture* search(size_t index) const
{
assert(index < ltex.size());
return &ltex.at(index);
}
int getSize() { return ltex.size(); }
int getSize() const { return ltex.size(); }
virtual void listIdentifier (std::vector<std::string>& identifier) const {} virtual void listIdentifier (std::vector<std::string>& identifier) const {}
@ -236,9 +242,9 @@ namespace ESMS
virtual ~LandList() {} virtual ~LandList() {}
// Map containing all landscapes // Map containing all landscapes
typedef std::map<int, Land*> LandsCol; typedef std::pair<int, int> LandCoord;
typedef std::map<int, LandsCol> Lands; typedef std::map<LandCoord, Land*> LandMap;
Lands lands; LandMap lands;
int count; int count;
LandList() : count(0) {} LandList() : count(0) {}
@ -249,15 +255,13 @@ namespace ESMS
// Find land for the given coordinates. Return null if no data. // Find land for the given coordinates. Return null if no data.
Land *search(int x, int y) const Land *search(int x, int y) const
{ {
Lands::const_iterator it = lands.find(x); LandMap::const_iterator itr = lands.find(std::make_pair<int, int>(x, y));
if(it==lands.end()) if ( itr == lands.end() )
{
return NULL; return NULL;
}
LandsCol::const_iterator it2 = it->second.find(y); return itr->second;
if(it2 == it->second.end())
return NULL;
return it2->second;
} }
void load(ESMReader &esm, const std::string &id) void load(ESMReader &esm, const std::string &id)
@ -266,11 +270,11 @@ namespace ESMS
// Create the structure and load it. This actually skips the // Create the structure and load it. This actually skips the
// landscape data and remembers the file position for later. // landscape data and remembers the file position for later.
Land *land = new Land; Land *land = new Land();
land->load(esm); land->load(esm);
// Store the structure // Store the structure
lands[land->X][land->Y] = land; lands[std::make_pair<int, int>(land->X, land->Y)] = land;
} }
}; };