mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-08 09:37:53 +00:00
112 lines
3.4 KiB
C++
112 lines
3.4 KiB
C++
#include "esmstore.hpp"
|
|
|
|
#include <set>
|
|
#include <iostream>
|
|
|
|
namespace MWWorld
|
|
{
|
|
|
|
static bool isCacheableRecord(int id)
|
|
{
|
|
if (id == ESM::REC_ACTI || id == ESM::REC_ALCH || id == ESM::REC_APPA || id == ESM::REC_ARMO ||
|
|
id == ESM::REC_BOOK || id == ESM::REC_CLOT || id == ESM::REC_CONT || id == ESM::REC_CREA ||
|
|
id == ESM::REC_DOOR || id == ESM::REC_INGR || id == ESM::REC_LEVC || id == ESM::REC_LEVI ||
|
|
id == ESM::REC_LIGH || id == ESM::REC_LOCK || id == ESM::REC_MISC || id == ESM::REC_NPC_ ||
|
|
id == ESM::REC_PROB || id == ESM::REC_REPA || id == ESM::REC_STAT || id == ESM::REC_WEAP)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void ESMStore::load(ESM::ESMReader &esm)
|
|
{
|
|
std::set<std::string> missing;
|
|
|
|
ESM::Dialogue *dialogue = 0;
|
|
|
|
// 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->mInfo.push_back(ESM::DialInfo());
|
|
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");
|
|
it->second->load(esm, id);
|
|
|
|
if (n.val==ESM::REC_DIAL) {
|
|
// dirty hack, but it is better than non-const search()
|
|
// or friends
|
|
dialogue = &mDialogs.mStatic.back();
|
|
assert (dialogue->mId == id);
|
|
} else {
|
|
dialogue = 0;
|
|
}
|
|
// Insert the reference into the global lookup
|
|
if (!id.empty() && isCacheableRecord(n.val)) {
|
|
mIds[id] = n.val;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 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++ )
|
|
cout << *it << " ";
|
|
cout << endl;
|
|
*/
|
|
setUp();
|
|
}
|
|
|
|
void ESMStore::setUp()
|
|
{
|
|
std::map<int, StoreBase *>::iterator it = mStores.begin();
|
|
for (; it != mStores.end(); ++it) {
|
|
it->second->setUp();
|
|
}
|
|
mSkills.setUp();
|
|
mMagicEffects.setUp();
|
|
mAttributes.setUp();
|
|
|
|
ESM::NPC item;
|
|
item.mId = "player";
|
|
|
|
std::vector<ESM::NPC>::iterator pIt =
|
|
std::lower_bound(mNpcs.mStatic.begin(), mNpcs.mStatic.end(), item, RecordCmp());
|
|
assert(pIt != mNpcs.mStatic.end() && pIt->mId == "player");
|
|
|
|
mNpcs.insert(*pIt);
|
|
mNpcs.mStatic.erase(pIt);
|
|
}
|
|
|
|
} // end namespace
|