OpenMW
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
cellstore.hpp
Go to the documentation of this file.
1 #ifndef GAME_MWWORLD_CELLSTORE_H
2 #define GAME_MWWORLD_CELLSTORE_H
3 
4 #include <algorithm>
5 #include <stdexcept>
6 #include <string>
7 #include <typeinfo>
8 #include <map>
9 
10 #include <boost/shared_ptr.hpp>
11 
12 #include "livecellref.hpp"
13 #include "cellreflist.hpp"
14 
35 
36 #include "../mwmechanics/pathgrid.hpp" // TODO: maybe belongs in mwworld
37 
38 #include "timestamp.hpp"
39 #include "ptr.hpp"
40 
41 namespace ESM
42 {
43  struct CellState;
44  struct FogState;
45  struct CellId;
46 }
47 
48 namespace MWWorld
49 {
50  class ESMStore;
51 
53  class CellStore
54  {
55  public:
56 
57  enum State
58  {
60  };
61 
62  private:
63 
65  std::vector<ESM::ESMReader>& mReader;
66 
67  // Even though fog actually belongs to the player and not cells,
68  // it makes sense to store it here since we need it once for each cell.
69  // Note this is NULL until the cell is explored to save some memory
70  boost::shared_ptr<ESM::FogState> mFogState;
71 
72  const ESM::Cell *mCell;
74  bool mHasState;
75  std::vector<std::string> mIds;
76  float mWaterLevel;
77 
79 
80  // List of refs owned by this cell
102 
103  typedef std::map<LiveCellRefBase*, MWWorld::CellStore*> MovedRefTracker;
104  // References owned by a different cell that have been moved here.
105  // <reference, cell the reference originally came from>
107  // References owned by this cell that have been moved to another cell.
108  // <reference, cell the reference was moved to>
110 
111  // Merged list of ref's currently in this cell - i.e. with added refs from mMovedHere, removed refs from mMovedToAnotherCell
112  std::vector<LiveCellRefBase*> mMergedRefs;
113 
114  // Get the Ptr for the given ref which originated from this cell (possibly moved to another cell at this point).
116 
118  void moveFrom(const MWWorld::Ptr& object, MWWorld::CellStore* from);
119 
121  void updateMergedRefs();
122 
123  // helper function for forEachInternal
124  template<class Visitor, class List>
125  bool forEachImp (Visitor& visitor, List& list)
126  {
127  for (typename List::List::iterator iter (list.mList.begin()); iter!=list.mList.end();
128  ++iter)
129  {
130  if (!isAccessible(iter->mData, iter->mRef))
131  continue;
132  if (!visitor (MWWorld::Ptr(&*iter, this)))
133  return false;
134  }
135  return true;
136  }
137 
138  // listing only objects owned by this cell. Internal use only, you probably want to use forEach() so that moved objects are accounted for.
139  template<class Visitor>
140  bool forEachInternal (Visitor& visitor)
141  {
142  return
143  forEachImp (visitor, mActivators) &&
144  forEachImp (visitor, mPotions) &&
145  forEachImp (visitor, mAppas) &&
146  forEachImp (visitor, mArmors) &&
147  forEachImp (visitor, mBooks) &&
148  forEachImp (visitor, mClothes) &&
149  forEachImp (visitor, mContainers) &&
150  forEachImp (visitor, mDoors) &&
151  forEachImp (visitor, mIngreds) &&
152  forEachImp (visitor, mItemLists) &&
153  forEachImp (visitor, mLights) &&
154  forEachImp (visitor, mLockpicks) &&
155  forEachImp (visitor, mMiscItems) &&
156  forEachImp (visitor, mProbes) &&
157  forEachImp (visitor, mRepairs) &&
158  forEachImp (visitor, mStatics) &&
159  forEachImp (visitor, mWeapons) &&
160  forEachImp (visitor, mBodyParts) &&
161  forEachImp (visitor, mCreatures) &&
162  forEachImp (visitor, mNpcs) &&
163  forEachImp (visitor, mCreatureLists);
164  }
165 
168  template <class T>
169  CellRefList<T>& get();
170 
171  public:
172 
177  static bool isAccessible(const MWWorld::RefData& refdata, const MWWorld::CellRef& cref)
178  {
179  return !refdata.isDeletedByContentFile() && (cref.hasContentFile() || refdata.getCount() > 0);
180  }
181 
186  MWWorld::Ptr moveTo(const MWWorld::Ptr& object, MWWorld::CellStore* cellToMoveTo);
187 
191  template <typename T>
193  {
194  mHasState = true;
195  CellRefList<T>& list = get<T>();
196  LiveCellRefBase* ret = &list.insert(*ref);
198  return ret;
199  }
200 
202  CellStore (const ESM::Cell *cell_,
203  const MWWorld::ESMStore& store,
204  std::vector<ESM::ESMReader>& readerList);
205 
206  const ESM::Cell *getCell() const;
207 
208  State getState() const;
209 
210  const std::vector<std::string>& getPreloadedIds() const;
212 
213  bool hasState() const;
215 
216  bool hasId (const std::string& id) const;
220 
221  Ptr search (const std::string& id);
225 
226  ConstPtr searchConst (const std::string& id) const;
230 
231  Ptr searchViaActorId (int id);
233 
234  float getWaterLevel() const;
235 
236  void setWaterLevel (float level);
237 
238  void setFog (ESM::FogState* fog);
240 
241  ESM::FogState* getFog () const;
242 
243  int count() const;
245 
246  void load ();
248 
249  void preload ();
251 
258  template<class Visitor>
259  bool forEach (Visitor& visitor)
260  {
261  if (mState != State_Loaded)
262  return false;
263 
264  if (mMergedRefs.empty())
265  return true;
266 
267  mHasState = true;
268 
269  for (unsigned int i=0; i<mMergedRefs.size(); ++i)
270  {
271  if (!isAccessible(mMergedRefs[i]->mData, mMergedRefs[i]->mRef))
272  continue;
273 
274  if (!visitor(MWWorld::Ptr(mMergedRefs[i], this)))
275  return false;
276  }
277  return true;
278  }
279 
285  template<class Visitor>
286  bool forEachConst (Visitor& visitor) const
287  {
288  if (mState != State_Loaded)
289  return false;
290 
291  for (unsigned int i=0; i<mMergedRefs.size(); ++i)
292  {
293  if (!isAccessible(mMergedRefs[i]->mData, mMergedRefs[i]->mRef))
294  continue;
295 
296  if (!visitor(MWWorld::ConstPtr(mMergedRefs[i], this)))
297  return false;
298  }
299  return true;
300  }
301 
302 
308  template <class T, class Visitor>
309  bool forEachType(Visitor& visitor)
310  {
311  if (mState != State_Loaded)
312  return false;
313 
314  if (mMergedRefs.empty())
315  return true;
316 
317  mHasState = true;
318 
319  CellRefList<T>& list = get<T>();
320 
321  for (typename CellRefList<T>::List::iterator it (list.mList.begin()); it!=list.mList.end(); ++it)
322  {
323  LiveCellRefBase* base = &*it;
324  if (mMovedToAnotherCell.find(base) != mMovedToAnotherCell.end())
325  continue;
326  if (!isAccessible(base->mData, base->mRef))
327  continue;
328  if (!visitor(MWWorld::Ptr(base, this)))
329  return false;
330  }
331 
332  for (MovedRefTracker::const_iterator it = mMovedHere.begin(); it != mMovedHere.end(); ++it)
333  {
334  LiveCellRefBase* base = it->first;
335  if (dynamic_cast<LiveCellRef<T>*>(base))
336  if (!visitor(MWWorld::Ptr(base, this)))
337  return false;
338  }
339  return true;
340  }
341 
342  // NOTE: does not account for moved references
343  // Should be phased out when we have const version of forEach
345  {
346  return mDoors;
347  }
349  {
350  return mStatics;
351  }
352 
353  bool isExterior() const;
354 
355  Ptr searchInContainer (const std::string& id);
356 
357  void loadState (const ESM::CellState& state);
358 
359  void saveState (ESM::CellState& state) const;
360 
361  void writeFog (ESM::ESMWriter& writer) const;
362 
363  void readFog (ESM::ESMReader& reader);
364 
365  void writeReferences (ESM::ESMWriter& writer) const;
366 
368  {
369  public:
371  virtual CellStore* getCellStore(const ESM::CellId& cellId) = 0;
372  };
373 
375  void readReferences (ESM::ESMReader& reader, const std::map<int, int>& contentFileMap, GetCellStoreCallback* callback);
376 
377  void respawn ();
379 
380  bool isPointConnected(const int start, const int end) const;
381 
382  std::list<ESM::Pathgrid::Point> aStarSearch(const int start, const int end) const;
383 
384  private:
385 
387  void listRefs();
388 
389  void loadRefs();
390 
391  void loadRef (ESM::CellRef& ref, bool deleted, std::map<ESM::RefNum, std::string>& refNumToID);
395 
397  };
398 
399  template<>
400  inline CellRefList<ESM::Activator>& CellStore::get<ESM::Activator>()
401  {
402  mHasState = true;
403  return mActivators;
404  }
405 
406  template<>
407  inline CellRefList<ESM::Potion>& CellStore::get<ESM::Potion>()
408  {
409  mHasState = true;
410  return mPotions;
411  }
412 
413  template<>
414  inline CellRefList<ESM::Apparatus>& CellStore::get<ESM::Apparatus>()
415  {
416  mHasState = true;
417  return mAppas;
418  }
419 
420  template<>
421  inline CellRefList<ESM::Armor>& CellStore::get<ESM::Armor>()
422  {
423  mHasState = true;
424  return mArmors;
425  }
426 
427  template<>
428  inline CellRefList<ESM::Book>& CellStore::get<ESM::Book>()
429  {
430  mHasState = true;
431  return mBooks;
432  }
433 
434  template<>
435  inline CellRefList<ESM::Clothing>& CellStore::get<ESM::Clothing>()
436  {
437  mHasState = true;
438  return mClothes;
439  }
440 
441  template<>
442  inline CellRefList<ESM::Container>& CellStore::get<ESM::Container>()
443  {
444  mHasState = true;
445  return mContainers;
446  }
447 
448  template<>
449  inline CellRefList<ESM::Creature>& CellStore::get<ESM::Creature>()
450  {
451  mHasState = true;
452  return mCreatures;
453  }
454 
455  template<>
456  inline CellRefList<ESM::Door>& CellStore::get<ESM::Door>()
457  {
458  mHasState = true;
459  return mDoors;
460  }
461 
462  template<>
463  inline CellRefList<ESM::Ingredient>& CellStore::get<ESM::Ingredient>()
464  {
465  mHasState = true;
466  return mIngreds;
467  }
468 
469  template<>
470  inline CellRefList<ESM::CreatureLevList>& CellStore::get<ESM::CreatureLevList>()
471  {
472  mHasState = true;
473  return mCreatureLists;
474  }
475 
476  template<>
477  inline CellRefList<ESM::ItemLevList>& CellStore::get<ESM::ItemLevList>()
478  {
479  mHasState = true;
480  return mItemLists;
481  }
482 
483  template<>
484  inline CellRefList<ESM::Light>& CellStore::get<ESM::Light>()
485  {
486  mHasState = true;
487  return mLights;
488  }
489 
490  template<>
491  inline CellRefList<ESM::Lockpick>& CellStore::get<ESM::Lockpick>()
492  {
493  mHasState = true;
494  return mLockpicks;
495  }
496 
497  template<>
498  inline CellRefList<ESM::Miscellaneous>& CellStore::get<ESM::Miscellaneous>()
499  {
500  mHasState = true;
501  return mMiscItems;
502  }
503 
504  template<>
505  inline CellRefList<ESM::NPC>& CellStore::get<ESM::NPC>()
506  {
507  mHasState = true;
508  return mNpcs;
509  }
510 
511  template<>
512  inline CellRefList<ESM::Probe>& CellStore::get<ESM::Probe>()
513  {
514  mHasState = true;
515  return mProbes;
516  }
517 
518  template<>
519  inline CellRefList<ESM::Repair>& CellStore::get<ESM::Repair>()
520  {
521  mHasState = true;
522  return mRepairs;
523  }
524 
525  template<>
526  inline CellRefList<ESM::Static>& CellStore::get<ESM::Static>()
527  {
528  mHasState = true;
529  return mStatics;
530  }
531 
532  template<>
533  inline CellRefList<ESM::Weapon>& CellStore::get<ESM::Weapon>()
534  {
535  mHasState = true;
536  return mWeapons;
537  }
538 
539  template<>
540  inline CellRefList<ESM::BodyPart>& CellStore::get<ESM::BodyPart>()
541  {
542  mHasState = true;
543  return mBodyParts;
544  }
545 
546  bool operator== (const CellStore& left, const CellStore& right);
547  bool operator!= (const CellStore& left, const CellStore& right);
548 }
549 
550 #endif
State
Definition: cellstore.hpp:57
MWMechanics::PathgridGraph mPathgridGraph
Definition: cellstore.hpp:396
Used to create pointers to hold any type of LiveCellRef<> object.
Definition: livecellref.hpp:22
CellStore(const ESM::Cell *cell_, const MWWorld::ESMStore &store, std::vector< ESM::ESMReader > &readerList)
Definition: cellstore.cpp:331
Encapsulated variant of ESM::CellRef with change tracking.
Definition: cellref.hpp:15
static bool isAccessible(const MWWorld::RefData &refdata, const MWWorld::CellRef &cref)
Definition: cellstore.hpp:177
bool forEachType(Visitor &visitor)
Definition: cellstore.hpp:309
LiveCellRefBase * insert(const LiveCellRef< T > *ref)
Definition: cellstore.hpp:192
const MWWorld::ESMStore & mStore
Definition: cellstore.hpp:64
const ESM::Cell * mCell
Definition: cellstore.hpp:72
CellRefList< ESM::Potion > mPotions
Definition: cellstore.hpp:82
const ESM::Cell * getCell() const
Definition: cellstore.cpp:337
bool operator==(const LiveCellRef< X > &ref, int pRefnum)
Definition: cellstore.cpp:205
const CellRefList< ESM::Static > & getReadOnlyStatics() const
Definition: cellstore.hpp:348
CellRefList< ESM::Repair > mRepairs
Definition: cellstore.hpp:98
CellRefList< ESM::Ingredient > mIngreds
Definition: cellstore.hpp:90
Definition: esmreader.hpp:21
void load()
Load references from content file.
Definition: cellstore.cpp:438
float mWaterLevel
Definition: cellstore.hpp:76
Definition: cellstore.hpp:367
float getWaterLevel() const
Definition: cellstore.cpp:420
Definition: fogstate.hpp:19
bool forEach(Visitor &visitor)
Definition: cellstore.hpp:259
bool isPointConnected(const int start, const int end) const
Definition: cellstore.cpp:940
bool mHasState
Definition: cellstore.hpp:74
MWWorld::CellRef mRef
Definition: livecellref.hpp:29
MWWorld::Ptr moveTo(const MWWorld::Ptr &object, MWWorld::CellStore *cellToMoveTo)
Definition: cellstore.cpp:238
CellRefList< ESM::Probe > mProbes
Definition: cellstore.hpp:97
int list(Bsa::BSAFile &bsa, Arguments &info)
Definition: bsatool.cpp:183
void loadRefs()
Definition: cellstore.cpp:521
void updateMergedRefs()
Repopulate mMergedRefs.
Definition: cellstore.cpp:323
CellRefList< ESM::Miscellaneous > mMiscItems
Definition: cellstore.hpp:95
const CellRefList< ESM::Door > & getReadOnlyDoors() const
Definition: cellstore.hpp:344
CellRefList< ESM::Activator > mActivators
Definition: cellstore.hpp:81
Definition: livecellref.hpp:77
State getState() const
Definition: cellstore.cpp:342
bool isExterior() const
Definition: cellstore.cpp:576
bool hasId(const std::string &id) const
Definition: cellstore.cpp:357
bool isDeletedByContentFile() const
Returns true if the object was deleted by a content file.
Definition: refdata.cpp:180
LiveRef & insert(const LiveRef &item)
Definition: cellreflist.hpp:27
Definition: refdata.hpp:29
RefData mData
Definition: livecellref.hpp:32
void moveFrom(const MWWorld::Ptr &object, MWWorld::CellStore *from)
Moves object from the given cell to this cell.
Definition: cellstore.cpp:218
void writeFog(ESM::ESMWriter &writer) const
Definition: cellstore.cpp:700
void saveState(ESM::CellState &state) const
Definition: cellstore.cpp:688
CellRefList< ESM::NPC > mNpcs
Definition: cellstore.hpp:96
Definition: esmwriter.hpp:17
Definition: cellstore.hpp:59
bool forEachConst(Visitor &visitor) const
Definition: cellstore.hpp:286
int count() const
Return total number of references, including deleted ones.
Definition: cellstore.cpp:433
Definition: esmstore.hpp:17
CellRefList< ESM::Clothing > mClothes
Definition: cellstore.hpp:86
void respawn()
Check mLastRespawn and respawn references if necessary. This is a no-op if the cell is not loaded...
Definition: cellstore.cpp:968
void loadRef(ESM::CellRef &ref, bool deleted, std::map< ESM::RefNum, std::string > &refNumToID)
Definition: cellstore.cpp:601
CellRefList< ESM::CreatureLevList > mCreatureLists
Definition: cellstore.hpp:91
int getCount() const
Definition: refdata.cpp:149
ConstPtr searchConst(const std::string &id) const
Definition: cellstore.cpp:392
void listRefs()
Run through references and store IDs.
Definition: cellstore.cpp:465
Ptr search(const std::string &id)
Definition: cellstore.cpp:384
std::list< ESM::Pathgrid::Point > aStarSearch(const int start, const int end) const
Definition: cellstore.cpp:945
Mutable state of a cell.
Definition: cellstore.hpp:53
List mList
Definition: cellreflist.hpp:16
bool forEachInternal(Visitor &visitor)
Definition: cellstore.hpp:140
Pointer to a const LiveCellRef.
Definition: ptr.hpp:90
CellRefList< ESM::Book > mBooks
Definition: cellstore.hpp:85
bool forEachImp(Visitor &visitor, List &list)
Definition: cellstore.hpp:125
void preload()
Build ID list from content file.
Definition: cellstore.cpp:455
MovedRefTracker mMovedHere
Definition: cellstore.hpp:106
Definition: cellref.hpp:34
Definition: loadcell.hpp:64
CellRefList< ESM::ItemLevList > mItemLists
Definition: cellstore.hpp:92
std::vector< ESM::ESMReader > & mReader
Definition: cellstore.hpp:65
bool hasState() const
Does this cell have state that needs to be stored in a saved game file?
Definition: cellstore.cpp:352
In-game time stamp.
Definition: timestamp.hpp:14
CellRefList< ESM::Static > mStatics
Definition: cellstore.hpp:99
CellRefList< ESM::Creature > mCreatures
Definition: cellstore.hpp:88
ESM::FogState * getFog() const
Definition: cellstore.cpp:955
void loadState(const ESM::CellState &state)
Definition: cellstore.cpp:677
void setWaterLevel(float level)
Definition: cellstore.cpp:427
CellRefList< ESM::Light > mLights
Definition: cellstore.hpp:93
std::vector< std::string > mIds
Definition: cellstore.hpp:75
std::map< LiveCellRefBase *, MWWorld::CellStore * > MovedRefTracker
Definition: cellstore.hpp:103
CellRefList< ESM::Container > mContainers
Definition: cellstore.hpp:87
void readFog(ESM::ESMReader &reader)
Definition: cellstore.cpp:708
Ptr searchInContainer(const std::string &id)
Definition: cellstore.cpp:581
Definition: pathgrid.hpp:20
Definition: cellstore.hpp:59
virtual CellStore * getCellStore(const ESM::CellId &cellId)=0
CellRefList< ESM::Weapon > mWeapons
Definition: cellstore.hpp:100
void setFog(ESM::FogState *fog)
Definition: cellstore.cpp:950
CellRefList< ESM::BodyPart > mBodyParts
Definition: cellstore.hpp:101
Definition: cellstore.hpp:59
State mState
Definition: cellstore.hpp:73
CellRefList< ESM::Armor > mArmors
Definition: cellstore.hpp:84
boost::shared_ptr< ESM::FogState > mFogState
Definition: cellstore.hpp:70
Ptr getCurrentPtr(MWWorld::LiveCellRefBase *ref)
Definition: cellstore.cpp:210
Pointer to a LiveCellRef.
Definition: ptr.hpp:19
void readReferences(ESM::ESMReader &reader, const std::map< int, int > &contentFileMap, GetCellStoreCallback *callback)
Definition: cellstore.cpp:749
bool operator!=(const CellStore &left, const CellStore &right)
Definition: cellstore.cpp:935
CellRefList< ESM::Lockpick > mLockpicks
Definition: cellstore.hpp:94
void writeReferences(ESM::ESMWriter &writer) const
Definition: cellstore.cpp:714
Definition: cellid.hpp:11
MWWorld::TimeStamp mLastRespawn
Definition: cellstore.hpp:78
bool hasContentFile() const
Does the RefNum have a content file?
Definition: cellref.cpp:13
CellRefList< ESM::Apparatus > mAppas
Definition: cellstore.hpp:83
Ptr searchViaActorId(int id)
Will return an empty Ptr if cell is not loaded.
Definition: cellstore.cpp:400
std::vector< LiveCellRefBase * > mMergedRefs
Definition: cellstore.hpp:112
CellRefList< ESM::Door > mDoors
Definition: cellstore.hpp:89
MovedRefTracker mMovedToAnotherCell
Definition: cellstore.hpp:109
const std::vector< std::string > & getPreloadedIds() const
Get Ids of objects in this cell, only valid in State_Preloaded.
Definition: cellstore.cpp:347
Definition: cellstate.hpp:16