diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 7410780e08..7a2e93edfa 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -174,6 +174,9 @@ namespace CSMWorld { ColumnId_PcRank, "PC Rank" }, { ColumnId_Scope, "Scope" }, { ColumnId_ReferenceableId, "Referenceable ID" }, + { ColumnId_CombatState, "Combat" }, + { ColumnId_MagicState, "Magic" }, + { ColumnId_StealthState, "Stealth" }, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 1dba99b895..db31113e1d 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -167,6 +167,9 @@ namespace CSMWorld ColumnId_PcRank = 154, ColumnId_Scope = 155, ColumnId_ReferenceableId = 156, + ColumnId_CombatState = 157, + ColumnId_MagicState = 158, + ColumnId_StealthState = 159, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index a7b37be5bc..7e7756ff3e 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -15,7 +15,10 @@ namespace CSMWorld void load (ESM::ESMReader& reader, bool base); - void load (const ESXRecordT& record, bool base); + /// \param index Index at which the record can be found. + /// Special values: -2 index unknown, -1 record does not exist yet and therefore + /// does not have an index + void load (const ESXRecordT& record, bool base, int index = -2); bool tryDelete (const std::string& id); ///< Try deleting \a id. If the id does not exist or can't be deleted the call is ignored. @@ -56,17 +59,28 @@ namespace CSMWorld else { ESXRecordT record; - IdAccessorT().getId (record) = id; + + int index = this->searchId (id); + + if (index==-1) + IdAccessorT().getId (record) = id; + else + { + record = this->getRecord (index).get(); + } + record.load (reader); - load (record, base); + load (record, base, index); } } template - void IdCollection::load (const ESXRecordT& record, bool base) + void IdCollection::load (const ESXRecordT& record, bool base, + int index) { - int index = this->searchId (IdAccessorT().getId (record)); + if (index==-2) + index = this->searchId (IdAccessorT().getId (record)); if (index==-1) { diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index f00e9fc77b..d9a691abdc 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -248,6 +248,15 @@ QVariant CSMWorld::CreatureRefIdAdapter::getData (const RefIdColumn *column, con if (column==mColumns.mOriginal) return QString::fromUtf8 (record.get().mOriginal.c_str()); + if (column==mColumns.mCombat) + return static_cast (record.get().mData.mCombat); + + if (column==mColumns.mMagic) + return static_cast (record.get().mData.mMagic); + + if (column==mColumns.mStealth) + return static_cast (record.get().mData.mStealth); + std::map::const_iterator iter = mColumns.mFlags.find (column); @@ -271,6 +280,12 @@ void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdDa record.get().mScale = value.toFloat(); else if (column==mColumns.mOriginal) record.get().mOriginal = value.toString().toUtf8().constData(); + else if (column==mColumns.mCombat) + record.get().mData.mCombat = value.toInt(); + else if (column==mColumns.mMagic) + record.get().mData.mMagic = value.toInt(); + else if (column==mColumns.mStealth) + record.get().mData.mStealth = value.toInt(); else { std::map::const_iterator iter = diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index bd509a86b6..034905781d 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -34,7 +34,7 @@ namespace CSMWorld BaseRefIdAdapter (UniversalId::Type type, const BaseColumns& base); virtual std::string getId (const RecordBase& record) const; - + virtual void setId (RecordBase& record, const std::string& id); virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) @@ -57,7 +57,7 @@ namespace CSMWorld { (dynamic_cast&> (record).get().mId) = id; } - + template std::string BaseRefIdAdapter::getId (const RecordBase& record) const { @@ -631,6 +631,9 @@ namespace CSMWorld const RefIdColumn *mSoul; const RefIdColumn *mScale; const RefIdColumn *mOriginal; + const RefIdColumn *mCombat; + const RefIdColumn *mMagic; + const RefIdColumn *mStealth; CreatureColumns (const ActorColumns& actorColumns); }; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 46a22edede..c16218a0be 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -175,6 +175,15 @@ CSMWorld::RefIdCollection::RefIdCollection() creatureColumns.mScale = &mColumns.back(); mColumns.push_back (RefIdColumn (Columns::ColumnId_OriginalCreature, ColumnBase::Display_String)); creatureColumns.mOriginal = &mColumns.back(); + mColumns.push_back ( + RefIdColumn (Columns::ColumnId_CombatState, ColumnBase::Display_Integer)); + creatureColumns.mCombat = &mColumns.back(); + mColumns.push_back ( + RefIdColumn (Columns::ColumnId_MagicState, ColumnBase::Display_Integer)); + creatureColumns.mMagic = &mColumns.back(); + mColumns.push_back ( + RefIdColumn (Columns::ColumnId_StealthState, ColumnBase::Display_Integer)); + creatureColumns.mStealth = &mColumns.back(); static const struct { diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 20cd6abb5a..1ee32fa970 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -15,13 +15,18 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() bool modified = false; bool setCamera = false; + const CSMWorld::IdCollection& cells = mDocument.getData().getCells(); + { // remove std::map::iterator iter (mCells.begin()); while (iter!=mCells.end()) { - if (!mSelection.has (iter->first)) + int index = cells.searchId (iter->first.getId (mWorldspace)); + + if (!mSelection.has (iter->first) || index==-1 || + cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted) { delete iter->second; mCells.erase (iter++); @@ -39,7 +44,10 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() for (CSMWorld::CellSelection::Iterator iter (mSelection.begin()); iter!=mSelection.end(); ++iter) { - if (mCells.find (*iter)==mCells.end()) + int index = cells.searchId (iter->getId (mWorldspace)); + + if (index!=0 && cells.getRecord (index).mState!=CSMWorld::RecordBase::State_Deleted && + mCells.find (*iter)==mCells.end()) { if (setCamera) { @@ -49,7 +57,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() mCells.insert (std::make_pair (*iter, new Cell (mDocument.getData(), getSceneManager(), - iter->getId ("std::default")))); + iter->getId (mWorldspace)))); modified = true; } @@ -121,11 +129,19 @@ void CSVRender::PagedWorldspaceWidget::referenceAdded (const QModelIndex& parent flagAsModified(); } - - CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document) -: WorldspaceWidget (document, parent), mDocument (document) -{} +: WorldspaceWidget (document, parent), mDocument (document), mWorldspace ("std::default") +{ + QAbstractItemModel *cells = + document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells); + + connect (cells, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), + this, SLOT (cellDataChanged (const QModelIndex&, const QModelIndex&))); + connect (cells, SIGNAL (rowsRemoved (const QModelIndex&, int, int)), + this, SLOT (cellRemoved (const QModelIndex&, int, int))); + connect (cells, SIGNAL (rowsInserted (const QModelIndex&, int, int)), + this, SLOT (cellAdded (const QModelIndex&, int, int))); +} CSVRender::PagedWorldspaceWidget::~PagedWorldspaceWidget() { @@ -219,4 +235,27 @@ CSVRender::WorldspaceWidget::dropRequirments CSVRender::PagedWorldspaceWidget::g default: return ignored; } +} + +void CSVRender::PagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft, + const QModelIndex& bottomRight) +{ + /// \todo check if no selected cell is affected and do not update, if that is the case + if (adjustCells()) + flagAsModified(); +} + +void CSVRender::PagedWorldspaceWidget::cellRemoved (const QModelIndex& parent, int start, + int end) +{ + if (adjustCells()) + flagAsModified(); +} + +void CSVRender::PagedWorldspaceWidget::cellAdded (const QModelIndex& index, int start, + int end) +{ + /// \todo check if no selected cell is affected and do not update, if that is the case + if (adjustCells()) + flagAsModified(); } \ No newline at end of file diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 7f9a66f82b..c4fb789ee6 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -17,6 +17,7 @@ namespace CSVRender CSMDoc::Document& mDocument; CSMWorld::CellSelection mSelection; std::map mCells; + std::string mWorldspace; private: @@ -60,6 +61,15 @@ namespace CSVRender signals: void cellSelectionChanged (const CSMWorld::CellSelection& selection); + + private slots: + + virtual void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + + virtual void cellRemoved (const QModelIndex& parent, int start, int end); + + virtual void cellAdded (const QModelIndex& index, int start, int end); + }; }