OpenMW
|
00001 #ifndef CSM_WOLRD_REFIDDATA_H 00002 #define CSM_WOLRD_REFIDDATA_H 00003 00004 #include <vector> 00005 #include <map> 00006 00007 #include <components/esm/loadacti.hpp> 00008 #include <components/esm/loadalch.hpp> 00009 #include <components/esm/loadappa.hpp> 00010 #include <components/esm/loadarmo.hpp> 00011 #include <components/esm/loadbook.hpp> 00012 #include <components/esm/loadclot.hpp> 00013 #include <components/esm/loadcont.hpp> 00014 #include <components/esm/loadcrea.hpp> 00015 #include <components/esm/loaddoor.hpp> 00016 #include <components/esm/loadingr.hpp> 00017 #include <components/esm/loadlevlist.hpp> 00018 #include <components/esm/loadligh.hpp> 00019 #include <components/esm/loadlock.hpp> 00020 #include <components/esm/loadprob.hpp> 00021 #include <components/esm/loadrepa.hpp> 00022 #include <components/esm/loadstat.hpp> 00023 #include <components/esm/loadweap.hpp> 00024 #include <components/esm/loadnpc.hpp> 00025 #include <components/esm/loadmisc.hpp> 00026 #include <components/esm/esmwriter.hpp> 00027 00028 #include "record.hpp" 00029 #include "universalid.hpp" 00030 00031 namespace ESM 00032 { 00033 class ESMReader; 00034 } 00035 00036 namespace CSMWorld 00037 { 00038 struct RefIdDataContainerBase 00039 { 00040 virtual ~RefIdDataContainerBase(); 00041 00042 virtual int getSize() const = 0; 00043 00044 virtual const RecordBase& getRecord (int index) const = 0; 00045 00046 virtual RecordBase& getRecord (int index)= 0; 00047 00048 virtual void appendRecord (const std::string& id) = 0; 00049 00050 virtual void load (int index, ESM::ESMReader& reader, bool base) = 0; 00051 00052 virtual void erase (int index, int count) = 0; 00053 00054 virtual std::string getId (int index) const = 0; 00055 00056 virtual void save (int index, ESM::ESMWriter& writer) const = 0; 00057 }; 00058 00059 template<typename RecordT> 00060 struct RefIdDataContainer : public RefIdDataContainerBase 00061 { 00062 std::vector<Record<RecordT> > mContainer; 00063 00064 virtual int getSize() const; 00065 00066 virtual const RecordBase& getRecord (int index) const; 00067 00068 virtual RecordBase& getRecord (int index); 00069 00070 virtual void appendRecord (const std::string& id); 00071 00072 virtual void load (int index, ESM::ESMReader& reader, bool base); 00073 00074 virtual void erase (int index, int count); 00075 00076 virtual std::string getId (int index) const; 00077 00078 virtual void save (int index, ESM::ESMWriter& writer) const; 00079 }; 00080 00081 template<typename RecordT> 00082 int RefIdDataContainer<RecordT>::getSize() const 00083 { 00084 return static_cast<int> (mContainer.size()); 00085 } 00086 00087 template<typename RecordT> 00088 const RecordBase& RefIdDataContainer<RecordT>::getRecord (int index) const 00089 { 00090 return mContainer.at (index); 00091 } 00092 00093 template<typename RecordT> 00094 RecordBase& RefIdDataContainer<RecordT>::getRecord (int index) 00095 { 00096 return mContainer.at (index); 00097 } 00098 00099 template<typename RecordT> 00100 void RefIdDataContainer<RecordT>::appendRecord (const std::string& id) 00101 { 00102 Record<RecordT> record; 00103 record.mModified.mId = id; 00104 record.mModified.blank(); 00105 record.mState = RecordBase::State_ModifiedOnly; 00106 00107 mContainer.push_back (record); 00108 } 00109 00110 template<typename RecordT> 00111 void RefIdDataContainer<RecordT>::load (int index, ESM::ESMReader& reader, bool base) 00112 { 00113 (base ? mContainer.at (index).mBase : mContainer.at (index).mModified).load (reader); 00114 } 00115 00116 template<typename RecordT> 00117 void RefIdDataContainer<RecordT>::erase (int index, int count) 00118 { 00119 if (index<0 || index+count>=getSize()) 00120 throw std::runtime_error ("invalid RefIdDataContainer index"); 00121 00122 mContainer.erase (mContainer.begin()+index, mContainer.begin()+index+count); 00123 } 00124 00125 template<typename RecordT> 00126 std::string RefIdDataContainer<RecordT>::getId (int index) const 00127 { 00128 return mContainer.at (index).get().mId; 00129 } 00130 00131 template<typename RecordT> 00132 void RefIdDataContainer<RecordT>::save (int index, ESM::ESMWriter& writer) const 00133 { 00134 CSMWorld::RecordBase::State state = mContainer.at (index).mState; 00135 00136 if (state==CSMWorld::RecordBase::State_Modified || 00137 state==CSMWorld::RecordBase::State_ModifiedOnly) 00138 { 00139 std::string type; 00140 for (int i=0; i<4; ++i) 00142 type += reinterpret_cast<const char *> (&mContainer.at (index).mModified.sRecordId)[i]; 00143 00144 writer.startRecord (type); 00145 writer.writeHNCString ("NAME", getId (index)); 00146 mContainer.at (index).mModified.save (writer); 00147 writer.endRecord (type); 00148 } 00149 else if (state==CSMWorld::RecordBase::State_Deleted) 00150 { 00152 } 00153 } 00154 00155 00156 class RefIdData 00157 { 00158 public: 00159 00160 typedef std::pair<int, UniversalId::Type> LocalIndex; 00161 00162 private: 00163 00164 RefIdDataContainer<ESM::Activator> mActivators; 00165 RefIdDataContainer<ESM::Potion> mPotions; 00166 RefIdDataContainer<ESM::Apparatus> mApparati; 00167 RefIdDataContainer<ESM::Armor> mArmors; 00168 RefIdDataContainer<ESM::Book> mBooks; 00169 RefIdDataContainer<ESM::Clothing> mClothing; 00170 RefIdDataContainer<ESM::Container> mContainers; 00171 RefIdDataContainer<ESM::Creature> mCreatures; 00172 RefIdDataContainer<ESM::Door> mDoors; 00173 RefIdDataContainer<ESM::Ingredient> mIngredients; 00174 RefIdDataContainer<ESM::CreatureLevList> mCreatureLevelledLists; 00175 RefIdDataContainer<ESM::ItemLevList> mItemLevelledLists; 00176 RefIdDataContainer<ESM::Light> mLights; 00177 RefIdDataContainer<ESM::Lockpick> mLockpicks; 00178 RefIdDataContainer<ESM::Miscellaneous> mMiscellaneous; 00179 RefIdDataContainer<ESM::NPC> mNpcs; 00180 RefIdDataContainer<ESM::Probe> mProbes; 00181 RefIdDataContainer<ESM::Repair> mRepairs; 00182 RefIdDataContainer<ESM::Static> mStatics; 00183 RefIdDataContainer<ESM::Weapon> mWeapons; 00184 00185 std::map<std::string, LocalIndex> mIndex; 00186 00187 std::map<UniversalId::Type, RefIdDataContainerBase *> mRecordContainers; 00188 00189 void erase (const LocalIndex& index, int count); 00191 00192 public: 00193 00194 RefIdData(); 00195 00196 LocalIndex globalToLocalIndex (int index) const; 00197 00198 int localToGlobalIndex (const LocalIndex& index) const; 00199 00200 LocalIndex searchId (const std::string& id) const; 00201 00202 void erase (int index, int count); 00203 00204 const RecordBase& getRecord (const LocalIndex& index) const; 00205 00206 RecordBase& getRecord (const LocalIndex& index); 00207 00208 void appendRecord (UniversalId::Type type, const std::string& id); 00209 00210 int getAppendIndex (UniversalId::Type type) const; 00211 00212 void load (const LocalIndex& index, ESM::ESMReader& reader, bool base); 00213 00214 int getSize() const; 00215 00216 std::vector<std::string> getIds (bool listDeleted = true) const; 00220 00221 void save (int index, ESM::ESMWriter& writer) const; 00222 }; 00223 } 00224 00225 #endif