keep track of which cells have state that needs to be saved

actorid
Marc Zinnschlag 11 years ago
parent bfcd768078
commit 9b18e01507

@ -66,8 +66,11 @@ MWWorld::Ptr MWWorld::Cells::getPtrAndCache (const std::string& name, CellStore&
return ptr; 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; ESM::CellState cellState;
cell.saveState (cellState); cell.saveState (cellState);
@ -79,17 +82,6 @@ void MWWorld::Cells::writeCell (ESM::ESMWriter& writer, const CellStore& cell) c
writer.endRecord (ESM::REC_CSTA); 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<ESM::ESMReader>& reader) MWWorld::Cells::Cells (const MWWorld::ESMStore& store, std::vector<ESM::ESMReader>& reader)
: mStore (store), mReader (reader), : mStore (store), mReader (reader),
mIdCache (40, std::pair<std::string, CellStore *> ("", (CellStore*)0)), /// \todo make cache size configurable mIdCache (40, std::pair<std::string, CellStore *> ("", (CellStore*)0)), /// \todo make cache size configurable
@ -274,12 +266,12 @@ int MWWorld::Cells::countSavedGameRecords() const
for (std::map<std::string, CellStore>::const_iterator iter (mInteriors.begin()); for (std::map<std::string, CellStore>::const_iterator iter (mInteriors.begin());
iter!=mInteriors.end(); ++iter) iter!=mInteriors.end(); ++iter)
if (hasState (iter->second)) if (iter->second.hasState())
++count; ++count;
for (std::map<std::pair<int, int>, CellStore>::const_iterator iter (mExteriors.begin()); for (std::map<std::pair<int, int>, CellStore>::const_iterator iter (mExteriors.begin());
iter!=mExteriors.end(); ++iter) iter!=mExteriors.end(); ++iter)
if (hasState (iter->second)) if (iter->second.hasState())
++count; ++count;
return count; return count;
@ -287,14 +279,14 @@ int MWWorld::Cells::countSavedGameRecords() const
void MWWorld::Cells::write (ESM::ESMWriter& writer) const void MWWorld::Cells::write (ESM::ESMWriter& writer) const
{ {
for (std::map<std::pair<int, int>, CellStore>::const_iterator iter (mExteriors.begin()); for (std::map<std::pair<int, int>, CellStore>::iterator iter (mExteriors.begin());
iter!=mExteriors.end(); ++iter) iter!=mExteriors.end(); ++iter)
if (hasState (iter->second)) if (iter->second.hasState())
writeCell (writer, iter->second); writeCell (writer, iter->second);
for (std::map<std::string, CellStore>::const_iterator iter (mInteriors.begin()); for (std::map<std::string, CellStore>::iterator iter (mInteriors.begin());
iter!=mInteriors.end(); ++iter) iter!=mInteriors.end(); ++iter)
if (hasState (iter->second)) if (iter->second.hasState())
writeCell (writer, iter->second); writeCell (writer, iter->second);
} }

