1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-03-31 04:36:40 +00:00

properly handle cells that don't exist

This commit is contained in:
Marc Zinnschlag 2015-10-15 14:46:08 +02:00
parent 773df6fd22
commit 361634489e
3 changed files with 73 additions and 34 deletions

View file

@ -51,8 +51,9 @@ bool CSVRender::Cell::addObjects (int start, int end)
return modified; return modified;
} }
CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id) CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id,
: mData (data), mId (Misc::StringUtils::lowerCase (id)) bool deleted)
: mData (data), mId (Misc::StringUtils::lowerCase (id)), mDeleted (deleted)
{ {
std::pair<CSMWorld::CellCoordinates, bool> result = CSMWorld::CellCoordinates::fromId (id); std::pair<CSMWorld::CellCoordinates, bool> result = CSMWorld::CellCoordinates::fromId (id);
@ -62,24 +63,27 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::st
mCellNode = new osg::Group; mCellNode = new osg::Group;
rootNode->addChild(mCellNode); rootNode->addChild(mCellNode);
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> ( if (!mDeleted)
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
int rows = references.rowCount();
addObjects (0, rows-1);
const CSMWorld::IdCollection<CSMWorld::Land>& land = mData.getLand();
int landIndex = land.searchId(mId);
if (landIndex != -1)
{ {
const ESM::Land& esmLand = land.getRecord(mId).get(); CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
if (esmLand.getLandData (ESM::Land::DATA_VHGT)) int rows = references.rowCount();
addObjects (0, rows-1);
const CSMWorld::IdCollection<CSMWorld::Land>& land = mData.getLand();
int landIndex = land.searchId(mId);
if (landIndex != -1)
{ {
mTerrain.reset(new Terrain::TerrainGrid(mCellNode, data.getResourceSystem().get(), NULL, new TerrainStorage(mData), Element_Terrain<<1)); const ESM::Land& esmLand = land.getRecord(mId).get();
mTerrain->loadCell(esmLand.mX,
esmLand.mY); if (esmLand.getLandData (ESM::Land::DATA_VHGT))
{
mTerrain.reset(new Terrain::TerrainGrid(mCellNode, data.getResourceSystem().get(), NULL, new TerrainStorage(mData), Element_Terrain<<1));
mTerrain->loadCell(esmLand.mX,
esmLand.mY);
}
} }
} }
} }
@ -125,6 +129,9 @@ bool CSVRender::Cell::referenceableAboutToBeRemoved (const QModelIndex& parent,
bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft, bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft,
const QModelIndex& bottomRight) const QModelIndex& bottomRight)
{ {
if (mDeleted)
return false;
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> ( CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
*mData.getTableModel (CSMWorld::UniversalId::Type_References)); *mData.getTableModel (CSMWorld::UniversalId::Type_References));
@ -192,6 +199,9 @@ bool CSVRender::Cell::referenceAboutToBeRemoved (const QModelIndex& parent, int
if (parent.isValid()) if (parent.isValid())
return false; return false;
if (mDeleted)
return false;
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> ( CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
*mData.getTableModel (CSMWorld::UniversalId::Type_References)); *mData.getTableModel (CSMWorld::UniversalId::Type_References));
@ -212,6 +222,9 @@ bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int
if (parent.isValid()) if (parent.isValid())
return false; return false;
if (mDeleted)
return false;
return addObjects (start, end); return addObjects (start, end);
} }
@ -258,3 +271,8 @@ CSMWorld::CellCoordinates CSVRender::Cell::getCoordinates() const
{ {
return mCoordinates; return mCoordinates;
} }
bool CSVRender::Cell::isDeleted() const
{
return mDeleted;
}

View file

@ -40,6 +40,7 @@ namespace CSVRender
std::auto_ptr<Terrain::TerrainGrid> mTerrain; std::auto_ptr<Terrain::TerrainGrid> mTerrain;
CSMWorld::CellCoordinates mCoordinates; CSMWorld::CellCoordinates mCoordinates;
std::auto_ptr<CellArrow> mCellArrows[4]; std::auto_ptr<CellArrow> mCellArrows[4];
bool mDeleted;
/// Ignored if cell does not have an object with the given ID. /// Ignored if cell does not have an object with the given ID.
/// ///
@ -62,7 +63,10 @@ namespace CSVRender
public: public:
Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id); /// \note Deleted covers both cells that are deleted and cells that don't exist in
/// the first place.
Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id,
bool deleted = false);
~Cell(); ~Cell();
@ -93,6 +97,8 @@ namespace CSVRender
/// Returns 0, 0 in case of an unpaged cell. /// Returns 0, 0 in case of an unpaged cell.
CSMWorld::CellCoordinates getCoordinates() const; CSMWorld::CellCoordinates getCoordinates() const;
bool isDeleted() const;
}; };
} }

View file

@ -1,5 +1,6 @@
#include "pagedworldspacewidget.hpp" #include "pagedworldspacewidget.hpp"
#include <memory>
#include <sstream> #include <sstream>
#include <QMouseEvent> #include <QMouseEvent>
@ -26,17 +27,14 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
const CSMWorld::IdCollection<CSMWorld::Cell>& cells = mDocument.getData().getCells(); const CSMWorld::IdCollection<CSMWorld::Cell>& cells = mDocument.getData().getCells();
{ {
// remove (or name/region modified) // remove/update
std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter (mCells.begin()); std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter (mCells.begin());
while (iter!=mCells.end()) while (iter!=mCells.end())
{ {
int index = cells.searchId (iter->first.getId (mWorldspace)); if (!mSelection.has (iter->first))
/// \todo handle cells that don't exist
if (!mSelection.has (iter->first) || index==-1 ||
cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted)
{ {
// remove
delete iter->second; delete iter->second;
mCells.erase (iter++); mCells.erase (iter++);
@ -44,12 +42,33 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
} }
else else
{ {
// check if name or region field has changed // update
// FIXME: config setting int index = cells.searchId (iter->first.getId (mWorldspace));
//std::string name = cells.getRecord(index).get().mName;
//std::string region = cells.getRecord(index).get().mRegion;
// cell marker update goes here bool deleted = index==-1 ||
cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted;
if (deleted!=iter->second->isDeleted())
{
modified = true;
std::auto_ptr<Cell> cell (new Cell (mDocument.getData(), mRootNode,
iter->first.getId (mWorldspace), deleted));
delete iter->second;
iter->second = cell.release();
}
else if (!deleted)
{
// delete state has not changed -> just update
// TODO check if name or region field has changed (cell marker)
// FIXME: config setting
//std::string name = cells.getRecord(index).get().mName;
//std::string region = cells.getRecord(index).get().mRegion;
modified = true;
}
++iter; ++iter;
} }
@ -60,11 +79,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
for (CSMWorld::CellSelection::Iterator iter (mSelection.begin()); iter!=mSelection.end(); for (CSMWorld::CellSelection::Iterator iter (mSelection.begin()); iter!=mSelection.end();
++iter) ++iter)
{ {
int index = cells.searchId (iter->getId (mWorldspace)); if (mCells.find (*iter)==mCells.end())
/// \todo handle cells that don't exist
if (index > 0 && cells.getRecord (index).mState!=CSMWorld::RecordBase::State_Deleted &&
mCells.find (*iter)==mCells.end())
{ {
Cell *cell = new Cell (mDocument.getData(), mRootNode, Cell *cell = new Cell (mDocument.getData(), mRootNode,
iter->getId (mWorldspace)); iter->getId (mWorldspace));