OpenMW
|
00001 #ifndef OPENMW_ESM_CELL_H 00002 #define OPENMW_ESM_CELL_H 00003 00004 #include <string> 00005 #include <vector> 00006 #include <list> 00007 00008 #include "esmcommon.hpp" 00009 #include "defs.hpp" 00010 #include "cellref.hpp" 00011 00012 namespace MWWorld 00013 { 00014 class ESMStore; 00015 } 00016 00017 namespace ESM 00018 { 00019 class ESMReader; 00020 class ESMWriter; 00021 00022 /* Moved cell reference tracking object. This mainly stores the target cell 00023 of the reference, so we can easily know where it has been moved when another 00024 plugin tries to move it independently. 00025 Unfortunately, we need to implement this here. 00026 */ 00027 class MovedCellRef 00028 { 00029 public: 00030 int mRefnum; 00031 00032 // Target cell (if exterior) 00033 int mTarget[2]; 00034 00035 // TODO: Support moving references between exterior and interior cells! 00036 // This may happen in saves, when an NPC follows the player. Tribunal 00037 // introduces a henchman (which no one uses), so we may need this as well. 00038 }; 00039 00041 bool operator==(const MovedCellRef& ref, int pRefnum); 00042 bool operator==(const CellRef& ref, int pRefnum); 00043 00044 typedef std::list<MovedCellRef> MovedCellRefTracker; 00045 typedef std::list<CellRef> CellRefTracker; 00046 00047 /* Cells hold data about objects, creatures, statics (rocks, walls, 00048 buildings) and landscape (for exterior cells). Cells frequently 00049 also has other associated LAND and PGRD records. Combined, all this 00050 data can be huge, and we cannot load it all at startup. Instead, 00051 the strategy we use is to remember the file position of each cell 00052 (using ESMReader::getContext()) and jumping back into place 00053 whenever we need to load a given cell. 00054 */ 00055 struct Cell 00056 { 00057 static unsigned int sRecordId; 00058 00059 enum Flags 00060 { 00061 Interior = 0x01, // Interior cell 00062 HasWater = 0x02, // Does this cell have a water surface 00063 NoSleep = 0x04, // Is it allowed to sleep here (without a bed) 00064 QuasiEx = 0x80 // Behave like exterior (Tribunal+), with 00065 // skybox and weather 00066 }; 00067 00068 struct DATAstruct 00069 { 00070 int mFlags; 00071 int mX, mY; 00072 }; 00073 00074 struct AMBIstruct 00075 { 00076 Color mAmbient, mSunlight, mFog; 00077 float mFogDensity; 00078 }; 00079 00080 // Interior cells are indexed by this (it's the 'id'), for exterior 00081 // cells it is optional. 00082 std::string mName; 00083 00084 // Optional region name for exterior and quasi-exterior cells. 00085 std::string mRegion; 00086 00087 std::vector<ESM_Context> mContextList; // File position; multiple positions for multiple plugin support 00088 DATAstruct mData; 00089 AMBIstruct mAmbi; 00090 float mWater; // Water level 00091 bool mWaterInt; 00092 int mMapColor; 00093 int mNAM0; 00094 00095 // References "leased" from another cell (i.e. a different cell 00096 // introduced this ref, and it has been moved here by a plugin) 00097 CellRefTracker mLeasedRefs; 00098 MovedCellRefTracker mMovedRefs; 00099 00100 void preLoad(ESMReader &esm); 00101 void postLoad(ESMReader &esm); 00102 00103 // This method is left in for compatibility with esmtool. Parsing moved references currently requires 00104 // passing ESMStore, bit it does not know about this parameter, so we do it this way. 00105 void load(ESMReader &esm, bool saveContext = true); 00106 void save(ESMWriter &esm) const; 00107 00108 bool isExterior() const 00109 { 00110 return !(mData.mFlags & Interior); 00111 } 00112 00113 int getGridX() const 00114 { 00115 return mData.mX; 00116 } 00117 00118 int getGridY() const 00119 { 00120 return mData.mY; 00121 } 00122 00123 bool hasWater() const 00124 { 00125 return (mData.mFlags&HasWater); 00126 } 00127 00128 // Restore the given reader to the stored position. Will try to open 00129 // the file matching the stored file name. If you want to read from 00130 // somewhere other than the file system, you need to pre-open the 00131 // ESMReader, and the filename must match the stored filename 00132 // exactly. 00133 void restore(ESMReader &esm, int iCtx) const; 00134 00135 std::string getDescription() const; 00137 00138 /* Get the next reference in this cell, if any. Returns false when 00139 there are no more references in the cell. 00140 00141 All fields of the CellRef struct are overwritten. You can safely 00142 reuse one memory location without blanking it between calls. 00143 */ 00144 static bool getNextRef(ESMReader &esm, CellRef &ref); 00145 00146 /* This fetches an MVRF record, which is used to track moved references. 00147 * Since they are comparably rare, we use a separate method for this. 00148 */ 00149 static bool getNextMVRF(ESMReader &esm, MovedCellRef &mref); 00150 00151 void blank(); 00153 }; 00154 } 00155 #endif