本文整理汇总了C++中esm::ESMReader::isNextSub方法的典型用法代码示例。如果您正苦于以下问题:C++ ESMReader::isNextSub方法的具体用法?C++ ESMReader::isNextSub怎么用?C++ ESMReader::isNextSub使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类esm::ESMReader
的用法示例。
在下文中一共展示了ESMReader::isNextSub方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: loadData
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);
}
}
}
示例2: while
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;
}
}
示例3: if
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;
}
}
}
示例4: if
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);
}
}
}
示例5: read
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));
}
}
}
示例6: if
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);
}
}
示例7: if
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);
}
}
示例8: readReferences
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;
//.........这里部分代码省略.........
示例9: readReferences
void CellStore::readReferences (ESM::ESMReader& reader, const std::map<int, int>& contentFileMap, GetCellStoreCallback* callback)
{
mHasState = true;
while (reader.isNextSub ("OBJE"))
{
unsigned int unused;
reader.getHT (unused);
// load the RefID first so we know what type of object it is
ESM::CellRef cref;
cref.loadId(reader, true);
int type = MWBase::Environment::get().getWorld()->getStore().find(cref.mRefID);
if (type == 0)
{
std::cerr << "Dropping reference to '" << cref.mRefID << "' (object no longer exists)" << std::endl;
reader.skipHSubUntil("OBJE");
continue;
}
switch (type)
{
case ESM::REC_ACTI:
readReferenceCollection<ESM::ObjectState> (reader, mActivators, cref, contentFileMap);
break;
case ESM::REC_ALCH:
readReferenceCollection<ESM::ObjectState> (reader, mPotions, cref, contentFileMap);
break;
case ESM::REC_APPA:
readReferenceCollection<ESM::ObjectState> (reader, mAppas, cref, contentFileMap);
break;
case ESM::REC_ARMO:
readReferenceCollection<ESM::ObjectState> (reader, mArmors, cref, contentFileMap);
break;
case ESM::REC_BOOK:
readReferenceCollection<ESM::ObjectState> (reader, mBooks, cref, contentFileMap);
break;
case ESM::REC_CLOT:
readReferenceCollection<ESM::ObjectState> (reader, mClothes, cref, contentFileMap);
break;
case ESM::REC_CONT:
readReferenceCollection<ESM::ContainerState> (reader, mContainers, cref, contentFileMap);
break;
case ESM::REC_CREA:
readReferenceCollection<ESM::CreatureState> (reader, mCreatures, cref, contentFileMap);
break;
case ESM::REC_DOOR:
readReferenceCollection<ESM::DoorState> (reader, mDoors, cref, contentFileMap);
break;
case ESM::REC_INGR:
readReferenceCollection<ESM::ObjectState> (reader, mIngreds, cref, contentFileMap);
break;
case ESM::REC_LEVC:
readReferenceCollection<ESM::CreatureLevListState> (reader, mCreatureLists, cref, contentFileMap);
break;
case ESM::REC_LEVI:
readReferenceCollection<ESM::ObjectState> (reader, mItemLists, cref, contentFileMap);
break;
case ESM::REC_LIGH:
readReferenceCollection<ESM::ObjectState> (reader, mLights, cref, contentFileMap);
break;
case ESM::REC_LOCK:
readReferenceCollection<ESM::ObjectState> (reader, mLockpicks, cref, contentFileMap);
break;
case ESM::REC_MISC:
readReferenceCollection<ESM::ObjectState> (reader, mMiscItems, cref, contentFileMap);
break;
case ESM::REC_NPC_:
//.........这里部分代码省略.........
示例10: load
void PCDT::load(ESM::ESMReader &esm)
{
while (esm.isNextSub("DNAM"))
{
mKnownDialogueTopics.push_back(esm.getHString());
}
mHasMark = false;
if (esm.isNextSub("MNAM"))
{
mHasMark = true;
mMNAM = esm.getHString();
}
esm.getHNT(mPNAM, "PNAM");
if (esm.isNextSub("SNAM"))
esm.skipHSub();
if (esm.isNextSub("NAM9"))
esm.skipHSub();
// Rest state. You shouldn't even be able to save during rest, but skip just in case.
if (esm.isNextSub("RNAM"))
/*
int hoursLeft;
float x, y, z; // resting position
*/
esm.skipHSub(); // 16 bytes
mBounty = 0;
esm.getHNOT(mBounty, "CNAM");
mBirthsign = esm.getHNOString("BNAM");
// Holds the names of the last used Alchemy apparatus. Don't need to import this ATM,
// because our GUI auto-selects the best apparatus.
if (esm.isNextSub("NAM0"))
esm.skipHSub();
if (esm.isNextSub("NAM1"))
esm.skipHSub();
if (esm.isNextSub("NAM2"))
esm.skipHSub();
if (esm.isNextSub("NAM3"))
esm.skipHSub();
mHasENAM = false;
if (esm.isNextSub("ENAM"))
{
mHasENAM = true;
esm.getHT(mENAM);
}
if (esm.isNextSub("LNAM"))
esm.skipHSub();
while (esm.isNextSub("FNAM"))
{
FNAM fnam;
esm.getHT(fnam);
mFactions.push_back(fnam);
}
mHasAADT = false;
if (esm.isNextSub("AADT")) // Attack animation data?
{
mHasAADT = true;
esm.getHT(mAADT);
}
if (esm.isNextSub("KNAM"))
esm.skipHSub(); // assigned Quick Keys, I think
if (esm.isNextSub("ANIS"))
esm.skipHSub(); // 16 bytes
if (esm.isNextSub("WERE"))
{
// some werewolf data, 152 bytes
// maybe current skills and attributes for werewolf form
esm.getSubHeader();
esm.skip(152);
}
}
示例11: load
void ActorData::load(ESM::ESMReader &esm)
{
if (esm.isNextSub("ACTN"))
esm.skipHSub();
if (esm.isNextSub("STPR"))
esm.skipHSub();
if (esm.isNextSub("MNAM"))
esm.skipHSub();
ESM::CellRef::loadData(esm);
// FIXME: not all actors have this, add flag
esm.getHNOT(mACDT, "ACDT");
ACSC acsc;
esm.getHNOT(acsc, "ACSC");
esm.getHNOT(acsc, "ACSL");
if (esm.isNextSub("CSTN"))
esm.skipHSub(); // "PlayerSaveGame", link to some object?
if (esm.isNextSub("LSTN"))
esm.skipHSub(); // "PlayerSaveGame", link to some object?
// unsure at which point between LSTN and TGTN
if (esm.isNextSub("CSHN"))
esm.skipHSub(); // "PlayerSaveGame", link to some object?
// unsure if before or after CSTN/LSTN
if (esm.isNextSub("LSHN"))
esm.skipHSub(); // "PlayerSaveGame", link to some object?
while (esm.isNextSub("TGTN"))
esm.skipHSub(); // "PlayerSaveGame", link to some object?
while (esm.isNextSub("FGTN"))
esm.getHString(); // fight target?
// unsure at which point between TGTN and CRED
if (esm.isNextSub("AADT"))
{
// occured when a creature was in the middle of its attack, 44 bytes
esm.skipHSub();
}
// unsure at which point between FGTN and CHRD
if (esm.isNextSub("PWPC"))
esm.skipHSub();
if (esm.isNextSub("PWPS"))
esm.skipHSub();
// unsure at which point between LSTN and CHRD
if (esm.isNextSub("APUD"))
esm.skipHSub(); // 40 bytes, starts with string "ancestor guardian". maybe spellcasting in progress?
if (esm.isNextSub("WNAM"))
{
std::string id = esm.getHString();
if (esm.isNextSub("XNAM"))
mSelectedEnchantItem = esm.getHString();
else
mSelectedSpell = id;
if (esm.isNextSub("YNAM"))
esm.skipHSub(); // 4 byte, 0
}
// FIXME: not all actors have this, add flag
if (esm.isNextSub("CHRD")) // npc only
esm.getHExact(mSkills, 27*2*sizeof(int));
if (esm.isNextSub("CRED")) // creature only
esm.getHExact(mCombatStats, 3*2*sizeof(int));
mSCRI.load(esm);
if (esm.isNextSub("ND3D"))
esm.skipHSub();
if (esm.isNextSub("ANIS"))
esm.skipHSub();
}
示例12: load
void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener)
{
listener->setProgressRange(1000);
std::set<std::string> missing;
ESM::Dialogue *dialogue = 0;
/// \todo Move this to somewhere else. ESMReader?
// Cache parent esX files by tracking their indices in the global list of
// all files/readers used by the engine. This will greaty accelerate
// refnumber mangling, as required for handling moved references.
int index = ~0;
const std::vector<ESM::Header::MasterData> &masters = esm.getGameFiles();
std::vector<ESM::ESMReader> *allPlugins = esm.getGlobalReaderList();
for (size_t j = 0; j < masters.size(); j++) {
ESM::Header::MasterData &mast = const_cast<ESM::Header::MasterData&>(masters[j]);
std::string fname = mast.name;
for (int i = 0; i < esm.getIndex(); i++) {
const std::string &candidate = allPlugins->at(i).getContext().filename;
std::string fnamecandidate = boost::filesystem::path(candidate).filename().string();
if (fname == fnamecandidate) {
index = i;
break;
}
}
if (index == (int)~0) {
// Tried to load a parent file that has not been loaded yet. This is bad,
// the launcher should have taken care of this.
std::string fstring = "File " + esm.getName() + " asks for parent file " + masters[j].name
+ ", but it has not been loaded yet. Please check your load order.";
esm.fail(fstring);
}
mast.index = index;
}
// Loop through all records
while(esm.hasMoreRecs())
{
ESM::NAME n = esm.getRecName();
esm.getRecHeader();
// Look up the record type.
std::map<int, StoreBase *>::iterator it = mStores.find(n.val);
if (it == mStores.end()) {
if (n.val == ESM::REC_INFO) {
std::string id = esm.getHNOString("INAM");
if (dialogue) {
dialogue->mInfo.push_back(ESM::DialInfo());
dialogue->mInfo.back().mId = id;
dialogue->mInfo.back().load(esm);
} else {
std::cerr << "error: info record without dialog" << std::endl;
esm.skipRecord();
}
} else if (n.val == ESM::REC_MGEF) {
mMagicEffects.load (esm);
} else if (n.val == ESM::REC_SKIL) {
mSkills.load (esm);
} else {
// Not found (this would be an error later)
esm.skipRecord();
missing.insert(n.toString());
}
} else {
// Load it
std::string id = esm.getHNOString("NAME");
// ... unless it got deleted! This means that the following record
// has been deleted, and trying to load it using standard assumptions
// on the structure will (probably) fail.
if (esm.isNextSub("DELE")) {
esm.skipRecord();
it->second->eraseStatic(id);
continue;
}
it->second->load(esm, id);
if (n.val==ESM::REC_DIAL) {
dialogue = const_cast<ESM::Dialogue*>(mDialogs.find(id));
} else {
dialogue = 0;
}
// Insert the reference into the global lookup
if (!id.empty() && isCacheableRecord(n.val)) {
mIds[Misc::StringUtils::lowerCase (id)] = n.val;
}
}
listener->setProgress(esm.getFileOffset() / (float)esm.getFileSize() * 1000);
}
/* This information isn't needed on screen. But keep the code around
for debugging purposes later.
cout << "\n" << mStores.size() << " record types:\n";
for(RecListList::iterator it = mStores.begin(); it != mStores.end(); it++)
cout << " " << toStr(it->first) << ": " << it->second->getSize() << endl;
cout << "\nNot implemented yet: ";
for(set<string>::iterator it = missing.begin();
it != missing.end(); it++ )
//.........这里部分代码省略.........
示例13: load
void Inventory::load(ESM::ESMReader &esm)
{
while (esm.isNextSub("NPCO"))
{
ESM::ContItem contItem;
esm.getHT(contItem);
InventoryItem item;
item.mId = contItem.mItem.toString();
item.mCount = contItem.mCount;
item.mRelativeEquipmentSlot = -1;
unsigned int itemCount = std::abs(item.mCount);
bool separateStacks = false;
for (unsigned int i=0;i<itemCount;++i)
{
bool newStack = esm.isNextSub("XIDX");
if (newStack)
{
unsigned int idx;
esm.getHT(idx);
separateStacks = true;
item.mCount = 1;
}
item.mSCRI.load(esm);
// for XSOL and XCHG seen so far, but probably others too
bool isDeleted = false;
item.ESM::CellRef::loadData(esm, isDeleted);
int charge=-1;
esm.getHNOT(charge, "XHLT");
item.mChargeInt = charge;
if (newStack)
mItems.push_back(item);
}
if (!separateStacks)
mItems.push_back(item);
}
// equipped items
while (esm.isNextSub("WIDX"))
{
// note: same item can be equipped 2 items (e.g. 2 rings)
// and will be *stacked* in the NPCO list, unlike openmw!
// this is currently not handled properly.
esm.getSubHeader();
int itemIndex; // index of the item in the NPCO list
esm.getT(itemIndex);
if (itemIndex < 0 || itemIndex >= int(mItems.size()))
esm.fail("equipment item index out of range");
// appears to be a relative index for only the *possible* slots this item can be equipped in,
// i.e. 0 most of the time
int slotIndex;
esm.getT(slotIndex);
mItems[itemIndex].mRelativeEquipmentSlot = slotIndex;
}
}
示例14: load
void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener)
{
listener->setProgressRange(1000);
ESM::Dialogue *dialogue = 0;
/// \todo Move this to somewhere else. ESMReader?
// Cache parent esX files by tracking their indices in the global list of
// all files/readers used by the engine. This will greaty accelerate
// refnumber mangling, as required for handling moved references.
const std::vector<ESM::Header::MasterData> &masters = esm.getGameFiles();
std::vector<ESM::ESMReader> *allPlugins = esm.getGlobalReaderList();
for (size_t j = 0; j < masters.size(); j++) {
ESM::Header::MasterData &mast = const_cast<ESM::Header::MasterData&>(masters[j]);
std::string fname = mast.name;
int index = ~0;
for (int i = 0; i < esm.getIndex(); i++) {
const std::string &candidate = allPlugins->at(i).getContext().filename;
std::string fnamecandidate = boost::filesystem::path(candidate).filename().string();
if (Misc::StringUtils::ciEqual(fname, fnamecandidate)) {
index = i;
break;
}
}
if (index == (int)~0) {
// Tried to load a parent file that has not been loaded yet. This is bad,
// the launcher should have taken care of this.
std::string fstring = "File " + esm.getName() + " asks for parent file " + masters[j].name
+ ", but it has not been loaded yet. Please check your load order.";
esm.fail(fstring);
}
mast.index = index;
}
// Loop through all records
while(esm.hasMoreRecs())
{
ESM::NAME n = esm.getRecName();
esm.getRecHeader();
// Look up the record type.
std::map<int, StoreBase *>::iterator it = mStores.find(n.val);
if (it == mStores.end()) {
if (n.val == ESM::REC_INFO) {
if (dialogue)
{
dialogue->readInfo(esm, esm.getIndex() != 0);
}
else
{
std::cerr << "error: info record without dialog" << std::endl;
esm.skipRecord();
}
} else if (n.val == ESM::REC_MGEF) {
mMagicEffects.load (esm);
} else if (n.val == ESM::REC_SKIL) {
mSkills.load (esm);
}
else if (n.val==ESM::REC_FILT || ESM::REC_DBGP)
{
// ignore project file only records
esm.skipRecord();
}
else {
std::stringstream error;
error << "Unknown record: " << n.toString();
throw std::runtime_error(error.str());
}
} else {
// Load it
std::string id = esm.getHNOString("NAME");
// ... unless it got deleted! This means that the following record
// has been deleted, and trying to load it using standard assumptions
// on the structure will (probably) fail.
if (esm.isNextSub("DELE")) {
esm.skipRecord();
it->second->eraseStatic(id);
continue;
}
it->second->load(esm, id);
// DELE can also occur after the usual subrecords
if (esm.isNextSub("DELE")) {
esm.skipRecord();
it->second->eraseStatic(id);
continue;
}
if (n.val==ESM::REC_DIAL) {
dialogue = const_cast<ESM::Dialogue*>(mDialogs.find(id));
} else {
dialogue = 0;
}
// Insert the reference into the global lookup
if (!id.empty() && isCacheableRecord(n.val)) {
mIds[Misc::StringUtils::lowerCase (id)] = n.val;
}
}
listener->setProgress(esm.getFileOffset() / (float)esm.getFileSize() * 1000);
//.........这里部分代码省略.........
示例15: while
void Store<ESM::Cell>::load(ESM::ESMReader &esm, const std::string &id)
{
// Don't automatically assume that a new cell must be spawned. Multiple plugins write to the same cell,
// and we merge all this data into one Cell object. However, we can't simply search for the cell id,
// as many exterior cells do not have a name. Instead, we need to search by (x,y) coordinates - and they
// are not available until both cells have been loaded! So first, proceed as usual.
// All cells have a name record, even nameless exterior cells.
std::string idLower = Misc::StringUtils::lowerCase(id);
ESM::Cell *cell = new ESM::Cell;
cell->mName = id;
//First part of cell loading
cell->preLoad(esm);
//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.
cell->getNextRef(esm, ref);
std::string lowerCase;
std::transform (ref.mRefID.begin(), ref.mRefID.end(), std::back_inserter (lowerCase),
(int(*)(int)) std::tolower);
// 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;
}
//Second part of cell loading
cell->postLoad(esm);
if(cell->mData.mFlags & ESM::Cell::Interior)
{
// Store interior cell by name, try to merge with existing parent data.
ESM::Cell *oldcell = const_cast<ESM::Cell*>(search(idLower));
if (oldcell) {
// push the new references on the list of references to manage
oldcell->mContextList.push_back(cell->mContextList.at(0));
// copy list into new cell
cell->mContextList = oldcell->mContextList;
// have new cell replace old cell
*oldcell = *cell;
} else
mInt[idLower] = *cell;
}
else
{
// Store exterior cells by grid position, try to merge with existing parent data.
ESM::Cell *oldcell = const_cast<ESM::Cell*>(search(cell->getGridX(), cell->getGridY()));
if (oldcell) {
// push the new references on the list of references to manage
oldcell->mContextList.push_back(cell->mContextList.at(0));
// copy list into new cell
cell->mContextList = oldcell->mContextList;
// merge lists of leased references, use newer data in case of conflict
for (ESM::MovedCellRefTracker::const_iterator it = cell->mMovedRefs.begin(); it != cell->mMovedRefs.end(); it++) {
// remove reference from current leased ref tracker and add it to new cell
ESM::MovedCellRefTracker::iterator itold = std::find(oldcell->mMovedRefs.begin(), oldcell->mMovedRefs.end(), it->mRefnum);
if (itold != oldcell->mMovedRefs.end()) {
ESM::MovedCellRef target0 = *itold;
ESM::Cell *wipecell = const_cast<ESM::Cell*>(search(target0.mTarget[0], target0.mTarget[1]));
ESM::CellRefTracker::iterator it_lease = std::find(wipecell->mLeasedRefs.begin(), wipecell->mLeasedRefs.end(), it->mRefnum);
wipecell->mLeasedRefs.erase(it_lease);
*itold = *it;
}
}
cell->mMovedRefs = oldcell->mMovedRefs;
// have new cell replace old cell
*oldcell = *cell;
} else
mExt[std::make_pair(cell->mData.mX, cell->mData.mY)] = *cell;
}
delete cell;
}