void DataFilesModel::addMasters(const QString &path) { QDir dir(path); dir.setNameFilters(QStringList(QLatin1String("*.esp"))); // Read the dependencies from the plugins foreach (const QString &path, dir.entryList()) { try { ESM::ESMReader fileReader; fileReader.setEncoding(mEncoding.toStdString()); fileReader.open(dir.absoluteFilePath(path).toStdString()); ESM::ESMReader::MasterList mlist = fileReader.getMasters(); for (unsigned int i = 0; i < mlist.size(); ++i) { QString master = QString::fromStdString(mlist[i].name); // Add the plugin to the internal dependency map mDependencies[master].append(path); // Don't add esps if (master.endsWith(".esp", Qt::CaseInsensitive)) continue; QFileInfo info(dir.absoluteFilePath(master)); EsmFile *file = new EsmFile(master); file->setDates(info.lastModified(), info.lastRead()); // Add the master to the table if (findItem(master) == 0) addFile(file); } } catch(std::runtime_error &e) { // An error occurred while reading the .esp qWarning() << "Error reading esp: " << e.what(); continue; } } // See if the masters actually exist in the filesystem dir.setNameFilters(QStringList(QLatin1String("*.esm"))); foreach (const QString &path, dir.entryList()) { QFileInfo info(dir.absoluteFilePath(path)); if (findItem(path) == 0) { EsmFile *file = new EsmFile(path); file->setDates(info.lastModified(), info.lastRead()); addFile(file); } // Make the master selectable mAvailableFiles.append(path); } }
void MWState::StateManager::loadGame(const std::string& filepath) { for (CharacterIterator it = mCharacterManager.begin(); it != mCharacterManager.end(); ++it) { const MWState::Character& character = *it; for (MWState::Character::SlotIterator slotIt = character.begin(); slotIt != character.end(); ++slotIt) { const MWState::Slot& slot = *slotIt; if (slot.mPath == boost::filesystem::path(filepath)) { loadGame(&character, slot.mPath.string()); return; } } } // have to peek into the save file to get the player name ESM::ESMReader reader; reader.open (filepath); if (reader.getRecName()!=ESM::REC_SAVE) return; // invalid save file -> ignore reader.getRecHeader(); ESM::SavedGame profile; profile.load (reader); reader.close(); MWState::Character* character = mCharacterManager.getCurrentCharacter(true, profile.mPlayerName); loadGame(character, filepath); mTimePlayed = profile.mTimePlayed; }
void CSMWorld::RefIdCollection::load (ESM::ESMReader& reader, bool base, UniversalId::Type type) { std::string id = reader.getHNOString ("NAME"); int index = searchId (id); if (reader.isNextSub ("DELE")) { reader.skipRecord(); if (index==-1) { // deleting a record that does not exist // ignore it for now /// \todo report the problem to the user } else if (base) { mData.erase (index, 1); } else { mData.getRecord (mData.globalToLocalIndex (index)).mState = RecordBase::State_Deleted; } } else { if (index==-1) { // new record int index = mData.getAppendIndex (type); mData.appendRecord (type, id); RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index); mData.load (localIndex, reader, base); mData.getRecord (localIndex).mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; } else { // old record RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index); if (!base) if (mData.getRecord (localIndex).mState==RecordBase::State_Erased) throw std::logic_error ("attempt to access a deleted record"); mData.load (localIndex, reader, base); if (!base) mData.getRecord (localIndex).mState = RecordBase::State_Modified; } } }
void IdCollection<ESXRecordT>::load (ESM::ESMReader& reader, bool base) { std::string id = reader.getHNOString ("NAME"); if (reader.isNextSub ("DELE")) { int index = searchId (id); reader.skipRecord(); if (index==-1) { // deleting a record that does not exist // ignore it for now /// \todo report the problem to the user } else if (base) { removeRows (index, 1); } else { mRecords[index].mState = RecordBase::State_Deleted; } } else { ESXRecordT record; record.mId = id; record.load (reader); int index = searchId (record.mId); if (index==-1) { // new record Record<ESXRecordT> record2; record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; (base ? record2.mBase : record2.mModified) = record; appendRecord (record2); } else { // old record Record<ESXRecordT>& record2 = mRecords[index]; if (base) record2.mBase = record; else record2.setModified (record); } } }
void REFR::load(ESM::ESMReader &esm) { esm.getHNT(mRefNum.mIndex, "FRMR"); mRefID = esm.getHNString("NAME"); mActorData.load(esm); esm.getHNOT(mPos, "DATA", 24); }
bool Land::condLoad(ESM::ESMReader& reader, int flags, int dataFlag, void *ptr, unsigned int size) const { if ((mDataLoaded & dataFlag) == 0 && (flags & dataFlag) != 0) { reader.getHExact(ptr, size); mDataLoaded |= dataFlag; return true; } reader.skipHSubSize(size); return false; }
bool ESMStore::readRecord (ESM::ESMReader& reader, uint32_t type) { switch (type) { case ESM::REC_ALCH: case ESM::REC_ARMO: case ESM::REC_BOOK: case ESM::REC_CLAS: case ESM::REC_CLOT: case ESM::REC_ENCH: case ESM::REC_SPEL: case ESM::REC_WEAP: case ESM::REC_NPC_: case ESM::REC_LEVI: case ESM::REC_LEVC: { std::string id = reader.getHNString ("NAME"); mStores[type]->read (reader, id); // FIXME: there might be stale dynamic IDs in mIds from an earlier savegame // that really should be cleared instead of just overwritten mIds[id] = type; } if (type==ESM::REC_NPC_) { // NPC record will always be last and we know that there can be only one // dynamic NPC record (player) -> We are done here with dynamic record laoding setUp(); const ESM::NPC *player = mNpcs.find ("player"); if (!mRaces.find (player->mRace) || !mClasses.find (player->mClass)) throw std::runtime_error ("Invalid player record (race or class unavailable"); } return true; case ESM::REC_DYNA: reader.getSubNameIs("COUN"); reader.getHT(mDynamicCount); return true; default: return false; } }
virtual void read(ESM::ESMReader &esm) { std::string id = esm.getHNString("NAME"); CNTC cntc; cntc.load(esm); mContext->mContainerChanges.insert(std::make_pair(std::make_pair(cntc.mIndex,id), cntc)); }
void CNTC::load(ESM::ESMReader &esm) { mIndex = 0; esm.getHNT(mIndex, "INDX"); mInventory.load(esm); }
void Store<ESM::Cell>::handleMovedCellRefs(ESM::ESMReader& esm, ESM::Cell* cell) { //Handling MovedCellRefs, there is no way to do it inside loadcell while (esm.isNextSub("MVRF")) { ESM::CellRef ref; ESM::MovedCellRef cMRef; cell->getNextMVRF(esm, cMRef); MWWorld::Store<ESM::Cell> &cStore = const_cast<MWWorld::Store<ESM::Cell>&>(mEsmStore->get<ESM::Cell>()); ESM::Cell *cellAlt = const_cast<ESM::Cell*>(cStore.searchOrCreate(cMRef.mTarget[0], cMRef.mTarget[1])); // Get regular moved reference data. Adapted from CellStore::loadRefs. Maybe we can optimize the following // implementation when the oher implementation works as well. bool deleted = false; cell->getNextRef(esm, ref, deleted); // Add data required to make reference appear in the correct cell. // We should not need to test for duplicates, as this part of the code is pre-cell merge. cell->mMovedRefs.push_back(cMRef); // But there may be duplicates here! ESM::CellRefTracker::iterator iter = std::find(cellAlt->mLeasedRefs.begin(), cellAlt->mLeasedRefs.end(), ref.mRefNum); if (iter == cellAlt->mLeasedRefs.end()) cellAlt->mLeasedRefs.push_back(ref); else *iter = ref; } }
virtual void read(ESM::ESMReader &esm) { std::string id = esm.getHNString("NAME"); CREC crec; crec.load(esm); mContext->mCreatureChanges.insert(std::make_pair(std::make_pair(crec.mIndex,id), crec)); }
void IdCollection<ESXRecordT, IdAccessorT>::load (ESM::ESMReader& reader, bool base) { std::string id = reader.getHNOString ("NAME"); if (reader.isNextSub ("DELE")) { int index = Collection<ESXRecordT, IdAccessorT>::searchId (id); reader.skipRecord(); if (index==-1) { // deleting a record that does not exist // ignore it for now /// \todo report the problem to the user } else if (base) { Collection<ESXRecordT, IdAccessorT>::removeRows (index, 1); } else { Record<ESXRecordT> record = Collection<ESXRecordT, IdAccessorT>::getRecord (index); record.mState = RecordBase::State_Deleted; this->setRecord (index, record); } } else { ESXRecordT record; int index = this->searchId (id); if (index==-1) IdAccessorT().getId (record) = id; else { record = this->getRecord (index).get(); } record.load (reader); load (record, base, index); } }
virtual void read(ESM::ESMReader& esm) { std::string id = esm.getHNString("NAME"); DIAL dial; dial.load(esm); if (dial.mIndex > 0) mDials[id] = dial; }
bool ESMStore::readRecord (ESM::ESMReader& reader, uint32_t type) { switch (type) { case ESM::REC_ALCH: case ESM::REC_ARMO: case ESM::REC_BOOK: case ESM::REC_CLAS: case ESM::REC_CLOT: case ESM::REC_ENCH: case ESM::REC_SPEL: case ESM::REC_WEAP: case ESM::REC_NPC_: case ESM::REC_LEVI: case ESM::REC_LEVC: { mStores[type]->read (reader); } if (type==ESM::REC_NPC_) { // NPC record will always be last and we know that there can be only one // dynamic NPC record (player) -> We are done here with dynamic record loading setUp(); const ESM::NPC *player = mNpcs.find ("player"); if (!mRaces.find (player->mRace) || !mClasses.find (player->mClass)) throw std::runtime_error ("Invalid player record (race or class unavailable"); } return true; case ESM::REC_DYNA: reader.getSubNameIs("COUN"); reader.getHT(mDynamicCount); return true; default: return false; } }
QSet<QString> CellNameLoader::getCellNames(QStringList &contentPaths) { QSet<QString> cellNames; ESM::ESMReader esmReader; // Loop through all content files for (auto &contentPath : contentPaths) { esmReader.open(contentPath.toStdString()); // Loop through all records while(esmReader.hasMoreRecs()) { ESM::NAME recordName = esmReader.getRecName(); esmReader.getRecHeader(); if (isCellRecord(recordName)) { QString cellName = getCellName(esmReader); if (!cellName.isEmpty()) { cellNames.insert(cellName); } } // Stop loading content for this record and continue to the next esmReader.skipRecord(); } } return cellNames; }
void CSMWorld::InfoCollection::load (ESM::ESMReader& reader, bool base, const ESM::Dialogue& dialogue) { std::string id = Misc::StringUtils::lowerCase (dialogue.mId) + "#" + reader.getHNOString ("INAM"); if (reader.isNextSub ("DELE")) { int index = searchId (id); reader.skipRecord(); if (index==-1) { // deleting a record that does not exist // ignore it for now /// \todo report the problem to the user } else if (base) { removeRows (index, 1); } else { Record<Info> record = getRecord (index); record.mState = RecordBase::State_Deleted; setRecord (index, record); } } else { Info record; record.mTopicId = dialogue.mId; record.mId = id; record.load (reader); load (record, base); } }
void Land::loadData(int flags) const { OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex); // Try to load only available data flags = flags & mDataTypes; // Return if all required data is loaded if ((mDataLoaded & flags) == flags) { return; } // Create storage if nothing is loaded if (mLandData == NULL) { mLandData = new LandData; mLandData->mDataTypes = mDataTypes; } ESM::ESMReader reader; reader.restoreContext(mContext); if (reader.isNextSub("VNML")) { condLoad(reader, flags, DATA_VNML, mLandData->mNormals, sizeof(mLandData->mNormals)); } if (reader.isNextSub("VHGT")) { static VHGT vhgt; if (condLoad(reader, flags, DATA_VHGT, &vhgt, sizeof(vhgt))) { float rowOffset = vhgt.mHeightOffset; for (int y = 0; y < LAND_SIZE; y++) { rowOffset += vhgt.mHeightData[y * LAND_SIZE]; mLandData->mHeights[y * LAND_SIZE] = rowOffset * HEIGHT_SCALE; float colOffset = rowOffset; for (int x = 1; x < LAND_SIZE; x++) { colOffset += vhgt.mHeightData[y * LAND_SIZE + x]; mLandData->mHeights[x + y * LAND_SIZE] = colOffset * HEIGHT_SCALE; } } mLandData->mUnk1 = vhgt.mUnk1; mLandData->mUnk2 = vhgt.mUnk2; } } if (reader.isNextSub("WNAM")) { condLoad(reader, flags, DATA_WNAM, mLandData->mWnam, 81); } if (reader.isNextSub("VCLR")) condLoad(reader, flags, DATA_VCLR, mLandData->mColours, 3 * LAND_NUM_VERTS); if (reader.isNextSub("VTEX")) { static uint16_t vtex[LAND_NUM_TEXTURES]; if (condLoad(reader, flags, DATA_VTEX, vtex, sizeof(vtex))) { LandData::transposeTextureData(vtex, mLandData->mTextures); } } }
void printRaw(ESM::ESMReader &esm) { while(esm.hasMoreRecs()) { ESM::NAME n = esm.getRecName(); std::cout << "Record: " << n.toString() << std::endl; esm.getRecHeader(); while(esm.hasMoreSubs()) { uint64_t offs = esm.getOffset(); esm.getSubName(); esm.skipHSub(); n = esm.retSubName(); std::cout << " " << n.toString() << " - " << esm.getSubSize() << " bytes @ 0x" << std::hex << offs << "\n"; } } }
void MWState::Character::addSlot (const boost::filesystem::path& path, const std::string& game) { Slot slot; slot.mPath = path; slot.mTimeStamp = boost::filesystem::last_write_time (path); ESM::ESMReader reader; reader.open (slot.mPath.string()); if (reader.getRecName()!=ESM::REC_SAVE) return; // invalid save file -> ignore reader.getRecHeader(); slot.mProfile.load (reader); if (Misc::StringUtils::lowerCase (slot.mProfile.mContentFiles.at (0))!= Misc::StringUtils::lowerCase (game)) return; // this file is for a different game -> ignore mSlots.push_back (slot); }
void CSMTools::FinishMergedDocumentStage::perform (int stage, CSMDoc::Messages& messages) { // We know that the content file list contains at least two entries and that the first one // does exist on disc (otherwise it would have been impossible to initiate a merge on that // document). boost::filesystem::path path = mState.mSource.getContentFiles()[0]; ESM::ESMReader reader; reader.setEncoder (&mEncoder); reader.open (path.string()); CSMWorld::MetaData source; source.mId = "sys::meta"; source.load (reader); CSMWorld::MetaData target = mState.mTarget->getData().getMetaData(); target.mAuthor = source.mAuthor; target.mDescription = source.mDescription; mState.mTarget->getData().setMetaData (target); mState.mCompleted = true; }
virtual void read(ESM::ESMReader &esm) { std::string id = esm.getHNString("NAME"); NPCC npcc; npcc.load(esm); if (id == "PlayerSaveGame") { convertNPCC(npcc, mContext->mPlayer.mObject); } else { int index = npcc.mNPDT.mIndex; mContext->mNpcChanges.insert(std::make_pair(std::make_pair(index,id), npcc)); } }
void DataFilesModel::addPlugins(const QString &path) { QDir dir(path); dir.setNameFilters(QStringList(QLatin1String("*.esp"))); foreach (const QString &path, dir.entryList()) { QFileInfo info(dir.absoluteFilePath(path)); EsmFile *file = new EsmFile(path); try { ESM::ESMReader fileReader; ToUTF8::Utf8Encoder encoder (ToUTF8::calculateEncoding(mEncoding.toStdString())); fileReader.setEncoder(&encoder); fileReader.open(dir.absoluteFilePath(path).toStdString()); ESM::ESMReader::MasterList mlist = fileReader.getMasters(); QStringList masters; for (unsigned int i = 0; i < mlist.size(); ++i) { QString master = QString::fromStdString(mlist[i].name); masters.append(master); // Add the plugin to the internal dependency map mDependencies[master].append(path); } file->setAuthor(QString::fromStdString(fileReader.getAuthor())); file->setSize(info.size()); file->setDates(info.lastModified(), info.lastRead()); file->setVersion(fileReader.getFVer()); file->setPath(info.absoluteFilePath()); file->setMasters(masters); file->setDescription(QString::fromStdString(fileReader.getDesc())); // Put the file in the table addFile(file); } catch(std::runtime_error &e) { // An error occurred while reading the .esp qWarning() << "Error reading esp: " << e.what(); continue; } } }
bool MWWorld::Cells::readRecord (ESM::ESMReader& reader, uint32_t type, const std::map<int, int>& contentFileMap) { if (type==ESM::REC_CSTA) { ESM::CellState state; state.mId.load (reader); CellStore *cellStore = 0; try { cellStore = getCell (state.mId); } catch (...) { // silently drop cells that don't exist anymore std::cerr << "Dropping state for cell " << state.mId.mWorldspace << " (cell no longer exists)" << std::endl; reader.skipRecord(); return true; } state.load (reader); cellStore->loadState (state); if (state.mHasFogOfWar) cellStore->readFog(reader); if (cellStore->getState()!=CellStore::State_Loaded) cellStore->load (); GetCellStoreCallback callback(*this); cellStore->readReferences (reader, contentFileMap, &callback); return true; } return false; }
bool MWWorld::Cells::readRecord (ESM::ESMReader& reader, uint32_t type, const std::map<int, int>& contentFileMap) { if (type==ESM::REC_CSTA) { ESM::CellState state; state.mId.load (reader); CellStore *cellStore = 0; try { cellStore = getCell (state.mId); } catch (...) { // silently drop cells that don't exist anymore reader.skipRecord(); return true; /// \todo log } state.load (reader); cellStore->loadState (state); if (state.mHasFogOfWar) cellStore->readFog(reader); if (cellStore->getState()!=CellStore::State_Loaded) cellStore->load (mStore, mReader); cellStore->readReferences (reader, contentFileMap); return true; } return false; }
void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base) { ESM::ESMReader reader; /// \todo set encoding properly, once config implementation has been fixed. ToUTF8::Utf8Encoder encoder (ToUTF8::calculateEncoding ("win1252")); reader.setEncoder (&encoder); reader.open (path.string()); // Note: We do not need to send update signals here, because at this point the model is not connected // to any view. while (reader.hasMoreRecs()) { ESM::NAME n = reader.getRecName(); reader.getRecHeader(); switch (n.val) { case ESM::REC_GLOB: mGlobals.load (reader, base); break; case ESM::REC_GMST: mGmsts.load (reader, base); break; case ESM::REC_SKIL: mSkills.load (reader, base); break; case ESM::REC_CLAS: mClasses.load (reader, base); break; case ESM::REC_FACT: mFactions.load (reader, base); break; case ESM::REC_RACE: mRaces.load (reader, base); break; case ESM::REC_SOUN: mSounds.load (reader, base); break; case ESM::REC_SCPT: mScripts.load (reader, base); break; case ESM::REC_REGN: mRegions.load (reader, base); break; case ESM::REC_BSGN: mBirthsigns.load (reader, base); break; case ESM::REC_SPEL: mSpells.load (reader, base); break; case ESM::REC_CELL: mCells.load (reader, base); break; default: /// \todo throw an exception instead, once all records are implemented reader.skipRecord(); } } }
std::map<int, int> MWState::StateManager::buildContentFileIndexMap (const ESM::ESMReader& reader) const { const std::vector<std::string>& current = MWBase::Environment::get().getWorld()->getContentFiles(); const std::vector<ESM::Header::MasterData>& prev = reader.getGameFiles(); std::map<int, int> map; for (int iPrev = 0; iPrev<static_cast<int> (prev.size()); ++iPrev) { std::string id = Misc::StringUtils::lowerCase (prev[iPrev].name); for (int iCurrent = 0; iCurrent<static_cast<int> (current.size()); ++iCurrent) if (id==Misc::StringUtils::lowerCase (current[iCurrent])) { map.insert (std::make_pair (iPrev, iCurrent)); break; } } return map; }
virtual void read(ESM::ESMReader &esm) { std::string itemid = esm.getHNString("NAME"); Misc::StringUtils::lowerCaseInPlace(itemid); while (esm.isNextSub("FNAM") || esm.isNextSub("ONAM")) { if (esm.retSubName().toString() == "FNAM") { std::string factionid = esm.getHString(); mStolenItems[itemid].insert(std::make_pair(Misc::StringUtils::lowerCase(factionid), true)); } else { std::string ownerid = esm.getHString(); mStolenItems[itemid].insert(std::make_pair(Misc::StringUtils::lowerCase(ownerid), false)); } } }
virtual void read(ESM::ESMReader& esm) { std::string id = esm.getHNString("NAME"); QUES quest; quest.load(esm); }
void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base) { ESM::ESMReader reader; /// \todo set encoding properly, once config implementation has been fixed. ToUTF8::Utf8Encoder encoder (ToUTF8::calculateEncoding ("win1252")); reader.setEncoder (&encoder); reader.open (path.string()); // Note: We do not need to send update signals here, because at this point the model is not connected // to any view. while (reader.hasMoreRecs()) { ESM::NAME n = reader.getRecName(); reader.getRecHeader(); switch (n.val) { case ESM::REC_GLOB: mGlobals.load (reader, base); break; case ESM::REC_GMST: mGmsts.load (reader, base); break; case ESM::REC_SKIL: mSkills.load (reader, base); break; case ESM::REC_CLAS: mClasses.load (reader, base); break; case ESM::REC_FACT: mFactions.load (reader, base); break; case ESM::REC_RACE: mRaces.load (reader, base); break; case ESM::REC_SOUN: mSounds.load (reader, base); break; case ESM::REC_SCPT: mScripts.load (reader, base); break; case ESM::REC_REGN: mRegions.load (reader, base); break; case ESM::REC_BSGN: mBirthsigns.load (reader, base); break; case ESM::REC_SPEL: mSpells.load (reader, base); break; case ESM::REC_CELL: mCells.load (reader, base); mRefs.load (reader, mCells.getSize()-1, base); break; case ESM::REC_ACTI: mReferenceables.load (reader, base, UniversalId::Type_Activator); break; case ESM::REC_ALCH: mReferenceables.load (reader, base, UniversalId::Type_Potion); break; case ESM::REC_APPA: mReferenceables.load (reader, base, UniversalId::Type_Apparatus); break; case ESM::REC_ARMO: mReferenceables.load (reader, base, UniversalId::Type_Armor); break; case ESM::REC_BOOK: mReferenceables.load (reader, base, UniversalId::Type_Book); break; case ESM::REC_CLOT: mReferenceables.load (reader, base, UniversalId::Type_Clothing); break; case ESM::REC_CONT: mReferenceables.load (reader, base, UniversalId::Type_Container); break; case ESM::REC_CREA: mReferenceables.load (reader, base, UniversalId::Type_Creature); break; case ESM::REC_DOOR: mReferenceables.load (reader, base, UniversalId::Type_Door); break; case ESM::REC_INGR: mReferenceables.load (reader, base, UniversalId::Type_Ingredient); break; case ESM::REC_LEVC: mReferenceables.load (reader, base, UniversalId::Type_CreatureLevelledList); break; case ESM::REC_LEVI: mReferenceables.load (reader, base, UniversalId::Type_ItemLevelledList); break; case ESM::REC_LIGH: mReferenceables.load (reader, base, UniversalId::Type_Light); break; case ESM::REC_LOCK: mReferenceables.load (reader, base, UniversalId::Type_Lockpick); break; case ESM::REC_MISC: mReferenceables.load (reader, base, UniversalId::Type_Miscellaneous); break; case ESM::REC_NPC_: mReferenceables.load (reader, base, UniversalId::Type_Npc); break; case ESM::REC_PROB: mReferenceables.load (reader, base, UniversalId::Type_Probe); break; case ESM::REC_REPA: mReferenceables.load (reader, base, UniversalId::Type_Repair); break; case ESM::REC_STAT: mReferenceables.load (reader, base, UniversalId::Type_Static); break; case ESM::REC_WEAP: mReferenceables.load (reader, base, UniversalId::Type_Weapon); break; default: /// \todo throw an exception instead, once all records are implemented reader.skipRecord(); } } }
void CellStore::readReferences (ESM::ESMReader& reader, const std::map<int, int>& contentFileMap) { while (reader.isNextSub ("OBJE")) { unsigned int id = 0; reader.getHT (id); switch (id) { case ESM::REC_ACTI: readReferenceCollection<ESM::ObjectState> (reader, mActivators, contentFileMap); break; case ESM::REC_ALCH: readReferenceCollection<ESM::ObjectState> (reader, mPotions, contentFileMap); break; case ESM::REC_APPA: readReferenceCollection<ESM::ObjectState> (reader, mAppas, contentFileMap); break; case ESM::REC_ARMO: readReferenceCollection<ESM::ObjectState> (reader, mArmors, contentFileMap); break; case ESM::REC_BOOK: readReferenceCollection<ESM::ObjectState> (reader, mBooks, contentFileMap); break; case ESM::REC_CLOT: readReferenceCollection<ESM::ObjectState> (reader, mClothes, contentFileMap); break; case ESM::REC_CONT: readReferenceCollection<ESM::ContainerState> (reader, mContainers, contentFileMap); break; case ESM::REC_CREA: readReferenceCollection<ESM::CreatureState> (reader, mCreatures, contentFileMap); break; case ESM::REC_DOOR: readReferenceCollection<ESM::ObjectState> (reader, mDoors, contentFileMap); break; case ESM::REC_INGR: readReferenceCollection<ESM::ObjectState> (reader, mIngreds, contentFileMap); break; case ESM::REC_LEVC: readReferenceCollection<ESM::ObjectState> (reader, mCreatureLists, contentFileMap); break; case ESM::REC_LEVI: readReferenceCollection<ESM::ObjectState> (reader, mItemLists, contentFileMap); break; case ESM::REC_LIGH: readReferenceCollection<ESM::LightState> (reader, mLights, contentFileMap); break; case ESM::REC_LOCK: readReferenceCollection<ESM::ObjectState> (reader, mLockpicks, contentFileMap); break; case ESM::REC_MISC: readReferenceCollection<ESM::ObjectState> (reader, mMiscItems, contentFileMap); break; case ESM::REC_NPC_: readReferenceCollection<ESM::NpcState> (reader, mNpcs, contentFileMap); break; case ESM::REC_PROB: readReferenceCollection<ESM::ObjectState> (reader, mProbes, contentFileMap); break; case ESM::REC_REPA: readReferenceCollection<ESM::ObjectState> (reader, mRepairs, contentFileMap); break; case ESM::REC_STAT: readReferenceCollection<ESM::ObjectState> (reader, mStatics, contentFileMap); break; case ESM::REC_WEAP: readReferenceCollection<ESM::ObjectState> (reader, mWeapons, contentFileMap); break; default: throw std::runtime_error ("unknown type in cell reference section"); } } }