#ifndef GAME_MWWORLD_CELLSTORE_H #define GAME_MWWORLD_CELLSTORE_H #include #include #include "livecellref.hpp" #include "esmstore.hpp" namespace MWWorld { /// A list of cell references template struct CellRefList { typedef LiveCellRef LiveRef; typedef std::list List; List mList; // Search for the given reference in the given reclist from // ESMStore. Insert the reference into the list if a match is // found. If not, throw an exception. // Moved to cpp file, as we require a custom compare operator for it, // and the build will fail with an ugly three-way cyclic header dependence // so we need to pass the instantiation of the method to the lnker, when // all methods are known. void load(ESM::CellRef &ref, const MWWorld::ESMStore &esmStore); LiveRef *find (const std::string& name) { for (typename std::list::iterator iter (mList.begin()); iter!=mList.end(); ++iter) { if (iter->mData.getCount() > 0 && iter->mRef.mRefID == name) return &*iter; } return 0; } LiveRef &insert(const LiveRef &item) { mList.push_back(item); return mList.back(); } }; /// A storage struct for one single cell reference. class CellStore { public: enum State { State_Unloaded, State_Preloaded, State_Loaded }; CellStore (const ESM::Cell *cell_); const ESM::Cell *mCell; State mState; std::vector mIds; float mWaterLevel; // Lists for each individual object type CellRefList mActivators; CellRefList mPotions; CellRefList mAppas; CellRefList mArmors; CellRefList mBooks; CellRefList mClothes; CellRefList mContainers; CellRefList mCreatures; CellRefList mDoors; CellRefList mIngreds; CellRefList mCreatureLists; CellRefList mItemLists; CellRefList mLights; CellRefList mLockpicks; CellRefList mMiscItems; CellRefList mNpcs; CellRefList mProbes; CellRefList mRepairs; CellRefList mStatics; CellRefList mWeapons; void load (const MWWorld::ESMStore &store, std::vector &esm); void preload (const MWWorld::ESMStore &store, std::vector &esm); /// Call functor (ref) for each reference. functor must return a bool. Returning /// false will abort the iteration. /// \return Iteration completed? template bool forEach (Functor& functor) { return forEachImp (functor, mActivators) && forEachImp (functor, mPotions) && forEachImp (functor, mAppas) && forEachImp (functor, mArmors) && forEachImp (functor, mBooks) && forEachImp (functor, mClothes) && forEachImp (functor, mContainers) && forEachImp (functor, mCreatures) && forEachImp (functor, mDoors) && forEachImp (functor, mIngreds) && forEachImp (functor, mCreatureLists) && forEachImp (functor, mItemLists) && forEachImp (functor, mLights) && forEachImp (functor, mLockpicks) && forEachImp (functor, mMiscItems) && forEachImp (functor, mNpcs) && forEachImp (functor, mProbes) && forEachImp (functor, mRepairs) && forEachImp (functor, mStatics) && forEachImp (functor, mWeapons); } bool operator==(const CellStore &cell) { return mCell->mName == cell.mCell->mName && mCell->mData.mX == cell.mCell->mData.mX && mCell->mData.mY == cell.mCell->mData.mY; } bool operator!=(const CellStore &cell) { return !(*this == cell); } bool isExterior() const { return mCell->isExterior(); } Ptr searchInContainer (const std::string& id); private: template bool forEachImp (Functor& functor, List& list) { for (typename List::List::iterator iter (list.mList.begin()); iter!=list.mList.end(); ++iter) { if (!iter->mData.getCount()) continue; if (!functor (MWWorld::Ptr(&*iter, this))) return false; } return true; } /// Run through references and store IDs void listRefs(const MWWorld::ESMStore &store, std::vector &esm); void loadRefs(const MWWorld::ESMStore &store, std::vector &esm); }; } #endif