@ -24,8 +24,8 @@ namespace MWWorld
{ {
const MWWorld::ESMStore& mStore; const MWWorld::ESMStore& mStore;
std::vector<ESM::ESMReader>& mReader; std::vector<ESM::ESMReader>& mReader;
std::map<std::string, CellStore> mInteriors; mutable std::map<std::string, CellStore> mInteriors;
std::map<std::pair<int, int>, CellStore> mExteriors; mutable std::map<std::pair<int, int>, CellStore> mExteriors;
std::vector<std::pair<std::string, CellStore *> > mIdCache; std::vector<std::pair<std::string, CellStore *> > mIdCache;
std::size_t mIdCacheIndex; std::size_t mIdCacheIndex;
@ -36,10 +36,7 @@ namespace MWWorld
Ptr getPtrAndCache (const std::string& name, CellStore& cellStore); Ptr getPtrAndCache (const std::string& name, CellStore& cellStore);
void writeCell (ESM::ESMWriter& writer, const CellStore& cell) const; void writeCell (ESM::ESMWriter& writer, CellStore& cell) const;
bool hasState (const CellStore& cellStore) const;
///< Check if cell has state that needs to be included in a saved game file.
public: public:

@ -141,7 +141,7 @@ namespace MWWorld
} }
CellStore::CellStore (const ESM::Cell *cell) CellStore::CellStore (const ESM::Cell *cell)
: mCell (cell), mState (State_Unloaded) : mCell (cell), mState (State_Unloaded), mHasState (false)
{ {
mWaterLevel = cell->mWater; mWaterLevel = cell->mWater;
} }
@ -156,6 +156,11 @@ namespace MWWorld
return mState; return mState;
} }
bool CellStore::hasState() const
{
return mHasState;
}
bool CellStore::hasId (const std::string& id) const bool CellStore::hasId (const std::string& id) const
{ {
if (mState==State_Unloaded) if (mState==State_Unloaded)
@ -170,6 +175,10 @@ namespace MWWorld
Ptr CellStore::search (const std::string& id) Ptr CellStore::search (const std::string& id)
{ {
bool oldState = mHasState;
mHasState = true;
if (LiveCellRef<ESM::Activator> *ref = mActivators.find (id)) if (LiveCellRef<ESM::Activator> *ref = mActivators.find (id))
return Ptr (ref, this); return Ptr (ref, this);
@ -230,11 +239,17 @@ namespace MWWorld
if (LiveCellRef<ESM::Weapon> *ref = mWeapons.find (id)) if (LiveCellRef<ESM::Weapon> *ref = mWeapons.find (id))
return Ptr (ref, this); return Ptr (ref, this);
mHasState = oldState;
return Ptr(); return Ptr();
} }
Ptr CellStore::searchViaHandle (const std::string& handle) Ptr CellStore::searchViaHandle (const std::string& handle)
{ {
bool oldState = mHasState;
mHasState = true;
if (LiveCellRef<ESM::Activator> *ref = mActivators.searchViaHandle (handle)) if (LiveCellRef<ESM::Activator> *ref = mActivators.searchViaHandle (handle))
return Ptr (ref, this); return Ptr (ref, this);
@ -295,6 +310,8 @@ namespace MWWorld
if (LiveCellRef<ESM::Weapon> *ref = mWeapons.searchViaHandle (handle)) if (LiveCellRef<ESM::Weapon> *ref = mWeapons.searchViaHandle (handle))
return Ptr (ref, this); return Ptr (ref, this);
mHasState = oldState;
return Ptr(); return Ptr();
} }
@ -306,6 +323,7 @@ namespace MWWorld
void CellStore::setWaterLevel (float level) void CellStore::setWaterLevel (float level)
{ {
mWaterLevel = level; mWaterLevel = level;
mHasState = true;
} }
int CellStore::count() const int CellStore::count() const
@ -437,6 +455,10 @@ namespace MWWorld
Ptr CellStore::searchInContainer (const std::string& id) Ptr CellStore::searchInContainer (const std::string& id)
{ {
bool oldState = mHasState;
mHasState = true;
if (Ptr ptr = searchInContainerList (mContainers, id)) if (Ptr ptr = searchInContainerList (mContainers, id))
return ptr; return ptr;
@ -446,6 +468,8 @@ namespace MWWorld
if (Ptr ptr = searchInContainerList (mNpcs, id)) if (Ptr ptr = searchInContainerList (mNpcs, id))
return ptr; return ptr;
mHasState = oldState;
return Ptr(); return Ptr();
} }
@ -486,6 +510,8 @@ namespace MWWorld
void CellStore::loadState (const ESM::CellState& state) void CellStore::loadState (const ESM::CellState& state)
{ {
mHasState = true;
if (mCell->mData.mFlags & ESM::Cell::Interior && mCell->mData.mFlags & ESM::Cell::HasWater) if (mCell->mData.mFlags & ESM::Cell::Interior && mCell->mData.mFlags & ESM::Cell::HasWater)
mWaterLevel = state.mWaterLevel; mWaterLevel = state.mWaterLevel;
@ -529,6 +555,8 @@ namespace MWWorld
void CellStore::readReferences (ESM::ESMReader& reader, void CellStore::readReferences (ESM::ESMReader& reader,
const std::map<int, int>& contentFileMap) const std::map<int, int>& contentFileMap)
{ {
mHasState = true;
while (reader.isNextSub ("OBJE")) while (reader.isNextSub ("OBJE"))
{ {
unsigned int id = 0; unsigned int id = 0;

@ -31,6 +31,7 @@ namespace MWWorld
const ESM::Cell *mCell; const ESM::Cell *mCell;
State mState; State mState;
bool mHasState;
std::vector<std::string> mIds; std::vector<std::string> mIds;
float mWaterLevel; float mWaterLevel;
@ -63,6 +64,9 @@ namespace MWWorld
State getState() const; 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; bool hasId (const std::string& id) const;
///< May return true for deleted IDs when in preload state. Will return false, if cell is ///< May return true for deleted IDs when in preload state. Will return false, if cell is
/// unloaded. /// unloaded.
@ -95,6 +99,8 @@ namespace MWWorld
template<class Functor> template<class Functor>
bool forEach (Functor& functor) bool forEach (Functor& functor)
{ {
mHasState = true;
return return
forEachImp (functor, mActivators) && forEachImp (functor, mActivators) &&
forEachImp (functor, mPotions) && forEachImp (functor, mPotions) &&
@ -165,120 +171,140 @@ namespace MWWorld
template<> template<>
inline CellRefList<ESM::Activator>& CellStore::get<ESM::Activator>() inline CellRefList<ESM::Activator>& CellStore::get<ESM::Activator>()
{ {
mHasState = true;
return mActivators; return mActivators;
} }
template<> template<>
inline CellRefList<ESM::Potion>& CellStore::get<ESM::Potion>() inline CellRefList<ESM::Potion>& CellStore::get<ESM::Potion>()
{ {
mHasState = true;
return mPotions; return mPotions;
} }
template<> template<>
inline CellRefList<ESM::Apparatus>& CellStore::get<ESM::Apparatus>() inline CellRefList<ESM::Apparatus>& CellStore::get<ESM::Apparatus>()
{ {
mHasState = true;
return mAppas; return mAppas;
} }
template<> template<>
inline CellRefList<ESM::Armor>& CellStore::get<ESM::Armor>() inline CellRefList<ESM::Armor>& CellStore::get<ESM::Armor>()
{ {
mHasState = true;
return mArmors; return mArmors;
} }
template<> template<>
inline CellRefList<ESM::Book>& CellStore::get<ESM::Book>() inline CellRefList<ESM::Book>& CellStore::get<ESM::Book>()
{ {
mHasState = true;
return mBooks; return mBooks;
} }
template<> template<>
inline CellRefList<ESM::Clothing>& CellStore::get<ESM::Clothing>() inline CellRefList<ESM::Clothing>& CellStore::get<ESM::Clothing>()
{ {
mHasState = true;
return mClothes; return mClothes;
} }
template<> template<>
inline CellRefList<ESM::Container>& CellStore::get<ESM::Container>() inline CellRefList<ESM::Container>& CellStore::get<ESM::Container>()
{ {
mHasState = true;
return mContainers; return mContainers;
} }
template<> template<>
inline CellRefList<ESM::Creature>& CellStore::get<ESM::Creature>() inline CellRefList<ESM::Creature>& CellStore::get<ESM::Creature>()
{ {
mHasState = true;
return mCreatures; return mCreatures;
} }
template<> template<>
inline CellRefList<ESM::Door>& CellStore::get<ESM::Door>() inline CellRefList<ESM::Door>& CellStore::get<ESM::Door>()
{ {
mHasState = true;
return mDoors; return mDoors;
} }
template<> template<>
inline CellRefList<ESM::Ingredient>& CellStore::get<ESM::Ingredient>() inline CellRefList<ESM::Ingredient>& CellStore::get<ESM::Ingredient>()
{ {
mHasState = true;
return mIngreds; return mIngreds;
} }
template<> template<>
inline CellRefList<ESM::CreatureLevList>& CellStore::get<ESM::CreatureLevList>() inline CellRefList<ESM::CreatureLevList>& CellStore::get<ESM::CreatureLevList>()
{ {
mHasState = true;
return mCreatureLists; return mCreatureLists;
} }
template<> template<>
inline CellRefList<ESM::ItemLevList>& CellStore::get<ESM::ItemLevList>() inline CellRefList<ESM::ItemLevList>& CellStore::get<ESM::ItemLevList>()
{ {
mHasState = true;
return mItemLists; return mItemLists;
} }
template<> template<>
inline CellRefList<ESM::Light>& CellStore::get<ESM::Light>() inline CellRefList<ESM::Light>& CellStore::get<ESM::Light>()
{ {
mHasState = true;
return mLights; return mLights;
} }
template<> template<>
inline CellRefList<ESM::Lockpick>& CellStore::get<ESM::Lockpick>() inline CellRefList<ESM::Lockpick>& CellStore::get<ESM::Lockpick>()
{ {
mHasState = true;
return mLockpicks; return mLockpicks;
} }
template<> template<>
inline CellRefList<ESM::Miscellaneous>& CellStore::get<ESM::Miscellaneous>() inline CellRefList<ESM::Miscellaneous>& CellStore::get<ESM::Miscellaneous>()
{ {
mHasState = true;
return mMiscItems; return mMiscItems;
} }
template<> template<>
inline CellRefList<ESM::NPC>& CellStore::get<ESM::NPC>() inline CellRefList<ESM::NPC>& CellStore::get<ESM::NPC>()
{ {
mHasState = true;
return mNpcs; return mNpcs;
} }
template<> template<>
inline CellRefList<ESM::Probe>& CellStore::get<ESM::Probe>() inline CellRefList<ESM::Probe>& CellStore::get<ESM::Probe>()
{ {
mHasState = true;
return mProbes; return mProbes;
} }
template<> template<>
inline CellRefList<ESM::Repair>& CellStore::get<ESM::Repair>() inline CellRefList<ESM::Repair>& CellStore::get<ESM::Repair>()
{ {
mHasState = true;
return mRepairs; return mRepairs;
} }
template<> template<>
inline CellRefList<ESM::Static>& CellStore::get<ESM::Static>() inline CellRefList<ESM::Static>& CellStore::get<ESM::Static>()
{ {
mHasState = true;
return mStatics; return mStatics;
} }
template<> template<>
inline CellRefList<ESM::Weapon>& CellStore::get<ESM::Weapon>() inline CellRefList<ESM::Weapon>& CellStore::get<ESM::Weapon>()
{ {
mHasState = true;
return mWeapons; return mWeapons;
} }

Loading…
Cancel
Save