void ESM::DebugProfile::load (ESMReader& esm, bool &isDeleted) { isDeleted = false; while (esm.hasMoreSubs()) { esm.getSubName(); switch (esm.retSubName().intval) { case ESM::SREC_NAME: mId = esm.getHString(); break; case ESM::FourCC<'D','E','S','C'>::value: mDescription = esm.getHString(); break; case ESM::FourCC<'S','C','R','P'>::value: mScriptText = esm.getHString(); break; case ESM::FourCC<'F','L','A','G'>::value: esm.getHT(mFlags); break; case ESM::SREC_DELE: esm.skipHSub(); isDeleted = true; break; default: esm.fail("Unknown subrecord"); break; } } }
void Door::load(ESMReader &esm) { while (esm.hasMoreSubs()) { esm.getSubName(); uint32_t name = esm.retSubName().val; switch (name) { case ESM::FourCC<'M','O','D','L'>::value: mModel = esm.getHString(); break; case ESM::FourCC<'F','N','A','M'>::value: mName = esm.getHString(); break; case ESM::FourCC<'S','C','R','I'>::value: mScript = esm.getHString(); break; case ESM::FourCC<'S','N','A','M'>::value: mOpenSound = esm.getHString(); break; case ESM::FourCC<'A','N','A','M'>::value: mCloseSound = esm.getHString(); break; default: esm.fail("Unknown subrecord"); } } }
void BodyPart::load(ESMReader &esm) { bool hasData = false; while (esm.hasMoreSubs()) { esm.getSubName(); uint32_t name = esm.retSubName().val; switch (name) { case ESM::FourCC<'M','O','D','L'>::value: mModel = esm.getHString(); break; case ESM::FourCC<'F','N','A','M'>::value: mRace = esm.getHString(); break; case ESM::FourCC<'B','Y','D','T'>::value: esm.getHT(mData, 4); hasData = true; break; default: esm.fail("Unknown subrecord"); } } if (!hasData) esm.fail("Missing BYDT subrecord"); }
void StartScript::load(ESMReader &esm, bool &isDeleted) { isDeleted = false; bool hasData = false; bool hasName = false; while (esm.hasMoreSubs()) { esm.getSubName(); switch (esm.retSubName().val) { case ESM::SREC_NAME: mId = esm.getHString(); hasName = true; break; case ESM::FourCC<'D','A','T','A'>::value: mData = esm.getHString(); hasData = true; break; case ESM::SREC_DELE: esm.skipHSub(); isDeleted = true; break; default: esm.fail("Unknown subrecord"); break; } } if (!hasName) esm.fail("Missing NAME"); if (!hasData && !isDeleted) esm.fail("Missing DATA"); }
void SpellState::load(ESMReader &esm) { while (esm.isNextSub("SPEL")) { std::string id = esm.getHString(); std::map<const int, float> random; while (esm.isNextSub("INDX")) { int index; esm.getHT(index); float magnitude; esm.getHNT(magnitude, "RAND"); random[index] = magnitude; } mSpells[id] = random; } while (esm.isNextSub("USED")) { std::string id = esm.getHString(); TimeStamp time; esm.getHNT(time, "TIME"); mUsedPowers[id] = time; } mSelectedSpell = esm.getHNOString("SLCT"); }
void Weapon::load(ESMReader &esm) { bool hasData = false; while (esm.hasMoreSubs()) { esm.getSubName(); uint32_t name = esm.retSubName().val; switch (name) { case ESM::FourCC<'M','O','D','L'>::value: mModel = esm.getHString(); break; case ESM::FourCC<'F','N','A','M'>::value: mName = esm.getHString(); break; case ESM::FourCC<'W','P','D','T'>::value: esm.getHT(mData, 32); hasData = true; break; case ESM::FourCC<'S','C','R','I'>::value: mScript = esm.getHString(); break; case ESM::FourCC<'I','T','E','X'>::value: mIcon = esm.getHString(); break; case ESM::FourCC<'E','N','A','M'>::value: mEnchant = esm.getHString(); break; default: esm.fail("Unknown subrecord"); } } if (!hasData) esm.fail("Missing WPDT subrecord"); }
void Faction::load(ESMReader &esm, bool &isDeleted) { isDeleted = false; mReactions.clear(); for (int i=0;i<10;++i) mRanks[i].clear(); int rankCounter = 0; bool hasName = false; bool hasData = false; while (esm.hasMoreSubs()) { esm.getSubName(); switch (esm.retSubName().val) { case ESM::SREC_NAME: mId = esm.getHString(); hasName = true; break; case ESM::FourCC<'F','N','A','M'>::value: mName = esm.getHString(); break; case ESM::FourCC<'R','N','A','M'>::value: if (rankCounter >= 10) esm.fail("Rank out of range"); mRanks[rankCounter++] = esm.getHString(); break; case ESM::FourCC<'F','A','D','T'>::value: esm.getHT(mData, 240); if (mData.mIsHidden > 1) esm.fail("Unknown flag!"); hasData = true; break; case ESM::FourCC<'A','N','A','M'>::value: { std::string faction = esm.getHString(); int reaction; esm.getHNT(reaction, "INTV"); mReactions[faction] = reaction; break; } case ESM::SREC_DELE: esm.skipHSub(); isDeleted = true; break; default: esm.fail("Unknown subrecord"); break; } } if (!hasName) esm.fail("Missing NAME subrecord"); if (!hasData && !isDeleted) esm.fail("Missing FADT subrecord"); }
void GameSetting::load(ESMReader &esm) { assert(mId != ""); // We are apparently allowed to be empty if (!esm.hasMoreSubs()) { mType = VT_None; return; } // Load some data esm.getSubName(); NAME n = esm.retSubName(); if (n == "STRV") { mStr = esm.getHString(); mType = VT_String; } else if (n == "INTV") { esm.getHT(mI); mType = VT_Int; } else if (n == "FLTV") { esm.getHT(mF); mType = VT_Float; } else esm.fail("Unwanted subrecord type"); }
void Skill::load(ESMReader &esm) { bool hasIndex = false; bool hasData = false; while (esm.hasMoreSubs()) { esm.getSubName(); uint32_t name = esm.retSubName().val; switch (name) { case ESM::FourCC<'I','N','D','X'>::value: esm.getHT(mIndex); hasIndex = true; break; case ESM::FourCC<'S','K','D','T'>::value: esm.getHT(mData, 24); hasData = true; break; case ESM::FourCC<'D','E','S','C'>::value: mDescription = esm.getHString(); break; default: esm.fail("Unknown subrecord"); } } if (!hasIndex) esm.fail("Missing INDX"); if (!hasData) esm.fail("Missing SKDT"); // create an ID from the index and the name (only used in the editor and likely to change in the // future) mId = indexToId (mIndex); }
void ESM::Header::load (ESMReader &esm) { if (esm.isNextSub("HEDR")) { esm.getSubHeader(); esm.getT(mData.version); esm.getT(mData.type); mData.author.assign(esm.getString(sizeof(mData.author.name))); mData.desc.assign(esm.getString(sizeof(mData.desc.name))); esm.getT(mData.records); } if (esm.isNextSub ("FORM")) { esm.getHT (mFormat); if (mFormat<0) esm.fail ("invalid format code"); } else mFormat = 0; while (esm.isNextSub ("MAST")) { MasterData m; m.name = esm.getHString(); m.size = esm.getHNLong ("DATA"); mMaster.push_back (m); } }
void Script::load(ESMReader &esm) { SCHD data; esm.getHNT(data, "SCHD", 52); mData = data.mData; mId = data.mName.toString(); mVarNames.clear(); while (esm.hasMoreSubs()) { esm.getSubName(); uint32_t name = esm.retSubName().val; switch (name) { case ESM::FourCC<'S','C','V','R'>::value: // list of local variables loadSCVR(esm); break; case ESM::FourCC<'S','C','D','T'>::value: // compiled script mScriptData.resize(mData.mScriptDataSize); esm.getHExact(&mScriptData[0], mScriptData.size()); break; case ESM::FourCC<'S','C','T','X'>::value: mScriptText = esm.getHString(); break; default: esm.fail("Unknown subrecord"); } } }
void AIPackageList::add(ESMReader &esm) { AIPackage pack; if (esm.retSubName() == AI_CNDT) { mList.back().mCellName = esm.getHString(); } else if (esm.retSubName() == AI_Wander) { pack.mType = AI_Wander; esm.getHExact(&pack.mWander, 14); mList.push_back(pack); } else if (esm.retSubName() == AI_Travel) { pack.mType = AI_Travel; esm.getHExact(&pack.mTravel, 16); mList.push_back(pack); } else if (esm.retSubName() == AI_Escort || esm.retSubName() == AI_Follow) { pack.mType = (esm.retSubName() == AI_Escort) ? AI_Escort : AI_Follow; esm.getHExact(&pack.mTarget, 48); mList.push_back(pack); } else if (esm.retSubName() == AI_Activate) { pack.mType = AI_Activate; esm.getHExact(&pack.mActivate, 33); mList.push_back(pack); } else { // not AI package related data, so leave return; } }
void Apparatus::load(ESMReader &esm, bool &isDeleted) { isDeleted = false; bool hasName = false; bool hasData = false; while (esm.hasMoreSubs()) { esm.getSubName(); switch (esm.retSubName().intval) { case ESM::SREC_NAME: mId = esm.getHString(); hasName = true; break; case ESM::FourCC<'M','O','D','L'>::value: mModel = esm.getHString(); break; case ESM::FourCC<'F','N','A','M'>::value: mName = esm.getHString(); break; case ESM::FourCC<'A','A','D','T'>::value: esm.getHT(mData); hasData = true; break; case ESM::FourCC<'S','C','R','I'>::value: mScript = esm.getHString(); break; case ESM::FourCC<'I','T','E','X'>::value: mIcon = esm.getHString(); break; case ESM::SREC_DELE: esm.skipHSub(); isDeleted = true; break; default: esm.fail("Unknown subrecord"); break; } } if (!hasName) esm.fail("Missing NAME subrecord"); if (!hasData && !isDeleted) esm.fail("Missing AADT subrecord"); }
void NPC::load(ESMReader &esm) { mNpdt52.mGold = -10; mPersistent = esm.getRecordFlags() & 0x0400; mModel = esm.getHNOString("MODL"); mName = esm.getHNOString("FNAM"); mRace = esm.getHNString("RNAM"); mClass = esm.getHNString("CNAM"); mFaction = esm.getHNString("ANAM"); mHead = esm.getHNString("BNAM"); mHair = esm.getHNString("KNAM"); mScript = esm.getHNOString("SCRI"); esm.getSubNameIs("NPDT"); esm.getSubHeader(); if (esm.getSubSize() == 52) { mNpdtType = 52; esm.getExact(&mNpdt52, 52); } else if (esm.getSubSize() == 12) { mNpdtType = 12; esm.getExact(&mNpdt12, 12); } else esm.fail("NPC_NPDT must be 12 or 52 bytes long"); esm.getHNT(mFlags, "FLAG"); mInventory.load(esm); mSpells.load(esm); if (esm.isNextSub("AIDT")) { esm.getHExact(&mAiData, sizeof(mAiData)); mHasAI= true; } else mHasAI = false; while (esm.isNextSub("DODT") || esm.isNextSub("DNAM")) { if (esm.retSubName() == 0x54444f44) { // DODT struct Dest dodt; esm.getHExact(&dodt.mPos, 24); mTransport.push_back(dodt); } else if (esm.retSubName() == 0x4d414e44) { // DNAM struct mTransport.back().mCellName = esm.getHString(); } } mAiPackage.load(esm); esm.skipRecord(); }
void Container::load(ESMReader &esm) { mInventory.mList.clear(); bool hasWeight = false; bool hasFlags = false; while (esm.hasMoreSubs()) { esm.getSubName(); uint32_t name = esm.retSubName().val; switch (name) { case ESM::FourCC<'M','O','D','L'>::value: mModel = esm.getHString(); break; case ESM::FourCC<'F','N','A','M'>::value: mName = esm.getHString(); break; case ESM::FourCC<'C','N','D','T'>::value: esm.getHT(mWeight, 4); hasWeight = true; break; case ESM::FourCC<'F','L','A','G'>::value: esm.getHT(mFlags, 4); if (mFlags & 0xf4) esm.fail("Unknown flags"); if (!(mFlags & 0x8)) esm.fail("Flag 8 not set"); hasFlags = true; break; case ESM::FourCC<'S','C','R','I'>::value: mScript = esm.getHString(); break; case ESM::FourCC<'N','P','C','O'>::value: mInventory.add(esm); break; default: esm.fail("Unknown subrecord"); } } if (!hasWeight) esm.fail("Missing CNDT subrecord"); if (!hasFlags) esm.fail("Missing FLAG subrecord"); }
void Spell::load(ESMReader &esm, bool &isDeleted) { isDeleted = false; mEffects.mList.clear(); bool hasName = false; bool hasData = false; while (esm.hasMoreSubs()) { esm.getSubName(); switch (esm.retSubName().val) { case ESM::SREC_NAME: mId = esm.getHString(); hasName = true; break; case ESM::FourCC<'F','N','A','M'>::value: mName = esm.getHString(); break; case ESM::FourCC<'S','P','D','T'>::value: esm.getHT(mData, 12); hasData = true; break; case ESM::FourCC<'E','N','A','M'>::value: ENAMstruct s; esm.getHT(s, 24); mEffects.mList.push_back(s); break; case ESM::SREC_DELE: esm.skipHSub(); isDeleted = true; break; default: esm.fail("Unknown subrecord"); break; } } if (!hasName) esm.fail("Missing NAME subrecord"); if (!hasData && !isDeleted) esm.fail("Missing SPDT subrecord"); }
void Race::load(ESMReader &esm, bool &isDeleted) { isDeleted = false; mPowers.mList.clear(); bool hasName = false; bool hasData = false; while (esm.hasMoreSubs()) { esm.getSubName(); switch (esm.retSubName().val) { case ESM::SREC_NAME: mId = esm.getHString(); hasName = true; break; case ESM::FourCC<'F','N','A','M'>::value: mName = esm.getHString(); break; case ESM::FourCC<'R','A','D','T'>::value: esm.getHT(mData, 140); hasData = true; break; case ESM::FourCC<'D','E','S','C'>::value: mDescription = esm.getHString(); break; case ESM::FourCC<'N','P','C','S'>::value: mPowers.add(esm); break; case ESM::SREC_DELE: esm.skipHSub(); isDeleted = true; break; default: esm.fail("Unknown subrecord"); } } if (!hasName) esm.fail("Missing NAME subrecord"); if (!hasData && !isDeleted) esm.fail("Missing RADT subrecord"); }
void ESM::DialogueState::load (ESMReader &esm) { while (esm.isNextSub ("TOPI")) mKnownTopics.push_back (esm.getHString()); while (esm.isNextSub ("FACT")) { std::string faction = esm.getHString(); while (esm.isNextSub ("REAC")) { std::string faction2 = esm.getHString(); int reaction; esm.getHNT(reaction, "INTV"); mModFactionReaction[faction][faction2] = reaction; } } }
void Faction::load(ESMReader &esm) { mReactions.clear(); for (int i=0;i<10;++i) mRanks[i].clear(); int rankCounter=0; bool hasData = false; while (esm.hasMoreSubs()) { esm.getSubName(); uint32_t name = esm.retSubName().val; switch (name) { case ESM::FourCC<'F','N','A','M'>::value: mName = esm.getHString(); break; case ESM::FourCC<'R','N','A','M'>::value: if (rankCounter >= 10) esm.fail("Rank out of range"); mRanks[rankCounter++] = esm.getHString(); break; case ESM::FourCC<'F','A','D','T'>::value: esm.getHT(mData, 240); if (mData.mIsHidden > 1) esm.fail("Unknown flag!"); hasData = true; break; case ESM::FourCC<'A','N','A','M'>::value: { std::string faction = esm.getHString(); int reaction; esm.getHNT(reaction, "INTV"); mReactions[faction] = reaction; break; } default: esm.fail("Unknown subrecord"); } } if (!hasData) esm.fail("Missing FADT subrecord"); }
void Class::load(ESMReader &esm, bool &isDeleted) { isDeleted = false; bool hasName = false; bool hasData = false; while (esm.hasMoreSubs()) { esm.getSubName(); switch (esm.retSubName().intval) { case ESM::SREC_NAME: mId = esm.getHString(); hasName = true; break; case ESM::FourCC<'F','N','A','M'>::value: mName = esm.getHString(); break; case ESM::FourCC<'C','L','D','T'>::value: esm.getHT(mData, 60); if (mData.mIsPlayable > 1) esm.fail("Unknown bool value"); hasData = true; break; case ESM::FourCC<'D','E','S','C'>::value: mDescription = esm.getHString(); break; case ESM::SREC_DELE: esm.skipHSub(); isDeleted = true; break; default: esm.fail("Unknown subrecord"); break; } } if (!hasName) esm.fail("Missing NAME subrecord"); if (!hasData && !isDeleted) esm.fail("Missing CLDT subrecord"); }
void Apparatus::load(ESMReader &esm) { // we will not treat duplicated subrecords as errors here while (esm.hasMoreSubs()) { esm.getSubName(); NAME subName = esm.retSubName(); if (subName == "MODL") mModel = esm.getHString(); else if (subName == "FNAM") mName = esm.getHString(); else if (subName == "AADT") esm.getHT(mData); else if (subName == "SCRI") mScript = esm.getHString(); else if (subName == "ITEX") mIcon = esm.getHString(); else esm.fail("wrong subrecord type " + subName.toString() + " for APPA record"); } }
void ESM::VariantStringData::read (ESMReader& esm, Variant::Format format, VarType type) { if (type!=VT_String) throw std::logic_error ("not a string type"); if (format==Variant::Format_Global) esm.fail ("global variables of type string not supported"); if (format==Variant::Format_Info) esm.fail ("info variables of type string not supported"); // GMST mValue = esm.getHString(); }
void Cell::loadNameAndData(ESMReader &esm, bool &isDeleted) { isDeleted = false; blank(); bool hasData = false; bool isLoaded = false; while (!isLoaded && esm.hasMoreSubs()) { esm.getSubName(); switch (esm.retSubName().intval) { case ESM::SREC_NAME: mName = esm.getHString(); break; case ESM::FourCC<'D','A','T','A'>::value: esm.getHT(mData, 12); hasData = true; break; case ESM::SREC_DELE: esm.skipHSub(); isDeleted = true; break; default: esm.cacheSubName(); isLoaded = true; break; } } if (!hasData) esm.fail("Missing DATA subrecord"); mCellId.mPaged = !(mData.mFlags & Interior); if (mCellId.mPaged) { mCellId.mWorldspace = ESM::CellId::sDefaultWorldspace; mCellId.mIndex.mX = mData.mX; mCellId.mIndex.mY = mData.mY; } else { mCellId.mWorldspace = Misc::StringUtils::lowerCase (mName); mCellId.mIndex.mX = 0; mCellId.mIndex.mY = 0; } }
void Cell::loadCell(ESMReader &esm, bool saveContext) { bool isLoaded = false; while (!isLoaded && esm.hasMoreSubs()) { esm.getSubName(); switch (esm.retSubName().intval) { case ESM::FourCC<'I','N','T','V'>::value: int waterl; esm.getHT(waterl); mWater = static_cast<float>(waterl); mWaterInt = true; break; case ESM::FourCC<'W','H','G','T'>::value: esm.getHT(mWater); mWaterInt = false; break; case ESM::FourCC<'A','M','B','I'>::value: esm.getHT(mAmbi); break; case ESM::FourCC<'R','G','N','N'>::value: mRegion = esm.getHString(); break; case ESM::FourCC<'N','A','M','5'>::value: esm.getHT(mMapColor); break; case ESM::FourCC<'N','A','M','0'>::value: esm.getHT(mRefNumCounter); break; default: esm.cacheSubName(); isLoaded = true; break; } } if (saveContext) { mContextList.push_back(esm.getContext()); esm.skipRecord(); } }
void ESM::Header::load (ESMReader &esm) { esm.getHNT (mData, "HEDR", 300); if (esm.isNextSub ("FORM")) { esm.getHT (mFormat); if (mFormat<0) esm.fail ("invalid format code"); } else mFormat = 0; while (esm.isNextSub ("MAST")) { MasterData m; m.name = esm.getHString(); m.size = esm.getHNLong ("DATA"); mMaster.push_back (m); } }
void load(ESMReader &esm) { name = esm.getHNString("FNAM"); // Read rank names. These are optional. int i = 0; while(esm.isNextSub("RNAM") && i<10) ranks[i++] = esm.getHString(); // Main data struct esm.getHNT(data, "FADT", 240); if(data.isHidden > 1) esm.fail("Unknown flag!"); // Read faction response values while(esm.hasMoreSubs()) { Reaction r; r.faction = esm.getHNString("ANAM"); esm.getHNT(r.reaction, "INTV"); reactions.push_back(r); } }
void Enchantment::load(ESMReader &esm, bool &isDeleted) { isDeleted = false; mEffects.mList.clear(); bool hasName = false; bool hasData = false; while (esm.hasMoreSubs()) { esm.getSubName(); switch (esm.retSubName().intval) { case ESM::SREC_NAME: mId = esm.getHString(); hasName = true; break; case ESM::FourCC<'E','N','D','T'>::value: esm.getHT(mData, 16); hasData = true; break; case ESM::FourCC<'E','N','A','M'>::value: mEffects.add(esm); break; case ESM::SREC_DELE: esm.skipHSub(); isDeleted = true; break; default: esm.fail("Unknown subrecord"); break; } } if (!hasName) esm.fail("Missing NAME subrecord"); if (!hasData && !isDeleted) esm.fail("Missing ENDT subrecord"); }
void Door::load(ESMReader &esm, bool &isDeleted) { isDeleted = false; bool hasName = false; while (esm.hasMoreSubs()) { esm.getSubName(); switch (esm.retSubName().val) { case ESM::SREC_NAME: mId = esm.getHString(); hasName = true; break; case ESM::FourCC<'M','O','D','L'>::value: mModel = esm.getHString(); break; case ESM::FourCC<'F','N','A','M'>::value: mName = esm.getHString(); break; case ESM::FourCC<'S','C','R','I'>::value: mScript = esm.getHString(); break; case ESM::FourCC<'S','N','A','M'>::value: mOpenSound = esm.getHString(); break; case ESM::FourCC<'A','N','A','M'>::value: mCloseSound = esm.getHString(); break; case ESM::SREC_DELE: esm.skipHSub(); isDeleted = true; break; default: esm.fail("Unknown subrecord"); break; } } if (!hasName) esm.fail("Missing NAME subrecord"); }
void DialInfo::load(ESMReader &esm) { mId = esm.getHNString("INAM"); mPrev = esm.getHNString("PNAM"); mNext = esm.getHNString("NNAM"); // Not present if deleted if (esm.isNextSub("DATA")) { esm.getHT(mData, 12); } // What follows is somewhat spaghetti-ish, but it's worth if for // an extra speedup. INFO is by far the most common record type. // subName is a reference to the original, so it changes whenever // a new sub name is read. esm.isEmptyOrGetName() will get the // next name for us, or return true if there are no more records. esm.getSubName(); const NAME &subName = esm.retSubName(); if (subName.val == REC_ONAM) { mActor = esm.getHString(); if (esm.isEmptyOrGetName()) return; } if (subName.val == REC_RNAM) { mRace = esm.getHString(); if (esm.isEmptyOrGetName()) return; } if (subName.val == REC_CNAM) { mClass = esm.getHString(); if (esm.isEmptyOrGetName()) return; } mFactionLess = false; if (subName.val == REC_FNAM) { mNpcFaction = esm.getHString(); if (mNpcFaction == "FFFF") mFactionLess = true; if (esm.isEmptyOrGetName()) return; } if (subName.val == REC_ANAM) { mCell = esm.getHString(); if (esm.isEmptyOrGetName()) return; } if (subName.val == REC_DNAM) { mPcFaction = esm.getHString(); if (esm.isEmptyOrGetName()) return; } if (subName.val == REC_SNAM) { mSound = esm.getHString(); if (esm.isEmptyOrGetName()) return; } if (subName.val == REC_NAME) { mResponse = esm.getHString(); if (esm.isEmptyOrGetName()) return; } while (subName.val == REC_SCVR) { SelectStruct ss; ss.mSelectRule = esm.getHString(); esm.isEmptyOrGetName(); if (subName.val == REC_INTV) { ss.mType = VT_Int; esm.getHT(ss.mI); } else if (subName.val == REC_FLTV) { ss.mType = VT_Float; esm.getHT(ss.mF); } else esm.fail( "INFO.SCVR must precede INTV or FLTV, not " + subName.toString()); mSelects.push_back(ss); if (esm.isEmptyOrGetName()) return; } if (subName.val == REC_BNAM) { mResultScript = esm.getHString(); if (esm.isEmptyOrGetName()) return; } mQuestStatus = QS_None; if (subName.val == REC_QSTN) mQuestStatus = QS_Name; else if (subName.val == REC_QSTF) mQuestStatus = QS_Finished; else if (subName.val == REC_QSTR) mQuestStatus = QS_Restart; else if (subName.val == REC_DELE) mQuestStatus = QS_Deleted; else esm.fail( "Don't know what to do with " + subName.toString() + " in INFO " + mId); if (mQuestStatus != QS_None) // Skip rest of record esm.skipRecord(); }
void LevelledListBase::load(ESMReader &esm, bool &isDeleted) { isDeleted = false; bool hasName = false; bool hasList = false; while (esm.hasMoreSubs()) { esm.getSubName(); switch (esm.retSubName().val) { case ESM::SREC_NAME: mId = esm.getHString(); hasName = true; break; case ESM::FourCC<'D','A','T','A'>::value: esm.getHT(mFlags); break; case ESM::FourCC<'N','N','A','M'>::value: esm.getHT(mChanceNone); break; case ESM::FourCC<'I','N','D','X'>::value: { int length = 0; esm.getHT(length); mList.resize(length); // If this levelled list was already loaded by a previous content file, // we overwrite the list. Merging lists should probably be left to external tools, // with the limited amount of information there is in the records, all merging methods // will be flawed in some way. For a proper fix the ESM format would have to be changed // to actually track list changes instead of including the whole list for every file // that does something with that list. for (size_t i = 0; i < mList.size(); i++) { LevelItem &li = mList[i]; li.mId = esm.getHNString(mRecName); esm.getHNT(li.mLevel, "INTV"); } hasList = true; break; } case ESM::SREC_DELE: esm.skipHSub(); isDeleted = true; break; default: { if (!hasList) { // Original engine ignores rest of the record, even if there are items following mList.clear(); esm.skipRecord(); } else { esm.fail("Unknown subrecord"); } break; } } } if (!hasName) esm.fail("Missing NAME subrecord"); }