diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index 74df0f79d..acffe20f3 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -66,8 +66,11 @@ MWWorld::Ptr MWWorld::Cells::getPtrAndCache (const std::string& name, CellStore& return ptr; } -void MWWorld::Cells::writeCell (ESM::ESMWriter& writer, const CellStore& cell) const +void MWWorld::Cells::writeCell (ESM::ESMWriter& writer, CellStore& cell) const { + if (cell.getState()!=CellStore::State_Loaded) + cell.load (mStore, mReader); + ESM::CellState cellState; cell.saveState (cellState); @@ -79,17 +82,6 @@ void MWWorld::Cells::writeCell (ESM::ESMWriter& writer, const CellStore& cell) c writer.endRecord (ESM::REC_CSTA); } -bool MWWorld::Cells::hasState (const CellStore& cellStore) const -{ - if (cellStore.getState()==CellStore::State_Loaded) - return true; - - if (cellStore.getCell()->mData.mFlags & ESM::Cell::Interior) - return cellStore.getCell()->mData.mFlags & ESM::Cell::HasWater; - else - return false; -} - MWWorld::Cells::Cells (const MWWorld::ESMStore& store, std::vector& reader) : mStore (store), mReader (reader), mIdCache (40, std::pair ("", (CellStore*)0)), /// \todo make cache size configurable @@ -274,12 +266,12 @@ int MWWorld::Cells::countSavedGameRecords() const for (std::map::const_iterator iter (mInteriors.begin()); iter!=mInteriors.end(); ++iter) - if (hasState (iter->second)) + if (iter->second.hasState()) ++count; for (std::map, CellStore>::const_iterator iter (mExteriors.begin()); iter!=mExteriors.end(); ++iter) - if (hasState (iter->second)) + if (iter->second.hasState()) ++count; return count; @@ -287,14 +279,14 @@ int MWWorld::Cells::countSavedGameRecords() const void MWWorld::Cells::write (ESM::ESMWriter& writer) const { - for (std::map, CellStore>::const_iterator iter (mExteriors.begin()); + for (std::map, CellStore>::iterator iter (mExteriors.begin()); iter!=mExteriors.end(); ++iter) - if (hasState (iter->second)) + if (iter->second.hasState()) writeCell (writer, iter->second); - for (std::map::const_iterator iter (mInteriors.begin()); + for (std::map::iterator iter (mInteriors.begin()); iter!=mInteriors.end(); ++iter) - if (hasState (iter->second)) + if (iter->second.hasState()) writeCell (writer, iter->second); } diff --git a/apps/openmw/mwworld/cells.hpp b/apps/openmw/mwworld/cells.hpp index 0df55b586..5209aa51a 100644 --- a/apps/openmw/mwworld/cells.hpp +++ b/apps/openmw/mwworld/cells.hpp @@ -24,8 +24,8 @@ namespace MWWorld { const MWWorld::ESMStore& mStore; std::vector& mReader; - std::map mInteriors; - std::map, CellStore> mExteriors; + mutable std::map mInteriors; + mutable std::map, CellStore> mExteriors; std::vector > mIdCache; std::size_t mIdCacheIndex; @@ -36,10 +36,7 @@ namespace MWWorld Ptr getPtrAndCache (const std::string& name, CellStore& cellStore); - void writeCell (ESM::ESMWriter& writer, const CellStore& cell) const; - - bool hasState (const CellStore& cellStore) const; - ///< Check if cell has state that needs to be included in a saved game file. + void writeCell (ESM::ESMWriter& writer, CellStore& cell) const; public: diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index f84b35b58..3f1ef8ab2 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -141,7 +141,7 @@ namespace MWWorld } CellStore::CellStore (const ESM::Cell *cell) - : mCell (cell), mState (State_Unloaded) + : mCell (cell), mState (State_Unloaded), mHasState (false) { mWaterLevel = cell->mWater; } @@ -156,6 +156,11 @@ namespace MWWorld return mState; } + bool CellStore::hasState() const + { + return mHasState; + } + bool CellStore::hasId (const std::string& id) const { if (mState==State_Unloaded) @@ -170,6 +175,10 @@ namespace MWWorld Ptr CellStore::search (const std::string& id) { + bool oldState = mHasState; + + mHasState = true; + if (LiveCellRef *ref = mActivators.find (id)) return Ptr (ref, this); @@ -230,11 +239,17 @@ namespace MWWorld if (LiveCellRef *ref = mWeapons.find (id)) return Ptr (ref, this); + mHasState = oldState; + return Ptr(); } Ptr CellStore::searchViaHandle (const std::string& handle) { + bool oldState = mHasState; + + mHasState = true; + if (LiveCellRef *ref = mActivators.searchViaHandle (handle)) return Ptr (ref, this); @@ -295,6 +310,8 @@ namespace MWWorld if (LiveCellRef *ref = mWeapons.searchViaHandle (handle)) return Ptr (ref, this); + mHasState = oldState; + return Ptr(); } @@ -306,6 +323,7 @@ namespace MWWorld void CellStore::setWaterLevel (float level) { mWaterLevel = level; + mHasState = true; } int CellStore::count() const @@ -437,6 +455,10 @@ namespace MWWorld Ptr CellStore::searchInContainer (const std::string& id) { + bool oldState = mHasState; + + mHasState = true; + if (Ptr ptr = searchInContainerList (mContainers, id)) return ptr; @@ -446,6 +468,8 @@ namespace MWWorld if (Ptr ptr = searchInContainerList (mNpcs, id)) return ptr; + mHasState = oldState; + return Ptr(); } @@ -486,6 +510,8 @@ namespace MWWorld void CellStore::loadState (const ESM::CellState& state) { + mHasState = true; + if (mCell->mData.mFlags & ESM::Cell::Interior && mCell->mData.mFlags & ESM::Cell::HasWater) mWaterLevel = state.mWaterLevel; @@ -529,6 +555,8 @@ namespace MWWorld void CellStore::readReferences (ESM::ESMReader& reader, const std::map& contentFileMap) { + mHasState = true; + while (reader.isNextSub ("OBJE")) { unsigned int id = 0; diff --git a/apps/openmw/mwworld/cellstore.hpp b/apps/openmw/mwworld/cellstore.hpp index 6c18d1ce1..4b7c0011b 100644 --- a/apps/openmw/mwworld/cellstore.hpp +++ b/apps/openmw/mwworld/cellstore.hpp @@ -31,6 +31,7 @@ namespace MWWorld const ESM::Cell *mCell; State mState; + bool mHasState; std::vector mIds; float mWaterLevel; @@ -63,6 +64,9 @@ namespace MWWorld State getState() const; + bool hasState() const; + ///< Does this cell have state that needs to be stored in a saved game file? + bool hasId (const std::string& id) const; ///< May return true for deleted IDs when in preload state. Will return false, if cell is /// unloaded. @@ -95,6 +99,8 @@ namespace MWWorld template bool forEach (Functor& functor) { + mHasState = true; + return forEachImp (functor, mActivators) && forEachImp (functor, mPotions) && @@ -165,120 +171,140 @@ namespace MWWorld template<> inline CellRefList& CellStore::get() { + mHasState = true; return mActivators; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mPotions; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mAppas; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mArmors; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mBooks; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mClothes; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mContainers; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mCreatures; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mDoors; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mIngreds; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mCreatureLists; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mItemLists; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mLights; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mLockpicks; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mMiscItems; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mNpcs; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mProbes; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mRepairs; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mStatics; } template<> inline CellRefList& CellStore::get() { + mHasState = true; return mWeapons; }